September Morn Update

This commit is contained in:
Ingy döt Net 2019-09-12 10:33:56 -07:00
parent 4e2d22a71d
commit aac6731f2c
6856 changed files with 141342 additions and 21127 deletions

View file

@ -0,0 +1,3 @@
number_name := n -> convert(n, english)
number_name(2001);
"two thousand one"

View file

@ -2,21 +2,21 @@ Eng(n:int)={
my(tmp,s="");
if (n >= 1000000,
tmp = n\1000000;
s = Str(Eng(tmp), " million");
s = Str(s, Eng(tmp), " million");
n -= tmp * 1000000;
if (!n, return(s));
s = Str(s, " ")
);
if (n >= 1000,
tmp = n\1000;
s = Str(Eng(tmp), " thousand");
s = Str(s, Eng(tmp), " thousand");
n -= tmp * 1000;
if (!n, return(s));
s = Str(s, " ")
);
if (n >= 100,
tmp = n\100;
s = Str(Edigit(tmp), " hundred");
s = Str(s, Edigit(tmp), " hundred");
n -= tmp * 100;
if (!n, return(s));
s = Str(s, " ")

View file

@ -1,4 +1,4 @@
use Lingua::EN::Numbers::Cardinal;
use Lingua::EN::Numbers; # Version 2.4.0 or higher
put join "\n", .&cardinal, .&cardinal(:improper) with -7/4;

View file

@ -0,0 +1,71 @@
use std::io::{self, Write, stdout};
const SMALL: &[&str] = &[
"zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten",
"eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen",
"nineteen",
];
const TENS: &[&str] = &[
"PANIC", "PANIC", "twenty", "thirty", "forty", "fifty", "sixty", "seventy", "eighty", "ninety",
];
const MAGNITUDE: &[&str] = &[
"PANIC", "thousand", "million", "billion", "trillion", "quadrillion", "quintillion",
];
fn wordify<W: Write>(w: &mut W, mut number: i64) -> Result<(), io::Error> {
if number == 0 {
return write!(w, "zero");
}
if number < 0 {
write!(w, "negative ")?;
number = -number;
}
while number != 0 {
if number < 20 {
write!(w, "{}", SMALL[number as usize])?;
break;
} else if number < 100 {
write!(w, "{}", TENS[number as usize / 10])?;
number %= 10;
if number != 0 {
write!(w, "-")?;
}
} else if number < 1_000 {
write!(w, "{} hundred", SMALL[number as usize / 100])?;
number %= 100;
if number != 0 {
write!(w, " and ")?;
}
} else {
let mut top = number;
let mut magnitude = 0i64;
let mut magnitude_pow = 1i64;
while top >= 1_000 {
top /= 1_000;
magnitude += 1;
magnitude_pow *= 1_000;
}
wordify(w, top)?;
number %= magnitude_pow;
if number == 0 {
write!(w, " {}", MAGNITUDE[magnitude as usize])?;
} else if number > 100 {
write!(w, " {}, ", MAGNITUDE[magnitude as usize])?;
} else {
write!(w, " {} and ", MAGNITUDE[magnitude as usize])?;
}
}
}
Ok(())
}
fn main() {
let stdout = stdout();
let mut stdout = stdout.lock();
for &n in &[12, 1048576, 9_000_000_000_000_000_000, -2, 0, 5_000_000_000_000_000_001, -555_555_555_555] {
wordify(&mut stdout, n).unwrap();
write!(&mut stdout, "\n").unwrap();
}
}

View file

@ -0,0 +1,134 @@
extension Int {
private static let bigNames = [
1_000: "thousand",
1_000_000: "million",
1_000_000_000: "billion",
1_000_000_000_000: "trillion",
1_000_000_000_000_000: "quadrillion",
1_000_000_000_000_000_000: "quintillion"
]
private static let names = [
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"
]
public var numberName: String {
guard self != 0 else {
return "zero"
}
let neg = self < 0
let maxNeg = self == Int.min
var nn: Int
if maxNeg {
nn = -(self + 1)
} else if neg {
nn = -self
} else {
nn = self
}
var digits3 = [Int](repeating: 0, count: 7)
for i in 0..<7 {
digits3[i] = (nn % 1000)
nn /= 1000
}
func threeDigitsToText(n: Int) -> String {
guard n != 0 else {
return ""
}
var ret = ""
let hundreds = n / 100
let remainder = n % 100
if hundreds > 0 {
ret += "\(Int.names[hundreds]!) hundred"
if remainder > 0 {
ret += " "
}
}
if remainder > 0 {
let tens = remainder / 10
let units = remainder % 10
if tens > 1 {
ret += Int.names[tens * 10]!
if units > 0 {
ret += "-\(Int.names[units]!)"
}
} else {
ret += Int.names[remainder]!
}
}
return ret
}
let strings = (0..<7).map({ threeDigitsToText(n: digits3[$0]) })
var name = strings[0]
var big = 1000
for i in 1...6 {
if digits3[i] > 0 {
var name2 = "\(strings[i]) \(Int.bigNames[big]!)"
if name.count > 0 {
name2 += ", "
}
name = name2 + name
}
big &*= 1000
}
if maxNeg {
name = String(name.dropLast(5) + "eight")
}
return neg ? "minus \(name)" : name
}
}
let nums = [
0, 1, 7, 10, 18, 22, 67, 99, 100, 105, 999, -1056, 1000005000,
2074000000, 1234000000745003, Int.min
]
for number in nums {
print("\(number) => \(number.numberName)")
}

View file

@ -0,0 +1,114 @@
Public twenties As Variant
Public decades As Variant
Public orders As Variant
Private Sub init()
twenties = [{"zero","one","two","three","four","five","six","seven","eight","nine","ten", "eleven","twelve","thirteen","fourteen","fifteen","sixteen","seventeen","eighteen","nineteen"}]
decades = [{"twenty","thirty","forty","fifty","sixty","seventy","eighty","ninety"}]
orders = [{1E15,"quadrillion"; 1E12,"trillion"; 1E9,"billion"; 1E6,"million"; 1E3,"thousand"}]
End Sub
Private Function Twenty(N As Variant)
Twenty = twenties(N Mod 20 + 1)
End Function
Private Function Decade(N As Variant)
Decade = decades(N Mod 10 - 1)
End Function
Private Function Hundred(N As Variant)
If N < 20 Then
Hundred = Twenty(N)
Exit Function
Else
If N Mod 10 = 0 Then
Hundred = Decade((N \ 10) Mod 10)
Exit Function
End If
End If
Hundred = Decade(N \ 10) & "-" & Twenty(N Mod 10)
End Function
Private Function Thousand(N As Variant, withand As String)
If N < 100 Then
Thousand = withand & Hundred(N)
Exit Function
Else
If N Mod 100 = 0 Then
Thousand = withand & Twenty(WorksheetFunction.Floor_Precise(N / 100)) & " hundred"
Exit Function
End If
End If
Thousand = Twenty(N \ 100) & " hundred and " & Hundred(N Mod 100)
End Function
Private Function Triplet(N As Variant)
Dim Order, High As Variant, Low As Variant
Dim Name As String, res As String
For i = 1 To UBound(orders)
Order = orders(i, 1)
Name = orders(i, 2)
High = WorksheetFunction.Floor_Precise(N / Order)
Low = N - High * Order 'N Mod Order
If High <> 0 Then
res = res & Thousand(High, "") & " " & Name
End If
N = Low
If Low = 0 Then Exit For
If Len(res) And High <> 0 Then
res = res & ", "
End If
Next i
If N <> 0 Or res = "" Then
res = res & Thousand(WorksheetFunction.Floor_Precise(N), IIf(res = "", "", "and "))
N = N - Int(N)
If N > 0.000001 Then
res = res & " point"
For i = 1 To 10
n_ = WorksheetFunction.Floor_Precise(N * 10.0000001)
res = res & " " & twenties(n_ + 1)
N = N * 10 - n_
If Abs(N) < 0.000001 Then Exit For
Next i
End If
End If
Triplet = res
End Function
Private Function spell(N As Variant)
Dim res As String
If N < 0 Then
res = "minus "
N = -N
End If
res = res & Triplet(N)
spell = res
End Function
Private Function smartp(N As Variant)
Dim res As String
If N = WorksheetFunction.Floor_Precise(N) Then
smartp = CStr(N)
Exit Function
End If
res = CStr(N)
If InStr(1, res, ".") Then
res = Left(res, InStr(1, res, "."))
End If
smartp = res
End Function
Sub Main()
Dim si As Variant
init
Samples1 = [{99, 300, 310, 417, 1501, 12609, 200000000000100, 999999999999999, -123456787654321,102003000400005,1020030004,102003,102,1,0,-1,-99, -1501,1234,12.34}]
Samples2 = [{10000001.2,1E-3,-2.7182818, 201021002001,-20102100200,2010210020,-201021002,20102100,-2010210, 201021,-20102,2010,-201,20,-2}]
For i = 1 To UBound(Samples1)
si = Samples1(i)
Debug.Print Format(smartp(si), "@@@@@@@@@@@@@@@@"); " "; spell(si)
Next i
For i = 1 To UBound(Samples2)
si = Samples2(i)
Debug.Print Format(smartp(si), "@@@@@@@@@@@@@@@@"); " "; spell(si)
Next i
End Sub