WiP
This commit is contained in:
parent
253633f09d
commit
42b8fa388b
@ -1,9 +1,9 @@
|
|||||||
Nombres
|
Nombres
|
||||||
=========
|
=========
|
||||||
|
|
||||||
Convert ints into french.
|
Convert integers into french.
|
||||||
|
|
||||||
Provided as a 1-function library, and a basic command-line utility (`nbr` — will
|
Provided as a 1-function library and a basic command-line utility (`nbr` — will
|
||||||
certainly be renamed to something longer and less likely to name clash).
|
certainly be renamed to something longer and less likely to name clash).
|
||||||
|
|
||||||
More advanced functionnalities could be added when needed. Here are some
|
More advanced functionnalities could be added when needed. Here are some
|
||||||
|
@ -4,14 +4,16 @@ let rec parse_and_print () =
|
|||||||
input_line stdin |> function
|
input_line stdin |> function
|
||||||
| "q" | "Q" -> ()
|
| "q" | "Q" -> ()
|
||||||
| "h" | "?" | "H" ->
|
| "h" | "?" | "H" ->
|
||||||
print_endline "Je n'accepte que des entiers positifs. Et pas trop grands…\n'q' ou 'Q' pour quitter.";
|
print_endline
|
||||||
|
"Je n'accepte que des entiers positifs. Et pas trop grands…\n\
|
||||||
|
'q' ou 'Q' pour quitter.";
|
||||||
flush stdout;
|
flush stdout;
|
||||||
parse_and_print ()
|
parse_and_print ()
|
||||||
| str ->
|
| str ->
|
||||||
str |> int_of_string
|
str |> int_of_string
|
||||||
|> (fun i ->
|
|> (fun i ->
|
||||||
match i with
|
match i with
|
||||||
| i -> i |> Nombres.nombre_of_int |> print_endline
|
| i -> i |> Nombres.nombre |> print_endline
|
||||||
| exception _ -> ())
|
| exception _ -> ())
|
||||||
|> parse_and_print
|
|> parse_and_print
|
||||||
|
|
||||||
|
14
dune-project
14
dune-project
@ -1,11 +1,19 @@
|
|||||||
(lang dune 2.8)
|
(lang dune 3.0)
|
||||||
|
(name nombres)
|
||||||
|
(version 0.9)
|
||||||
|
|
||||||
(generate_opam_files true)
|
(generate_opam_files true)
|
||||||
(name nombres)
|
|
||||||
|
(source (github ttamttam/nombres))
|
||||||
|
(license ISC)
|
||||||
|
(authors "Matthieu Dubuget")
|
||||||
|
(maintainers "matthieu.dubuget@gmail.com")
|
||||||
|
|
||||||
(package
|
(package
|
||||||
(name nombres)
|
(name nombres)
|
||||||
|
(synopsis "Conversion of integers to french.")
|
||||||
(description
|
(description
|
||||||
"\| Convert ints into french.
|
"\| Convert integers into french.
|
||||||
"\|
|
"\|
|
||||||
"\| Some references:
|
"\| Some references:
|
||||||
"\| - https://leconjugueur.lefigaro.fr/frlesnombres.php
|
"\| - https://leconjugueur.lefigaro.fr/frlesnombres.php
|
||||||
|
4
lib/dune
4
lib/dune
@ -1,2 +1,4 @@
|
|||||||
(library
|
(library
|
||||||
(name nombres))
|
(name nombres)
|
||||||
|
(public_name nombres)
|
||||||
|
(libraries fmt))
|
||||||
|
236
lib/nombres.ml
236
lib/nombres.ml
@ -1,56 +1,188 @@
|
|||||||
let rec nombre_of_int = function
|
type options =
|
||||||
| 0 -> "zéro"
|
| Septante
|
||||||
| 1 -> "un"
|
| Huitante
|
||||||
| 2 -> "deux"
|
| Nonante
|
||||||
| 3 -> "trois"
|
| Belgique (* Septante Nonante *)
|
||||||
| 4 -> "quatre"
|
| VVF (* Septante Huitante Nonante *)
|
||||||
| 5 -> "cinq"
|
|
||||||
| 6 -> "six"
|
|
||||||
| 7 -> "sept"
|
|
||||||
| 8 -> "huit"
|
|
||||||
| 9 -> "neuf"
|
|
||||||
| 10 -> "dix"
|
|
||||||
| 11 -> "onze"
|
|
||||||
| 12 -> "douze"
|
|
||||||
| 13 -> "treize"
|
|
||||||
| 14 -> "quatorze"
|
|
||||||
| 15 -> "quinze"
|
|
||||||
| 16 -> "seize"
|
|
||||||
| 20 -> "vingt"
|
|
||||||
| 30 -> "trente"
|
|
||||||
| 40 -> "quarante"
|
|
||||||
| 50 -> "cinquante"
|
|
||||||
| 60 -> "soixante"
|
|
||||||
| 80 -> "quatre-vingts"
|
|
||||||
| 100 -> "cent"
|
|
||||||
| 1000 -> "mille"
|
|
||||||
| n when n < 70 -> jusqua_70 n
|
|
||||||
| n when n < 80 -> jusqua_100 "soixante" n
|
|
||||||
| n when n < 100 -> jusqua_100 "quatre-vingt" n
|
|
||||||
| n when n < 1_000 -> jusqua_1000 n
|
|
||||||
| n when n < 1_000_000 -> jusqua_1000000 n
|
|
||||||
| _ -> "--------------------"
|
|
||||||
|
|
||||||
and jusqua_70 n =
|
let int_of_options = function
|
||||||
let dizaine = nombre_of_int (n / 10 * 10) in
|
| Septante -> 0x1
|
||||||
let unite = n mod 10 in
|
| Huitante -> 0x2
|
||||||
[ dizaine; nombre_of_int unite ]
|
| Nonante -> 0x8
|
||||||
|> String.concat (if unite = 1 then " et " else "-")
|
| Belgique -> 0x1 lor 0x8
|
||||||
|
| VVF -> 0x1 lor 0x2 lor 0x8
|
||||||
|
|
||||||
and jusqua_100 dizaine n =
|
type mode = [ `Belgique | `VVF | `France ]
|
||||||
let unite = n mod 10 in
|
|
||||||
[ dizaine; nombre_of_int (n mod 20) ]
|
|
||||||
|> String.concat (if unite = 1 && n < 80 then " et " else "-")
|
|
||||||
|
|
||||||
and jusqua_1000 n =
|
let options_of_mode = function
|
||||||
let centaine = n / 100 and reste = n mod 100 in
|
| `Belgique -> [ Belgique ]
|
||||||
let cent = if centaine > 1 && reste = 0 then "cents" else "cent" in
|
| `VVF -> [ VVF ]
|
||||||
((if centaine = 1 then [ cent ] else [ nombre_of_int centaine; cent ])
|
| `France -> []
|
||||||
@ if reste = 0 then [] else [ nombre_of_int reste ])
|
|
||||||
|> String.concat " "
|
|
||||||
|
|
||||||
and jusqua_1000000 n =
|
let int_of_mode m =
|
||||||
let milliers = n / 1000 and reste = n mod 1000 in
|
m |> options_of_mode |> List.map int_of_options
|
||||||
((if milliers = 1 then [ "mille" ] else [ nombre_of_int milliers; "mille" ])
|
|> ListLabels.fold_left ~f:( + ) ~init:0
|
||||||
@ if reste = 0 then [] else [ nombre_of_int reste ])
|
|
||||||
|> String.concat " "
|
let mode_of_int = function
|
||||||
|
| 0 -> `France
|
||||||
|
| 1 -> `Belgique
|
||||||
|
| 2 -> `VVF
|
||||||
|
| _ -> assert false
|
||||||
|
|
||||||
|
let opts options lst = List.exists (fun opt -> List.mem opt options) lst
|
||||||
|
|
||||||
|
let nombre ?(options = []) n =
|
||||||
|
let has_opts = opts options in
|
||||||
|
if n = min_int then invalid_arg "Nombre hors domaine"
|
||||||
|
else
|
||||||
|
(* if debug then Fmt.pr "@[<v 2>nombre %d:@," n; *)
|
||||||
|
let rec schu =
|
||||||
|
[|
|
||||||
|
"";
|
||||||
|
"un";
|
||||||
|
"deux";
|
||||||
|
"trois";
|
||||||
|
"quatre";
|
||||||
|
"cinq";
|
||||||
|
"six";
|
||||||
|
"sept";
|
||||||
|
"huit";
|
||||||
|
"neuf";
|
||||||
|
"dix";
|
||||||
|
"onze";
|
||||||
|
"douze";
|
||||||
|
"treize";
|
||||||
|
"quatorze";
|
||||||
|
"quinze";
|
||||||
|
"seize";
|
||||||
|
|]
|
||||||
|
and schd =
|
||||||
|
[|
|
||||||
|
"";
|
||||||
|
"dix";
|
||||||
|
"vingt";
|
||||||
|
"trente";
|
||||||
|
"quarante";
|
||||||
|
"cinquante";
|
||||||
|
"soixante";
|
||||||
|
"soixante";
|
||||||
|
|]
|
||||||
|
and nombre_of_int ?(singular = false) ?(accu = []) current () =
|
||||||
|
match current with
|
||||||
|
| 0 ->
|
||||||
|
if accu <> [] then accu |> List.rev |> String.concat " "
|
||||||
|
else "zéro"
|
||||||
|
| n when n < 0 -> nombre_of_int ~accu (-n) ()
|
||||||
|
| n when n < 17 -> unroll (schu.(n) :: accu)
|
||||||
|
| n when n mod 10 = 0 && n < 61 -> unroll (schd.(n / 10) :: accu)
|
||||||
|
| 80 ->
|
||||||
|
let nom, noms =
|
||||||
|
if has_opts [ Huitante; VVF ] then ("huitante", "huitante")
|
||||||
|
else ("quatre-vingt", "quatre-vingts")
|
||||||
|
in
|
||||||
|
unroll ((if singular then nom else noms) :: accu)
|
||||||
|
| 100 -> unroll ("cent" :: accu)
|
||||||
|
| 1000 -> unroll ("mille" :: accu)
|
||||||
|
| n when n < 70 ->
|
||||||
|
let dizaines = nombre_of_int (n / 10 * 10) () in
|
||||||
|
let unites = n mod 10 in
|
||||||
|
let accu =
|
||||||
|
([
|
||||||
|
dizaines;
|
||||||
|
(if unites = 1 then " et " else "-");
|
||||||
|
nombre_of_int unites ();
|
||||||
|
]
|
||||||
|
|> String.concat "")
|
||||||
|
:: accu
|
||||||
|
in
|
||||||
|
unroll accu
|
||||||
|
| n when n < 80 ->
|
||||||
|
let unites = n mod 10 in
|
||||||
|
let accu =
|
||||||
|
if has_opts [ Septante; Belgique; VVF ] then
|
||||||
|
([
|
||||||
|
(if n < 70 then "soixante" else "septante");
|
||||||
|
(if unites = 1 && n < 80 then " et "
|
||||||
|
else if unites > 0 then "-"
|
||||||
|
else "");
|
||||||
|
(if unites > 0 then nombre_of_int unites () else "");
|
||||||
|
]
|
||||||
|
|> String.concat "")
|
||||||
|
:: accu
|
||||||
|
else
|
||||||
|
([
|
||||||
|
"soixante";
|
||||||
|
(if unites = 1 && n < 80 then " et " else "-");
|
||||||
|
nombre_of_int (n mod 20) ();
|
||||||
|
]
|
||||||
|
|> String.concat "")
|
||||||
|
:: accu
|
||||||
|
in
|
||||||
|
unroll accu
|
||||||
|
| n when n < 100 ->
|
||||||
|
let unites = n mod 10 in
|
||||||
|
let accu =
|
||||||
|
if has_opts [ Huitante; VVF ] && n < 90 then
|
||||||
|
([
|
||||||
|
"huitante";
|
||||||
|
(if unites = 1 then " et " else if unites > 0 then "-" else "");
|
||||||
|
(if unites > 0 then nombre_of_int unites () else "");
|
||||||
|
]
|
||||||
|
|> String.concat "")
|
||||||
|
:: accu
|
||||||
|
else if has_opts [ Nonante; VVF; Belgique ] && n >= 90 then
|
||||||
|
([
|
||||||
|
"nonante";
|
||||||
|
(if unites = 1 then " et " else if unites > 0 then "-" else "");
|
||||||
|
(if unites > 0 then nombre_of_int unites () else "");
|
||||||
|
]
|
||||||
|
|> String.concat "")
|
||||||
|
:: accu
|
||||||
|
else
|
||||||
|
([
|
||||||
|
"quatre-vingt";
|
||||||
|
(if unites = 1 && n < 80 then " et " else "-");
|
||||||
|
nombre_of_int (n mod 20) ();
|
||||||
|
]
|
||||||
|
|> String.concat "")
|
||||||
|
:: accu
|
||||||
|
in
|
||||||
|
unroll accu
|
||||||
|
| n when n < 1_000 -> jusqua_x ~singular accu 100 ~nom:"cent" ~un:false n
|
||||||
|
| n when n < 1_000_000 -> jusqua_x accu 1000 ~nom:"mille" ~un:false n
|
||||||
|
| n when n < 1_000_000_000 ->
|
||||||
|
jusqua_x accu 1_000_000 ~nom:"million" ~un:true n
|
||||||
|
| n when n < 1_000_000_000_000 ->
|
||||||
|
jusqua_x accu 1_000_000_000 ~nom:"milliard" ~un:true n
|
||||||
|
| n when n < 1_000_000_000_000_000 ->
|
||||||
|
jusqua_x accu 1_000_000_000_000 ~nom:"billion" ~un:true n
|
||||||
|
| n when n < 1_000_000_000_000_000_000 ->
|
||||||
|
jusqua_x accu 1_000_000_000_000_000 ~nom:"billiard" ~un:true n
|
||||||
|
| n when n <= max_int ->
|
||||||
|
jusqua_x accu 1_000_000_000_000_000_000 ~nom:"trillion" ~un:true n
|
||||||
|
| _ -> assert false
|
||||||
|
and unroll accu = List.rev accu |> String.concat " "
|
||||||
|
and jusqua_x ?(singular = false) accu lim ~nom ~un n =
|
||||||
|
let un = if un then "un" else "" in
|
||||||
|
let noms =
|
||||||
|
match (nom, singular) with
|
||||||
|
| "mille", _ -> "mille"
|
||||||
|
| nom, true -> nom
|
||||||
|
| nom, false -> nom ^ "s"
|
||||||
|
in
|
||||||
|
let count = n / lim and reste = n mod lim in
|
||||||
|
|
||||||
|
let accu =
|
||||||
|
match count with
|
||||||
|
| 1 -> nom :: un :: accu |> List.filter (( <> ) "")
|
||||||
|
| _ ->
|
||||||
|
let noms = if lim = 100 && reste <> 0 then nom else noms in
|
||||||
|
noms
|
||||||
|
:: nombre_of_int ~singular:(singular || lim = 1000) count ()
|
||||||
|
:: accu
|
||||||
|
in
|
||||||
|
|
||||||
|
nombre_of_int ~singular ~accu reste ()
|
||||||
|
in
|
||||||
|
|
||||||
|
nombre_of_int n ()
|
||||||
|
12
nombres.opam
12
nombres.opam
@ -1,15 +1,22 @@
|
|||||||
# This file is generated by dune, edit dune-project instead
|
# This file is generated by dune, edit dune-project instead
|
||||||
opam-version: "2.0"
|
opam-version: "2.0"
|
||||||
|
version: "0.9"
|
||||||
|
synopsis: "Conversion of integers to french."
|
||||||
description: """
|
description: """
|
||||||
Convert ints into french.
|
Convert integers into french.
|
||||||
|
|
||||||
Some references:
|
Some references:
|
||||||
- https://leconjugueur.lefigaro.fr/frlesnombres.php
|
- https://leconjugueur.lefigaro.fr/frlesnombres.php
|
||||||
- https://www.miakinen.net/vrac/nombres
|
- https://www.miakinen.net/vrac/nombres
|
||||||
- https://www.dcode.fr/ecriture-nombre-lettres
|
- https://www.dcode.fr/ecriture-nombre-lettres
|
||||||
"""
|
"""
|
||||||
|
maintainer: ["matthieu.dubuget@gmail.com"]
|
||||||
|
authors: ["Matthieu Dubuget"]
|
||||||
|
license: "ISC"
|
||||||
|
homepage: "https://github.com/ttamttam/nombres"
|
||||||
|
bug-reports: "https://github.com/ttamttam/nombres/issues"
|
||||||
depends: [
|
depends: [
|
||||||
"dune" {>= "2.8"}
|
"dune" {>= "3.0"}
|
||||||
"odoc" {with-doc}
|
"odoc" {with-doc}
|
||||||
]
|
]
|
||||||
build: [
|
build: [
|
||||||
@ -26,3 +33,4 @@ build: [
|
|||||||
"@doc" {with-doc}
|
"@doc" {with-doc}
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
|
dev-repo: "git+https://github.com/ttamttam/nombres.git"
|
||||||
|
Loading…
Reference in New Issue
Block a user