Four is magic: Difference between revisions

Content deleted Content added
m →‎{{header|REXX}}: added whitespace.
Markjreed (talk | contribs)
→‎{{header|UNIX Shell}}: Fix bug in name translation.
Line 3,272: Line 3,272:
=={{header|UNIX Shell}}==
=={{header|UNIX Shell}}==
{{works with|Bash|4+}}
{{works with|Bash|4+}}
<lang sh># Names for numbers that fit in a bash integer
<lang sh>#!/usr/bin/env bash
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)

# The powers of 10 above 10, in descending order
powers_of_10=($(printf '%s\n' "${!names[@]}" | sort -nr | grep '00$'))

# 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

name_of() {
name_of() {
# return the English name for a numeric value
local -i n=$1
# Names for numbers that fit in a bash integer
local suffix=$2
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
# check for easy case first - exclude exact powers of 10
local powers_of_10=($(printf '%s\n' "${!names[@]}" | sort -nr | grep '00$'))
# above 10 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


local -i n=$1
# find the largest power of 10 that is smaller than n
# find the largest power of 10 that is smaller than n
local -i i=0
local -i i=0
Line 3,309: Line 3,299:


# if we found one, split on it and construct quotient 'name' remainder
# if we found one, split on it and construct quotient 'name' remainder
# since both quotient and remainder require recursion, we can't use
# tail-recursion for both.
if (( n >= p )); then
if (( n >= p )); then
local -i quotient=n/p
local -i quotient=n/p
Line 3,318: Line 3,306:
remname=$(name_of $remainder)
remname=$(name_of $remainder)
fi
fi
name_of "$quotient" "${names[$p]}${remname:+ $remname}${suffix:+ $suffix}"
printf '%s %s\n' "$(name_of $quotient)" "${names[$p]}${remname:+ $remname}"
elif (( n > 20 )); then
else
# things are a little different under 100, since the multiples of
# things are a little different under 100, since the multiples of
# 10 have their own names
# 10 have their own names
Line 3,328: Line 3,316:
remname=-$(name_of $remainder)
remname=-$(name_of $remainder)
fi
fi
printf '%s%s%s\n' "${names[$tens]}" "${remname}" ${suffix:+" $suffix"}
printf '%s\n' "${names[$tens]}${remname:+$remname}"
else
printf '%s\n' "${names[$n]}"
fi
fi