Skip to content

Instantly share code, notes, and snippets.

@sheepla
Last active July 21, 2026 12:34
Show Gist options
  • Select an option

  • Save sheepla/eea25876cbbb487077f3d286d76ba41f to your computer and use it in GitHub Desktop.

Select an option

Save sheepla/eea25876cbbb487077f3d286d76ba41f to your computer and use it in GitHub Desktop.
Nabeatsu in F#
// Usage: dotnet fsi Nabeatsu.fsx
let rec hasThree n =
if n = 0 then false
elif abs (n % 10) = 3 then true
else hasThree (n / 10)
let isAho n = n <> 0 && (n % 3 = 0 || hasThree n)
type SoundSet = {
Digits: string[]
Units: string[]
LargeUnits: string[]
Suffix: string
}
let normalSet = {
Digits = [| ""; "イチ"; "ニ"; "サン"; "ヨン"; "ゴ"; "ロク"; "ナナ"; "ハチ"; "キュウ" |]
Units = [| ""; "ジュウ"; "ヒャク"; "セン" |]
LargeUnits = [| ""; "マン"; "オク"; "チョウ" |]
Suffix = ""
}
let ahoSet = {
Digits = [| ""; "イチ"; "ニ"; "サァ~ン"; "ヨォ~ン"; "ゴ"; "ロォク"; "ナナ"; "ハチ"; "キュウ" |]
Units = [| ""; "ジュゥ~"; "ヒャァク"; "セェ~ン" |]
LargeUnits = [| ""; "マァ~ン"; "オック"; "チョ~ウ" |]
Suffix = "~~ッ! (アホ)"
}
let readUnder10000 (s: SoundSet) n =
[ n / 1000; (n / 100) % 10; (n / 10) % 10; n % 10 ]
|> List.zip [ 3; 2; 1; 0 ]
|> List.choose (fun (uIdx, d) ->
if d = 0 then None
else
let numStr = if d = 1 && uIdx > 0 then "" else s.Digits.[d]
Some (numStr + s.Units.[uIdx]))
|> String.concat ""
let rec split4 n =
if n = 0 then []
else (n % 10000) :: split4 (n / 10000)
let readNumber (s: SoundSet) n =
if n = 0 then "ゼロ" + s.Suffix
else
split4 (abs n)
|> List.mapi (fun i part ->
if part = 0 then ""
else readUnder10000 s part + s.LargeUnits.[i])
|> List.rev
|> String.concat ""
|> fun text -> text + s.Suffix
let toAho n =
let soundSet = if isAho n then ahoSet else normalSet
readNumber soundSet n
[1..100]
|> List.iter (fun n ->
printfn "%2d: %s" n (toAho n)
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment