1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
mod tests;
pub fn analyze(s: &[char]) -> Option<i64> {
match s {
['無'] => Some(0),
['下', tail @ ..] => positive(tail).map(|a| -a),
simple => positive(simple),
}
}
fn less_than_10(s: char) -> Option<i64> {
match s {
'一' => Some(1),
'二' => Some(2),
'三' => Some(3),
'四' => Some(4),
'五' => Some(5),
'六' => Some(6),
'七' => Some(7),
'八' => Some(8),
'九' => Some(9),
_ => None,
}
}
fn less_than_100(s: &[char]) -> Option<i64> {
match s {
['十'] => Some(10),
[digit] => less_than_10(*digit),
[digit, '十'] => less_than_10(*digit).map(|a| a * 10),
['十', digit] => less_than_10(*digit).map(|a| a + 10),
[digit1, '十', digit2] => {
let d1 = less_than_10(*digit1)?;
let d2 = less_than_10(*digit2)?;
Some(d1 * 10 + d2)
}
_ => None,
}
}
fn less_than_100_nun1_elided(s: &[char]) -> Option<i64> {
match s {
['十'] => Some(10),
[digit] => less_than_10(*digit),
[digit, '十'] => less_than_10(*digit).map(|a| a * 10),
['十', digit] => less_than_10(*digit).map(|a| a + 10),
[digit1, digit2] => {
let d1 = less_than_10(*digit1)?;
let d2 = less_than_10(*digit2)?;
Some(d1 * 10 + d2)
}
_ => None,
}
}
#[allow(clippy::many_single_char_names)]
fn less_than_10000_0000(input: &[char]) -> Option<i64> {
match input {
['万'] => Some(10000),
[head @ .., '万'] => less_than_10000_or_elided(head).map(|w| w * 10000),
['万', tail @ ..] => Some(10000 + less_than_10000_or_elided(tail)?),
[a, '万', tail @ ..] => {
Some(less_than_10000_or_elided(&[*a])? * 10000 + less_than_10000_or_elided(tail)?)
}
[a, b, '万', tail @ ..] => {
Some(less_than_10000_or_elided(&[*a, *b])? * 10000 + less_than_10000_or_elided(tail)?)
}
[a, b, c, '万', tail @ ..] => Some(
less_than_10000_or_elided(&[*a, *b, *c])? * 10000 + less_than_10000_or_elided(tail)?,
),
[a, b, c, d, '万', tail @ ..] => Some(
less_than_10000_or_elided(&[*a, *b, *c, *d])? * 10000
+ less_than_10000_or_elided(tail)?,
),
[a, b, c, d, e, '万', tail @ ..] => Some(
less_than_10000_or_elided(&[*a, *b, *c, *d, *e])? * 10000
+ less_than_10000_or_elided(tail)?,
),
_ => less_than_10000(input),
}
}
pub fn less_than_10000_or_elided(s: &[char]) -> Option<i64> {
match less_than_100_nun1_elided(s) {
Some(n) => Some(n),
None => less_than_10000(s),
}
}
pub fn less_than_10000_0000_or_elided(s: &[char]) -> Option<i64> {
match less_than_100_nun1_elided(s) {
Some(n) => Some(n),
None => less_than_10000_0000(s),
}
}
pub fn less_than_10000(s: &[char]) -> Option<i64> {
match s {
['百'] => Some(100),
[a, '百'] => less_than_100_nun1_elided(&[*a]).map(|w| w * 100),
[a, b, '百'] => less_than_100_nun1_elided(&[*a, *b]).map(|w| w * 100),
['百', c] => less_than_100_nun1_elided(&[*c]).map(|a| 100 + a),
['百', c, d] => less_than_100_nun1_elided(&[*c, *d]).map(|a| 100 + a),
['百', c, d, e] => less_than_100(&[*c, *d, *e]).map(|a| 100 + a),
[a, '百', tail @ ..] => {
Some(less_than_100_nun1_elided(&[*a])? * 100 + less_than_100_nun1_elided(tail)?)
}
[a, b, '百', tail @ ..] => {
Some(less_than_100_nun1_elided(&[*a, *b])? * 100 + less_than_100_nun1_elided(tail)?)
}
_ => less_than_100(s),
}
}
fn positive(s: &[char]) -> Option<i64> {
match s {
['億'] => Some(1_0000_0000),
[head @ .., '億'] => less_than_10000_0000_or_elided(head).map(|w| w * 1_0000_0000),
['億', tail @ ..] => Some(1_0000_0000 + less_than_10000_0000_or_elided(tail)?),
[a, '億', tail @ ..] => Some(
less_than_10000_0000_or_elided(&[*a])? * 1_0000_0000
+ less_than_10000_0000_or_elided(tail)?,
),
[a, b, '億', tail @ ..] => Some(
less_than_10000_0000_or_elided(&[*a, *b])? * 1_0000_0000
+ less_than_10000_0000_or_elided(tail)?,
),
[a, b, c, '億', tail @ ..] => Some(
less_than_10000_0000_or_elided(&[*a, *b, *c])? * 1_0000_0000
+ less_than_10000_0000_or_elided(tail)?,
),
_ => less_than_10000_0000(s),
}
}