(* exo du concours général 97 *) (* 1997 personnes sont assises autour d'une table, chacun a un carton avec un entier relatif, la somme de ces entiers vaut 1. Peut-on trouver un convive tel que si l'on tourne dans le sens des aiguilles d'une montre en ajoutant les valeurs des cartons, la somme soit toujours positive? nombre de solutions? *) (* on m'avait communiqué cet énoncé oralement, dans celui d'origine, on demandait que la somme soit toujours strictement positive, cela restreint à la dernière des solutions trouvées *) open Random;; let n=50;; (* 50 n'est qu'une autre valeur de 1997 *) let table=Array.make n 0;; let creation()= let total=ref 0 in for k=0 to n-2 do begin table.(k)<-(int 100 -50); total:=!total +table.(k) end done; table.(n-1)<-(1- !total) ;; let cherche_min tab= let mini= ref 10000 and recordmen=ref [] in for k=0 to (n-1) do if tab.(k)< !mini then begin mini:=tab.(k); recordmen:= [k] end else if tab.(k)= !mini then recordmen:=k::!recordmen; done; print_string "il faut commencer par un des convives aux places"; List.map (function t->t+1) !recordmen;; (* la liste 1..n dont on a tout le temps besoin *) let range n= let rec prefixe p q= if p=q then [q] else p::prefixe (p+1) q in prefixe 1 n ;; (* sautage de lignes automatique quand caml ne le fait pas: on peut l'automatiser en redéfinissant let print_i z= saute_ligne();print_int z let print_s z= saute_ligne();print_string z *) let global = ref (pos_out stdout);; let saute_ligne()= let actuel = (pos_out stdout) in if (actuel-(!global))>40 then begin global:=actuel; print_newline() end ;; let verifie_aff tab= List.iter (fun k->print_string " (";print_int k;print_string ": ";print_int tab.(k-1);print_string ") ") (range n);; verifie_aff table;;