Advertisement
Guest User

Untitled

a guest
Jan 22nd, 2018
60
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
OCaml 3.58 KB | None | 0 0
  1. (* Autor: Gabriel Bożek   *)
  2. (* Code review :  *)
  3.  
  4.  
  5. let nwd a b =
  6.   let rec pom a b =
  7.     if b = 0 then a else pom b (a mod b)
  8.   in
  9.   pom (max a b) (min a b)
  10.  
  11. let array_nwd ar = Array.fold_left (fun acc x -> nwd acc x) 0 ar
  12.  
  13. let array_fst ar2 = Array.init (Array.length ar2) (fun n -> fst (ar2.(n)))
  14.  
  15. let array_snd ar2 = Array.init (Array.length ar2) (fun n -> snd (ar2.(n)))
  16.  
  17.  
  18. (*sprawdza czy jest w ogole szansa, zeby rozwiazanie istniało *)
  19. let check_end_state ar2 =  
  20.   let ar_nwd = array_nwd (array_fst ar2) in
  21.    if ar_nwd = 0 then
  22.     true  (*przypadek gdzie mamy zero szklanek lub szklanki zerowe*)
  23.     else
  24.       (Array.fold_left (fun a (_, y) -> (a && (y mod ar_nwd = 0))) true ar2)
  25.       (*sprawdza czy nwd pojemnosci dzieli koncowe stany *)
  26.       &&
  27.       (Array.fold_left (fun a (x, y) -> (a || x = y || y = 0)) false ar2)
  28.       (*czy ostatni stan jest osiagalny*)
  29.       (*w ostatnim ruchu albo opróżniamy jedną szklanke do 0
  30.         albo jedna dolewamy do zera *)
  31.      
  32. let refill state k capacity= (*dolanie do k szklanki *)    
  33.     let copy = Array.copy state in
  34.     (
  35.       copy.(k) <- capacity.(k);
  36.       copy;
  37.     )
  38.    
  39. let spill state k  = (*opróżnienie k szklanki *)
  40.     let copy = Array.copy state in
  41.     (
  42.       copy.(k) <- 0;
  43.       copy;
  44.     )
  45.    
  46. let pour state k1 k2 capacity = (*przelanie z k1 to k2*)
  47.     let copy = Array.copy state in
  48.       if (capacity.(k2) - copy.(k2) < copy.(k1)) then
  49.               (
  50.                 copy.(k1) <- copy.(k1) - capacity.(k2) + copy.(k2);
  51.                 copy.(k2) <- capacity.(k2);
  52.                 copy;
  53.                 )
  54.             else
  55.               (
  56.                 copy.(k2) <- copy.(k2) + copy.(k1);
  57.                 copy.(k1) <- 0;
  58.                 copy;
  59.               )
  60. (* dodaje do tablicy hashy stan tylko jeśli wczesniej w nim nie byliśmy *)
  61. let add_state hash_table states_queue state time =
  62.   if not (Hashtbl.mem hash_table state) then
  63.   (
  64.     Hashtbl.add hash_table state time;
  65.     Queue.push state states_queue;
  66.   )
  67.  
  68. (*Na kolejkę wrzucamy stany do rozpatrzenia, wrzucamy tylko te ktore
  69.   nie są w tablicy hashy, żeby ich nie rozpatrywać wielokrotnie*)  
  70.  
  71. let przelewanka glass =
  72.   let capacity = array_fst glass in
  73.   let end_state = array_snd glass in
  74.   let size = Array.length glass in
  75.  
  76.   if check_end_state glass then
  77.   (
  78.     let state = Array.make (size) 0 in
  79.     let hash_table = Hashtbl.create 123 in
  80.     let states_queue = Queue.create () in
  81.     let answer = ref (-1) in
  82.       (
  83.         Hashtbl.add hash_table state 0;
  84.         Queue.push state states_queue;
  85.         while (not (Queue.is_empty states_queue) && !answer = -1) do
  86.           let temp_state = Queue.pop states_queue in
  87.           let time = Hashtbl.find hash_table temp_state + 1 in
  88.           if (temp_state=end_state) then (answer := time - 1;)
  89.           (*Z powodu tego, że używamy BFS jest to najszybszy możliwy sposób *)
  90.           else
  91.             (
  92.               for i = 0 to (size - 1) do
  93.               (
  94.                 add_state hash_table states_queue
  95.                                           (refill temp_state i capacity) time;
  96.                 add_state hash_table states_queue (spill temp_state i ) time;
  97.                 for j=0 to (size-1) do
  98.                 if j<>i then add_state hash_table states_queue
  99.                                           (pour temp_state i j capacity) time;
  100.                 done;
  101.                 )
  102.               done;
  103.               );
  104.         done;
  105.         !answer;
  106.         );
  107.   )
  108.   else (-1);;  (* Jeżeli stan końcowy nie osiągalny *)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement