Partage
  • Partager sur Facebook
  • Partager sur Twitter

Algorithmes divers multi-langage

tris, pathfinder, calcul, matrice, etc.

Anonyme
    9 novembre 2012 à 1:21:09

    Merci de relever mon erreur, je ne suis pas très spécialiste. Pour mon code j'ai suivi la 1ère formule. Par contre je n'ai pas très bien compris cette histoire de terme d'erreur.
    • Partager sur Facebook
    • Partager sur Twitter
      9 novembre 2012 à 3:40:05

      En fait quand ta fonction le permet (dérivable un certain nombre de fois, etc.) tu peux l'approximer par un polynôme. Seulement ce n'est qu'une approximation, et il y a donc un terme d'erreur (un reste) qu'on note souvent <math>\(R_n\)</math>.

      De manière générale, il y a une formule, de Taylor, qui nous dit que pour une fonction f dérivable en a n fois, on peut l'approximer par
      <math>\(f(x) =\sum_{k=0}^n \frac{f^{(k)}(a)}{k!}(x-a)^k + R_n(x)\)</math>

      Grâce à un changement de variable, on peut facilement se ramener à a =0 et en pratique c'est ce que l'on fait.
      Tu sais sûrement que la dérivée de l'exponentielle est elle-même et vaut 1 en 0, du coup on obtient :
      <math>\(e^x =\sum_{k=0}^n \frac{x^k}{k!} +R_n(x)\)</math>

      Il faut maintenant qu'on s'occupe du reste <math>\(R_n\)</math> (reste à l'ordre n). Revenons alors au cas général, si notre fonction f est en plus dérivable (et à dérivée continue) à l'ordre n+1, il existe une formule qui nous donne le reste à l'ordre n (un peu brutale encore) :
      <math>\(R_n = \int_a^x \frac{f^{(n+1)} (t)}{n!} (x - t)^n \,\mathrm dt\)</math>

      Et comme la théorie est bien faite, il se trouve que la fonction exponentielle est dérivable autant de fois que l'on veut et elle est bien continue. On peut donc dériver encore une fois (donc jusqu'à l'ordre n+1). On exprime alors le reste (dans le cas de l'exponentielle, toujours avec a = 0) :
      <math>\(R_n = \int_0^x \frac{e^t}{n!} (x - t)^n \,\mathrm dt\)</math>

      À présent, on retrouve alors le développement limité à l'ordre n, en 0, de l'exponentielle. En effet le rapport de ce reste par x^n tend bien vers 0 lorsque x tend vers 0, on note alors <math>\(R_n = o(x^n)\)</math>.
      Et alors lorsque x tend vers 0, notre fonction exponentielle admet un développement limité d'ordre n (en 0) et on écrit :
      <math>\(e^x =\sum_{k=0}^n \frac{x^k}{k!} + o(x^n)\)</math>

      Aussi, lorsque cette erreur (ou reste) tend vers 0 lorsque n tend vers l'infini, on dit (en vrai c'est pas tout à fait ça) que notre série admet un développement en série entière et on a alors la formule sans reste (mais en l'infini)
      <math>\(e^x =\sum_{k=0}^{+\infty} \frac{x^k}{k!}\)</math>


      Voilà j'ai raconté plein de trucs, c'est peut-être pas très clair (je ne connais pas ton niveau en maths), si tu as des questions n'hésite pas. Mais là je dois aller dormir :d. Enfin, vu l'heure qu'il est, j'ai sûrement dit des bêtises, n'hésitez pas à me corriger.
      • Partager sur Facebook
      • Partager sur Twitter
        31 mars 2013 à 22:31:50

        C'est pas forcément un algorithme super utile, mais comme je débute et que je suis plutôt content de mon truc, je me permet de le partager. Un algo qui résoud les sudoku, codé en Caml-Light :

        let sudoku t = 
        (* On commence par définir le même tableau en référence pour travailler dessus *)
        let tab2 = ref (copy_vect t) in
        
        (* Ici on va définir tous les sous-tableaux non nous auront besoin *)
        let l1 = ref (make_vect 9 [0]) in
        let l2 = ref (make_vect 9 [0]) in
        let l3 = ref (make_vect 9 [0]) in
        let l4 = ref (make_vect 9 [0]) in
        let l5 = ref (make_vect 9 [0]) in
        let l6 = ref (make_vect 9 [0]) in
        let l7 = ref (make_vect 9 [0]) in
        let l8 = ref (make_vect 9 [0]) in
        let l9 = ref (make_vect 9 [0]) in
        
        let def_l1 l tab= 
        for k = 0 to 8 do
        l.(k)<-[tab.(k)]
        done; in
        let def_l2 l tab= 
        for k = 9 to 17 do
        l.(k-9)<-[tab.(k)]
        done; in
        let def_l3 l tab= 
        for k = 18 to 26 do
        l.(k-18)<-[tab.(k)]
        done; in
        let def_l4 l tab = 
        for k = 27 to 35 do
        l.(k-27)<-[tab.(k)]
        done; in
        let def_l5 l tab = 
        for k = 36 to 44 do
        l.(k-36)<-[tab.(k)]
        done; in
        let def_l6 l tab = 
        for k = 45 to 53 do
        l.(k-45)<-[tab.(k)]
        done; in
        let def_l7 l tab = 
        for k = 54 to 62 do
        l.(k-54)<-[tab.(k)]
        done; in
        let def_l8 l tab = 
        for k = 63 to 71 do
        l.(k-63)<-[tab.(k)]
        done; in
        let def_l9 l tab = 
        for k = 72 to 80 do
        l.(k-72)<-[tab.(k)]
        done; in
        
        (* Ici on va définir des fonctions basiques dont nous auront besoin par la suite !*)
        let change l =
        for k = 0 to 8 do
        if l.(k)= [0] then l.(k) <- [1;2;3;4;5;6;7;8;9] done; in
        
        let rec delete l x = match l with
        | [] -> []
        | t::q when t = x -> q
        | t::q -> t::( delete q x) in	
        
        let rec appartient x l = match l with 
        	| [] -> false
        	| t::q when x = t -> true
        	| t::q -> appartient x q in
        	
        let rec list_length l nb = match l with 
        | [] -> nb
        | t::q -> (list_length q (nb+1)) in
        
        (* Première fonction d'appartenance qui vérifiera si l'élément est compris dans la ligne ! *)	
        let appartient_t x tab debut fin =
        let test = ref false in
        let k = ref debut in
        	while !k <= fin & !test = false do
        	if x=tab.(!k) then test := true;
        	incr k;
        	done;
        !test;
        in
        
        let rec aux l debut fin tab =match l with 
        | [] -> []
        | t::q when (appartient_t t tab debut fin) = true -> aux q debut fin tab 
        | t::q -> t::(aux q debut fin tab) in
        
        let choix_ligne l debut fin tab= if (list_length l 0) = 1 then l else aux l debut fin tab in
        
        let total_li tab = 
        l1 :=  [|choix_ligne !l1.(0) 0 8 tab; choix_ligne !l1.(1) 0 8 tab; choix_ligne !l1.(2) 0 8 tab; choix_ligne !l1.(3) 0 8 tab ; choix_ligne !l1.(4) 0 8 tab; choix_ligne !l1.(5) 0 8 tab; choix_ligne !l1.(6) 0 8 tab; choix_ligne !l1.(7) 0 8 tab; choix_ligne !l1.(8) 0 8 tab|];
        l2 :=  [|choix_ligne !l2.(0) 9 17 tab; choix_ligne !l2.(1) 9 17 tab; choix_ligne !l2.(2) 9 17 tab; choix_ligne !l2.(3) 9 17 tab; choix_ligne !l2.(4) 9 17 tab; choix_ligne !l2.(5) 9 17 tab; choix_ligne !l2.(6) 9 17 tab; choix_ligne !l2.(7) 9 17 tab; choix_ligne !l2.(8) 9 17 tab;|];
        l3 :=  [|choix_ligne !l3.(0) 18 26 tab; choix_ligne !l3.(1) 18 26 tab; choix_ligne !l3.(2) 18 26 tab; choix_ligne !l3.(3) 18 26 tab; choix_ligne !l3.(4) 18 26 tab; choix_ligne !l3.(5) 18 26 tab; choix_ligne !l3.(6) 18 26 tab; choix_ligne !l3.(7) 18 26 tab; choix_ligne !l3.(8) 18 26 tab|];
        l4 :=  [|choix_ligne !l4.(0) 27 35 tab; choix_ligne !l4.(1) 27 35 tab; choix_ligne !l4.(2) 27 35 tab; choix_ligne !l4.(3) 27 35 tab; choix_ligne !l4.(4) 27 35 tab; choix_ligne !l4.(5) 27 35 tab; choix_ligne !l4.(6) 27 35 tab; choix_ligne !l4.(7) 27 35 tab; choix_ligne !l4.(8) 27 35 tab|];
        l5 :=  [|choix_ligne !l5.(0) 36 44 tab; choix_ligne !l5.(1) 36 44 tab; choix_ligne !l5.(2) 36 44 tab; choix_ligne !l5.(3) 36 44 tab; choix_ligne !l5.(4) 36 44 tab; choix_ligne !l5.(5) 36 44 tab; choix_ligne !l5.(6) 36 44 tab; choix_ligne !l5.(7) 36 44 tab; choix_ligne !l5.(8) 36 44 tab|];
        l6 :=  [|choix_ligne !l6.(0) 45 53 tab; choix_ligne !l6.(1) 45 53 tab; choix_ligne !l6.(2) 45 53 tab; choix_ligne !l6.(3) 45 53 tab; choix_ligne !l6.(4) 45 53 tab; choix_ligne !l6.(5) 45 53 tab; choix_ligne !l6.(6) 45 53 tab; choix_ligne !l6.(7) 45 53 tab; choix_ligne !l6.(8) 45 53 tab|];
        l7 :=  [|choix_ligne !l7.(0) 54 62 tab; choix_ligne !l7.(1) 54 62 tab; choix_ligne !l7.(2) 54 62 tab; choix_ligne !l7.(3) 54 62 tab; choix_ligne !l7.(4) 54 62 tab; choix_ligne !l7.(5) 54 62 tab; choix_ligne !l7.(6) 54 62 tab; choix_ligne !l7.(7) 54 62 tab; choix_ligne !l7.(8) 54 62 tab|];
        l8 :=  [|choix_ligne !l8.(0) 63 71 tab; choix_ligne !l8.(1) 63 71 tab; choix_ligne !l8.(2) 63 71 tab; choix_ligne !l8.(3) 63 71 tab; choix_ligne !l8.(4) 63 71 tab; choix_ligne !l8.(5) 63 71 tab; choix_ligne !l8.(6) 63 71 tab; choix_ligne !l8.(7) 63 71 tab; choix_ligne !l8.(8) 63 71 tab|];
        l9 :=  [|choix_ligne !l9.(0) 72 80 tab; choix_ligne !l9.(1) 72 80 tab; choix_ligne !l9.(2) 72 80 tab; choix_ligne !l9.(3) 72 80 tab; choix_ligne !l9.(4) 72 80 tab; choix_ligne !l9.(5) 72 80 tab; choix_ligne !l9.(6) 72 80 tab; choix_ligne !l9.(7) 72 80 tab; choix_ligne !l9.(8) 72 80 tab|]
        in
        
        (*Maintenant, on va s'intéresser au cas des colonnes en appliquant un raisnonnement similaire au code précédent *)
        
        let appartient_t2 x tab debut fin =
        let test = ref false in
        let k = ref debut in
        	while !k <= fin & !test = false do
        	if x=tab.(!k) then test := true;
        	k:= !k + 9 ; (* La différence avec le 2x2 est qu'ici les lignes font 9 cases, donc +9 pour accéder a la case d'en dessous *)
        	done;
        !test;
        in
        
        let rec aux2 l debut fin tab=match l with 
        | [] -> []
        | t::q when (appartient_t2 t tab debut fin) = true -> aux2 q debut fin tab
        | t::q -> t::(aux2 q debut fin tab) in
        
        let choix_col l debut fin tab = if (list_length l 0) = 1 then l else aux2 l debut fin tab in
        
        let total_col tab = 
        l1 :=  [|choix_col !l1.(0) 0 72 tab; choix_col !l1.(1) 1 73 tab; choix_col !l1.(2) 2 74 tab; choix_col !l1.(3) 3 75 tab; choix_col !l1.(4) 4 76 tab; choix_col !l1.(5) 5 77 tab; choix_col !l1.(6) 6 78 tab; choix_col !l1.(7) 7 79 tab; choix_col !l1.(8) 8 80 tab|];
        l2 :=  [|choix_col !l2.(0) 0 72 tab; choix_col !l2.(1) 1 73 tab; choix_col !l2.(2) 2 74 tab; choix_col !l2.(3) 3 75 tab; choix_col !l2.(4) 4 76 tab; choix_col !l2.(5) 5 77 tab; choix_col !l2.(6) 6 78 tab; choix_col !l2.(7) 7 79 tab; choix_col !l2.(8) 8 80 tab|];
        l3 :=  [|choix_col !l3.(0) 0 72 tab; choix_col !l3.(1) 1 73 tab; choix_col !l3.(2) 2 74 tab; choix_col !l3.(3) 3 75 tab; choix_col !l3.(4) 4 76 tab; choix_col !l3.(5) 5 77 tab; choix_col !l3.(6) 6 78 tab; choix_col !l3.(7) 7 79 tab; choix_col !l3.(8) 8 80 tab|];
        l4 :=  [|choix_col !l4.(0) 0 72 tab; choix_col !l4.(1) 1 73 tab; choix_col !l4.(2) 2 74 tab; choix_col !l4.(3) 3 75 tab; choix_col !l4.(4) 4 76 tab; choix_col !l4.(5) 5 77 tab; choix_col !l4.(6) 6 78 tab; choix_col !l4.(7) 7 79 tab; choix_col !l4.(8) 8 80 tab|];
        l5 :=  [|choix_col !l5.(0) 0 72 tab; choix_col !l5.(1) 1 73 tab; choix_col !l5.(2) 2 74 tab; choix_col !l5.(3) 3 75 tab; choix_col !l5.(4) 4 76 tab; choix_col !l5.(5) 5 77 tab; choix_col !l5.(6) 6 78 tab; choix_col !l5.(7) 7 79 tab; choix_col !l5.(8) 8 80 tab|];
        l6 :=  [|choix_col !l6.(0) 0 72 tab; choix_col !l6.(1) 1 73 tab; choix_col !l6.(2) 2 74 tab; choix_col !l6.(3) 3 75 tab; choix_col !l6.(4) 4 76 tab; choix_col !l6.(5) 5 77 tab; choix_col !l6.(6) 6 78 tab; choix_col !l6.(7) 7 79 tab; choix_col !l6.(8) 8 80 tab|];
        l7 :=  [|choix_col !l7.(0) 0 72 tab; choix_col !l7.(1) 1 73 tab; choix_col !l7.(2) 2 74 tab; choix_col !l7.(3) 3 75 tab; choix_col !l7.(4) 4 76 tab; choix_col !l7.(5) 5 77 tab; choix_col !l7.(6) 6 78 tab; choix_col !l7.(7) 7 79 tab; choix_col !l7.(8) 8 80 tab|];
        l8 :=  [|choix_col !l8.(0) 0 72 tab; choix_col !l8.(1) 1 73 tab; choix_col !l8.(2) 2 74 tab; choix_col !l8.(3) 3 75 tab; choix_col !l8.(4) 4 76 tab; choix_col !l8.(5) 5 77 tab; choix_col !l8.(6) 6 78 tab; choix_col !l8.(7) 7 79 tab; choix_col !l8.(8) 8 80 tab|];
        l9 :=  [|choix_col !l9.(0) 0 72 tab; choix_col !l9.(1) 1 73 tab; choix_col !l9.(2) 2 74 tab; choix_col !l9.(3) 3 75 tab; choix_col !l9.(4) 4 76 tab; choix_col !l9.(5) 5 77 tab; choix_col !l9.(6) 6 78 tab; choix_col !l9.(7) 7 79 tab; choix_col !l9.(8) 8 80 tab|]
        in
        
        (* Il nous reste a redéfinir la recherche dans un sous tableau, et c'est la que ca etre le plus dure ... *)
        
        let appartient_t3 x tab debut fin =
        let test = ref false in
        let k = ref debut in
        let i = ref 1 in
        	while !k <= fin & !test = false do
        	if x=tab.(!k) then test := true;
        	if !i mod 3 <> 0 then begin k:= !k + 1; i:= !i +1 end else begin k:= !k + 7; i:= !i + 7 end (* La grosse différence ici, c'est qu'on va devoir faire une variable spéciale pour définir l'incrémentation en +1 +1 +7 +1 +1 *)
        	done;
        !test;
        in
        
        let rec aux3 l debut fin tab =match l with
        | [] -> []
        | t::q when (appartient_t3 t tab debut fin) = true -> aux3 q debut fin tab
        | t::q -> t::(aux3 q debut fin tab) in
        
        let choix_st l debut fin tab = if (list_length l 0) = 1 then l else aux3 l debut fin tab in
        
        let total_st tab  = 
        l1 :=  [|choix_st !l1.(0) 0 20 tab; choix_st !l1.(1) 0 20 tab; choix_st !l1.(2) 0 20 tab; choix_st !l1.(3) 3 23 tab; choix_st !l1.(4) 3 23 tab; choix_st !l1.(5) 3 23 tab; choix_st !l1.(6) 6 26 tab; choix_st !l1.(7) 7 26 tab; choix_st !l1.(8) 8 26 tab|];
        l2 :=  [|choix_st !l2.(0) 0 20 tab; choix_st !l2.(1) 0 20 tab; choix_st !l2.(2) 0 20 tab; choix_st !l2.(3) 3 23 tab; choix_st !l2.(4) 3 23 tab; choix_st !l2.(5) 3 23 tab; choix_st !l2.(6) 6 26 tab; choix_st !l2.(7) 7 26 tab; choix_st !l2.(8) 8 26 tab|];
        l3 :=  [|choix_st !l3.(0) 0 20 tab; choix_st !l3.(1) 0 20 tab; choix_st !l3.(2) 0 20 tab; choix_st !l3.(3) 3 23 tab; choix_st !l3.(4) 3 23 tab; choix_st !l3.(5) 3 23 tab; choix_st !l3.(6) 6 26 tab; choix_st !l3.(7) 7 26 tab; choix_st !l3.(8) 8 26 tab|];
        l4 :=  [|choix_st !l4.(0) 27 47 tab; choix_st !l4.(1) 27 47 tab; choix_st !l4.(2) 27 47 tab; choix_st !l4.(3) 30 50 tab; choix_st !l4.(4) 30 50 tab; choix_st !l4.(5) 30 50 tab; choix_st !l4.(6) 33 53 tab; choix_st !l4.(7) 33 53 tab; choix_st !l4.(8) 33 53 tab|];
        l5 :=  [|choix_st !l5.(0) 27 47 tab; choix_st !l5.(1) 27 47 tab; choix_st !l5.(2) 27 47 tab; choix_st !l5.(3) 30 50 tab; choix_st !l5.(4) 30 50 tab; choix_st !l5.(5) 30 50 tab; choix_st !l5.(6) 33 53 tab; choix_st !l5.(7) 33 53 tab; choix_st !l5.(8) 33 53 tab|];
        l6 :=  [|choix_st !l6.(0) 27 47 tab; choix_st !l6.(1) 27 47 tab; choix_st !l6.(2) 27 47 tab; choix_st !l6.(3) 30 50 tab; choix_st !l6.(4) 30 50 tab; choix_st !l6.(5) 30 50 tab; choix_st !l6.(6) 33 53 tab; choix_st !l6.(7) 33 53 tab; choix_st !l6.(8) 33 53 tab|];
        l7 :=  [|choix_st !l7.(0) 54 74 tab; choix_st !l7.(1) 54 74 tab; choix_st !l7.(2) 54 74 tab; choix_st !l7.(3) 57 77 tab; choix_st !l7.(4) 57 77 tab; choix_st !l7.(5) 57 77 tab; choix_st !l7.(6) 60 80 tab; choix_st !l7.(7) 60 80 tab; choix_st !l7.(8) 60 80 tab|];
        l8 :=  [|choix_st !l8.(0) 54 74 tab; choix_st !l8.(1) 54 74 tab; choix_st !l8.(2) 54 74 tab; choix_st !l8.(3) 57 77 tab; choix_st !l8.(4) 57 77 tab; choix_st !l8.(5) 57 77 tab; choix_st !l8.(6) 60 80 tab; choix_st !l8.(7) 60 80 tab; choix_st !l8.(8) 60 80 tab|];
        l9 :=  [|choix_st !l9.(0) 54 74 tab; choix_st !l9.(1) 54 74 tab; choix_st !l9.(2) 54 74 tab; choix_st !l9.(3) 57 77 tab; choix_st !l9.(4) 57 77 tab; choix_st !l9.(5) 57 77 tab; choix_st !l9.(6) 60 80 tab; choix_st !l9.(7) 60 80 tab; choix_st !l9.(8) 60 80 tab|]
        in
        (* Il nous reste a recréer le tableau avec la récurrence, a nouveau, même code en plus long*)
        
        let reforme tab= 
        for k = 0 to 8 do
        if (list_length !l1.(k) 0)=1 & tab.(k)=0  then tab.(k)<- hd (!l1.(k)) done;
        for k = 9 to 17 do
        if (list_length !l2.(k-9) 0)=1 & tab.(k)=0 then tab.(k)<- hd (!l2.(k-9)) done;
        for k = 18 to 26 do
        if (list_length !l3.(k-18) 0)=1 & tab.(k)=0 then tab.(k)<- hd (!l3.(k-18))done;
        for k = 27 to 35 do
        if (list_length !l4.(k-27) 0)=1 & tab.(k)=0 then tab.(k)<- hd (!l4.(k-27)) done;
        for k = 36 to 44 do
        if (list_length !l5.(k-36) 0)=1 & tab.(k)=0 then tab.(k)<- hd (!l5.(k-36)) done;
        for k = 45 to 53 do
        if (list_length !l6.(k-45) 0)=1 & tab.(k)=0 then tab.(k)<- hd (!l6.(k-45)) done;
        for k = 54 to 62 do
        if (list_length !l7.(k-54) 0)=1 & tab.(k)=0 then tab.(k)<- hd (!l7.(k-54)) done;
        for k = 63 to 71 do
        if (list_length !l8.(k-63) 0)=1 & tab.(k)=0 then tab.(k)<- hd (!l8.(k-63)) done;
        for k = 72 to 80 do
        if (list_length !l9.(k-72) 0)=1 & tab.(k)=0 then tab.(k)<- hd (!l9.(k-72)) done;      
        in  
        (* La on crée la fonction qui va recréer le tableau *) 
        
        let rec final_tot tab nb = match tab,nb with
        | _,500 -> raise TropComplique
        | tab,_ when (appartient_t 0 tab 0 15) = true ->  def_l1 !l1 tab; 
        													def_l2 !l2 tab; 
        													def_l3 !l3 tab; 
        													def_l4 !l4 tab;
        													def_l5 !l5 tab;
        													def_l6 !l6 tab;
        													def_l7 !l7 tab;
        													def_l8 !l8 tab;
        													def_l9 !l9 tab;
        													change !l1;
        													change !l2;
        													change !l3;
        													change !l4;
        													change !l5;
        													change !l6;
        													change !l7;
        													change !l8;
        													change !l9;
        													total_li tab; 
        													total_col tab; 
        													total_st tab; 
        													reforme tab; 
        													(final_tot tab (nb + 1));
        | tab,_ -> tab in
        
        try final_tot !tab2 0 with TropComplique ->[|0|];;
        
        (* Et après test, ca marche du tonerre ! *)

        Améliorable je dirais, notamment parce qu'il ne sait pas faire de supposition.

        • Partager sur Facebook
        • Partager sur Twitter
          1 avril 2013 à 16:42:18

          Je connais pas ce langage mais je suppose que c'est du mega-heurisitique à ce que je vois. Très honnêtement ce n'est pas très intéressant sans passer par les singleton cachés qui ne sont pas accessibles par un backtraking et qui sont la sources de pas mal de solutions (en particulier pour les sudoku très difficiles). 

          Et puis quitte à passer par des heuristiques, autant ne pas limiter la taille du tableau mais laisser à l'utilisateur le choix, c'est long à écrire et chiant à lire mais moins complexe, alors autant en profiter ;)

          Je pense que tu devrais essayer de faire un backtraking avec un tri au début pour avoir un ordre des cases avec un nombre de possibilités croissant, ça limite la casse et c'est un autre point de vu assez intéressant à faire.

          • Partager sur Facebook
          • Partager sur Twitter
            7 avril 2013 à 11:30:56

            En effet, il manque au code des manières de raisonner, ce qu'il fait qu'il ne trouve pas de solution alors qu'il devrait. Reste le cas des hypothèses à faire, mais là, j'y suis pas encore.

            Pour ce qui est de la taille, je vois a  peu près ce que tu veux dire, je l'avais codé pour 9x9 afin d'avoir une approche du problème avec un code que je savais fonctionnel :)

            En revanche, je ne comprends pas ta dernière remarque :o (Même si j'ai p'tet une idée à tester en se basant  sur des représentations matricielles du truc, qui permettrait de tout résoudre de manière très différente )

            • Partager sur Facebook
            • Partager sur Twitter
              7 avril 2013 à 15:54:07

              Le backtraking y a un exemple dans les tutos (et c'est même fait pour les sudoku !)

              Pour ce qui est d'un premier tri il faudrait évaluer l'ensembles des solutions possibles et trier l'ordre de passage par nombre de solutions possibles, c'est au premier passage forcément la meilleur manière de résoudre, par la suite par forcément mais au vu du coût de calculer le nombre de possibilités, une fois suffit pour déjà optimiser pas mal, après le faire toutes les 10 cases pourquoi pas, à toi de voir :)

              • Partager sur Facebook
              • Partager sur Twitter
                10 juin 2013 à 21:24:53

                Je vais faire le langage le plus facile pour ça, le Ruby. La grande force de Ruby, c'est justement que sa librairie standard contient vraiment énormément de choses, donc la majeure partie des algorithmes ici ne sont pas vraiment un problème (appel à une méthode quoi). Donc PGCD, PPCM, tris, mélange aléatoires, changement de base, ça se résume en 1 méthode,  cf. doc !

                Calcul de factorielle :

                Ici il y'a plein de façons, tous les algorithmes utilisés dans les autres langages sont parfaitement adaptables au Ruby... Mais bon, allons-y pour une solution purement Ruby, plutôt performante (factorielle 400 calculé en... juste le temps de cligner des yeux)

                class Integer
                  def factorial
                    (1..self).reduce(:*)
                  end
                end
                
                400.factorial
                #=> ... trop long à écrire 

                Crible d'Eratosthènes : 

                Une version très optimisée du pseudo-code de Wikipedia...

                def sieve(n)
                  s = (0..n).to_a
                  s[0] = s[1] = nil
                  s.each do |p|
                    next unless p
                    break if p * p > n
                    (p*p).step(n, p) { |m| s[m] = nil }
                  end
                  s.compact
                end

                Décomposition en facteurs premiers : 

                Là y'a 2 écoles : la beauté du code, ou l'efficacité. Première solution, totalement naïve, lente mais jolie. Sur des petits nombres, vous sentirez pas la différence de toute façon

                def prime_factors(i)
                  v = (2..i-1).detect{|j| i % j == 0} 
                  v ? ([v] + prime_factors(i/v)) : [i]
                end

                Deuxième solution, beaucoup plus complexe, mais infiniment plus rapide

                def prime_factors(i)
                  factors = []
                
                  # Les lambda, c'est la vie
                  check = proc do |p|
                    while(q, r = i.divmod(p)
                          r.zero?)
                      factors << p
                      i = q
                    end
                  end
                
                  check[2]
                  check[3]
                  p = 5
                
                  while p * p <= i
                    check[p]
                    p += 2
                    check[p]
                    p += 4    # Osef des multiples de 2 et 3
                  end
                
                  factors << i if i > 1
                  factors
                end

                Voilà pour une petite contribution, je repasserai à l'occasion ;)




                -
                Edité par stdio.h 10 juin 2013 à 21:32:07

                • Partager sur Facebook
                • Partager sur Twitter
                  10 juin 2014 à 19:20:44

                  Salut,

                  J'ai écris un algo de décomposition d'un nombre en facteur premier en TI-Basic (version traduite) et je suis tombé un peu après sur ce sujet. C'est un algo utile en Terminale S spe Math alors le voilà :

                  Décomposition d'un entier en facteurs premiers :

                  //Initialisation
                  :[[1][1->[A] :1->D:0->C :Prompt N
                  //On commence par faire pour 2
                  :While non(partDec(.5N :.5N->N :C+1->C :End :If C: Then :C->[A](1,1 :2->[A](2,1 :2->D :End //Ensuite on répete la même opération pour les nombres impaires :For(I,3,sqrt(N),2 :0->C :While non(partDec(N/I //tant que N/I est entier :N/I->N :C+1->C :End :If C: Then :{2,D->dim([A] :C->[A](1,X :I->[A](2,X :X+1->X :End :If N=1:Goto 0 //on sort prématurement de la boucle si N=1 :End //end for :{2,D->dim([A] :1->[A](1,X :N->[A](2,X :Lbl 0 :[A] //on affiche la matrice

                  Note : Les // désigne un commentaire mais ne sont pas valide en Ti c'est juste pour ici. sqrt est les racine carré. [A] est la matrice A. L'avantage de cet algo c'est qu'il présente le résultat sous la forme de cette matrice. Dans la ligne du bas il y a les facteurs premier et dans la ligne du haut les puissance. Par exemple pour N = 198 (2*3^2*11) la sortie est :

                  [[1 2 1  ]
                   [2 3 11 ]]


                  Pour le bout de code qu'il y a entre le end du for et le lbl 0, il est la car si N est différent de 1 quand on sort de la boucle alors N est forcement un nombre premier facteur du nombre initial.

                  Comme c'est pour une calculette la vitesse est importante. C'est pour cela que l'on ne passe pas en revus les nombres pairs et que l'on fait 2 à part et aussi que l'on ne dépasse pas la racine carré du nombre initial.

                  -
                  Edité par WorkInProgress 10 juin 2014 à 19:28:46

                  • Partager sur Facebook
                  • Partager sur Twitter
                  Ce que j'ai appris sur le *SDZ* : Blender, Python, TI-Basic, C, C++, JavaScript, HTML
                    1 juillet 2014 à 1:32:48

                    Salut tout le monde :)

                    Shareman, je t'ai envoyé un MP, mais je me suis rendu compte peu après que j'avais deux trois algo en perl qui correspondait au sujet (en plus de celui que je t'ai envoyé).

                    Perso en Perl j'ai :

                    -Un programme qui, à la manière d'une bruteforce pour trouver un mot de passe, va tester tous les nombres entiers pour voir s'ils répondent à la conjecture de Syracuse jusqu'à ce qu'on lui dise de s'arrêter. Il existe en plusieurs versions, dont une qui écrit le nombre d'étapes avant d'arriver à 1.

                    -Un programme qui teste tous les nombres entier pour voir s'ils sont premiers, et note dans un fichier texte ceux qui le sont.

                    -Un programme qui calcule le nombre total de carrés compris dans un carré que l'on aurait divisé en 4 n fois. (Je sais pas tellement si c'est clair, dites-moi si cela vous est obscur ^^ )

                    -Un programme qui fait la même chose, mais ce avec des triangles équilatéraux que l'on divise à la manière d'une triforce.

                    Sinon, comme je l'ai proposé à shareman, j'ai un traducteur Français => Leet_Speak qui existe à différents niveaux d'encodage.

                    Voila, parmi eux, lesquels devrai-je poster ? ^^

                    Ah une dernière chose : Qu'est-ce que la complexité ? Comment l'exprime-t-on/la calcule-t-on ?

                    Merci d'avance :)

                    • Partager sur Facebook
                    • Partager sur Twitter
                      11 novembre 2016 à 20:25:31


                      jaguar001 a écrit:

                      Methode d'arrondi sur une precision près
                      Je pense que beaucoup de monde la demande cette petite méthode bien pratique, et même si elle n'est pas bien difficile l'avoir sous la main est bien plus agréable.

                      Principe
                      Cette méthode quelque soit le langage est implémentée et utilisable de la même façon.
                      Elle permet de garder autant de chiffres que l'on souhaite derrière la virgule.
                      Il y a deux paramètres :
                      - nber : le nombre à arrondir
                      - precision : précision (10eme, 100eme, 1000eme...)

                      Exemple si besoin est :
                      Si on a 100.22234444 et que l'on souhaite une precision au centieme près
                      alors la valeur des paramètres est : nber = 100.22234444 et precision = 100
                      On aura comme réponse 100.22 comme souhaité

                      Les différents langages

                      public static double arrondir(double nber, int precision)
                                   {
                      	             double result = (int)(nber*precision);
                      	             return result/precision;
                                   }
                      



                      double arrondir(double nber, int precision)
                      {
                      	int result = (int)(nber*precision);
                      	return result/precision;
                      }
                      



                      let arrondir (nber:float) (precision:int) = 
                      	let prec = float_of_int(precision) in
                      		let result = int_of_float(nber*.prec)  in 
                      			float_of_int(result)/.prec;;
                      



                      (define (arrondir nber precision)
                      	(let* ((result ( * nber precision)))
                                
                                (/ (round result) precision)))
                      



                      def arrondir(nber, precision) :
                      	result = int(nber*precision)
                      	return result/(1.0*precision)
                      



                      Conclusion
                      Voilà je pense que c'est pas mal, je n'ai pas dit que c'était parfait et qu'il n'y a pas moyen de faire plus condenser mais j'ai voulu faire clair et visuel dans les codes.
                      J'espère que vous apprécierez.


                      Cette approche de l'arithmétique des machines est un peu naïve:

                      $ cat arrondi.c
                      #include <stdio.h>
                      
                      int main(int argc, char **argv) {
                      
                        printf("4.22= %.40f\n", 4.22);
                      
                      
                        float x=4.22;
                      
                        printf("4.22  * 100  - 422 = %.40f\n", 100*x - 422);
                      
                      }

                      A l'exécution:

                      4.22= 4.2199999999999997513100424839649349451065
                      4.22  * 100  - 422 = -0.0000305175781250000000000000000000000000

                      Les ordinateurs ne savent manipuler avec les types float et double, que des nombres représentées par une somme de puissances de deux.

                      Donc arrondir 0.11 en 0.1 va revenir te hanter beaucoup plus tard.. Après si c'est juste pour un programme jetable sans utilisateurs et qui compile  juste une fois, OK. Sinon... You're gonna have a BAD TIME !!

                      • Partager sur Facebook
                      • Partager sur Twitter
                        9 décembre 2017 à 13:10:49

                        salut les amis  

                        je suis vraiment bloqué ; je sens l’odeur de backtracking mais je pas trouver comment  .

                        je veux vérifier si un tableau de chaine de caractère peut être ordonné de façon que chaque chaine commence avec la dernière lettre de la précédente si oui on doit afficher une solution sinon an affiche que ce impossible {on doit utiliser tous les mots } 
                        exmple :
                        358 123 874 826 638
                        on doit afficher oui ce possible et la solution est :123358 826 638 874
                        alors pour :521 894 189 577 400 on affiche impossible

                        merci de m'aider par une solution.

                        • Partager sur Facebook
                        • Partager sur Twitter
                        Anonyme
                          14 décembre 2017 à 18:20:05

                          ordonne chacune de tes chaines, ordonnes les entre elles, et regarde si ca marche (est ce que la dernière lettre est la première de la chaine suivante) peut etre ? :/
                          • Partager sur Facebook
                          • Partager sur Twitter
                            18 mars 2018 à 20:07:30

                            @mouradj2006

                            Tu doit effectivement pouvoir trouver une solution avec du backtracking.

                            Le plus simple pour faire ça c'est d'utiliser une fonction récursive.

                            liste = ['123', '45', '25', '99', '7582', '564', '51']
                            
                            def ranger(l, acc):  # l est la liste des elements qu'il reste a ranger, acc est la liste des elements déja rangé
                                if len(l) == 0:  # si l est vide c'est que ça marche
                                    return acc
                                else:
                                    for i, el in enumerate(l):  # on essaye chaque element restant
                                        if len(acc) == 0 or acc[-1][-1] == el[0]:  # si ça colle on continue
                                            acc.append(l.pop(i))  # on déplace l'element d'une liste à l'autre
                                            res = ranger(l, acc)  # et on essaye de continuer
                                            if res:  # si res n'est pas None c'est qu'on a reussi
                                                return res  # on fait remonter
                                            else:  # sinon on remet l'element a sa place et on passe au suivant
                                                l.insert(i, acc.pop())
                                    return None  # si aucun element ne fait l'affaire on renvoie None pour signaler qu'on est dans une impasse
                            
                            res = ranger(l, [])
                            
                            if res:
                                print("C'est possible !", res)
                            else:
                                print("C'est impossible.")
                            


                            Oups j'avais pas vu la date de la question désolé :/

                            -
                            Edité par WorkInProgress 18 mars 2018 à 20:09:53

                            • Partager sur Facebook
                            • Partager sur Twitter
                            Ce que j'ai appris sur le *SDZ* : Blender, Python, TI-Basic, C, C++, JavaScript, HTML

                            Algorithmes divers multi-langage

                            × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                            × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                            • Editeur
                            • Markdown