Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- let process_array arr =
- let len = Array.length arr in
- let final_state = Array.make len 0 in
- let max_capacity = Array.make len 0 in
- begin
- for i = 0 to len - 1 do
- max_capacity.(i) <- fst arr.(i);
- final_state.(i) <- snd arr.(i);
- done;
- end;
- (final_state, max_capacity)
- let gcdarray arr =
- let len = Array.length arr in
- let div = ref arr.(0) in
- let c = ref 0 in
- for i = 1 to len - 1 do
- while arr.(i) <> 0 do
- c := !div mod arr.(i);
- div := arr.(i);
- arr.(i) <- !c;
- done;
- done; !div
- let gcd_case final_state max_capacity =
- let len = Array.length final_state in
- let gcdarr = gcdarray (Array.copy max_capacity) in
- let flag = ref 1 in
- begin
- for i = 0 to len - 1 do
- if (final_state.(i) <> max_capacity.(i)) && (final_state.(i) mod gcdarr <> 0) then begin flag := (-1); end;
- done;
- end;
- !flag
- let empty_full_case final_state max_capacity =
- let len = Array.length final_state in
- let count = ref 0 in
- let flag = ref 1 in
- begin
- for i = 0 to len - 1 do
- if (final_state.(i) = max_capacity.(i)) && (max_capacity.(i) <> 0) then (count := !count + 1;)
- else if (final_state.(i) <> max_capacity.(i)) && (final_state.(i) <> 0) then (flag := 0 )
- else (flag := !flag;);
- done;
- end;
- if (!flag = 1) then !count else (-1)
- let przelewanka arr =
- let (final_state, max_capacity) = process_array arr in
- let flag = ref 0 in
- begin
- let a = gcd_case final_state max_capacity in
- let b = empty_full_case final_state max_capacity in
- if a=(-1) then begin flag := (-1) end
- else if b>=0 then begin flag := b end
- else begin flag := (-2) end;
- end;
- if (!flag >= 0) then !flag
- else if (!flag = (-1)) then (-1)
- else
- let len = Array.length arr in
- let current_state = ref (Array.make len 0) in
- let current_moves = ref 0 in
- let generated_state = ref (Array.make len 0) in
- let q = Queue.create () in
- let distance = Hashtbl.create len in
- begin
- Hashtbl.add distance !current_state 0;
- Queue.add !current_state q;
- while Queue.is_empty q = false do
- current_state := Queue.top q;
- Queue.pop q;
- current_moves := Hashtbl.find distance !current_state;
- generated_state := Array.copy !current_state;
- for i = 0 to len - 1 do
- if !current_state.(i) <> 0 then
- begin
- !generated_state.(i) <- 0;
- let x = Array.copy !generated_state in
- if Hashtbl.find_opt distance x = None then
- begin Hashtbl.add distance x (!current_moves + 1); Queue.add x q; end;
- !generated_state.(i) <- !current_state.(i);
- end;
- if !current_state.(i) <> max_capacity.(i) then
- begin
- !generated_state.(i) <- max_capacity.(i);
- let x = Array.copy !generated_state in
- if Hashtbl.find_opt distance x = None then
- begin Hashtbl.add distance x (!current_moves + 1); Queue.add x q; end;
- !generated_state.(i) <- !current_state.(i);
- end;
- for j = 0 to len - 1 do
- if (i <> j) && (!current_state.(i) <> 0) then
- begin
- !generated_state.(i) <- max 0 (!current_state.(i) - max_capacity.(j) + !current_state.(j));
- !generated_state.(j) <- min max_capacity.(j) (!current_state.(j) + !current_state.(i));
- let x = Array.copy !generated_state in
- if Hashtbl.find_opt distance x = None then
- begin Hashtbl.add distance x (!current_moves + 1); Queue.add x q; end;
- end;
- !generated_state.(i) <- !current_state.(i);
- !generated_state.(j) <- !current_state.(j);
- done;
- done;
- if Hashtbl.find_opt distance final_state <> None then Hashtbl.find_opt distance final_state
- else None;
- done;
- end;
- match Hashtbl.find_opt distance final_state with
- | Some x -> x
- | _ -> (-1)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement