Informatique/MPSI/spe/decomp.ml
2020-09-01 16:07:00 +02:00

54 lines
1.9 KiB
OCaml

open Format
let premiers = [1;2;4;8;16;32;64;128;256;512;1024;2048;4096;8192];;
let rec print_int_list l = match l with
|[] -> printf "\n"
|h::t -> begin printf "%d " h;print_int_list t end;;
let print_sum l =
let rec aux l = match l with
| [] -> printf "\n"
| h::t -> begin printf " + %d" h;aux t end in
match l with
|[] -> printf "0\n"
|h::t -> begin printf "%d" h;aux t end;;
let rec sum l = match l with
| [] -> 0
| h::t -> h + sum t;;
let rec dans a l = match l with
| [] -> false
| h::t -> if h=a then true else dans a t ;;
let rec retirer acc base modulo = match base with
| [] -> acc
| h::t -> if dans h modulo then retirer acc t modulo
else retirer (h::acc) t modulo ;;
let rec somme accn accl ban lim l = match l with
| [] -> (accn,accl,true)
| h::t -> if accn < lim then somme (accn+h) (h::accl) ban lim t
else if dans (accn - lim) ban then somme (accn+h) (h::accl) ban lim t
else (accn,accl,false);;
let decomp n =
let imp = ref [1] in
let rec aux impp n =
if dans n !imp then raise Not_found else
if dans n premiers then [n] else
let (a,l,f) = somme 0 [] !imp n premiers in
print_int_list (n::a::0::l);
match a - n with
|0 -> l
|d (*when d < n*) -> begin try retirer [] l (aux impp d) with
| Not_found when f -> raise Not_found
| Not_found -> begin imp:=(d::(!imp)); aux (d::impp) n end end
(*|d -> raise Not_found*) in
aux [1] n;;
for i = 0 to sum premiers do
try begin let d = decomp i in printf "%d = " i; print_sum d end with
| Not_found -> printf "%d : Pas de decomposition\n" i done;;
(*
let max = ref 0 in
let imax = ref 0 in
for i = 0 to sum premiers do
let c = ref 0 in
try let a=sum (decomp c i) in printf "Oui :%d : %d\n" i !c with
| Not_found -> printf "Non :%d : %d\n" i !c;
if !c > !max then begin max := !c; imax := i end done;
printf "%d : %d" !imax !max;; *)