Four is magic: Difference between revisions

Added Easylang
(→‎{{header|UNIX Shell}}: Add implementation)
(Added Easylang)
 
(42 intermediate revisions by 23 users not shown)
Line 53:
:*   [[Number names]]
:*   [[Self-describing numbers]]
:*   [[Self-referentialSummarize and say sequence]]
:*   [[Spelling of ordinal numbers]]
:*   [[De Bruijn sequences]]
<br><br>
 
=={{header|11l}}==
{{trans|Nim}}
 
<syntaxhighlight lang="11l">V Small = [‘zero’, ‘one’, ‘two’, ‘three’, ‘four’,
‘five’, ‘six’, ‘seven’, ‘eight’, ‘nine’,
‘ten’, ‘eleven’, ‘twelve’, ‘thirteen’, ‘fourteen’,
‘fifteen’, ‘sixteen’, ‘seventeen’, ‘eighteen’, ‘nineteen’]
 
V Tens = [‘’, ‘’, ‘twenty’, ‘thirty’, ‘forty’, ‘fifty’, ‘sixty’, ‘seventy’, ‘eighty’, ‘ninety’]
 
V Illions = [‘’, ‘ thousand’, ‘ million’, ‘ billion’, ‘ trillion’, ‘ quadrillion’, ‘ quintillion’]
 
F say(Int64 =n) -> String
V result = ‘’
I n < 0
result = ‘negative ’
n = -n
 
I n < 20
result ‘’= Small[Int(n)]
 
E I n < 100
result ‘’= Tens[Int(n I/ 10)]
V m = n % 10
I m != 0
result ‘’= ‘-’Small[Int(m)]
 
E I n < 1000
result ‘’= Small[Int(n I/ 100)]‘ hundred’
V m = n % 100
I m != 0
result ‘’= ‘ ’say(m)
 
E
V sx = ‘’
V i = 0
L n > 0
V m = n % 1000
n I/= 1000
I m != 0
V ix = say(m)‘’Illions[i]
I sx.len > 0
ix ‘’= ‘ ’sx
sx = ix
i++
result ‘’= sx
 
R result
 
F fourIsMagic(=n)
V s = say(n).capitalize()
V result = s
L n != 4
n = s.len
s = say(n)
result ‘’= ‘ is ’s‘, ’s
R result‘ is magic.’
 
L(n) [Int64(0), 4, 6, 11, 13, 75, 100, 337, -164, 7FFF'FFFF'FFFF'FFFF]
print(fourIsMagic(n))</syntaxhighlight>
 
{{out}}
<pre>
Zero is four, four is magic.
Four is magic.
Six is three, three is five, five is four, four is magic.
Eleven is six, six is three, three is five, five is four, four is magic.
Thirteen is eight, eight is five, five is four, four is magic.
Seventy-five is twelve, twelve is six, six is three, three is five, five is four, four is magic.
One hundred is eleven, eleven is six, six is three, three is five, five is four, four is magic.
Three hundred thirty-seven is twenty-six, twenty-six is ten, ten is three, three is five, five is four, four is magic.
Negative one hundred sixty-four is thirty-one, thirty-one is ten, ten is three, three is five, five is four, four is magic.
Nine quintillion two hundred twenty-three quadrillion three hundred seventy-two trillion thirty-six billion eight hundred fifty-four million seven hundred seventy-five thousand eight hundred seven is one hundred ninety-six, one hundred ninety-six is twenty-two, twenty-two is ten, ten is three, three is five, five is four, four is magic.
</pre>
 
=={{header|8086 Assembly}}==
<syntaxhighlight lang="asm">puts: equ 9h ; MS-DOS syscall to print a string
cpu 8086
bits 16
org 100h
section .text
;;; Read number from the MS-DOS command line
;;; The task says numbers up to 999999 need to be
;;; supported, so we can't get away with using MUL.
mov cl,[80h] ; Is there an argument?
test cl,cl
jnz havearg
mov ah,puts ; If not, print "no input"
mov dx,errinput
int 21h
ret ; And stop.
havearg: mov si,82h ; Start of argument string
xor ch,ch ; CX = argument length
dec cx ; Minus one (space before argument)
xor ax,ax ; Accumulator starts out at 0
xor dx,dx
numloop: mov bp,ax ; DX:AX *= 10
mov di,dx
add ax,ax ; ... *2
adc dx,dx
add ax,ax ; ... *4
adc dx,dx
add ax,bp ; ... *5
adc dx,di
add ax,ax ; ... *10
adc dx,dx
mov bx,ax
lodsb ; Get digit
sub al,'0'
xor ah,ah
add ax,bx ; Add digit
adc dx,0
loop numloop ; Next digit if there is one
;;; DX:AX now contains the binary representation of
;;; the decimal input.
cmp dx,0Fh ; Check that DX:AX <= 999999
jb donum
cmp ax,4240h ; 0F4240h = 1000000
jb donum
mov ah,puts ; Otherwise, print error message
mov dx,errhigh
int 21h
ret
;;; DX:AX = current number
donum: push dx ; Keep number
push ax
mov di,numstring ; Create the string for the number
call cardinal
mov [di],byte '$'
xor [numstring],byte 32 ; Capitalize first letter
.print: mov dx,numstring ; Print the string
mov ah,puts
int 21h
mov dx,is ; print ' is ',
int 21h
pop ax ; Retrieve number
pop dx
test dx,dx ; DX:AX = 4 = magic
jnz .nomagic ; DX <> 0 = not magic
cmp ax,4 ; If AX=4 then magic
je .magic
.nomagic: sub di,numstring ; Calculate length of string
xor dx,dx ; Set DX:AX to DI
mov ax,di
push dx ; Store new number on stack
push ax
mov di,numstring ; Make string for new number
call cardinal
mov [di],byte '$'
mov dx,numstring ; Print the string
mov ah,puts
int 21h
mov dx,commaspace ; Print comma and space
int 21h
jmp .print ; Then use next number as input
.magic: mov dx,magic ; print "magic.",
mov ah,puts
int 21h
ret ; and stop
;;; Subroutine: assuming 0 <= DX:AX <= 999999, write
;;; cardinal representation at ES:DI.
cardinal: mov bp,ax
or bp,dx
jz .zero ; If it is zero, return 'Zero'
mov bp,1000 ; Otherwise, get 1000s part
div bp
test ax,ax ; Above 1000?
jz .hundreds_dx ; If not, just find hundreds
push dx ; Otherwise, save <1000s part,
call .hundreds ; get string for how many thousands,
mov si,thousand ; Then add ' thousand',
call stradd
pop dx ; Restore <1000 part,
test dx,dx ; Even thousands?
jnz .hundreds_spc ; Then add hundreds
ret ; Otherwise we're done
.hundreds_spc: mov al,' ' ; Add space betweeen thousand and rest
stosb
.hundreds_dx: mov ax,dx
.hundreds: mov bp,100 ; Get hundreds part
xor dx,dx
div bp ; AX=100s
test ax,ax ; If zero, no hundreds
jz .tens_dx
dec ax ; Otherwise, look up in singles
shl ax,1 ; table,
mov bx,ax
mov si,[single+bx]
call stradd ; Add to the output string,
mov si,hundred ; Add ' hundred',
call stradd
test dx,dx ; Is there any more?
jne .tens_spc ; If so, add tens
ret ; Otherwise we're done
.tens_spc: mov al,' ' ; Add space between 'hundred' and tens
stosb
.tens_dx: mov ax,dx ; Tens in AX (from hundreds)
.tens: aam ; AH=10s digit, AL=1s digit
test ah,ah ; If 10s digit is 0, single digit
jz .ones
cmp ah,1 ; If 10s digit is 1, teens
jz .teens
mov bl,ah ; Look up tens digit in tens table
sub bl,2
shl bl,1
xor bh,bh
mov si,[tens+bx] ; Add to the output string
call stradd
test al,al ; Ones digit left?
jne .ones_dash ; If so, add dash and ones digit
ret ; Otherwise we're done
.ones_dash: mov [di],byte '-'
inc di
.ones: mov bl,al ; Look up ones digit in ones table
dec bl
shl bl,1
xor bh,bh
mov si,[single+bx]
jmp stradd
.teens: mov bl,al ; Look up ones digit in teens table
shl bl,1
xor bh,bh
mov si,[teens+bx]
jmp stradd
.zero: mov si,zero
;;; Copy $-terminated string at DS:SI to ES:DI, except
;;; the terminator.
stradd: push ax ; Keep AX register
.loop: lodsb ; Get byte from DS:SI
cmp al,'$' ; Are we there yet?
je .out ; If so, stop
stosb ; Otherwise, store at ES:DI
jmp .loop
.out: pop ax
ret
section .data
single: dw one,two,three,four
dw five,six,seven,eight,nine
teens: dw ten,eleven,twelve,thirteen,fourteen
dw fifteen,sixteen,seventeen,eighteen,nineteen
tens: dw twenty,thirty,forty,fifty
dw sixty,seventy,eighty,ninety
zero: db 'zero$'
one: db 'one$'
two: db 'two$'
three: db 'three$'
four: db 'four$'
five: db 'five$'
six: db 'six$'
seven: db 'seven$'
eight: db 'eight$'
nine: db 'nine$'
ten: db 'ten$'
eleven: db 'eleven$'
twelve: db 'twelve$'
thirteen: db 'thirteen$'
fourteen: db 'fourteen$'
fifteen: db 'fifteen$'
sixteen: db 'sixteen$'
seventeen: db 'seventeen$'
eighteen: db 'eighteen$'
nineteen: db 'nineteen$'
twenty: db 'twenty$'
thirty: db 'thirty$'
forty: db 'forty$'
fifty: db 'fifty$'
sixty: db 'sixty$'
seventy: db 'seventy$'
eighty: db 'eighty$'
ninety: db 'ninety$'
hundred: db ' hundred$'
thousand: db ' thousand$'
is: db ' is $'
magic: db 'magic.$'
commaspace: db ', $'
errinput: db 'No input$'
errhigh: db 'Max input 999999$'
section .bss
numstring: resb 1024</syntaxhighlight>
 
{{out}}
 
<pre>C:\>magic 0
Zero is four, four is magic.
C:\>magic 1
One is three, three is five, five is four, four is magic.
C:\>magic 2
Two is three, three is five, five is four, four is magic.
C:\>magic 3
Three is five, five is four, four is magic.
C:\>magic 4
Four is magic.
C:\>magic 123
One hundred twenty-three is twenty-four, twenty-four is eleven, eleven is six, six is three, three is five, five is four, four is magic.
C:\>magic 123456
One hundred twenty-three thousand four hundred fifty-six is fifty-six, fifty-six is nine, nine is four, four is magic.
C:\>magic 999999
Nine hundred ninety-nine thousand nine-hundred ninety-nine is fifty-eight, fifty-eight is eleven, eleven is six, six is three, three is five, five is four, four is magic.</pre>
 
=={{header|APL}}==
{{works with|Dyalog APL}}
<syntaxhighlight lang="apl">magic←{
t20←'one' 'two' 'three' 'four' 'five' 'six' 'seven' 'eight' 'nine'
t20←t20,'ten' 'eleven' 'twelve' 'thirteen' 'fourteen' 'fifteen' 'sixteen'
t20←t20,'seventeen' 'eighteen' 'nineteen'
tens←'twenty' 'thirty' 'forty' 'fifty' 'sixty' 'seventy' 'eighty' 'ninety'
spell←{
⍵=0:'zero'
{
⍵=0:''
⍵<20:⍵⊃t20
⍵<100:∊tens[(⌊⍵÷10)-1],((0≠≢r)/'-'),r←∇10|⍵
⍵<1000:(∇⌊⍵÷100),' hundred',((0≠≢r)/' '),r←∇100|⍵
⍵<1e6:(∇⌊⍵÷1000),' thousand',((0≠≢r)/' '),r←∇1000|⍵
⍵<1e9:(∇⌊⍵÷1e6),' million',((0≠≢r)/' '),r←∇1e6|⍵
⍵<1e12:(∇⌊⍵÷1e9),' billion',((0≠≢r)/' '),r←∇1e9|⍵
⍵<1e15:(∇⌊⍵÷1e12),' trillion',((0≠≢r)/' '),r←∇1e12|⍵
⍵<1e18:(∇⌊⍵÷1e15),' quadrillion',((0≠≢r)/' '),r←∇1e15|⍵
⍵<1e21:(∇⌊⍵÷1e18),' quintillion',((0≠≢r)/' '),r←∇1e18|⍵
'Overflow' ⎕SIGNAL 11
}⍵
}
1(819⌶)@1⊢{
n←spell ⍵
⍵=4:n,' is magic.'
n,' is ',(spell ≢n),', ',∇≢n
}⍵
}</syntaxhighlight>
{{out}}
<pre> magic 0
Zero is four, four is magic.
magic 4
Four is magic.
magic 10
Ten is three, three is five, five is four, four is magic.
magic 1234567
One million two hundred thirty-four thousand five hundred sixty-seven is sixty-n
ine, sixty-nine is ten, ten is three, three is five, five is four, four is
magic.
magic 2*64
Eighteen quintillion four hundred forty-six quadrillion seven hundred forty-four
trillion seventy-three billion seven hundred nine million five hundred fi
fty-one thousand six hundred sixteen is one hundred ninety, one hundred ni
nety is eighteen, eighteen is eight, eight is five, five is four, four is
magic.</pre>
 
=={{header|AppleScript}}==
<syntaxhighlight lang="applescript">(* Uses a Foundation number formatter for brevity. *)
use AppleScript version "2.4" -- OS X 10.10 (Yosemite) or later
use framework "Foundation"
 
on getNumberFormatter(localeID, numberStyle)
set formatter to current application's class "NSNumberFormatter"'s new()
tell formatter to setLocale:(current application's class "NSLocale"'s localeWithLocaleIdentifier:(localeID))
tell formatter to setNumberStyle:(numberStyle)
return formatter
end getNumberFormatter
 
on join(listOfText, delimiter)
set astid to AppleScript's text item delimiters
set AppleScript's text item delimiters to delimiter
set txt to listOfText as text
set AppleScript's text item delimiters to astid
return txt
end join
 
on fourIsMagic(n)
set n to n as number
if (n is 4) then return "Four is magic."
set formatter to getNumberFormatter("en_US", current application's NSNumberFormatterSpellOutStyle)
set nName to (formatter's stringFromNumber:(n)) as text
if (nName begins with "minus") then
set nName to "Negative " & text from word 2 to -1 of nName
else -- Crude ID-based capitalisation. Good enough for English number names.
set nName to character id ((id of character 1 of nName) - 32) & text 2 thru -1 of nName
end if
set output to {}
repeat until (n is 4)
set n to (count nName)
set lenName to (formatter's stringFromNumber:(n)) as text
set end of output to nName & " is " & lenName
set nName to lenName
end repeat
set end of output to "four is magic."
return join(output, ", ")
end fourIsMagic
 
local tests, output, n
set tests to {-19, 0, 4, 25, 32, 111, 1.234565789E+9}
set output to {}
repeat with n in tests
set end of output to fourIsMagic(n)
end repeat
return join(output, linefeed)</syntaxhighlight>
 
{{output}}
<syntaxhighlight lang="applescript">"Negative nineteen is seventeen, seventeen is nine, nine is four, four is magic.
Zero is four, four is magic.
Four is magic.
Twenty-five is eleven, eleven is six, six is three, three is five, five is four, four is magic.
Thirty-two is ten, ten is three, three is five, five is four, four is magic.
One hundred eleven is eighteen, eighteen is eight, eight is five, five is four, four is magic.
One billion two hundred thirty-four million five hundred sixty-five thousand seven hundred eighty-nine is one hundred two, one hundred two is fifteen, fifteen is seven, seven is five, five is four, four is magic."</syntaxhighlight>
 
=={{header|AutoHotkey}}==
Based on [http://www.rosettacode.org/wiki/Number_names#AutoHotkey Number names]
<syntaxhighlight lang="autohotkey">Four_is_magic(num){
nubmer := num
while (num <> 4)
result .= (res := spell(num)) " is " spell(num := StrLen(res)) ", "
return PrettyNumber(nubmer) " " result "four is magic!"
}
Spell(n) { ; recursive function to spell out the name of a max 36 digit integer, after leading 0s removed
Static p1=" thousand ",p2=" million ",p3=" billion ",p4=" trillion ",p5=" quadrillion ",p6=" quintillion "
, p7=" sextillion ",p8=" septillion ",p9=" octillion ",p10=" nonillion ",p11=" decillion "
, t2="twenty",t3="thirty",t4="forty",t5="fifty",t6="sixty",t7="seventy",t8="eighty",t9="ninety"
, o0="zero",o1="one",o2="two",o3="three",o4="four",o5="five",o6="six",o7="seven",o8="eight"
, o9="nine",o10="ten",o11="eleven",o12="twelve",o13="thirteen",o14="fourteen",o15="fifteen"
, o16="sixteen",o17="seventeen",o18="eighteen",o19="nineteen"
If (11 < d := (StrLen(n)-1)//3) ; #of digit groups of 3
Return "Number too big"
If (d) ; more than 3 digits
Return Spell(SubStr(n,1,-3*d)) p%d% ((s:=SubStr(n,1-3*d)) ? ", " Spell(s) : "")
i := SubStr(n,1,1)
If (n > 99) ; 3 digits
Return o%i% " hundred" ((s:=SubStr(n,2)) ? " " Spell(s) : "")
If (n > 19) ; n = 20..99
Return t%i% ((o:=SubStr(n,2)) ? "-" o%o% : "")
Return o%n% ; n = 0..19
}
PrettyNumber(n) { ; inserts thousands separators into a number string
Return RegExReplace(n, "\B(?=((\d{3})+$))", ",")
}</syntaxhighlight>
Examples:<syntaxhighlight lang="autohotkey">for i, num in StrSplit("7,54,235,8463,95723,485723,5472539,15750268,853956201,2736452849,94837286837,636478294710", ",")
result .= Four_is_magic(num) "`n"
MsgBox % result</syntaxhighlight>
Outputs:<pre>7 seven is five, five is four, four is magic!
54 fifty-four is ten, ten is three, three is five, five is four, four is magic!
235 two hundred thirty-five is twenty-three, twenty-three is twelve, twelve is six, six is three, three is five, five is four, four is magic!
8,463 eight thousand , four hundred sixty-three is forty-one, forty-one is nine, nine is four, four is magic!
95,723 ninety-five thousand , seven hundred twenty-three is forty-nine, forty-nine is ten, ten is three, three is five, five is four, four is magic!
485,723 four hundred eighty-five thousand , seven hundred twenty-three is sixty-two, sixty-two is nine, nine is four, four is magic!
5,472,539 five million , four hundred seventy-two thousand , five hundred thirty-nine is seventy-five, seventy-five is twelve, twelve is six, six is three, three is five, five is four, four is magic!
15,750,268 fifteen million , seven hundred fifty thousand , two hundred sixty-eight is seventy-two, seventy-two is eleven, eleven is six, six is three, three is five, five is four, four is magic!
853,956,201 eight hundred fifty-three million , nine hundred fifty-six thousand , two hundred one is eighty-five, eighty-five is eleven, eleven is six, six is three, three is five, five is four, four is magic!
2,736,452,849 two billion , seven hundred thirty-six million , four hundred fifty-two thousand , eight hundred forty-nine is one hundred seven, one hundred seven is seventeen, seventeen is nine, nine is four, four is magic!
94,837,286,837 ninety-four billion , eight hundred thirty-seven million , two hundred eighty-six thousand , eight hundred thirty-seven is one hundred nineteen, one hundred nineteen is twenty, twenty is six, six is three, three is five, five is four, four is magic!
636,478,294,710 six hundred thirty-six billion , four hundred seventy-eight million , two hundred ninety-four thousand , seven hundred ten is one hundred twenty-two, one hundred twenty-two is twenty-two, twenty-two is ten, ten is three, three is five, five is four, four is magic!</pre>
 
=={{header|AWK}}==
<syntaxhighlight lang="awk">
<lang AWK>
# syntax: GAWK -f FOUR_IS_MAGIC.AWK
BEGIN {
Line 121 ⟶ 577:
split("ten twenty thirty forty fifty sixty seventy eighty ninety",tens," ")
}
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 145 ⟶ 601:
=={{header|C}}==
{{libheader|GLib}}
<langsyntaxhighlight lang="c">#include <stdint.h>
#include <stdio.h>
#include <glib.h>
Line 242 ⟶ 698:
test_magic(10344658531277200972ULL);
return 0;
}</langsyntaxhighlight>
 
{{out}}
Line 260 ⟶ 716:
=={{header|C++}}==
Negative numbers are not supported.
<langsyntaxhighlight lang="cpp">#include <iostream>
#include <string>
#include <cctype>
Line 365 ⟶ 821:
test_magic(10344658531277200972ULL);
return 0;
}</langsyntaxhighlight>
 
{{out}}
Line 380 ⟶ 836:
Ten quintillion three hundred forty-four quadrillion six hundred fifty-eight trillion five hundred thirty-one billion two hundred seventy-seven million two hundred thousand nine hundred seventy-two is one hundred ninety-seven, one hundred ninety-seven is twenty-four, twenty-four is eleven, eleven is six, six is three, three is five, five is four, four is magic.
</pre>
 
=={{header|Clojure}}==
{{trans|UNIX Shell}}
<syntaxhighlight lang="clojure">(require '[clojure.edn :as edn])
(def names { 0 "zero" 1 "one" 2 "two" 3 "three" 4 "four" 5 "five"
6 "six" 7 "seven" 8 "eight" 9 "nine" 10 "ten" 11 "eleven"
12 "twelve" 13 "thirteen" 14 "fourteen" 15 "fifteen"
16 "sixteen" 17 "seventeen" 18 "eighteen" 19 "nineteen"
20 "twenty" 30 "thirty" 40 "forty" 50 "fifty" 60 "sixty"
70 "seventy" 80 "eighty" 90 "ninety" 100 "hundred"
 
1000 "thousand" 1000000 "million" 1000000000 "billion"
1000000000000 "trillion" 1000000000000000 "quadrillion"
1000000000000000000 "quintillion" })
 
(def powers-of-10 (reverse (sort (filter #(clojure.string/ends-with? (str %) "00") (keys names)))))
 
(defn name-of [n]
(let [p (first (filter #(>= n %) powers-of-10))]
(cond
(not (nil? p))
(let [quotient (quot n p)
remainder (rem n p)]
(str (name-of quotient) " " (names p) (if (> remainder 0) (str " " (name-of remainder)))))
 
(and (nil? p) (> n 20))
(let [remainder (rem n 10)
tens (- n remainder)]
(str (names tens) (if (> remainder 0) (str " " (name-of remainder)))))
 
true
(names n))))
 
(defn four-is-magic
([n] (four-is-magic n ""))
([n prefix]
(let [name ((if (empty? prefix) clojure.string/capitalize identity) (name-of n))
new-prefix (str prefix (if (not (empty? prefix)) ", "))]
(if (= n 4)
(str new-prefix name " is magic.")
(let [len (count name)]
(four-is-magic len (str new-prefix name " is " (name-of len))))))))
 
(defn report [n]
(println (str n ": " (four-is-magic n))))
 
(defn -main [& args]
(doall (map (comp report edn/read-string) args)))
 
 
(if (not= "repl" *command-line-args*)
(apply -main *command-line-args*))
</syntaxhighlight>
 
{{Out}}
 
<pre>$ clj four-is-magic.clj 3252003274489856000 1114111 42 23 {0..9}
3252003274489856000: Three quintillion two hundred fifty two quadrillion three trillion two hundred seventy four billion four hundred eighty nine million eight hundred fifty six thousand is one hundred sixty five, one hundred sixty five is twenty two, twenty two is ten, ten is three, three is five, five is four, four is magic.
1114111: One million one hundred fourteen thousand one hundred eleven is sixty, sixty is five, five is four, four is magic.
42: Forty two is nine, nine is four, four is magic.
23: Twenty three is twelve, twelve is six, six is three, three is five, five is four, four is magic.
0: Zero is four, four is magic.
1: One is three, three is five, five is four, four is magic.
2: Two is three, three is five, five is four, four is magic.
3: Three is five, five is four, four is magic.
4: Four is magic.
5: Five is four, four is magic.
6: Six is three, three is five, five is four, four is magic.
7: Seven is five, five is four, four is magic.
8: Eight is five, five is four, four is magic.
9: Nine is four, four is magic.</pre>
 
=={{header|Common Lisp}}==
<langsyntaxhighlight Lisplang="lisp">(defun integer-to-text (int)
(format nil "~@(~A~)" (with-output-to-string (out)
(loop for n = int then (length c)
Line 388 ⟶ 915:
while (/= n 4)
do (format out "~A is ~R, " c (length c))
finally (format out "four is magic.")))))</langsyntaxhighlight>
 
{{out}}
<pre>
"One thousand twenty-four is twenty-four, twenty-four is eleven, eleven is six, six is three, three is five, five is four, four is magic."
</pre>
 
=={{header|Delphi}}==
{{libheader| System.SysUtils}}
<syntaxhighlight lang="delphi">
program Four_is_magic;
 
{$APPTYPE CONSOLE}
 
uses
System.SysUtils;
 
// https://rosettacode.org/wiki/Number_names#Delphi
const
smallies: array[1..19] of string = ('one', 'two', 'three', 'four', 'five',
'six', 'seven', 'eight', 'nine', 'ten', 'eleven', 'twelve', 'thirteen',
'fourteen', 'fifteen', 'sixteen', 'seventeen', 'eighteen', 'nineteen');
tens: array[2..9] of string = ('twenty', 'thirty', 'forty', 'fifty', 'sixty',
'seventy', 'eighty', 'ninety');
 
function domaxies(number: int64): string;
const
maxies: array[0..5] of string = (' thousand', ' million', ' billion',
' trillion', ' quadrillion', ' quintillion');
begin
domaxies := '';
if number >= 0 then
domaxies := maxies[number];
end;
 
function doHundreds(number: int64): string;
begin
Result := '';
if number > 99 then
begin
Result := smallies[number div 100];
Result := Result + ' hundred';
number := number mod 100;
if number > 0 then
Result := Result + ' and ';
end;
if number >= 20 then
begin
Result := Result + tens[number div 10];
number := number mod 10;
if number > 0 then
Result := Result + '-';
end;
if (0 < number) and (number < 20) then
Result := Result + smallies[number];
end;
 
function spell(number: int64): string;
var
scaleFactor: int64;
maxieStart, h: int64;
begin
if number = 0 then
exit('zero');
 
scaleFactor := 1000000000000000000;
Result := '';
if number < 0 then
begin
number := -number;
Result := 'negative ';
end;
 
maxieStart := 5;
if number < 20 then
exit(smallies[number]);
while scaleFactor > 0 do
begin
if number > scaleFactor then
begin
h := number div scaleFactor;
Result := Result + doHundreds(h) + domaxies(maxieStart);
number := number mod scaleFactor;
if number > 0 then
Result := Result + ', ';
end;
scaleFactor := scaleFactor div 1000;
dec(maxieStart);
end;
end;
//****************************************************\\
 
const
numbers: array of Int64 = [0, 4, 6, 11, 13, 75, 100, 337, -164, int64.MaxValue];
 
function fourIsMagic(n: int64): string;
var
s: string;
begin
s := spell(n);
s[1] := upcase(s[1]);
var t := s;
 
while n <> 4 do
begin
n := s.Length;
s := spell(n);
t := t + ' is ' + s + ', ' + s;
end;
t := t + ' is magic.';
exit(t);
end;
 
begin
// writeln(spell(4));
for var n in numbers do
writeln(fourIsMagic(n));
readln;
end.</syntaxhighlight>
{{out}}
<pre>Zero is four, four is magic.
Four is magic.
Six is three, three is five, five is four, four is magic.
Eleven is six, six is three, three is five, five is four, four is magic.
Thirteen is eight, eight is five, five is four, four is magic.
Seventy-five is twelve, twelve is six, six is three, three is five, five is four, four is magic.
One hundred is eleven, eleven is six, six is three, three is five, five is four, four is magic.
Three hundred and thirty-seven is thirty, thirty is six, six is three, three is five, five is four, four is magic.
Negative one hundred and sixty-four is thirty-five, thirty-five is eleven, eleven is six, six is three, three is five, five is four, four is magic.
Nine quintillion, two hundred and twenty-three quadrillion, three hundred and seventy-two trillion, thirty-six billion, eight hundred and fifty-four million, seven hundred and seventy-five thousand, eight hundred and seven is two hundred and twenty-two, two hundred and twenty-two is twenty-six, twenty-six is ten, ten is three, three is five, five is four, four is magic.</pre>
 
=={{header|EasyLang}}==
{{trans|Go}}
<syntaxhighlight>
small$[] = [ "zero" "one" "two" "three" "four" "five" "six" "seven" "eight" "nine" "ten" "eleven" "twelve" "thirteen" "fourteen" "fifteen" "sixteen" "seventeen" "eighteen" "nineteen" ]
tens$[] = [ "" "" "twenty" "thirty" "forty" "fifty" "sixty" "seventy" "eighty" "ninety" ]
illions$[] = [ "" " thousand" " million" " billion" " trillion" " quadrillion" " quintillion" ]
func$ say n .
if n < 0
t$ = "negative "
n = -n
.
if n < 20
t$ &= small$[n + 1]
elif n < 100
t$ &= tens$[n div 10 + 1]
s = n mod 10
if s > 0
t$ &= "-" & small$[s + 1]
.
elif n < 1000
t$ &= small$[n div 100 + 1] & " hundred"
s = n mod 100
if s > 0
t$ &= " " & say s
.
else
i = 1
while n > 0
p = n mod 1000
n = n div 1000
if p > 0
ix$ = say p & illions$[i]
if sx$ <> ""
ix$ &= " " & sx$
.
sx$ = ix$
.
i += 1
.
t$ &= sx$
.
return t$
.
#
func$ toupper c$ .
c = strcode c$
if c >= 97 and c <= 122
c$ = strchar (c - 32)
.
return c$
.
func$ four_is_magic n .
s$ = say n
s$ = toupper substr s$ 1 1 & substr s$ 2 99999
t$ = s$
while n <> 4
n = len s$
s$ = say n
t$ &= " is " & s$ & ", " & s$
.
t$ &= " is magic."
return t$
.
for n in [ 6 13 75 111 337 99999999 ]
print four_is_magic n
.
</syntaxhighlight>
{{out}}
<pre>
Six is three, three is five, five is four, four is magic.
Thirteen is eight, eight is five, five is four, four is magic.
Seventy-five is twelve, twelve is six, six is three, three is five, five is four, four is magic.
One hundred eleven is eighteen, eighteen is eight, eight is five, five is four, four is magic.
Three hundred thirty-seven is twenty-six, twenty-six is ten, ten is three, three is five, five is four, four is magic.
Ninety-nine million nine hundred ninety-nine thousand nine hundred ninety-nine is seventy-eight, seventy-eight is thirteen, thirteen is eight, eight is five, five is four, four is magic.
</pre>
 
=={{header|F_Sharp|F#}}==
===The Function===
<langsyntaxhighlight lang="fsharp">
//Express an Integer in English Language. Nigel Galloway: September 19th., 2018
let fN=[|[|"";"one";"two";"three";"four";"five";"six";"seven";"eight";"nine"|];
Line 406 ⟶ 1,134:
|α when α<1000 ->I2α (α-(α/100)*100) (β+fN.[0].[α/100]+" hunred"+if α%100>0 then " and " else "")
|α when α<1000000->I2α (α%1000) (β+(I2α (α/1000) "")+" thousand"+if α%100=0 then "" else if (α-(α/1000)*1000)<100 then " and " else " ")
</syntaxhighlight>
</lang>
===The Task===
<langsyntaxhighlight lang="fsharp">
let rec printI2α=function |0->printf "naught->"; printI2α 6
|4->printfn "four is magic"
Line 415 ⟶ 1,143:
let N=System.Random()
List.init 25 (fun _->N.Next 999999) |> List.iter printI2α
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 454 ⟶ 1,182:
=={{header|Factor}}==
Factor's <code>math.text.english</code> vocabulary does most of the heavy lifting. Since <code>number>text</code> produces <tt><i>" and "</i></tt> and <tt><i>","</i></tt> in its output, they are removed with a regular expression.
<langsyntaxhighlight lang="factor">USING: ascii formatting io kernel make math.text.english regexp
sequences ;
IN: rosetta-code.four-is-magic
Line 487 ⟶ 1,215:
len-chain [ phrase ] map concat capitalize print ;
{ 1 4 -11 100 112719908181724 -612312 } [ say-magic ] each</langsyntaxhighlight>
{{out}}
<pre>
Line 497 ⟶ 1,225:
Negative six hundred twelve thousand three hundred twelve is fifty-seven, fifty-seven is eleven, eleven is six, six is three, three is five, five is four, four is magic.
</pre>
 
=={{header|Fortran}}==
<syntaxhighlight lang="fortran">MODULE FOUR_IS_MAGIC
IMPLICIT NONE
CHARACTER(8), DIMENSION(20) :: SMALL_NUMS
CHARACTER(7), DIMENSION(8) :: TENS
CHARACTER(7) :: HUNDRED
CHARACTER(8) :: THOUSAND
CHARACTER(8) :: MILLION
CHARACTER(8) :: BILLION
CHARACTER(9) :: TRILLION
CHARACTER(11) :: QUADRILLION
CHARACTER(11) :: QUINTILLION
CHARACTER(1) :: SEPARATOR
CHARACTER(1) :: SPACE
 
 
CONTAINS
 
SUBROUTINE INIT_ARRAYS
 
SMALL_NUMS(1) = "zero"
SMALL_NUMS(2) = "one"
SMALL_NUMS(3) = "two"
SMALL_NUMS(4) = "three"
SMALL_NUMS(5) = "four"
SMALL_NUMS(6) = "five"
SMALL_NUMS(7) = "six"
SMALL_NUMS(8) = "seven"
SMALL_NUMS(9) = "eight"
SMALL_NUMS(10) = "nine"
SMALL_NUMS(11) = "ten"
SMALL_NUMS(12) = "eleven"
SMALL_NUMS(13) = "twelve"
SMALL_NUMS(14) = "thirteen"
SMALL_NUMS(15) = "fourteen"
SMALL_NUMS(16) = "fifteen"
SMALL_NUMS(17) = "sixteen"
SMALL_NUMS(18) = "seventeen"
SMALL_NUMS(19) = "eighteen"
SMALL_NUMS(20) = "nineteen"
 
TENS(1) = "twenty"
TENS(2) = "thirty"
TENS(3) = "forty"
TENS(4) = "fifty"
TENS(5) = "sixty"
TENS(6) = "seventy"
TENS(7) = "eight"
TENS(8) = "ninety"
 
HUNDRED = "hundred"
THOUSAND = "thousand"
MILLION = "million"
BILLION = "billion"
TRILLION = "trillion"
QUADRILLION = "quadrillion"
QUINTILLION = "quintillion"
SEPARATOR = "-"
SPACE = " "
 
END SUBROUTINE INIT_ARRAYS
 
RECURSIVE FUNCTION STRING_REPRESENTATION(NUM) RESULT(NUM_AS_STR)
INTEGER(16), INTENT(IN) :: NUM
CHARACTER(1000) :: NUM_AS_STR
INTEGER(16), DIMENSION(9) :: COMPONENTS
 
CALL INIT_ARRAYS()
 
COMPONENTS = GET_COMPONENTS(NUM)
 
NUM_AS_STR = TRIM(ADJUSTL(GET_SUBSET(COMPONENTS(9), QUINTILLION)))
NUM_AS_STR = TRIM(NUM_AS_STR) // SPACE // TRIM(ADJUSTL(GET_SUBSET(COMPONENTS(8), QUADRILLION)))
NUM_AS_STR = TRIM(NUM_AS_STR) // SPACE // TRIM(ADJUSTL(GET_SUBSET(COMPONENTS(7), TRILLION)))
NUM_AS_STR = TRIM(NUM_AS_STR) // SPACE // TRIM(ADJUSTL(GET_SUBSET(COMPONENTS(6), BILLION)))
NUM_AS_STR = TRIM(NUM_AS_STR) // SPACE // TRIM(ADJUSTL(GET_SUBSET(COMPONENTS(5), MILLION)))
NUM_AS_STR = TRIM(NUM_AS_STR) // SPACE // TRIM(ADJUSTL(GET_SUBSET(COMPONENTS(4), THOUSAND)))
NUM_AS_STR = TRIM(NUM_AS_STR) // SPACE // TRIM(ADJUSTL(GET_SUBSET(COMPONENTS(3), HUNDRED)))
 
 
IF (COMPONENTS(2) .EQ. 1) THEN
NUM_AS_STR = TRIM(ADJUSTL(NUM_AS_STR)) // SPACE // TRIM(ADJUSTL(SMALL_NUMS(10 + COMPONENTS(1) + 1)))
ELSE
 
IF (COMPONENTS(1) .GT. 0) THEN
IF (COMPONENTS(2) .GT. 0) THEN
NUM_AS_STR = TRIM(ADJUSTL(NUM_AS_STR)) // SPACE // TRIM(ADJUSTL(TENS(COMPONENTS(2) - 1))) // SEPARATOR
NUM_AS_STR = TRIM(ADJUSTL(NUM_AS_STR)) // TRIM(ADJUSTL(SMALL_NUMS(COMPONENTS(1) + 1)))
ELSE
NUM_AS_STR = TRIM(ADJUSTL(NUM_AS_STR)) // SPACE // TRIM(ADJUSTL(SMALL_NUMS(COMPONENTS(1) + 1)))
ENDIF
ELSE IF (COMPONENTS(2) .GT. 0) THEN
NUM_AS_STR = TRIM(ADJUSTL(NUM_AS_STR)) // SPACE // TRIM(ADJUSTL(TENS(COMPONENTS(2) - 1)))
ENDIF
ENDIF
 
END FUNCTION STRING_REPRESENTATION
 
FUNCTION GET_COMPONENTS(NUM)
INTEGER(16), INTENT(IN) :: NUM
INTEGER(16), DIMENSION(9) :: GET_COMPONENTS
INTEGER(16) :: I_UNITS
INTEGER(16) :: I_TENS
INTEGER(16) :: I_HUNDREDS
INTEGER(16) :: I_THOUSANDS
INTEGER(16) :: I_MILLIONS
INTEGER(16) :: I_BILLIONS
INTEGER(16) :: I_TRILLIONS
INTEGER(16) :: I_QUADRILLIONS
INTEGER(16) :: I_QUINTILLIONS
REAL(16) DIVIDE_TEMP
 
I_UNITS = NUM
 
DIVIDE_TEMP = (I_UNITS - MOD(I_UNITS, 1000000000000000000))/1000000000000000000
I_QUINTILLIONS = FLOOR(DIVIDE_TEMP)
 
IF (I_QUINTILLIONS .NE. 0) THEN
I_UNITS = I_UNITS - I_QUINTILLIONS*1000000000000000000
ENDIF
 
 
DIVIDE_TEMP = (I_UNITS - MOD(I_UNITS, 1000000000000000))/1000000000000000
I_QUADRILLIONS = FLOOR(DIVIDE_TEMP)
 
IF (I_QUADRILLIONS .NE. 0) THEN
I_UNITS = I_UNITS - I_QUADRILLIONS*1000000000000000
ENDIF
 
DIVIDE_TEMP = (I_UNITS - MOD(I_UNITS, 1000000000000))/1000000000000
I_TRILLIONS = FLOOR(DIVIDE_TEMP)
 
IF (I_TRILLIONS .NE. 0) THEN
I_UNITS = I_UNITS - I_TRILLIONS*1000000000000
ENDIF
 
DIVIDE_TEMP = (I_UNITS - MOD(I_UNITS, 1000000000))/1000000000
I_BILLIONS = FLOOR(DIVIDE_TEMP)
 
IF (I_BILLIONS .NE. 0) THEN
I_UNITS = I_UNITS - I_BILLIONS*1000000000
ENDIF
 
DIVIDE_TEMP = (I_UNITS - MOD(I_UNITS, 1000000))/1000000
I_MILLIONS = FLOOR(DIVIDE_TEMP)
 
IF (I_MILLIONS .NE. 0) THEN
I_UNITS = I_UNITS - I_MILLIONS*1000000
ENDIF
 
DIVIDE_TEMP = (I_UNITS - MOD(I_UNITS, 1000))/1000
 
I_THOUSANDS = FLOOR(DIVIDE_TEMP)
 
IF (I_THOUSANDS .NE. 0) THEN
I_UNITS = I_UNITS - I_THOUSANDS*1000
ENDIF
 
DIVIDE_TEMP = I_UNITS/1E2
I_HUNDREDS = FLOOR(DIVIDE_TEMP)
 
IF (I_HUNDREDS .NE. 0) THEN
I_UNITS = I_UNITS - I_HUNDREDS*1E2
ENDIF
 
DIVIDE_TEMP = I_UNITS/10.
I_TENS = FLOOR(DIVIDE_TEMP)
 
IF (I_TENS .NE. 0) THEN
I_UNITS = I_UNITS - I_TENS*10
ENDIF
 
GET_COMPONENTS(1) = I_UNITS
GET_COMPONENTS(2) = I_TENS
GET_COMPONENTS(3) = I_HUNDREDS
GET_COMPONENTS(4) = I_THOUSANDS
GET_COMPONENTS(5) = I_MILLIONS
GET_COMPONENTS(6) = I_BILLIONS
GET_COMPONENTS(7) = I_TRILLIONS
GET_COMPONENTS(8) = I_QUADRILLIONS
GET_COMPONENTS(9) = I_QUINTILLIONS
 
END FUNCTION GET_COMPONENTS
 
FUNCTION GET_SUBSET(COUNTER, LABEL) RESULT(OUT_STR)
CHARACTER(*), INTENT(IN) :: LABEL
INTEGER(16), INTENT(IN) :: COUNTER
CHARACTER(100) :: OUT_STR
 
OUT_STR = ""
 
IF (COUNTER .GT. 0) THEN
IF (COUNTER .LT. 20) THEN
OUT_STR = SPACE // TRIM(ADJUSTL(SMALL_NUMS(COUNTER + 1)))
ELSE
OUT_STR = SPACE // TRIM(ADJUSTL(STRING_REPRESENTATION(COUNTER)))
ENDIF
OUT_STR = TRIM(ADJUSTL(OUT_STR)) // SPACE // TRIM(LABEL)
ENDIF
 
END FUNCTION GET_SUBSET
 
 
SUBROUTINE FIND_MAGIC(NUM)
INTEGER(16), INTENT(IN) :: NUM
INTEGER(16) :: CURRENT, LEN_SIZE
CHARACTER(1000) :: CURRENT_STR, CURRENT_STR_LEN
CHARACTER(1000) :: OUT_STR
 
CURRENT = NUM
OUT_STR = ""
 
DO WHILE (CURRENT .NE. 4)
CURRENT_STR = STRING_REPRESENTATION(CURRENT)
LEN_SIZE = LEN_TRIM(ADJUSTL(CURRENT_STR))
CURRENT_STR_LEN = STRING_REPRESENTATION(LEN_SIZE)
OUT_STR = TRIM(ADJUSTL(OUT_STR)) // SPACE // TRIM(ADJUSTL(CURRENT_STR))
OUT_STR = TRIM(ADJUSTL(OUT_STR)) // " is " // TRIM(ADJUSTL(CURRENT_STR_LEN)) // ","
CURRENT = LEN_SIZE
ENDDO
 
WRITE(*,*) TRIM(ADJUSTL(OUT_STR)) // SPACE // "four is magic."
END SUBROUTINE FIND_MAGIC
 
END MODULE FOUR_IS_MAGIC
 
PROGRAM TEST_NUM_NAME
USE FOUR_IS_MAGIC
IMPLICIT NONE
 
INTEGER(2) I
INTEGER(16), DIMENSION(10) :: TEST_NUMS = (/5, 13, 78, 797, 2739, 4000, 7893, 93497412, 2673497412, 10344658531277200972/)
CHARACTER(1000) :: NUM_NAME
 
DO I=1, SIZE(TEST_NUMS)
CALL FIND_MAGIC(TEST_NUMS(I))
ENDDO
END PROGRAM
</syntaxhighlight>
<pre>
five is four, four is magic.
thirteen is eight, eight is five, five is four, four is magic.
seventy-eight is thirteen, thirteen is eight, eight is five, five is four, four is magic.
seven hundred ninety-seven is twenty-six, twenty-six is ten, ten is three, three is five, five is four, four is magic.
two thousand seven hundred thirty-nine is thirty-eight, thirty-eight is twelve, twelve is six, six is three, three is five, five is four, four is magic.
four thousand is thirteen, thirteen is eight, eight is five, five is four, four is magic.
seven thousand eight hundred ninety-three is forty-one, forty-one is nine, nine is four, four is magic.
ninety-three million four hundred ninety-seven thousand four hundred twelve is seventy-five, seventy-five is twelve, twelve is six, six is three, three is five, five is four, four is magic.
two billion six hundred seventy-three million four hundred ninety-seven thousand four hundred twelve is one hundred, one hundred is eleven, eleven is six, six is three, three is five, five is four, four is magic.
ten quintillion three hundred forty-four quadrillion six hundred fifty-eight trillion five hundred thirty-one billion two hundred seventy-seven million two hundred thousand nine hundred seventy-two is one hundred ninety-seven, one hundred ninety-seven is twenty-four, twenty-four is eleven, eleven is six, six is three, three is five, five is four, four is magic.
</pre>
 
=={{header|FreeBASIC}}==
{{trans|Phix}}
<syntaxhighlight lang="freebasic">
#define floor(x) ((x*2.0-0.5) Shr 1)
 
Dim Shared veintes(1 To 20) As String*9 => _
{"zero", "one", "two", "three", "four", "five", "six", _
"seven", "eight", "nine", "ten", "eleven", "twelve", "thirteen", _
"fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "nineteen"}
 
Dim Shared decenas(1 To 8) As String*7 => _
{"twenty", "thirty", "forty", "fifty", "sixty", "seventy", "eighty", "ninety"}
 
Type myorder
var1 As Double
var2 As String*8
End Type
Dim Shared orders(1 To 4) As myorder => _
{(10^12,"trillion"), (10^9,"billion"), (10^6,"million"), (10^3,"thousand")}
 
Function centenas(n As Integer) As String
If n < 20 Then
Return veintes((n Mod 20)+1)
Elseif (n Mod 10) = 0 Then
Return decenas((floor(n/10) Mod 10)-1)
End If
Return decenas((floor(n/10) Mod 10)-1) & "-" & veintes((n Mod 10)+1)
End Function
 
Function miles(n As Integer) As String
If n < 100 Then
Return centenas(n)
Elseif (n Mod 100) = 0 Then
Return veintes((floor(n/100) Mod 20)+1) & " centenas"
End If
Return veintes((floor(n/100) Mod 20)+1) & " centenas " & centenas(n Mod 100)
End Function
 
Function triplet(n As Integer) As String
Dim As Integer order, high, low
Dim As String nombre, res = ""
For i As Integer = 1 To Ubound(orders)
order = orders(i).var1
nombre = orders(i).var2
high = floor(n/order)
low = (n Mod order)
If high <> 0 Then res &= miles(high) & " " & nombre
n = low
If low = 0 Then Exit For : End If
If Len(res) And high <> 0 Then res &= " "
Next i
If n <> 0 Or res="" Then
res &= miles(floor(n))
End If
Return res
End Function
 
Function deletrear(n As Integer) As String
Dim As String res = ""
If n < 0 Then
res = "negative "
n = -n
End If
res &= triplet(n)
Return res
End Function
 
Function fourIsMagic(n As Integer) As String
Dim As String s = deletrear(n)
s = Mid(Ucase(s), 1, 1) & Mid(s, 2, Len(s))
Dim As String t = s
While n <> 4
n = Len(s)
s = deletrear(n)
t &= " is " & s & ", " & s
Wend
t &= " is magic."
Return t
End Function
 
Dim As Longint tests(1 To 21) = _
{-21, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 12, _
34, 123, 456, 1024, 1234, 12345, 123456, 1010101}
 
For i As Integer = 1 To Ubound(tests)
Print Using "#######: &"; tests(i); fourIsMagic(tests(i))
Next i
Sleep</syntaxhighlight>
{{out}}
<pre>
-21: Negative twenty-one is nineteen, nineteen is eight, eight is five, five is four, four is magic.
-1: Negative one is twelve, twelve is six, six is three, three is five, five is four, four is magic.
0: Zero is four, four is magic.
1: One is three, three is five, five is four, four is magic.
2: Two is three, three is five, five is four, four is magic.
3: Three is five, five is four, four is magic.
4: Four is magic.
5: Five is four, four is magic.
6: Six is three, three is five, five is four, four is magic.
7: Seven is five, five is four, four is magic.
8: Eight is five, five is four, four is magic.
9: Nine is four, four is magic.
12: Twelve is six, six is three, three is five, five is four, four is magic.
34: Thirty-four is eleven, eleven is six, six is three, three is five, five is four, four is magic.
123: One centenas twenty-three is twenty-five, twenty-five is eleven, eleven is six, six is three, three is five, five is four, four is magic.
456: Four centenas fifty-six is twenty-three, twenty-three is twelve, twelve is six, six is three, three is five, five is four, four is magic.
1024: One thousand twenty-four is twenty-four, twenty-four is eleven, eleven is six, six is three, three is five, five is four, four is magic.
1234: One thousand two centenas thirty-four is thirty-seven, thirty-seven is twelve, twelve is six, six is three, three is five, five is four, four is magic.
12345: Twelve thousand three centenas forty-five is forty-one, forty-one is nine, nine is four, four is magic.
123456: One centenas twenty-three thousand four centenas fifty-six is fifty-eight, fifty-eight is eleven, eleven is six, six is three, three is five, five is four, four is magic.
1010101: One million ten thousand one centenas one is forty-one, forty-one is nine, nine is four, four is magic.
</pre>
 
 
=={{header|FutureBasic}}==
<syntaxhighlight lang="futurebasic">
include "NSLog.incl"
 
local fn FourIsMagic( number as CFNumberRef ) as CFStringRef
CFMutableStringRef result = fn MutableStringNew
NumberFormatterRef formatter = fn NumberFormatterWithStyle( NSNumberFormatterSpellOutStyle )
NumberFormatterSetLocale( formatter, fn LocaleWithIdentifier( @"en_EN" ) )
CFStringRef numberString = fn NumberFormatterStringFromNumber( formatter, number )
MutableStringAppendString( result, fn StringCapitalizedString( numberString ) )
while ( fn StringIsEqual( numberString, @"four" ) == NO )
numberString = fn NumberFormatterStringFromNumber( formatter, fn NumberWithInteger( len(numberString) ) )
MutableStringAppendString( result, fn StringWithFormat( @" is %@, %@", numberString, numberString ) )
wend
MutableStringAppendString( result, @" is magic." )
end fn = result
 
NSInteger i
CFNumberRef testInput
CFArrayRef testNumbers : testNumbers = @[@23, @1000000000, @20140, @100, @130, @151, @-7]
 
NSLog( @"Outputs 0 through 9:\n" )
for i = 0 to 9
NSLog( @"%@", fn FourIsMagic( fn NumberWithInteger( i ) ) )
next
 
NSLog( @"\nOther number tests:\n" )
for testInput in testNumbers
NSLog( @"%@", fn FourIsMagic( testInput ) )
next
 
HandleEvents
</syntaxhighlight>
{{output}}
<pre>
Outputs 0 through 9:
 
Zero is four, four is magic.
One is three, three is five, five is four, four is magic.
Two is three, three is five, five is four, four is magic.
Three is five, five is four, four is magic.
Four is magic.
Five is four, four is magic.
Six is three, three is five, five is four, four is magic.
Seven is five, five is four, four is magic.
Eight is five, five is four, four is magic.
Nine is four, four is magic.
 
Other number tests:
 
Twenty-Three is twelve, twelve is six, six is three, three is five, five is four, four is magic.
One Billion is eleven, eleven is six, six is three, three is five, five is four, four is magic.
Twenty Thousand One Hundred Forty is thirty-three, thirty-three is twelve, twelve is six, six is three, three is five, five is four, four is magic.
One Hundred is eleven, eleven is six, six is three, three is five, five is four, four is magic.
One Hundred Thirty is eighteen, eighteen is eight, eight is five, five is four, four is magic.
One Hundred Fifty-One is twenty-one, twenty-one is ten, ten is three, three is five, five is four, four is magic.
Minus Seven is eleven, eleven is six, six is three, three is five, five is four, four is magic.
 
</pre>
 
 
=={{header|Go}}==
Uses the <code>say</code> function from the
[[Number names#Go|Number names]] task.
<langsyntaxhighlight lang="go">package main
 
import (
Line 580 ⟶ 1,739:
}
return t
}</langsyntaxhighlight>
{{out}}
<pre>
Line 593 ⟶ 1,752:
Negative one hundred sixty-four is thirty-one, thirty-one is ten, ten is three, three is five, five is four, four is magic.
Nine quintillion two hundred twenty-three quadrillion three hundred seventy-two trillion thirty-six billion eight hundred fifty-four million seven hundred seventy-five thousand eight hundred seven is one hundred ninety-six, one hundred ninety-six is twenty-two, twenty-two is ten, ten is three, three is five, five is four, four is magic.
</pre>
 
=={{header|Haskell}}==
Negative numbers are supported.
 
<syntaxhighlight lang="haskell">module Main where
 
import Data.List (find)
import Data.Char (toUpper)
 
firstNums :: [String]
firstNums =
[ "zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten",
"eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "nineteen"
]
 
tens :: [String]
tens = ["twenty", "thirty", "forty", "fifty", "sixty", "seventy", "eighty", "ninety"]
 
biggerNumbers :: [(Int, String)]
biggerNumbers =
[(100, "hundred"), (1000, "thousand"), (1000000, "million"), (1000000000, "billion"), (1000000000000, "trillion")]
 
cardinal :: Int -> String
cardinal n
| n' < 20 =
negText ++ firstNums !! n'
| n' < 100 =
negText ++ tens !! (n' `div` 10 - 2) ++ if n' `mod` 10 /= 0 then "-" ++ firstNums !! (n' `mod` 10) else ""
| otherwise =
let (num, name) =
maybe
(last biggerNumbers)
fst
(find (\((num_, _), (num_', _)) -> n' < num_') (zip biggerNumbers (tail biggerNumbers)))
smallerNum = cardinal (n' `div` num)
in negText ++ smallerNum ++ " " ++ name ++ if n' `mod` num /= 0 then " " ++ cardinal (n' `mod` num) else ""
where
n' = abs n
negText = if n < 0 then "negative " else ""
 
capitalized :: String -> String
capitalized (x : xs) = toUpper x : xs
capitalized [] = []
 
magic :: Int -> String
magic =
go True
where
go first num =
let cardiNum = cardinal num
in (if first then capitalized else id) cardiNum ++ " is "
++ if num == 4
then "magic."
else cardinal (length cardiNum) ++ ", " ++ go False (length cardiNum)
 
main :: IO ()
main = do
putStrLn $ magic 3
putStrLn $ magic 15
putStrLn $ magic 4
putStrLn $ magic 10
putStrLn $ magic 20
putStrLn $ magic (-13)
putStrLn $ magic 999999
</syntaxhighlight>
{{out}}
<pre>
Three is five, five is four, four is magic.
Fifteen is seven, seven is five, five is four, four is magic.
Four is magic.
Ten is three, three is five, five is four, four is magic.
Twenty is six, six is three, three is five, five is four, four is magic.
Negative thirteen is seventeen, seventeen is nine, nine is four, four is magic.
Nine hundred ninety-nine thousand nine hundred ninety-nine is fifty-eight, fifty-eight is eleven, eleven is six, six is three, three is
five, five is four, four is magic.
</pre>
 
=={{header|J}}==
<syntaxhighlight lang="j">
<lang J>
names =. 'one';'two';'three';'four';'five';'six';'seven';'eight';'nine';'ten';'eleven';'twelve';'thirteen';'fourteen';'fifteen';'sixteen';'seventeen';'eighteen';'nineteen'
 
Line 641 ⟶ 1,876:
doall inputs
 
</syntaxhighlight>
</lang>
{{out}}
 
Line 667 ⟶ 1,902:
 
=={{header|Java}}==
<syntaxhighlight lang="java">
<lang Java>
public class FourIsMagic {
 
Line 741 ⟶ 1,976:
 
}
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 772 ⟶ 2,007:
 
To test whether a particular JavaScript interpreter implements <code>BigInt</code>, we can evaluate a boolean expression like:
<langsyntaxhighlight lang="javascript">Object.getOwnPropertyNames(this).includes('BigInt')</langsyntaxhighlight>
 
<langsyntaxhighlight lang="javascript">const reverseOrderedNumberToTextMap = (function () {
const rawNumberToTextMapping = { // Ported over from the Python solution.
[1n]: "one",
Line 954 ⟶ 2,189:
-4,
10n ** 3003n + 42n
].map(fourIsMagic).join("\n\n");</langsyntaxhighlight>
 
{{output}}
Line 972 ⟶ 2,207:
One millinillion forty two is twenty six, twenty six is ten, ten is three, three is five, five is four, four is magic.
</pre>
 
=={{header|jq}}==
'''Adapted from [[#Wren|Wren]]'''
{{works with|jq}}
'''Also works with gojq, the Go implementation of jq'''
 
'''Also works with fq, a Go implementation of a large subset of jq'''
<syntaxhighlight lang=jq>
def small: ["zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten", "eleven",
"twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "nineteen"];
 
def tens: ["", "", "twenty", "thirty", "forty", "fifty", "sixty", "seventy", "eighty", "ninety"];
 
def illions: ["", " thousand", " million", " billion"," trillion", " quadrillion", " quintillion"];
 
def say:
{n: ., t: ""}
| if .n < 0
then .t = "negative " | .n = -.n
else . end
| if .n < 20
then .t += small[.n]
elif .n < 100
then .t += tens[(.n/10)|floor]
| .s = .n % 10
| if (.s > 0) then .t += "-" + small[.s] else . end
elif .n < 1000
then .t += small[(.n/100)|floor] + " hundred"
| .s = .n % 100
| if .s > 0 then .t += " " + (.s|say) else . end
else .sx = ""
| .i = 0
| until(.n == 0;
.p = .n % 1000
| .n = (.n / 1000 |floor)
| if (.p > 0)
then .ix = (.p|say) + illions[.i]
| if (.sx != "") then .ix += " " + .sx else . end
| .sx = .ix
else .
end
| .i += 1 )
| .t += .sx
end
| .t;
 
def capitalize:
.[:1] as $x
| ($x | ascii_upcase) as $X
| if $x == $X then . else $X + .[1:] end;
def fourIsMagic:
{n: ., s: (say | capitalize)}
| .t = .s
| until(.n == 4;
.n = (.s|length)
| .s = (.n | say)
| .t += " is " + .s + ", " + .s )
| .t + " is magic." ;
 
(0, 4, 6, 11, 13, 75, 100, 337, -164, 9007199254740991)
| fourIsMagic
</syntaxhighlight>
'''Invocation:''' jq -rn -f four-is-magic.jq
{{output}}
As for [[#Wren|Wren]].
 
=={{header|Julia}}==
<langsyntaxhighlight lang="julia"># The num2text routines are from the "Number names" task, updated for Julia 1.0
 
const stext = ["one", "two", "three", "four", "five",
Line 1,075 ⟶ 2,376:
magic(n)
end
</langsyntaxhighlight> {{output}} <pre>
Zero is four, four is magic.
Four is magic.
Line 1,089 ⟶ 2,390:
=={{header|Kotlin}}==
This uses the code I wrote for the [[Number names]] task, appropriately adjusted to deal with this task. Input is limited to '''signed''' 64 bit integers as Kotlin doesn't currently support unsigned types.
<langsyntaxhighlight lang="scala">// version 1.1.4-3
 
val names = mapOf(
Line 1,196 ⟶ 2,497:
println()
}
}</langsyntaxhighlight>
 
{{out}}
Line 1,222 ⟶ 2,523:
 
=={{header|Lua}}==
<langsyntaxhighlight lang="lua">-- Four is magic, in Lua, 6/16/2020 db
local oneslist = { [0]="", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine" }
local teenlist = { [0]="ten", "eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "nineteen" }
Line 1,265 ⟶ 2,566:
for _, num in ipairs(numbers) do
print(num, fourismagic(num))
end</langsyntaxhighlight>
{{out}}
<pre>-21 Negative twenty-one is nineteen, nineteen is eight, eight is five, five is four, four is magic.
Line 1,288 ⟶ 2,589:
123456 One hundred twenty-three thousand four hundred fifty-six is fifty-six, fifty-six is nine, nine is four, four is magic.
1010101 One million ten thousand one hundred one is forty, forty is five, five is four, four is magic.</pre>
 
=={{header|Mathematica}}/{{header|Wolfram Language}}==
 
Define a simple function which generates the output, using FixedPointList to iterate until a magic number is reached.
 
<syntaxhighlight lang="mathematica">magic[num_] := Capitalize[ StringRiffle[ Partition[
FixedPointList[IntegerName[StringLength[#], "Cardinal"] &, IntegerName[num, "Cardinal"]],
2, 1] /. {n_, n_} :> {n, "magic"}, ", ", " is "] <> "."]</syntaxhighlight>
 
Call the function a few times to show the expected output:
{{out}}
<pre>
In[1]:= magic[0]
Out[1]= "Zero is four, four is magic."
 
In[2]:= magic[1]
Out[2]= "One is three, three is five, five is four, four is magic."
 
In[3]:= magic[10]
Out[3]= "Ten is three, three is five, five is four, four is magic."
 
In[4]:= magic[999999]
Out[4]= "Nine hundred ninety-nine thousand nine hundred ninety-nine is fifty-eight, fifty-eight is eleven, eleven is six, six is three, three is five, five is four, four is magic."
 
In[5]:= magic[RandomInteger[10^6]]
Out[5]= "One hundred ninety-four thousand sixty-four is forty-three, forty-three is eleven, eleven is six, six is three, three is five, five is four, four is magic."
</pre>
 
=={{header|Nim}}==
{{trans|Go}}
<syntaxhighlight lang="nim">import strutils
 
const
 
Small = ["zero", "one", "two", "three", "four",
"five", "six", "seven", "eight", "nine",
"ten", "eleven", "twelve", "thirteen", "fourteen",
"fifteen", "sixteen", "seventeen", "eighteen", "nineteen"]
 
Tens = ["", "", "twenty", "thirty", "forty", "fifty", "sixty", "seventy", "eighty", "ninety"]
 
Illions = ["", " thousand", " million", " billion", " trillion", " quadrillion", " quintillion"]
 
#---------------------------------------------------------------------------------------------------
 
func say(n: int64): string =
 
var n = n
 
if n < 0:
result = "negative "
n = -n
 
if n < 20:
result &= Small[n]
 
elif n < 100:
result &= Tens[n div 10]
let m = n mod 10
if m != 0: result &= '-' & Small[m]
 
elif n < 1000:
result &= Small[n div 100] & " hundred"
let m = n mod 100
if m != 0: result &= ' ' & m.say()
 
else:
# Work from right to left.
var sx = ""
var i = 0
while n > 0:
let m = n mod 1000
n = n div 1000
if m != 0:
var ix = m.say() & Illions[i]
if sx.len > 0: ix &= " " & sx
sx = ix
inc i
result &= sx
 
#---------------------------------------------------------------------------------------------------
 
func fourIsMagic(n: int64): string =
var n = n
var s = n.say().capitalizeAscii()
result = s
while n != 4:
n = s.len.int64
s = n.say()
result &= " is " & s & ", " & s
result &= " is magic."
 
 
#———————————————————————————————————————————————————————————————————————————————————————————————————
 
for n in [int64 0, 4, 6, 11, 13, 75, 100, 337, -164, int64.high]:
echo fourIsMagic(n)</syntaxhighlight>
 
{{out}}
<pre>Zero is four, four is magic.
Four is magic.
Six is three, three is five, five is four, four is magic.
Eleven is six, six is three, three is five, five is four, four is magic.
Thirteen is eight, eight is five, five is four, four is magic.
Seventy-five is twelve, twelve is six, six is three, three is five, five is four, four is magic.
One hundred is eleven, eleven is six, six is three, three is five, five is four, four is magic.
Three hundred thirty-seven is twenty-six, twenty-six is ten, ten is three, three is five, five is four, four is magic.
Negative one hundred sixty-four is thirty-one, thirty-one is ten, ten is three, three is five, five is four, four is magic.
Nine quintillion two hundred twenty-three quadrillion three hundred seventy-two trillion thirty-six billion eight hundred fifty-four million seven hundred seventy-five thousand eight hundred seven is one hundred ninety-six, one hundred ninety-six is twenty-two, twenty-two is ten, ten is three, three is five, five is four, four is magic.</pre>
 
=={{header|Perl}}==
{{trans|Raku}}
<langsyntaxhighlight lang="perl">use Lingua::EN::Numbers qw(num2en);
 
sub cardinal {
Line 1,315 ⟶ 2,725:
}
 
print magic($_) for 0, 4, 6, 11, 13, 75, 337, -164, 9_876_543_209;</langsyntaxhighlight>
{{out}}
<pre>Zero is four, four is magic.
Line 1,328 ⟶ 2,738:
 
=={{header|Phix}}==
Note that on 32-bit Phix integers/atoms are only accurate to 9,007,199,254,740,992 (a hardware limit of 64-bit floating point registers) and on 64-bit the limit is 18,446,744,073,709,551,616 (ditto 80-bit floating points) so if you need more than that this will need to be reworked to use bigatomsgmp or similar.
<!--<syntaxhighlight lang="phix">(phixonline)-->
<lang Phix>--<adapted from demo\rosetta\number_names.exw, which alas outputs ",", "and", uses "minus" instead of "negative", etc...>
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
constant twenties = {"zero","one","two","three","four","five","six","seven","eight","nine","ten",
<span style="color: #000080;font-style:italic;">--&lt;adapted from demo\rosetta\number_names.exw, which alas outputs ",", "and", uses "minus" instead of "negative", etc...&gt;</span>
"eleven","twelve","thirteen","fourteen","fifteen","sixteen","seventeen","eighteen","nineteen"},
<span style="color: #008080;">constant</span> <span style="color: #000000;">twenties</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #008000;">"zero"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"one"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"two"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"three"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"four"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"five"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"six"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"seven"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"eight"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"nine"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"ten"</span><span style="color: #0000FF;">,</span>
decades = {"twenty","thirty","forty","fifty","sixty","seventy","eighty","ninety"}
<span style="color: #008000;">"eleven"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"twelve"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"thirteen"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"fourteen"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"fifteen"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"sixteen"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"seventeen"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"eighteen"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"nineteen"</span><span style="color: #0000FF;">},</span>
<span style="color: #000000;">decades</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #008000;">"twenty"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"thirty"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"forty"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"fifty"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"sixty"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"seventy"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"eighty"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"ninety"</span><span style="color: #0000FF;">}</span>
function hundred(integer n)
if n<20 then
<span style="color: #008080;">function</span> <span style="color: #000000;">hundred</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">)</span>
return twenties[mod(n,20)+1]
<span style="color: #008080;">if</span> <span style="color: #000000;">n</span><span style="color: #0000FF;"><</span><span style="color: #000000;">20</span> <span style="color: #008080;">then</span>
elsif mod(n,10)=0 then
<span style="color: #008080;">return</span> <span style="color: #000000;">twenties</span><span style="color: #0000FF;">[</span><span style="color: #7060A8;">mod</span><span style="color: #0000FF;">(</span><span style="color: #000000;">n</span><span style="color: #0000FF;">,</span><span style="color: #000000;">20</span><span style="color: #0000FF;">)+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]</span>
return decades[mod(floor(n/10),10)-1]
<span style="color: #008080;">elsif</span> <span style="color: #7060A8;">mod</span><span style="color: #0000FF;">(</span><span style="color: #000000;">n</span><span style="color: #0000FF;">,</span><span style="color: #000000;">10</span><span style="color: #0000FF;">)=</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span>
end if
<span style="color: #008080;">return</span> <span style="color: #000000;">decades</span><span style="color: #0000FF;">[</span><span style="color: #7060A8;">mod</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">floor</span><span style="color: #0000FF;">(</span><span style="color: #000000;">n</span><span style="color: #0000FF;">/</span><span style="color: #000000;">10</span><span style="color: #0000FF;">),</span><span style="color: #000000;">10</span><span style="color: #0000FF;">)-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]</span>
return decades[mod(floor(n/10),10)-1] & '-' & twenties[mod(n,10)+1]
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
end function
<span style="color: #008080;">return</span> <span style="color: #000000;">decades</span><span style="color: #0000FF;">[</span><span style="color: #7060A8;">mod</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">floor</span><span style="color: #0000FF;">(</span><span style="color: #000000;">n</span><span style="color: #0000FF;">/</span><span style="color: #000000;">10</span><span style="color: #0000FF;">),</span><span style="color: #000000;">10</span><span style="color: #0000FF;">)-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">&</span> <span style="color: #008000;">'-'</span> <span style="color: #0000FF;">&</span> <span style="color: #000000;">twenties</span><span style="color: #0000FF;">[</span><span style="color: #7060A8;">mod</span><span style="color: #0000FF;">(</span><span style="color: #000000;">n</span><span style="color: #0000FF;">,</span><span style="color: #000000;">10</span><span style="color: #0000FF;">)+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
function thousand(integer n)
if n<100 then
<span style="color: #008080;">function</span> <span style="color: #000000;">thousand</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">)</span>
return hundred(n)
<span style="color: #008080;">if</span> <span style="color: #000000;">n</span><span style="color: #0000FF;"><</span><span style="color: #000000;">100</span> <span style="color: #008080;">then</span>
elsif mod(n,100)=0 then
<span style="color: #008080;">return</span> <span style="color: #000000;">hundred</span><span style="color: #0000FF;">(</span><span style="color: #000000;">n</span><span style="color: #0000FF;">)</span>
return twenties[mod(floor(n/100),20)+1]&" hundred"
<span style="color: #008080;">elsif</span> <span style="color: #7060A8;">mod</span><span style="color: #0000FF;">(</span><span style="color: #000000;">n</span><span style="color: #0000FF;">,</span><span style="color: #000000;">100</span><span style="color: #0000FF;">)=</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span>
end if
<span style="color: #008080;">return</span> <span style="color: #000000;">twenties</span><span style="color: #0000FF;">[</span><span style="color: #7060A8;">mod</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">floor</span><span style="color: #0000FF;">(</span><span style="color: #000000;">n</span><span style="color: #0000FF;">/</span><span style="color: #000000;">100</span><span style="color: #0000FF;">),</span><span style="color: #000000;">20</span><span style="color: #0000FF;">)+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]&</span><span style="color: #008000;">" hundred"</span>
return twenties[mod(floor(n/100),20)+1] & " hundred " & hundred(mod(n,100))
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
end function
<span style="color: #008080;">return</span> <span style="color: #000000;">twenties</span><span style="color: #0000FF;">[</span><span style="color: #7060A8;">mod</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">floor</span><span style="color: #0000FF;">(</span><span style="color: #000000;">n</span><span style="color: #0000FF;">/</span><span style="color: #000000;">100</span><span style="color: #0000FF;">),</span><span style="color: #000000;">20</span><span style="color: #0000FF;">)+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">&</span> <span style="color: #008000;">" hundred "</span> <span style="color: #0000FF;">&</span> <span style="color: #000000;">hundred</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">mod</span><span style="color: #0000FF;">(</span><span style="color: #000000;">n</span><span style="color: #0000FF;">,</span><span style="color: #000000;">100</span><span style="color: #0000FF;">))</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
constant orders = {{power(10,12),"trillion"},
{power(10,9),"billion"},
<span style="color: #008080;">constant</span> <span style="color: #000000;">orders</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{{</span><span style="color: #7060A8;">power</span><span style="color: #0000FF;">(</span><span style="color: #000000;">10</span><span style="color: #0000FF;">,</span><span style="color: #000000;">12</span><span style="color: #0000FF;">),</span><span style="color: #008000;">"trillion"</span><span style="color: #0000FF;">},</span>
{power(10,6),"million"},
<span style="color: #0000FF;">{</span><span style="color: #7060A8;">power</span><span style="color: #0000FF;">(</span><span style="color: #000000;">10</span><span style="color: #0000FF;">,</span><span style="color: #000000;">9</span><span style="color: #0000FF;">),</span><span style="color: #008000;">"billion"</span><span style="color: #0000FF;">},</span>
{power(10,3),"thousand"}}
<span style="color: #0000FF;">{</span><span style="color: #7060A8;">power</span><span style="color: #0000FF;">(</span><span style="color: #000000;">10</span><span style="color: #0000FF;">,</span><span style="color: #000000;">6</span><span style="color: #0000FF;">),</span><span style="color: #008000;">"million"</span><span style="color: #0000FF;">},</span>
<span style="color: #0000FF;">{</span><span style="color: #7060A8;">power</span><span style="color: #0000FF;">(</span><span style="color: #000000;">10</span><span style="color: #0000FF;">,</span><span style="color: #000000;">3</span><span style="color: #0000FF;">),</span><span style="color: #008000;">"thousand"</span><span style="color: #0000FF;">}}</span>
function triplet(integer n)
atom order, high, low
<span style="color: #008080;">function</span> <span style="color: #000000;">triplet</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">)</span>
string name, res = ""
<span style="color: #004080;">string</span> <span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">""</span>
for i=1 to length(orders) do
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">orders</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
{order,name} = orders[i]
<span style="color: #0000FF;">{</span><span style="color: #004080;">atom</span> <span style="color: #000000;">order</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">string</span> <span style="color: #000000;">name</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">orders</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span>
high = floor(n/order)
<span style="color: #004080;">atom</span> <span style="color: #000000;">high</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">floor</span><span style="color: #0000FF;">(</span><span style="color: #000000;">n</span><span style="color: #0000FF;">/</span><span style="color: #000000;">order</span><span style="color: #0000FF;">),</span>
low = mod(n,order)
<span style="color: #000000;">low</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">mod</span><span style="color: #0000FF;">(</span><span style="color: #000000;">n</span><span style="color: #0000FF;">,</span><span style="color: #000000;">order</span><span style="color: #0000FF;">)</span>
if high!=0 then
<span style="color: #008080;">if</span> <span style="color: #000000;">high</span><span style="color: #0000FF;">!=</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span>
res &= thousand(high)&' '&name
<span style="color: #000000;">res</span> <span style="color: #0000FF;">&=</span> <span style="color: #000000;">thousand</span><span style="color: #0000FF;">(</span><span style="color: #000000;">high</span><span style="color: #0000FF;">)&</span><span style="color: #008000;">' '</span><span style="color: #0000FF;">&</span><span style="color: #000000;">name</span>
end if
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
n = low
<span style="color: #000000;">n</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">low</span>
if low=0 then exit end if
<span style="color: #008080;">if</span> <span style="color: #000000;">low</span><span style="color: #0000FF;">=</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span> <span style="color: #008080;">exit</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
if length(res) and high!=0 then
<span style="color: #008080;">if</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">res</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">and</span> <span style="color: #000000;">high</span><span style="color: #0000FF;">!=</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span>
res &= " "
<span style="color: #000000;">res</span> <span style="color: #0000FF;">&=</span> <span style="color: #008000;">" "</span>
end if
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
end for
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
if n!=0 or res="" then
<span style="color: #008080;">if</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">!=</span><span style="color: #000000;">0</span> <span style="color: #008080;">or</span> <span style="color: #000000;">res</span><span style="color: #0000FF;">=</span><span style="color: #008000;">""</span> <span style="color: #008080;">then</span>
res &= thousand(floor(n))
<span style="color: #000000;">res</span> <span style="color: #0000FF;">&=</span> <span style="color: #000000;">thousand</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">floor</span><span style="color: #0000FF;">(</span><span style="color: #000000;">n</span><span style="color: #0000FF;">))</span>
end if
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
return res
<span style="color: #008080;">return</span> <span style="color: #000000;">res</span>
end function
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
function spell(integer n)
<span style="color: #008080;">function</span> <span style="color: #000000;">spell</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">)</span>
string res = ""
<span style="color: #004080;">string</span> <span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">""</span>
if n<0 then
<span style="color: #008080;">if</span> <span style="color: #000000;">n</span><span style="color: #0000FF;"><</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span>
res = "negative "
<span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">"negative "</span>
n = -n
<span style="color: #000000;">n</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">-</span><span style="color: #000000;">n</span>
end if
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
res &= triplet(n)
<span style="color: #000000;">res</span> <span style="color: #0000FF;">&=</span> <span style="color: #000000;">triplet</span><span style="color: #0000FF;">(</span><span style="color: #000000;">n</span><span style="color: #0000FF;">)</span>
return res
<span style="color: #008080;">return</span> <span style="color: #000000;">res</span>
end function
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
--</adapted from number_names.exw>
<span style="color: #000080;font-style:italic;">--&lt;/adapted from number_names.exw&gt;</span>
 
function fourIsMagic(atom n)
<span style="color: #008080;">function</span> <span style="color: #000000;">fourIsMagic</span><span style="color: #0000FF;">(</span><span style="color: #004080;">atom</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">)</span>
string s = spell(n)
<span style="color: #004080;">string</span> <span style="color: #000000;">s</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">spell</span><span style="color: #0000FF;">(</span><span style="color: #000000;">n</span><span style="color: #0000FF;">)</span>
s[1] = upper(s[1])
<span style="color: #000000;">s</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">upper</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">])</span>
string t = s
<span style="color: #004080;">string</span> <span style="color: #000000;">t</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">s</span>
while n!=4 do
<span style="color: #008080;">while</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">!=</span><span style="color: #000000;">4</span> <span style="color: #008080;">do</span>
n = length(s)
<span style="color: #000000;">n</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s</span><span style="color: #0000FF;">)</span>
s = spell(n)
<span style="color: #000000;">s</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">spell</span><span style="color: #0000FF;">(</span><span style="color: #000000;">n</span><span style="color: #0000FF;">)</span>
t &= " is " & s & ", " & s
<span style="color: #000000;">t</span> <span style="color: #0000FF;">&=</span> <span style="color: #008000;">" is "</span> <span style="color: #0000FF;">&</span> <span style="color: #000000;">s</span> <span style="color: #0000FF;">&</span> <span style="color: #008000;">", "</span> <span style="color: #0000FF;">&</span> <span style="color: #000000;">s</span>
end while
<span style="color: #008080;">end</span> <span style="color: #008080;">while</span>
t &= " is magic.\n"
<span style="color: #000000;">t</span> <span style="color: #0000FF;">&=</span> <span style="color: #008000;">" is magic.\n"</span>
return t
<span style="color: #008080;">return</span> <span style="color: #000000;">t</span>
end function
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
 
constant tests = {-7, -1, 0, 1, 2, 3, 4, 23, 1e9, 20140, 100, 130, 151, 999999}
<span style="color: #008080;">constant</span> <span style="color: #000000;">tests</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{-</span><span style="color: #000000;">7</span><span style="color: #0000FF;">,</span> <span style="color: #0000FF;">-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">0</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">2</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">3</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">4</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">23</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1e9</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">20140</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">100</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">130</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">151</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">999999</span><span style="color: #0000FF;">}</span>
for i=1 to length(tests) do
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">tests</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
puts(1,fourIsMagic(tests[i]))
<span style="color: #7060A8;">puts</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">fourIsMagic</span><span style="color: #0000FF;">(</span><span style="color: #000000;">tests</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]))</span>
end for</lang>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<!--</syntaxhighlight>-->
{{out}}
<pre>
Line 1,428 ⟶ 2,840:
Python 3 version. Should work for integers up to at least 10^3003. It can be extended easily to arbitrary integers by adding to the numbers dict.
 
<langsyntaxhighlight lang="python">import random
from collections import OrderedDict
 
Line 1,591 ⟶ 3,003:
 
for j in (random.randint(-10 ** 24, 10 ** 24) for i in range(2)):
print(j, ':\n', magic(j), '\n')</langsyntaxhighlight>
 
{{out}}
Line 1,614 ⟶ 3,026:
874143425855745733896030 :
Eight hundred seventy four sextillion one hundred forty three quintillion four hundred twenty five quadrillion eight hundred fifty five trillion seven hundred forty five billion seven hundred thirty three million eight hundred ninety six thousand thirty is two hundred fifty three, two hundred fifty three is twenty three, twenty three is twelve, twelve is six, six is three, three is five, five is four, four is magic. </pre>
=={{header|q}}==
<syntaxhighlight lang="q">C:``one`two`three`four`five`six`seven`eight`nine`ten,
`eleven`twelve`thirteen`fourteen`fifteen`sixteen`seventeen`eighteen`nineteen / cardinal numbers <20
 
T:``ten`twenty`thirty`forty`fifty`sixty`seventy`eighty`ninety / tens
M:``thousand`million`billion`trillion`quadrillion`quintillion`sextillion`septillion / magnitudes
 
st:{ / stringify <1000
$[x<20; C x;
x<100; (T;C)@'10 vs x;
{C[y],`hundred,$[z=0;`;x z]}[.z.s] . 100 vs x] }
 
s:{$[x=0; "zero"; {" "sv string except[;`]raze x{$[x~`;x;x,y]}'M reverse til count x} st each 1000 vs x]} / stringify
 
fim:{@[;0;upper],[;"four is magic.\n"] raze 1_{y," is ",x,", "}prior s each(count s@)\[x]} / four is magic
 
1 raze fim each 0 4 8 16 25 89 365 2586 25865 369854 40000000001; / tests</syntaxhighlight>
{{out}}
<pre>Zero is four, four is magic.
Four is magic.
Eight is five, five is four, four is magic.
Sixteen is seven, seven is five, five is four, four is magic.
Twenty five is eleven, eleven is six, six is three, three is five, five is four, four is magic.
Eighty nine is eleven, eleven is six, six is three, three is five, five is four, four is magic.
Three hundred sixty five is twenty four, twenty four is eleven, eleven is six, six is three, three is five, five is four, four is magic.
Two thousand five hundred eighty six is thirty six, thirty six is ten, ten is three, three is five, five is four, four is magic.
Twenty five thousand eight hundred sixty five is forty five, forty five is ten, ten is three, three is five, five is four, four is magic.
Three hundred sixty nine thousand eight hundred fifty four is fifty eight, fifty eight is eleven, eleven is six, six is three, three is five, five is four, four is magic.
Forty billion one is seventeen, seventeen is nine, nine is four, four is magic.</pre>
'''Comment'''
 
In q the same syntax applies a function to an argument or a list to its indexes. A consequence is that, with the Converge iterator <code>\</code> the lengths alone form a finite-state machine which can generate the convergence.
<syntaxhighlight lang="q">q)show sl:count each string C / string lengths
0 3 3 5 4 4 3 5 5 4 3 6 6 8 8 7 7 9 8 8
q)sl\[18]
18 8 5 4
q)sl\[19]
19 8 5 4</syntaxhighlight>
* [https://code.kx.com/q/ref/ Language Reference]
* [https://code.kx.com/q/learn/pb/four-magic/ The Q Playbook: Four is magic – analysis]
 
=={{header|R}}==
<syntaxhighlight lang="r">
# provided by neonira
 
integerToText <- function(value_n_1) {
english_words_for_numbers <- list(
simples = c(
'zero', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine',
'ten', 'eleven', 'twelve', 'thirteen', 'fourteen', 'fifteen', 'sixteen', 'seventeen', 'eighteen', 'nineteen'
),
tens = c('twenty', 'thirty', 'forty', 'fifty', 'sixty', 'seventy', 'eighty', 'ninety'),
powers = c(
'hundred' = 100,
'thousand' = 1000,
'million' = 1000000,
'billion' = 1000000000,
'trillion' = 1000000000000,
'quadrillion' = 1000000000000000,
'quintillion' = 1000000000000000000
)
)
 
buildResult <- function(x_s) {
if (value_n_1 < 0) return(paste('minus', x_s))
x_s
}
withDash <- function(a_s, b_s) paste(a_s, b_s, sep = '-')
val <- abs(value_n_1)
if (val < 20L) return(buildResult(english_words_for_numbers$simples[val + 1L]))
if (val < 100L) {
tens <- val %/% 10L - 1L
reminder <- val %% 10L
if (reminder == 0L) return(buildResult(english_words_for_numbers$ten[tens]))
return(buildResult(withDash(english_words_for_numbers$ten[tens], Recall(reminder))))
}
 
index <- l <- length(english_words_for_numbers$powers)
for(power in seq_len(l)) {
if (val < english_words_for_numbers$powers[power]) {
index <- power - 1L
break
}
}
 
f <- Recall(val %/% english_words_for_numbers$powers[index])
reminder <- val %% english_words_for_numbers$powers[index]
if (reminder == 0L) return(buildResult(paste(f, names(english_words_for_numbers$powers)[index])))
buildResult(paste(f, names(english_words_for_numbers$powers)[index], Recall(reminder)))
}
 
magic <- function(value_n_1) {
text <- vector('character')
while(TRUE) {
r <- integerToText(value_n_1)
nc <- nchar(r)
complement <- ifelse(value_n_1 == 4L, "is magic", paste("is", integerToText(nc)))
text[length(text) + 1L] <- paste(r, complement)
if (value_n_1 == 4L) break
value_n_1 <- nc
}
 
buildSentence <- function(x_s) paste0(toupper(substr(x_s, 1L, 1L)), substring(x_s, 2L), '.')
buildSentence(paste(text, collapse = ', '))
}
 
</syntaxhighlight>
 
{{out}}
 
<pre>
0
"Zero is four, four is magic."
 
199
"One hundred ninety-nine is twenty-three, twenty-three is twelve, twelve is six, six is three, three is five, five is four, four is magic."
 
4567
"Four thousand five hundred sixty-seven is thirty-eight, thirty-eight is twelve, twelve is six, six is three, three is five, five is four, four is magic."
</pre>
 
=={{header|Racket}}==
<langsyntaxhighlight lang="racket">
#lang racket
 
Line 1,672 ⟶ 3,204:
(displayln (number-magic n))
(newline))
</syntaxhighlight>
</lang>
 
{{out}}
Line 1,814 ⟶ 3,346:
Lingua::EN::Numbers module available from the [https://modules.raku.org/search/?q=Lingua%3A%3AEN%3A%3ANumbers Raku ecosystem].
 
<syntaxhighlight lang="raku" perl6line>use Lingua::EN::Numbers; # Version 2.4.0 or higher
 
sub card ($n) { cardinal($n).subst(/','/, '', :g) }
Line 1,832 ⟶ 3,364:
}
 
.&magic.say for 0, 4, 6, 11, 13, 75, 337, -164, 9876543209, 2**256;</langsyntaxhighlight>
{{out}}
<pre style="width:98%;overflow:wrap;">Zero is four, four is magic.
Line 1,858 ⟶ 3,390:
 
Numbers are limited to 3,003 decimal digits, the maximum number that the &nbsp; '''$SPELL#''' &nbsp; REXX program will handle.
<langsyntaxhighlight lang="rexx">/*REXX pgm converts a # to English into the phrase: a is b, b is c, ... four is magic. */
numeric digits 3003 /*be able to handle gihugic numbers. */
parse arg x /*obtain optional numbers from the C.L.*/
if x='' then x= -164 0 4 6 11 13 75 100 337 9223372036854775807 /*use these defaults?*/
@.=. . /*stemmed array used for memoization. */
do j=1 for words(x) /*process each of the numbers in list. */
say 4_is( word(x, j) ) /*display phrase that'll be returned. */
Line 1,869 ⟶ 3,401:
exit /*stick a fork in it, we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
4_is: procedure expose @.; parse arg #,,$ /*obtain the start number.*/
if #\==4 then do until L==4 /*Not 4? Process number.*/
@.#= $spell#(# 'quiet minus negative') /*spell number in English.*/
#= @.#; L= length(#) /*get the length of spelt#*/
if @.L==. then @.L= $spell#(L 'quiet') /*¬spelt before? Spell it.*/
$= $ # "is" @.L',' /*add phrase to the answer*/
#=L L /*use the new number, ··· */
end /*until*/ /* ··· which will be spelt*/
$= strip($ 'four is magic.') /*finish the sentence with the finale. */
parse var $ first 2 other; upper first /*capitalize the first letter of output*/
return first || other other /*return the sentence to the invoker. */</langsyntaxhighlight>
The &nbsp; '''$SPELL#.REX''' &nbsp; routine can be found here &nbsp; ───► &nbsp; [[$SPELL.REX|$SPELL#.REX]]. <br><br>
 
Line 1,907 ⟶ 3,439:
=={{header|Ring}}==
 
<langsyntaxhighlight lang="ring">
/* Checking numbers from 0 to 10 */
for c = 0 to 10
Line 2,018 ⟶ 3,550:
Return trim(Result)
</syntaxhighlight>
</lang>
Output:
<pre>
Line 2,033 ⟶ 3,565:
Ten is three, three is five, five is four, four is magic.
</pre>
=={{header|Ruby}}==
Using a 'refinement' to the Integer class, a way to a way to extend a class locally.
 
<syntaxhighlight lang="ruby">module NumberToWord
NUMBERS = { # taken from https://en.wikipedia.org/wiki/Names_of_large_numbers#cite_ref-a_14-3
1 => 'one',
2 => 'two',
3 => 'three',
4 => 'four',
5 => 'five',
6 => 'six',
7 => 'seven',
8 => 'eight',
9 => 'nine',
10 => 'ten',
11 => 'eleven',
12 => 'twelve',
13 => 'thirteen',
14 => 'fourteen',
15 => 'fifteen',
16 => 'sixteen',
17 => 'seventeen',
18 => 'eighteen',
19 => 'nineteen',
20 => 'twenty',
30 => 'thirty',
40 => 'forty',
50 => 'fifty',
60 => 'sixty',
70 => 'seventy',
80 => 'eighty',
90 => 'ninety',
100 => 'hundred',
1000 => 'thousand',
10 ** 6 => 'million',
10 ** 9 => 'billion',
10 ** 12 => 'trillion',
10 ** 15 => 'quadrillion',
10 ** 18 => 'quintillion',
10 ** 21 => 'sextillion',
10 ** 24 => 'septillion',
10 ** 27 => 'octillion',
10 ** 30 => 'nonillion',
10 ** 33 => 'decillion'}.reverse_each.to_h
refine Integer do
def to_english
return 'zero' if i.zero?
words = self < 0 ? ['negative'] : []
i = self.abs
NUMBERS.each do |k, v|
if k <= i then
times = i/k
words << times.to_english if k >= 100
words << v
i -= times * k
end
return words.join(" ") if i.zero?
end
end
end
end
using NumberToWord
def magic4(n)
words = []
until n == 4
s = n.to_english
n = s.size
words << "#{s} is #{n.to_english}"
end
words << "four is magic."
words.join(", ").capitalize
end
[0, 4, 6, 11, 13, 75, 337, -164, 9_876_543_209].each{|n| puts magic4(n) }
</syntaxhighlight>
{{out}}<pre>Zero is four, four is magic.
Four is magic.
Six is three, three is five, five is four, four is magic.
Eleven is six, six is three, three is five, five is four, four is magic.
Thirteen is eight, eight is five, five is four, four is magic.
Seventy five is twelve, twelve is six, six is three, three is five, five is four, four is magic.
Three hundred thirty seven is twenty six, twenty six is ten, ten is three, three is five, five is four, four is magic.
Negative one hundred sixty four is thirty one, thirty one is ten, ten is three, three is five, five is four, four is magic.
Nine billion eight hundred seventy six million five hundred forty three thousand two hundred nine is ninety seven, ninety seven is twelve, twelve is six, six is three, three is five, five is four, four is magic.
</pre>
 
=={{header|Rust}}==
<langsyntaxhighlight lang="rust">fn main() {
magic(4);
magic(2_340);
Line 2,113 ⟶ 3,734:
}
return cur;
}</langsyntaxhighlight>
 
{{out}}
Line 2,134 ⟶ 3,755:
=={{header|Sidef}}==
{{trans|Perl}}
<langsyntaxhighlight lang="ruby">func cardinal(n) {
static lingua_en = frequire("Lingua::EN::Numbers")
lingua_en.num2en(n) - / and|,/g
Line 2,156 ⟶ 3,777:
[0, 4, 6, 11, 13, 75, 337, -164, 9_876_543_209].each { |n|
say four_is_magic(n)
}</langsyntaxhighlight>
{{out}}
<pre>
Line 2,170 ⟶ 3,791:
</pre>
 
=={{header|UNIX ShellSwift}}==
<syntaxhighlight lang="swift">import Foundation
{{works with|Bash|4+}}
<lang sh># Names for numbers that fit in a bash integer
declare -A names=([0]=zero [1]=one [2]=two [3]=three [4]=four [5]=five [6]=six
[7]=seven [8]=eight [9]=nine [10]=ten [11]=eleven [12]=twelve
[13]=thirteen [14]=fourteen [15]=fifteen [16]=sixteen
[17]=seventeen [18]=eighteen [19]=nineteen [20]=twenty
[30]=thirty [40]=forty [50]=fifty [60]=sixty [70]=seventy
[80]=eighty [90]=ninety [100]=hundred [1000]=thousand
[1000000]=million [1000000000]=billion [1000000000000]=trillion
[1000000000000000]=quadrillion [1000000000000000000]=quintillion)
 
func fourIsMagic(_ number: NSNumber) -> String {
# The powers of 10 above 10, in descending order
let formatter = NumberFormatter()
powers_of_10=($(printf '%s\n' "${!names[@]}" | sort -nr | grep '00$'))
formatter.numberStyle = .spellOut
formatter.locale = Locale(identifier: "en_EN")
 
var result: [String] = []
# Function to return the name of a number given in numeric form
# If the second parameter is passed in, it is appended to the name
# with a space between them; this is to facilitate tail recursion
 
var numberString = formatter.string(from: number)!
result.append(numberString.capitalized)
 
while numberString != "four" {
numberString = formatter.string(from: NSNumber(value: numberString.count))!
result.append(contentsOf: [" is ", numberString, ", ", numberString])
}
 
result.append(" is magic.")
return result.joined()
}
 
for testInput in [23, 1000000000, 20140, 100, 130, 151, -7] {
print(fourIsMagic(testInput as NSNumber))
} </syntaxhighlight>
{{out}}
<pre>
Twenty-Three is twelve, twelve is six, six is three, three is five, five is four, four is magic.
One Billion is eleven, eleven is six, six is three, three is five, five is four, four is magic.
Twenty Thousand One Hundred Forty is thirty-three, thirty-three is twelve, twelve is six, six is three, three is five, five is four, four is magic.
One Hundred is eleven, eleven is six, six is three, three is five, five is four, four is magic.
One Hundred Thirty is eighteen, eighteen is eight, eight is five, five is four, four is magic.
One Hundred Fifty-One is twenty-one, twenty-one is ten, ten is three, three is five, five is four, four is magic.
Minus Seven is eleven, eleven is six, six is three, three is five, five is four, four is magic.
</pre>
 
=={{header|UNIX Shell}}==
{{works with|Bash|4+}}
<syntaxhighlight lang="sh">#!/usr/bin/env bash
name_of() {
# return the English name for a numeric value
local -i n=$1
local suffix-i n=$21
 
if (( n < 0 )); then
# check for easy case first - exclude exact powers of 10
printf 'negative %s\n' "$(name_of $(( -n )))"
# as we'll need to stick a "one" in front of those.
if [[ $n != *00 && -n ${names[$n]} ]]; then
printf '%s%s\n' "${names[$n]}" ${suffix:+" $suffix"}
return 0
fi
 
# findNames thefor largest power of 10numbers that nfit isin smallera thanbash ninteger
local -A names=([0]=zero [1]=one [2]=two [3]=three [4]=four [5]=five
[6]=six [7]=seven [8]=eight [9]=nine [10]=ten [11]=eleven
[12]=twelve [13]=thirteen [14]=fourteen [15]=fifteen
[16]=sixteen [17]=seventeen [18]=eighteen [19]=nineteen
[20]=twenty [30]=thirty [40]=forty [50]=fifty [60]=sixty
[70]=seventy [80]=eighty [90]=ninety [100]=hundred
[1000]=thousand [1000000]=million [1000000000]=billion
[1000000000000]=trillion [1000000000000000]=quadrillion
[1000000000000000000]=quintillion)
 
# The powers of 10 above 10, in descending order
local powers_of_10=($(printf '%s\n' "${!names[@]}" | sort -nr | grep '00$'))
 
# find the largest power of 10 that is smaller than n
local -i i=0
local -i p=${powers_of_10[i]}
Line 2,216 ⟶ 3,869:
remname=$(name_of $remainder)
fi
name_ofprintf '%s %s\n' "$(name_of $quotient)" "${names[$p]}${remname:+ $remname}${suffix:+ $suffix}"
elif (( n > 20 )); then
else
# things are a little different under 100, since the multiples of
# 10 have their own names
Line 2,226 ⟶ 3,879:
remname=-$(name_of $remainder)
fi
printf '%s%s%s\n' "${names[$tens]}" "${remname}" ${suffix:+" $suffixremname}"}
else
printf '%s\n' "${names[$n]}"
fi
 
Line 2,254 ⟶ 3,909:
four_is_magic "$len" "${prefix:+$prefix, }$name is $(name_of $len)"
fi
}</langsyntaxhighlight>
 
{{Out}}
<pre>
# sadly the number of RubkRubik's cubeCube permutations won't fit into a bash int,
# but this is that value minus the first digit (40 quintillion)
$ four_is_magic 3252003274489856000
Line 2,288 ⟶ 3,943:
Eight is five, five is four, four is magic.
Nine is four, four is magic.
</pre>
 
=={{header|V (Vlang)}}==
{{trans|go}}
<syntaxhighlight lang="v (vlang)">import math
fn main() {
for n in [i64(0), 4, 6, 11, 13, 75, 100, 337, -164,
math.max_i64,
] {
println(four_is_magic(n))
}
}
fn four_is_magic(nn i64) string {
mut n := nn
mut s := say(n)
s = s[..1].to_upper() + s[1..]
mut t := s
for n != 4 {
n = i64(s.len)
s = say(n)
t += " is " + s + ", " + s
}
t += " is magic."
return t
}
const small = ["zero", "one", "two", "three", "four", "five", "six",
"seven", "eight", "nine", "ten", "eleven", "twelve", "thirteen",
"fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "nineteen"]
const tens = ["", "", "twenty", "thirty", "forty",
"fifty", "sixty", "seventy", "eighty", "ninety"]
const illions = ["", " thousand", " million", " billion",
" trillion", " quadrillion", " quintillion"]
fn say(nn i64) string {
mut t := ''
mut n := nn
if n < 0 {
t = "negative "
// Note, for math.MinInt64 this leaves n negative.
n = -n
}
match true {
n < 20 {
t += small[n]
}
n < 100 {
t += tens[n/10]
s := n % 10
if s > 0 {
t += "-" + small[s]
}
}
n < 1000 {
t += small[n/100] + " hundred"
s := n % 100
if s > 0 {
t += " " + say(s)
}
}
else {
// work right-to-left
mut sx := ""
for i := 0; n > 0; i++ {
p := n % 1000
n /= 1000
if p > 0 {
mut ix := say(p) + illions[i]
if sx != "" {
ix += " " + sx
}
sx = ix
}
}
t += sx
}
}
return t
}</syntaxhighlight>
 
{{out}}
<pre>
Zero is four, four is magic.
Four is magic.
Six is three, three is five, five is four, four is magic.
Eleven is six, six is three, three is five, five is four, four is magic.
Thirteen is eight, eight is five, five is four, four is magic.
Seventy-five is twelve, twelve is six, six is three, three is five, five is four, four is magic.
One hundred is eleven, eleven is six, six is three, three is five, five is four, four is magic.
Three hundred thirty-seven is twenty-six, twenty-six is ten, ten is three, three is five, five is four, four is magic.
Negative one hundred sixty-four is thirty-one, thirty-one is ten, ten is three, three is five, five is four, four is magic.
Nine quadrillion seven trillion one hundred ninety-nine billion two hundred fifty-four million seven hundred forty thousand nine hundred ninety-one is one hundred forty-seven, one hundred forty-seven is twenty-three, twenty-three is twelve, twelve is six, six is three, three is five, five is four, four is magic.
</pre>
 
=={{header|Wren}}==
Line 2,296 ⟶ 4,044:
 
Note that it is not safe to use this script for numbers with an absolute magnitude >= 2^53 as integers cannot be expressed exactly by Wren's Num type beyond that limit.
<langsyntaxhighlight ecmascriptlang="wren">import "./str" for Str
 
var small = ["zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten", "eleven",
Line 2,321 ⟶ 4,069:
t = t + small[(n/100).floor] + " hundred"
var s = n % 100
System.write("") // guards against VM recursion bug
if (s > 0) t = t + " " + say.call(s)
} else {
Line 2,330 ⟶ 4,077:
n = (n/1000).floor
if (p > 0) {
System.write("") // guards against VM recursion bug
var ix = say.call(p) + illions[i]
if (sx != "") ix = ix + " " + sx
Line 2,355 ⟶ 4,101:
for (n in [0, 4, 6, 11, 13, 75, 100, 337, -164, 9007199254740991]) {
System.print(fourIsMagic.call(n))
}</langsyntaxhighlight>
 
{{out}}
Line 2,377 ⟶ 4,123:
Uses the nth function from [[Spelling_of_ordinal_numbers#zkl]]
 
<langsyntaxhighlight lang="zkl">fcn fourIsMagic(int){
if(int==0) return("Zero is four, four is magic.");
string:="";
Line 2,390 ⟶ 4,136:
}
string[0].toUpper() + string[1,*]
}</langsyntaxhighlight>
<langsyntaxhighlight lang="zkl">foreach n in (T(0,4,6,11,13,75,337,-164,9876543209)){
println(fourIsMagic(n),"\n")
}</langsyntaxhighlight>
{{out}}
<pre>
1,983

edits