Advertisement
Guest User

Untitled

a guest
Jan 24th, 2018
73
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.38 KB | None | 0 0
  1. (* Autor: Jan Kociniak
  2. Reviewer: Piotr Wojtczak
  3. WPF 2017Z - Przelewanka *)
  4.  
  5.  
  6. exception Solution of int
  7.  
  8. (* funkcja generujaca liste osiagalnych stanów, ktore nie sa jeszcze rozwiazaniem *)
  9. (* arr - poczatkowy stan, d - liczba krokow, comp - to co chcemy osiagnac *)
  10.  
  11. let states (arr, d) comp =
  12. let n = Array.length arr and d1 = d+1 and l = ref [] in
  13. for i = 0 to n-1 do
  14. let (xi, yi) = arr.(i) in
  15. (* dolanie do pełna i-tej szklanki *)
  16. arr.(i) <- (xi, xi);
  17. if arr = comp then raise (Solution (d1))
  18. else
  19. l := (Array.copy arr, d1)::!l;
  20. (* oproznienie i-tej szklanki *)
  21. arr.(i) <- (xi, 0);
  22. if arr = comp then raise (Solution (d1))
  23. else
  24. l := (Array.copy arr, d1)::!l;
  25. (* reset *)
  26. arr.(i) <- (xi, yi);
  27. for j = i+1 to n-1 do
  28. let (xj, yj) = arr.(j) in
  29. (* przelanie z i do j *)
  30. arr.(j) <- (xj, min (yj + yi) xj);
  31. arr.(i) <- (xi, max 0 (yi - xj + yj));
  32. if arr = comp then raise (Solution (d1))
  33. else
  34. l := (Array.copy arr, d1)::!l;
  35. (* przelanie z j do i *)
  36. arr.(i) <- (xi, min (yi + yj) xi);
  37. arr.(j) <- (xj, max 0 (yj - xi + yi));
  38. if arr = comp then raise (Solution (d1))
  39. else
  40. l := (Array.copy arr, d1)::!l;
  41. (* reset *)
  42. arr.(i) <- (xi, yi);
  43. arr.(j) <- (xj, yj);
  44. done;
  45. done;
  46. !l
  47.  
  48. let gcd arr =
  49. let rec euclid a b =
  50. let (m, n) = (max a b, min a b) in
  51. if n = 0 then m else euclid (m mod n) n
  52. in
  53. let gcd_x = Array.fold_left (fun a (x, _) -> euclid a x) 0 arr in
  54. Array.fold_left (fun a (_, y) -> a && y mod gcd_x = 0) true arr
  55.  
  56.  
  57. let bfs arr =
  58. if arr = Array.map (fun (x, _) -> (x, 0)) arr then 0 else
  59. if not (gcd arr) then -1 else
  60. let q = Queue.create()
  61. and been = Hashtbl.create 1000000
  62. and start = Array.map (fun (x, _) -> (x, 0)) arr in
  63. let filter (x, d) =
  64. if Hashtbl.mem been x = false then begin
  65. Queue.add (x, d) q;
  66. Hashtbl.add been x true; end
  67. in
  68. Hashtbl.add been start true;
  69. Queue.add (start, 0) q;
  70. while not (Queue.is_empty q) do
  71. let act = Queue.take q in
  72. List.iter filter (states act arr);
  73. done;
  74. -1
  75.  
  76. let przelewanka arr =
  77. try bfs arr with
  78. | Solution(x) -> x
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement