数字分类精简词库,测验支持 0-亿 随机出题
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -1,9 +1,10 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
enum NumberWords {
|
enum NumberWords {
|
||||||
static let range = 1...999
|
static let range = 0...999
|
||||||
|
|
||||||
private static let atomNumbers: [String: Int] = [
|
static let atomNumbers: [String: Int] = [
|
||||||
|
"zero": 0,
|
||||||
"one": 1, "two": 2, "three": 3, "four": 4, "five": 5,
|
"one": 1, "two": 2, "three": 3, "four": 4, "five": 5,
|
||||||
"six": 6, "seven": 7, "eight": 8, "nine": 9, "ten": 10,
|
"six": 6, "seven": 7, "eight": 8, "nine": 9, "ten": 10,
|
||||||
"eleven": 11, "twelve": 12, "thirteen": 13, "fourteen": 14, "fifteen": 15,
|
"eleven": 11, "twelve": 12, "thirteen": 13, "fourteen": 14, "fifteen": 15,
|
||||||
@@ -41,11 +42,17 @@ enum NumberWords {
|
|||||||
byNumber[number] = atom
|
byNumber[number] = atom
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return range.map { byNumber[$0] ?? makeWord($0) }
|
return range.filter { n in
|
||||||
|
n <= 9
|
||||||
|
|| (n >= 10 && n <= 99 && n % 10 == 0)
|
||||||
|
|| n == 100
|
||||||
|
}.map { byNumber[$0] ?? makeWord($0) }
|
||||||
}
|
}
|
||||||
|
|
||||||
static func english(_ n: Int) -> String {
|
static func english(_ n: Int) -> String {
|
||||||
switch n {
|
switch n {
|
||||||
|
case 0:
|
||||||
|
return "zero"
|
||||||
case 1...19:
|
case 1...19:
|
||||||
return ones[n - 1]
|
return ones[n - 1]
|
||||||
case 20...99:
|
case 20...99:
|
||||||
@@ -56,6 +63,16 @@ enum NumberWords {
|
|||||||
let head = "\(ones[n / 100 - 1]) hundred"
|
let head = "\(ones[n / 100 - 1]) hundred"
|
||||||
let rest = n % 100
|
let rest = n % 100
|
||||||
return rest == 0 ? head : "\(head) \(english(rest))"
|
return rest == 0 ? head : "\(head) \(english(rest))"
|
||||||
|
case 1_000...999_999:
|
||||||
|
let thousands = n / 1_000
|
||||||
|
let rest = n % 1_000
|
||||||
|
let head = "\(english(thousands)) thousand"
|
||||||
|
return rest == 0 ? head : "\(head) \(english(rest))"
|
||||||
|
case 1_000_000...999_999_999:
|
||||||
|
let millions = n / 1_000_000
|
||||||
|
let rest = n % 1_000_000
|
||||||
|
let head = "\(english(millions)) million"
|
||||||
|
return rest == 0 ? head : "\(head) \(english(rest))"
|
||||||
default:
|
default:
|
||||||
return "\(n)"
|
return "\(n)"
|
||||||
}
|
}
|
||||||
@@ -63,6 +80,8 @@ enum NumberWords {
|
|||||||
|
|
||||||
static func phonetic(_ n: Int) -> String {
|
static func phonetic(_ n: Int) -> String {
|
||||||
switch n {
|
switch n {
|
||||||
|
case 0:
|
||||||
|
return "ˈzɪroʊ"
|
||||||
case 1...19:
|
case 1...19:
|
||||||
return onesPhonetics[n - 1]
|
return onesPhonetics[n - 1]
|
||||||
case 20...99:
|
case 20...99:
|
||||||
@@ -73,6 +92,16 @@ enum NumberWords {
|
|||||||
let head = "\(onesPhonetics[n / 100 - 1]) ˈhʌndrəd"
|
let head = "\(onesPhonetics[n / 100 - 1]) ˈhʌndrəd"
|
||||||
let rest = n % 100
|
let rest = n % 100
|
||||||
return rest == 0 ? head : "\(head) \(phonetic(rest))"
|
return rest == 0 ? head : "\(head) \(phonetic(rest))"
|
||||||
|
case 1_000...999_999:
|
||||||
|
let thousands = n / 1_000
|
||||||
|
let rest = n % 1_000
|
||||||
|
let head = "\(phonetic(thousands)) ˈθaʊznd"
|
||||||
|
return rest == 0 ? head : "\(head) \(phonetic(rest))"
|
||||||
|
case 1_000_000...999_999_999:
|
||||||
|
let millions = n / 1_000_000
|
||||||
|
let rest = n % 1_000_000
|
||||||
|
let head = "\(phonetic(millions)) ˈmɪljən"
|
||||||
|
return rest == 0 ? head : "\(head) \(phonetic(rest))"
|
||||||
default:
|
default:
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
@@ -100,11 +129,39 @@ enum NumberWords {
|
|||||||
default:
|
default:
|
||||||
return head + digits[rest / 10] + "十" + (rest % 10 == 0 ? "" : digits[rest % 10])
|
return head + digits[rest / 10] + "十" + (rest % 10 == 0 ? "" : digits[rest % 10])
|
||||||
}
|
}
|
||||||
|
case 1_000...9_999:
|
||||||
|
let head = digits[n / 1_000] + "千"
|
||||||
|
let rest = n % 1_000
|
||||||
|
guard rest > 0 else { return head }
|
||||||
|
return rest < 100 ? head + "零" + chinese(rest) : head + chinese(rest)
|
||||||
|
case 10_000...99_999_999:
|
||||||
|
let head = chinese(n / 10_000) + "万"
|
||||||
|
let rest = n % 10_000
|
||||||
|
guard rest > 0 else { return head }
|
||||||
|
return rest < 1_000 ? head + "零" + chinese(rest) : head + chinese(rest)
|
||||||
|
case 100_000_000...999_999_999:
|
||||||
|
let head = digits[n / 100_000_000] + "亿"
|
||||||
|
let rest = n % 100_000_000
|
||||||
|
guard rest > 0 else { return head }
|
||||||
|
return rest < 10_000_000 ? head + "零" + chinese(rest) : head + chinese(rest)
|
||||||
default:
|
default:
|
||||||
return "\(n)"
|
return "\(n)"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static func randomWord() -> Word {
|
||||||
|
let n = Int.random(in: 0...999_999_999)
|
||||||
|
return Word(word: english(n),
|
||||||
|
phonetic: "/\(phonetic(n))/",
|
||||||
|
meaning: chinese(n),
|
||||||
|
example: "The number is \(english(n)).",
|
||||||
|
exampleMeaning: "这个数字是\(chinese(n))。")
|
||||||
|
}
|
||||||
|
|
||||||
|
static func randomWords(count: Int) -> [Word] {
|
||||||
|
(0..<count).map { _ in randomWord() }
|
||||||
|
}
|
||||||
|
|
||||||
private static func makeWord(_ n: Int) -> Word {
|
private static func makeWord(_ n: Int) -> Word {
|
||||||
Word(word: english(n),
|
Word(word: english(n),
|
||||||
phonetic: "/\(phonetic(n))/",
|
phonetic: "/\(phonetic(n))/",
|
||||||
|
|||||||
@@ -147,6 +147,7 @@
|
|||||||
"name": "数字",
|
"name": "数字",
|
||||||
"icon": "number",
|
"icon": "number",
|
||||||
"words": [
|
"words": [
|
||||||
|
{ "word": "zero", "phonetic": "/ˈzɪroʊ/", "meaning": "零", "example": "Zero means nothing.", "exampleMeaning": "零表示没有。" },
|
||||||
{ "word": "one", "phonetic": "/wʌn/", "meaning": "一", "example": "I have one book.", "exampleMeaning": "我有一本书。" },
|
{ "word": "one", "phonetic": "/wʌn/", "meaning": "一", "example": "I have one book.", "exampleMeaning": "我有一本书。" },
|
||||||
{ "word": "two", "phonetic": "/tuː/", "meaning": "二", "example": "Two birds are singing.", "exampleMeaning": "两只鸟在唱歌。" },
|
{ "word": "two", "phonetic": "/tuː/", "meaning": "二", "example": "Two birds are singing.", "exampleMeaning": "两只鸟在唱歌。" },
|
||||||
{ "word": "three", "phonetic": "/θriː/", "meaning": "三", "example": "Three cats are sleeping.", "exampleMeaning": "三只猫在睡觉。" },
|
{ "word": "three", "phonetic": "/θriː/", "meaning": "三", "example": "Three cats are sleeping.", "exampleMeaning": "三只猫在睡觉。" },
|
||||||
@@ -174,7 +175,13 @@
|
|||||||
{ "word": "seventy", "phonetic": "/ˈsevnti/", "meaning": "七十", "example": "My grandmother is seventy.", "exampleMeaning": "我奶奶七十岁。" },
|
{ "word": "seventy", "phonetic": "/ˈsevnti/", "meaning": "七十", "example": "My grandmother is seventy.", "exampleMeaning": "我奶奶七十岁。" },
|
||||||
{ "word": "eighty", "phonetic": "/ˈeɪti/", "meaning": "八十", "example": "He can count to eighty.", "exampleMeaning": "他能数到八十。" },
|
{ "word": "eighty", "phonetic": "/ˈeɪti/", "meaning": "八十", "example": "He can count to eighty.", "exampleMeaning": "他能数到八十。" },
|
||||||
{ "word": "ninety", "phonetic": "/ˈnaɪnti/", "meaning": "九十", "example": "The book has ninety pages.", "exampleMeaning": "这本书有九十页。" },
|
{ "word": "ninety", "phonetic": "/ˈnaɪnti/", "meaning": "九十", "example": "The book has ninety pages.", "exampleMeaning": "这本书有九十页。" },
|
||||||
{ "word": "hundred", "phonetic": "/ˈhʌndrəd/", "meaning": "百", "example": "One hundred people came.", "exampleMeaning": "来了一百个人。" }
|
{ "word": "hundred", "phonetic": "/ˈhʌndrəd/", "meaning": "百", "example": "One hundred people came.", "exampleMeaning": "来了一百个人。" },
|
||||||
|
{ "word": "thousand", "phonetic": "/ˈθaʊznd/", "meaning": "千", "example": "This library has thousands of books.", "exampleMeaning": "这个图书馆有数千本书。" },
|
||||||
|
{ "word": "ten thousand", "phonetic": "/ten ˈθaʊznd/", "meaning": "一万", "example": "Ten thousand people ran in the race.", "exampleMeaning": "一万人参加了赛跑。" },
|
||||||
|
{ "word": "hundred thousand", "phonetic": "/ˈhʌndrəd ˈθaʊznd/", "meaning": "十万", "example": "The house is worth two hundred thousand dollars.", "exampleMeaning": "这房子价值二十万美元。" },
|
||||||
|
{ "word": "million", "phonetic": "/ˈmɪljən/", "meaning": "百万", "example": "The city has a population of one million.", "exampleMeaning": "这个城市有一百万人口。" },
|
||||||
|
{ "word": "ten million", "phonetic": "/ten ˈmɪljən/", "meaning": "千万", "example": "Ten million viewers watched the show.", "exampleMeaning": "一千万观众看了这个节目。" },
|
||||||
|
{ "word": "hundred million", "phonetic": "/ˈhʌndrəd ˈmɪljən/", "meaning": "亿", "example": "Over a hundred million people speak Japanese.", "exampleMeaning": "超过一亿人说日语。" }
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -29,8 +29,11 @@ final class WordStore {
|
|||||||
let decoded = try JSONDecoder().decode(WordBank.self, from: data)
|
let decoded = try JSONDecoder().decode(WordBank.self, from: data)
|
||||||
let categories = decoded.categories.map { category -> WordCategory in
|
let categories = decoded.categories.map { category -> WordCategory in
|
||||||
guard category.id == "numbers" else { return category }
|
guard category.id == "numbers" else { return category }
|
||||||
|
var words = NumberWords.makeWords(atoms: category.words)
|
||||||
|
let extras = category.words.filter { NumberWords.atomNumbers[$0.word] == nil }
|
||||||
|
words.append(contentsOf: extras)
|
||||||
return WordCategory(id: category.id, name: category.name, icon: category.icon,
|
return WordCategory(id: category.id, name: category.name, icon: category.icon,
|
||||||
words: NumberWords.makeWords(atoms: category.words))
|
words: words)
|
||||||
}
|
}
|
||||||
bank = WordBank(version: decoded.version, categories: categories)
|
bank = WordBank(version: decoded.version, categories: categories)
|
||||||
} catch {
|
} catch {
|
||||||
|
|||||||
@@ -119,7 +119,13 @@ final class WordListViewController: UIViewController {
|
|||||||
|
|
||||||
private func startQuiz() {
|
private func startQuiz() {
|
||||||
Haptics.selection()
|
Haptics.selection()
|
||||||
let request = QuizSetupRequest(words: category.words)
|
let words: [Word]
|
||||||
|
if category.id == "numbers" {
|
||||||
|
words = NumberWords.randomWords(count: 50)
|
||||||
|
} else {
|
||||||
|
words = category.words
|
||||||
|
}
|
||||||
|
let request = QuizSetupRequest(words: words)
|
||||||
navigationController?.pushViewController(QuizSetupViewController(request: request), animated: true)
|
navigationController?.pushViewController(QuizSetupViewController(request: request), animated: true)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user