Advertisement
Guest User

Untitled

a guest
Jan 23rd, 2018
64
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
OCaml 2.16 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 dorzucajaca do kolejki q wszystkie stany osiagalne ze stanu arr
  9.    z zaktualizowaną liczbą ruchów (jesli nie sa rozwiazaniem) *)
  10.  
  11. let states (arr, d) q comp =
  12.   let n = Array.length arr and d1 = d+1 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)) else
  18.         Queue.add (Array.copy arr, d1) q;
  19.       (* oproznienie i-tej szklanki *)
  20.       arr.(i) <- (xi, 0);
  21.       if arr = comp then raise (Solution (d1)) else
  22.         Queue.add (Array.copy arr, d1) q;
  23.         (* reset *)
  24.         arr.(i) <- (xi, yi);
  25.       for j = i+1 to n-1 do
  26.         let (xj, yj) = arr.(j) in
  27.       (* przelanie z i do j *)
  28.         arr.(j) <- (xj, min (yj + yi) xj);
  29.         arr.(i) <- (xi, max 0 (yi - xj + yj));
  30.         if arr = comp then raise (Solution (d1)) else
  31.         Queue.add (Array.copy arr, d1) q;
  32.       (* przelanie z j do i *)
  33.         arr.(i) <- (xi, min (yi + yj) xi);
  34.         arr.(j) <- (xj, max 0 (yj - xi + yi));
  35.         Queue.add (Array.copy arr, d1) q;
  36.         if arr = comp then raise (Solution (d1)) else
  37.         (* reset *)
  38.         arr.(i) <- (xi, yi);
  39.         arr.(j) <- (xj, yj);
  40.       done;
  41.   done
  42.  
  43. let gcd arr =
  44.   let rec euclid a b =
  45.     let (m, n) = (max a b, min a b) in
  46.     if n = 0 then m else euclid (m mod n) n
  47.   in
  48.   let gcd_x = Array.fold_left (fun a (x, _) -> euclid a x) 0 arr in
  49.   Array.fold_left (fun a (_, y) -> a && y mod gcd_x = 0) true arr
  50.  
  51.  
  52. let bfs arr =
  53.   if arr = Array.map (fun (x, _) -> (x, 0)) arr then 0 else
  54.   if not (gcd arr) then -1 else
  55.     let q = Queue.create() and been = Hashtbl.create 1000000 in
  56.        Queue.add ((Array.map (fun (x, _) -> (x, 0)) arr), 0) q;
  57.        while not (Queue.is_empty q) do
  58.          let (st, d) = Queue.take q in
  59.          if not (Hashtbl.mem been st) then begin
  60.                Hashtbl.add been st true;
  61.                states (st, d) q arr; end
  62.        done;
  63.        -1
  64.  
  65. let przelewanka arr =
  66.   try bfs arr with
  67.   | Solution(x) -> x
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement