Advertisement
Guest User

Untitled

a guest
Jan 21st, 2020
120
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
OCaml 2.24 KB | None | 0 0
  1. let warunek_konieczny n kubelki =
  2.   let nwd a b =
  3.     if y = 0 || x = 0 then x + y
  4.     else nwd (min a b) ((max a b) mod (min a b))
  5.   in
  6.   let wspolny_dzielnik = ref 0 in
  7.   for i = 0 to (n - 1) do
  8.     wspolny_dzielnik := nwd !wspolny_dzielny (fst kubelki.(i))
  9.   done;
  10.   let wynik = ref true in
  11.   for i = 0 to (n - 1) do
  12.     if (snd kubelki.(i)) mod wspolny_dzielnik <> 0 then wynik := false;
  13.   done;
  14.   !wynik
  15.  
  16. let przelewanka kubelki =
  17.   let wynik = ref -1 in
  18.   let n = Array.size kubelki in
  19.   if warunek_konieczny n kubelki = true then
  20.   begin
  21.     let koniec = Array.init n (fun i -> snd kubelki.(i)) in
  22.     let stan_poczatkowy = Array.make n 0 in
  23.     let q = Queue.create in
  24.     Queue.add stan_poczatkowy q;
  25.     let liczba_krokow = ref 0 in
  26.     let znaleziono_wynik = ref false in
  27.     let visited = Hashtbl.create in
  28.     Hashtbl.add visited stan_poczatkowy 0;
  29.     while Queue.length <> 0 && !znaleziono_wynik = false do
  30.       let x = Queue.take q in
  31.       let cur_odl = Hashtbl.find visited x in
  32.       if x = koniec then
  33.       begin
  34.         znaleziono_wynik := true;
  35.         wynik := cur_odl;
  36.       end;
  37.       (* Wylewanie *)
  38.       for i = 0 to (n - 1) do
  39.         let stan = Array.copy x in
  40.         stan.(i) <- 0;
  41.         if not (Hashtbl.mem visited stan) then
  42.         begin
  43.           visited := Hashtbl.add visited stan;
  44.           Queue.add stan q;
  45.         end
  46.       done;
  47.       (* Wlewanie *)
  48.       for i = 0 to (n - 1) do
  49.         let stan = Array.copy x in
  50.         stan.(i) <- (fst kubelki.(i));
  51.         if not (Hashtbl.mem visited stan) then
  52.         begin
  53.           visited := Hashtbl.add visited stan;
  54.           Queue.add stan q;
  55.         end
  56.       done;
  57.       (* Przelewanie *)
  58.       for i = 0 to (n - 1) do
  59.         for j = 0 to (n - 1) do
  60.           if i <> j then
  61.           begin
  62.             let stan = Array.copy x in
  63.             let zmiana = min stan.(i) ((fst kubelki.(j)) - x.(j)) in
  64.             stan.(i) <- stan.(i) - zmiana;
  65.             stan.(j) <- stan.(j) + zmiana;
  66.             if not (Hashtbl.mem visited stan) then
  67.             begin
  68.               visited := Hashtbl.add visited stan;
  69.               Queue.add stan q;
  70.             end
  71.           end;
  72.         done
  73.       done
  74.     done
  75.   end;
  76.   !wynik
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement