794 lines
30 KiB
OCaml
794 lines
30 KiB
OCaml
open Graphics ;;
|
|
|
|
(* SOMMAIRE
|
|
- misc functions : 20 ~ 65
|
|
- main function : 68 - 120
|
|
- type 2 printing: 122 - 270
|
|
- DFS : 275 - 530 (yes the function is that big)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*)
|
|
|
|
Random.self_init () ;;
|
|
|
|
let pi = 3.14159265358979343 ;;
|
|
|
|
let rec ln10 n = match n with
|
|
| k when k < 0 -> failwith "Are you sure about that ?"
|
|
| k when k < 10 -> 0
|
|
| k -> 1 + ln10 (k/10) ;;
|
|
|
|
let delta i j =
|
|
if i = j then 1 else 0 ;;
|
|
|
|
let draw_integer x0 y n0 r =
|
|
(* 7-seg display *)
|
|
let n = ref n0 in
|
|
let size = ln10 n0 in
|
|
let len = r/3 in
|
|
let offset = size*(len/2) in
|
|
for i = 0 to size do
|
|
let x = x0 - (-(1 - delta size 0)*8 - offset + i * (len+8)) in
|
|
if Array.mem (!n mod 10) [|0; 4; 5; 6; 7; 8; 9|] then
|
|
draw_poly_line [|(x-len/2, y+len); (x-len/2, y)|];
|
|
|
|
if Array.mem (!n mod 10) [|0; 2; 3; 5; 6; 7; 8; 9|] then
|
|
draw_poly_line [|(x-len/2, y+len); (x+len/2, y+len)|];
|
|
|
|
if Array.mem (!n mod 10) [|0; 1; 2; 3; 4; 7; 8; 9|] then
|
|
draw_poly_line [|(x+len/2, y+len); (x+len/2, y)|];
|
|
|
|
if Array.mem (!n mod 10) [|2; 3; 4; 5; 6; 8; 9|] then
|
|
draw_poly_line [|(x-len/2, y); (x+len/2, y)|];
|
|
|
|
if Array.mem (!n mod 10) [|0; 1; 3; 4; 5; 6; 7; 8; 9|] then
|
|
draw_poly_line [|(x+len/2, y-len); (x+len/2, y)|];
|
|
|
|
if Array.mem (!n mod 10) [|0; 2; 3; 5; 6; 8; 9|] then
|
|
draw_poly_line [|(x-len/2, y-len); (x+len/2, y-len)|];
|
|
|
|
if Array.mem (!n mod 10) [|0; 2; 6; 8|] then
|
|
draw_poly_line [|(x-len/2, y-len); (x-len/2, y)|];
|
|
|
|
n := !n/10;
|
|
done ;;
|
|
|
|
let identity n = n ;;
|
|
|
|
let square x = x *. x ;;
|
|
|
|
let norm_int v1 v2 =
|
|
Float.sqrt (square (float_of_int ((fst v2) - (fst v1))) +. square (float_of_int ((snd v2) - -snd v1))) ;;
|
|
|
|
let improved_pretty_printing g wd ht r =
|
|
let n = Array.length g in
|
|
let coords = Array.make n (0, 0) in
|
|
|
|
let colors = Array.make n (rgb 0 0 0) in
|
|
for i = 0 to n-1 do
|
|
colors.(i) <- rgb ((255 * i) / n) ((255*(i+n/3)) / n) ((255*(2*i+n/3)) / n)
|
|
done;
|
|
|
|
for k = 0 to n-1 do
|
|
let theta = 2. *. pi *. (float_of_int k) /. (float_of_int (n)) +. pi /. (float_of_int (n)) in
|
|
let i = ref (int_of_float ((float_of_int wd) /. 2.) + int_of_float ((float_of_int wd) /. 2.2 *. cos theta)) in
|
|
let j = ref (int_of_float ((float_of_int ht) /. 2.) + int_of_float ((float_of_int ht) /. 2.2 *. sin theta)) in
|
|
set_line_width 8 ;
|
|
set_color colors.(k) ;
|
|
draw_circle !i !j r;
|
|
coords.(k) <- (!i, !j)
|
|
done ;
|
|
|
|
set_line_width 4 ;
|
|
set_color black ;
|
|
for k = 0 to n-1 do
|
|
for l = 0 to (Array.length g.(k))-1 do
|
|
if g.(k).(l) <> (-1) then begin
|
|
draw_poly_line [|coords.(k); coords.(g.(k).(l))|]
|
|
end
|
|
done
|
|
done;
|
|
|
|
set_line_width 8 ;
|
|
for k = 0 to n-1 do
|
|
set_color colors.(k) ;
|
|
for l = 0 to (Array.length g.(k))-1 do
|
|
if g.(k).(l) <> (-1) then begin
|
|
let slope = Float.atan2 (float_of_int (snd coords.(g.(k).(l)) - snd coords.(k))) (float_of_int (fst coords.(g.(k).(l)) - fst coords.(k))) in
|
|
|
|
let nexi = int_of_float (float_of_int (fst coords.(k)) +. (float_of_int r) *. 1.75 *. cos slope) in
|
|
let nexj = int_of_float (float_of_int (snd coords.(k)) +. (float_of_int r) *. 1.75 *. sin slope) in
|
|
draw_poly_line [|coords.(k); (nexi, nexj)|]
|
|
end
|
|
done
|
|
done;
|
|
|
|
for k = 0 to n-1 do
|
|
set_line_width 10 ;
|
|
set_color black ;
|
|
fill_circle (fst coords.(k)) (snd coords.(k)) r;
|
|
set_color colors.(k) ;
|
|
set_line_width 5 ;
|
|
draw_integer (fst coords.(k)) (snd coords.(k)) k r
|
|
done;
|
|
|
|
ignore (Scanf.bscanf Scanf.Scanning.stdin "%d\n" identity) ;;
|
|
|
|
(* Another version *)
|
|
|
|
type node = {tag : int; edges : int array} ;;
|
|
|
|
type type2graph = {width : int ; height : int ; g : node array array} ;;
|
|
(*
|
|
array is length 8 and indicate if there-s a path with the nodes
|
|
[| SO ; O ; NO ; N ; NE ; E ; SE ; S |]
|
|
*)
|
|
|
|
|
|
let generate_type2_graph w h freq inf sup =
|
|
|
|
let weighted_d100 i =
|
|
let res = Random.int 100 in
|
|
if res <= freq then res else (-1)
|
|
in
|
|
|
|
let gr = {width = w ; height = h ; g = Array.make w [||]} in
|
|
for i = 0 to w-1 do
|
|
let init_fct j = {tag = i*h + j; edges = Array.init 8 weighted_d100}
|
|
in
|
|
|
|
gr.g.(i) <- Array.init h init_fct;
|
|
done;
|
|
|
|
gr ;;
|
|
|
|
let another_type_of_graph_printing (gr : type2graph) r d =
|
|
let colors = Array.make_matrix gr.width gr.height (rgb 0 0 0) in
|
|
for i = 0 to gr.width -1 do
|
|
for j = 0 to gr.height -1 do
|
|
if (i*gr.width + j) mod 7 = 0 then
|
|
colors.(i).(j) <- rgb 0 0 200
|
|
|
|
else if (i*gr.width + j) mod 7 = 1 then
|
|
colors.(i).(j) <- rgb 0 200 0
|
|
|
|
else if (i*gr.width + j) mod 7 = 2 then
|
|
colors.(i).(j) <- rgb 0 200 200
|
|
|
|
else if (i*gr.width + j) mod 7 = 3 then
|
|
colors.(i).(j) <- rgb 200 0 0
|
|
|
|
else if (i*gr.width + j) mod 7 = 4 then
|
|
colors.(i).(j) <- rgb 200 0 200
|
|
|
|
else if (i*gr.width + j) mod 7 = 5 then
|
|
colors.(i).(j) <- rgb 200 200 0
|
|
|
|
else
|
|
colors.(i).(j) <- rgb 200 200 200
|
|
done
|
|
done;
|
|
|
|
set_line_width 4;
|
|
set_color black ;
|
|
for i = 0 to gr.width -1 do
|
|
for j = 0 to gr.height -1 do
|
|
let node_xy = ((r + (2*r + d)*i), (r + (2*r + d)*j)) in
|
|
if (i > 0 && j > 0) && gr.g.(i).(j).edges.(0) <> (-1) then begin (* SO *)
|
|
draw_poly_line [|node_xy; (r + (2*r + d)*(i-1)), (r + (2*r + d)*(j-1))|] ;
|
|
end;
|
|
|
|
if (i > 0) && gr.g.(i).(j).edges.(1) <> (-1) then begin (* O *)
|
|
draw_poly_line [|node_xy; (r + (2*r + d)*(i-1)), (r + (2*r + d)*j)|] ;
|
|
end;
|
|
|
|
if (i > 0 && j < gr.height -1) && gr.g.(i).(j).edges.(2) <> (-1) then begin (* NO *)
|
|
draw_poly_line [|node_xy; (r + (2*r + d)*(i-1)), (r + (2*r + d)*(j+1))|] ;
|
|
end;
|
|
|
|
if (j < gr.height -1) && gr.g.(i).(j).edges.(3) <> (-1) then begin (* N *)
|
|
draw_poly_line [|node_xy; (r + (2*r + d)*i), (r + (2*r + d)*(j+1))|] ;
|
|
end;
|
|
|
|
if (i < gr.width-1 && j < gr.height -1) && gr.g.(i).(j).edges.(4) <> (-1) then begin (* NE *)
|
|
draw_poly_line [|node_xy; (r + (2*r + d)*(i+1)), (r + (2*r + d)*(j+1))|] ;
|
|
end;
|
|
|
|
if (i < gr.width-1) && gr.g.(i).(j).edges.(5) <> (-1) then begin (* E *)
|
|
draw_poly_line [|node_xy; (r + (2*r + d)*(i+1)), (r + (2*r + d)*j)|] ;
|
|
end;
|
|
|
|
if (i < gr.width-1 && j > 0) && gr.g.(i).(j).edges.(6) <> (-1) then begin (* SE *)
|
|
draw_poly_line [|node_xy; (r + (2*r + d)*(i+1)), (r + (2*r + d)*(j-1))|] ;
|
|
end;
|
|
|
|
if (j > 0) && gr.g.(i).(j).edges.(7) <> (-1) then begin (* S *)
|
|
draw_poly_line [|node_xy; (r + (2*r + d)*i), (r + (2*r + d)*(j-1))|] ;
|
|
end;
|
|
|
|
done
|
|
done;
|
|
|
|
set_line_width 8;
|
|
for i = 0 to gr.width -1 do
|
|
for j = 0 to gr.height -1 do
|
|
set_color colors.(i).(j) ;
|
|
let node_xy = ((r + (2*r + d)*i), (r + (2*r + d)*j)) in
|
|
if (i > 0 && j > 0) && gr.g.(i).(j).edges.(0) <> (-1) then begin (* SO *)
|
|
draw_poly_line [|node_xy; (2 * (fst node_xy) + r + (2*r + d)*(i-1))/3, (2 * (snd node_xy) + r + (2*r + d)*(j-1))/3|] ;
|
|
end;
|
|
|
|
if (i > 0) && gr.g.(i).(j).edges.(1) <> (-1) then begin (* O *)
|
|
draw_poly_line [|node_xy; (2 * (fst node_xy) + r + (2*r + d)*(i-1))/3, (2 * (snd node_xy) + r + (2*r + d)*j)/3|] ;
|
|
end;
|
|
|
|
if (i > 0 && j < gr.height -1) && gr.g.(i).(j).edges.(2) <> (-1) then begin (* NO *)
|
|
draw_poly_line [|node_xy; (2 * (fst node_xy) + r + (2*r + d)*(i-1))/3, (2 * (snd node_xy) + r + (2*r + d)*(j+1))/3|] ;
|
|
end;
|
|
|
|
if (j < gr.height -1) && gr.g.(i).(j).edges.(3) <> (-1) then begin (* N *)
|
|
draw_poly_line [|node_xy; (2 * (fst node_xy) + r + (2*r + d)*i)/3, (2 * (snd node_xy) + r + (2*r + d)*(j+1))/3|] ;
|
|
end;
|
|
|
|
if (i < gr.width-1 && j < gr.height -1) && gr.g.(i).(j).edges.(4) <> (-1) then begin (* NE *)
|
|
draw_poly_line [|node_xy; (2 * (fst node_xy) + r + (2*r + d)*(i+1))/3, (2 * (snd node_xy) + r + (2*r + d)*(j+1))/3|] ;
|
|
end;
|
|
|
|
if (i < gr.width-1) && gr.g.(i).(j).edges.(5) <> (-1) then begin (* E *)
|
|
draw_poly_line [|node_xy; (2 * (fst node_xy) + r + (2*r + d)*(i+1))/3, (2 * (snd node_xy) + r + (2*r + d)*j)/3|] ;
|
|
end;
|
|
|
|
if (i < gr.width-1 && j > 0) && gr.g.(i).(j).edges.(6) <> (-1) then begin (* SE *)
|
|
draw_poly_line [|node_xy; (2 * (fst node_xy) + r + (2*r + d)*(i+1))/3, (2 * (snd node_xy) + r + (2*r + d)*(j-1))/3|] ;
|
|
end;
|
|
|
|
if (j > 0) && gr.g.(i).(j).edges.(7) <> (-1) then begin (* S *)
|
|
draw_poly_line [|node_xy; (2 * (fst node_xy) + r + (2*r + d)*i)/3, (2 * (snd node_xy) + r + (2*r + d)*(j-1))/3|] ;
|
|
end;
|
|
|
|
done
|
|
done;
|
|
|
|
set_line_width 5;
|
|
for i = 0 to gr.width -1 do
|
|
for j = 0 to gr.height -1 do
|
|
set_color (rgb 48 48 48) ;
|
|
fill_circle (r + (2*r + d)*i) (r + (2*r + d)*j) r ;
|
|
set_color black ;
|
|
draw_circle (r + (2*r + d)*i) (r + (2*r + d)*j) r ;
|
|
set_color colors.(i).(j) ;
|
|
draw_integer (r + (2*r + d)*i) (r + (2*r + d)*j) gr.g.(i).(j).tag r
|
|
done
|
|
done ;
|
|
|
|
ignore (Scanf.bscanf Scanf.Scanning.stdin "%d\n" identity) ;;
|
|
|
|
(* ------------------------------------------------------------*)
|
|
(* ------------------------------------------------------------*)
|
|
(* ------------------------------------------------------------*)
|
|
|
|
let another_type_of_dfs (gr : type2graph) r d =
|
|
let colors = Array.make_matrix gr.width gr.height (rgb 0 0 0) in
|
|
for i = 0 to gr.width -1 do
|
|
for j = 0 to gr.height -1 do
|
|
if (i*gr.width + j) mod 6 = 0 then
|
|
colors.(i).(j) <- rgb 0 0 200
|
|
|
|
else if (i*gr.width + j) mod 6 = 1 then
|
|
colors.(i).(j) <- rgb 0 200 0
|
|
|
|
else if (i*gr.width + j) mod 6 = 2 then
|
|
colors.(i).(j) <- rgb 0 200 200
|
|
|
|
else if (i*gr.width + j) mod 6 = 3 then
|
|
colors.(i).(j) <- rgb 200 0 0
|
|
|
|
else if (i*gr.width + j) mod 6 = 4 then
|
|
colors.(i).(j) <- rgb 200 0 200
|
|
|
|
else
|
|
colors.(i).(j) <- rgb 200 200 0
|
|
done
|
|
done;
|
|
|
|
set_line_width 4;
|
|
set_color (rgb 192 192 192) ;
|
|
for i = 0 to gr.width -1 do
|
|
for j = 0 to gr.height -1 do
|
|
let node_xy = ((r + (2*r + d)*i), (r + (2*r + d)*j)) in
|
|
if (i > 0 && j > 0) && gr.g.(i).(j).edges.(0) <> (-1) then begin (* SO *)
|
|
draw_poly_line [|node_xy; (r + (2*r + d)*(i-1)), (r + (2*r + d)*(j-1))|] ;
|
|
end;
|
|
|
|
if (i > 0) && gr.g.(i).(j).edges.(1) <> (-1) then begin (* O *)
|
|
draw_poly_line [|node_xy; (r + (2*r + d)*(i-1)), (r + (2*r + d)*j)|] ;
|
|
end;
|
|
|
|
if (i > 0 && j < gr.height -1) && gr.g.(i).(j).edges.(2) <> (-1) then begin (* NO *)
|
|
draw_poly_line [|node_xy; (r + (2*r + d)*(i-1)), (r + (2*r + d)*(j+1))|] ;
|
|
end;
|
|
|
|
if (j < gr.height -1) && gr.g.(i).(j).edges.(3) <> (-1) then begin (* N *)
|
|
draw_poly_line [|node_xy; (r + (2*r + d)*i), (r + (2*r + d)*(j+1))|] ;
|
|
end;
|
|
|
|
if (i < gr.width-1 && j < gr.height -1) && gr.g.(i).(j).edges.(4) <> (-1) then begin (* NE *)
|
|
draw_poly_line [|node_xy; (r + (2*r + d)*(i+1)), (r + (2*r + d)*(j+1))|] ;
|
|
end;
|
|
|
|
if (i < gr.width-1) && gr.g.(i).(j).edges.(5) <> (-1) then begin (* E *)
|
|
draw_poly_line [|node_xy; (r + (2*r + d)*(i+1)), (r + (2*r + d)*j)|] ;
|
|
end;
|
|
|
|
if (i < gr.width-1 && j > 0) && gr.g.(i).(j).edges.(6) <> (-1) then begin (* SE *)
|
|
draw_poly_line [|node_xy; (r + (2*r + d)*(i+1)), (r + (2*r + d)*(j-1))|] ;
|
|
end;
|
|
|
|
if (j > 0) && gr.g.(i).(j).edges.(7) <> (-1) then begin (* S *)
|
|
draw_poly_line [|node_xy; (r + (2*r + d)*i), (r + (2*r + d)*(j-1))|] ;
|
|
end;
|
|
|
|
done
|
|
done;
|
|
|
|
set_line_width 8;
|
|
for i = 0 to gr.width -1 do
|
|
for j = 0 to gr.height -1 do
|
|
let node_xy = ((r + (2*r + d)*i), (r + (2*r + d)*j)) in
|
|
if (i > 0 && j > 0) && gr.g.(i).(j).edges.(0) <> (-1) then begin (* SO *)
|
|
draw_poly_line [|node_xy; (2 * (fst node_xy) + r + (2*r + d)*(i-1))/3, (2 * (snd node_xy) + r + (2*r + d)*(j-1))/3|] ;
|
|
end;
|
|
|
|
if (i > 0) && gr.g.(i).(j).edges.(1) <> (-1) then begin (* O *)
|
|
draw_poly_line [|node_xy; (2 * (fst node_xy) + r + (2*r + d)*(i-1))/3, (2 * (snd node_xy) + r + (2*r + d)*j)/3|] ;
|
|
end;
|
|
|
|
if (i > 0 && j < gr.height -1) && gr.g.(i).(j).edges.(2) <> (-1) then begin (* NO *)
|
|
draw_poly_line [|node_xy; (2 * (fst node_xy) + r + (2*r + d)*(i-1))/3, (2 * (snd node_xy) + r + (2*r + d)*(j+1))/3|] ;
|
|
end;
|
|
|
|
if (j < gr.height -1) && gr.g.(i).(j).edges.(3) <> (-1) then begin (* N *)
|
|
draw_poly_line [|node_xy; (2 * (fst node_xy) + r + (2*r + d)*i)/3, (2 * (snd node_xy) + r + (2*r + d)*(j+1))/3|] ;
|
|
end;
|
|
|
|
if (i < gr.width-1 && j < gr.height -1) && gr.g.(i).(j).edges.(4) <> (-1) then begin (* NE *)
|
|
draw_poly_line [|node_xy; (2 * (fst node_xy) + r + (2*r + d)*(i+1))/3, (2 * (snd node_xy) + r + (2*r + d)*(j+1))/3|] ;
|
|
end;
|
|
|
|
if (i < gr.width-1) && gr.g.(i).(j).edges.(5) <> (-1) then begin (* E *)
|
|
draw_poly_line [|node_xy; (2 * (fst node_xy) + r + (2*r + d)*(i+1))/3, (2 * (snd node_xy) + r + (2*r + d)*j)/3|] ;
|
|
end;
|
|
|
|
if (i < gr.width-1 && j > 0) && gr.g.(i).(j).edges.(6) <> (-1) then begin (* SE *)
|
|
draw_poly_line [|node_xy; (2 * (fst node_xy) + r + (2*r + d)*(i+1))/3, (2 * (snd node_xy) + r + (2*r + d)*(j-1))/3|] ;
|
|
end;
|
|
|
|
if (j > 0) && gr.g.(i).(j).edges.(7) <> (-1) then begin (* S *)
|
|
draw_poly_line [|node_xy; (2 * (fst node_xy) + r + (2*r + d)*i)/3, (2 * (snd node_xy) + r + (2*r + d)*(j-1))/3|] ;
|
|
end;
|
|
|
|
done
|
|
done;
|
|
|
|
set_line_width 5;
|
|
for i = 0 to gr.width -1 do
|
|
for j = 0 to gr.height -1 do
|
|
set_color (rgb 192 192 192) ;
|
|
fill_circle (r + (2*r + d)*i) (r + (2*r + d)*j) r ;
|
|
set_color (rgb 100 100 100) ;
|
|
draw_circle (r + (2*r + d)*i) (r + (2*r + d)*j) r ;
|
|
draw_integer (r + (2*r + d)*i) (r + (2*r + d)*j) gr.g.(i).(j).tag r
|
|
done
|
|
done ;
|
|
|
|
let draw_tile i j =
|
|
set_line_width 5;
|
|
set_color (rgb 48 48 48) ;
|
|
fill_circle (r + (2*r + d)*i) (r + (2*r + d)*j) r ;
|
|
set_color black;
|
|
draw_circle (r + (2*r + d)*i) (r + (2*r + d)*j) r ;
|
|
set_color colors.(i).(j);
|
|
draw_integer (r + (2*r + d)*i) (r + (2*r + d)*j) gr.g.(i).(j).tag r ;
|
|
in
|
|
|
|
(* Now for the actual DFS *)
|
|
let visited = Array.make_matrix gr.width gr.height false in
|
|
|
|
let rec explore i j depth =
|
|
if visited.(i).(j) = false then begin
|
|
visited.(i).(j) <- true;
|
|
|
|
draw_tile i j;
|
|
|
|
set_color white;
|
|
fill_circle (1200-r) (800-r) r;
|
|
set_color black;
|
|
draw_integer (1200-r) (800-r) depth r;
|
|
|
|
Unix.sleepf 0.8;
|
|
|
|
let node_xy = ((r + (2*r + d)*i), (r + (2*r + d)*j)) in
|
|
|
|
if (i > 0 && j > 0) && gr.g.(i).(j).edges.(0) <> (-1) && (visited.(i-1).(j-1) = false) then begin (* SO *)
|
|
set_line_width 4;
|
|
set_color black;
|
|
draw_poly_line [|node_xy; (r + (2*r + d)*(i-1)), (r + (2*r + d)*(j-1))|] ;
|
|
set_color colors.(i).(j);
|
|
set_line_width 8;
|
|
draw_poly_line [|node_xy; (2 * (fst node_xy) + r + (2*r + d)*(i-1))/3, (2 * (snd node_xy) + r + (2*r + d)*(j-1))/3|] ;
|
|
|
|
draw_tile i j;
|
|
|
|
explore (i-1) (j-1) (depth+1) ;
|
|
end;
|
|
|
|
if (i > 0) && gr.g.(i).(j).edges.(1) <> (-1) && (visited.(i-1).(j) = false) then begin (* O *)
|
|
set_line_width 4;
|
|
set_color black;
|
|
draw_poly_line [|node_xy; (r + (2*r + d)*(i-1)), (r + (2*r + d)*j)|] ;
|
|
set_color colors.(i).(j);
|
|
set_line_width 8;
|
|
draw_poly_line [|node_xy; (2 * (fst node_xy) + r + (2*r + d)*(i-1))/3, (2 * (snd node_xy) + r + (2*r + d)*j)/3|] ;
|
|
|
|
draw_tile i j;
|
|
|
|
explore (i-1) j (depth+1);
|
|
end;
|
|
|
|
if (i > 0 && j < gr.height -1) && gr.g.(i).(j).edges.(2) <> (-1) && (visited.(i-1).(j+1) = false) then begin (* NO *)
|
|
set_line_width 4;
|
|
set_color black;
|
|
draw_poly_line [|node_xy; (r + (2*r + d)*(i-1)), (r + (2*r + d)*(j+1))|] ;
|
|
set_color colors.(i).(j);
|
|
set_line_width 8;
|
|
draw_poly_line [|node_xy; (2 * (fst node_xy) + r + (2*r + d)*(i-1))/3, (2 * (snd node_xy) + r + (2*r + d)*(j+1))/3|] ;
|
|
|
|
draw_tile i j;
|
|
|
|
explore (i-1) (j+1) (depth+1);
|
|
end;
|
|
|
|
if (j < gr.height -1) && gr.g.(i).(j).edges.(3) <> (-1) && (visited.(i).(j+1) = false) then begin (* N *)
|
|
set_line_width 4;
|
|
set_color black;
|
|
draw_poly_line [|node_xy; (r + (2*r + d)*i), (r + (2*r + d)*(j+1))|] ;
|
|
set_color colors.(i).(j);
|
|
set_line_width 8;
|
|
draw_poly_line [|node_xy; (2 * (fst node_xy) + r + (2*r + d)*i)/3, (2 * (snd node_xy) + r + (2*r + d)*(j+1))/3|] ;
|
|
|
|
draw_tile i j;
|
|
|
|
explore i (j+1) (depth+1);
|
|
end;
|
|
|
|
if (i < gr.width-1 && j < gr.height -1) && gr.g.(i).(j).edges.(4) <> (-1) && (visited.(i+1).(j+1) = false) then begin (* NE *)
|
|
set_line_width 4;
|
|
set_color black;
|
|
draw_poly_line [|node_xy; (r + (2*r + d)*(i+1)), (r + (2*r + d)*(j+1))|] ;
|
|
set_color colors.(i).(j);
|
|
set_line_width 8;
|
|
draw_poly_line [|node_xy; (2 * (fst node_xy) + r + (2*r + d)*(i+1))/3, (2 * (snd node_xy) + r + (2*r + d)*(j+1))/3|] ;
|
|
|
|
draw_tile i j;
|
|
|
|
explore (i+1) (j+1) (depth+1);
|
|
end;
|
|
|
|
if (i < gr.width-1) && gr.g.(i).(j).edges.(5) <> (-1) && (visited.(i+1).(j) = false) then begin (* E *)
|
|
set_line_width 4;
|
|
set_color black;
|
|
draw_poly_line [|node_xy; (r + (2*r + d)*(i+1)), (r + (2*r + d)*j)|] ;
|
|
set_color colors.(i).(j);
|
|
set_line_width 8;
|
|
draw_poly_line [|node_xy; (2 * (fst node_xy) + r + (2*r + d)*(i+1))/3, (2 * (snd node_xy) + r + (2*r + d)*j)/3|] ;
|
|
|
|
draw_tile i j;
|
|
|
|
explore (i+1) j (depth+1);
|
|
end;
|
|
|
|
if (i < gr.width-1 && j > 0) && gr.g.(i).(j).edges.(6) <> (-1) && (visited.(i+1).(j-1) = false) then begin (* SE *)
|
|
set_line_width 4;
|
|
set_color black;
|
|
draw_poly_line [|node_xy; (r + (2*r + d)*(i+1)), (r + (2*r + d)*(j-1))|] ;
|
|
set_color colors.(i).(j);
|
|
set_line_width 8;
|
|
draw_poly_line [|node_xy; (2 * (fst node_xy) + r + (2*r + d)*(i+1))/3, (2 * (snd node_xy) + r + (2*r + d)*(j-1))/3|] ;
|
|
|
|
draw_tile i j;
|
|
|
|
explore (i+1) (j-1) (depth+1);
|
|
end;
|
|
|
|
if (j > 0) && gr.g.(i).(j).edges.(7) <> (-1) && (visited.(i).(j-1) = false) then begin (* S *)
|
|
set_line_width 4;
|
|
set_color black;
|
|
draw_poly_line [|node_xy; (r + (2*r + d)*i), (r + (2*r + d)*(j-1))|] ;
|
|
set_color colors.(i).(j);
|
|
set_line_width 8;
|
|
draw_poly_line [|node_xy; (2 * (fst node_xy) + r + (2*r + d)*i)/3, (2 * (snd node_xy) + r + (2*r + d)*(j-1))/3|] ;
|
|
|
|
draw_tile i j;
|
|
|
|
explore i (j-1) (depth+1);
|
|
end;
|
|
|
|
end
|
|
in
|
|
|
|
explore (gr.width/2) (gr.height/2) 0;
|
|
|
|
ignore (Scanf.bscanf Scanf.Scanning.stdin "%d\n" identity) ;;
|
|
|
|
(* ------------------------------------------------------------*)
|
|
(* ------------------------------------------------------------*)
|
|
(* ------------------------------------------------------------*)
|
|
|
|
let another_type_of_bfs (gr : type2graph) r d =
|
|
let colors = Array.make_matrix gr.width gr.height (rgb 0 0 0) in
|
|
for i = 0 to gr.width -1 do
|
|
for j = 0 to gr.height -1 do
|
|
if (i*gr.width + j) mod 6 = 0 then
|
|
colors.(i).(j) <- rgb 0 0 200
|
|
|
|
else if (i*gr.width + j) mod 6 = 1 then
|
|
colors.(i).(j) <- rgb 0 200 0
|
|
|
|
else if (i*gr.width + j) mod 6 = 2 then
|
|
colors.(i).(j) <- rgb 0 200 200
|
|
|
|
else if (i*gr.width + j) mod 6 = 3 then
|
|
colors.(i).(j) <- rgb 200 0 0
|
|
|
|
else if (i*gr.width + j) mod 6 = 4 then
|
|
colors.(i).(j) <- rgb 200 0 200
|
|
|
|
else
|
|
colors.(i).(j) <- rgb 200 200 0
|
|
done
|
|
done;
|
|
|
|
set_line_width 4;
|
|
set_color (rgb 192 192 192) ;
|
|
for i = 0 to gr.width -1 do
|
|
for j = 0 to gr.height -1 do
|
|
let node_xy = ((r + (2*r + d)*i), (r + (2*r + d)*j)) in
|
|
if (i > 0 && j > 0) && gr.g.(i).(j).edges.(0) <> (-1) then begin (* SO *)
|
|
draw_poly_line [|node_xy; (r + (2*r + d)*(i-1)), (r + (2*r + d)*(j-1))|] ;
|
|
end;
|
|
|
|
if (i > 0) && gr.g.(i).(j).edges.(1) <> (-1) then begin (* O *)
|
|
draw_poly_line [|node_xy; (r + (2*r + d)*(i-1)), (r + (2*r + d)*j)|] ;
|
|
end;
|
|
|
|
if (i > 0 && j < gr.height -1) && gr.g.(i).(j).edges.(2) <> (-1) then begin (* NO *)
|
|
draw_poly_line [|node_xy; (r + (2*r + d)*(i-1)), (r + (2*r + d)*(j+1))|] ;
|
|
end;
|
|
|
|
if (j < gr.height -1) && gr.g.(i).(j).edges.(3) <> (-1) then begin (* N *)
|
|
draw_poly_line [|node_xy; (r + (2*r + d)*i), (r + (2*r + d)*(j+1))|] ;
|
|
end;
|
|
|
|
if (i < gr.width-1 && j < gr.height -1) && gr.g.(i).(j).edges.(4) <> (-1) then begin (* NE *)
|
|
draw_poly_line [|node_xy; (r + (2*r + d)*(i+1)), (r + (2*r + d)*(j+1))|] ;
|
|
end;
|
|
|
|
if (i < gr.width-1) && gr.g.(i).(j).edges.(5) <> (-1) then begin (* E *)
|
|
draw_poly_line [|node_xy; (r + (2*r + d)*(i+1)), (r + (2*r + d)*j)|] ;
|
|
end;
|
|
|
|
if (i < gr.width-1 && j > 0) && gr.g.(i).(j).edges.(6) <> (-1) then begin (* SE *)
|
|
draw_poly_line [|node_xy; (r + (2*r + d)*(i+1)), (r + (2*r + d)*(j-1))|] ;
|
|
end;
|
|
|
|
if (j > 0) && gr.g.(i).(j).edges.(7) <> (-1) then begin (* S *)
|
|
draw_poly_line [|node_xy; (r + (2*r + d)*i), (r + (2*r + d)*(j-1))|] ;
|
|
end;
|
|
|
|
done
|
|
done;
|
|
|
|
set_line_width 8;
|
|
for i = 0 to gr.width -1 do
|
|
for j = 0 to gr.height -1 do
|
|
let node_xy = ((r + (2*r + d)*i), (r + (2*r + d)*j)) in
|
|
if (i > 0 && j > 0) && gr.g.(i).(j).edges.(0) <> (-1) then begin (* SO *)
|
|
draw_poly_line [|node_xy; (2 * (fst node_xy) + r + (2*r + d)*(i-1))/3, (2 * (snd node_xy) + r + (2*r + d)*(j-1))/3|] ;
|
|
end;
|
|
|
|
if (i > 0) && gr.g.(i).(j).edges.(1) <> (-1) then begin (* O *)
|
|
draw_poly_line [|node_xy; (2 * (fst node_xy) + r + (2*r + d)*(i-1))/3, (2 * (snd node_xy) + r + (2*r + d)*j)/3|] ;
|
|
end;
|
|
|
|
if (i > 0 && j < gr.height -1) && gr.g.(i).(j).edges.(2) <> (-1) then begin (* NO *)
|
|
draw_poly_line [|node_xy; (2 * (fst node_xy) + r + (2*r + d)*(i-1))/3, (2 * (snd node_xy) + r + (2*r + d)*(j+1))/3|] ;
|
|
end;
|
|
|
|
if (j < gr.height -1) && gr.g.(i).(j).edges.(3) <> (-1) then begin (* N *)
|
|
draw_poly_line [|node_xy; (2 * (fst node_xy) + r + (2*r + d)*i)/3, (2 * (snd node_xy) + r + (2*r + d)*(j+1))/3|] ;
|
|
end;
|
|
|
|
if (i < gr.width-1 && j < gr.height -1) && gr.g.(i).(j).edges.(4) <> (-1) then begin (* NE *)
|
|
draw_poly_line [|node_xy; (2 * (fst node_xy) + r + (2*r + d)*(i+1))/3, (2 * (snd node_xy) + r + (2*r + d)*(j+1))/3|] ;
|
|
end;
|
|
|
|
if (i < gr.width-1) && gr.g.(i).(j).edges.(5) <> (-1) then begin (* E *)
|
|
draw_poly_line [|node_xy; (2 * (fst node_xy) + r + (2*r + d)*(i+1))/3, (2 * (snd node_xy) + r + (2*r + d)*j)/3|] ;
|
|
end;
|
|
|
|
if (i < gr.width-1 && j > 0) && gr.g.(i).(j).edges.(6) <> (-1) then begin (* SE *)
|
|
draw_poly_line [|node_xy; (2 * (fst node_xy) + r + (2*r + d)*(i+1))/3, (2 * (snd node_xy) + r + (2*r + d)*(j-1))/3|] ;
|
|
end;
|
|
|
|
if (j > 0) && gr.g.(i).(j).edges.(7) <> (-1) then begin (* S *)
|
|
draw_poly_line [|node_xy; (2 * (fst node_xy) + r + (2*r + d)*i)/3, (2 * (snd node_xy) + r + (2*r + d)*(j-1))/3|] ;
|
|
end;
|
|
|
|
done
|
|
done;
|
|
|
|
set_line_width 5;
|
|
for i = 0 to gr.width -1 do
|
|
for j = 0 to gr.height -1 do
|
|
set_color (rgb 192 192 192) ;
|
|
fill_circle (r + (2*r + d)*i) (r + (2*r + d)*j) r ;
|
|
set_color (rgb 100 100 100) ;
|
|
draw_circle (r + (2*r + d)*i) (r + (2*r + d)*j) r ;
|
|
draw_integer (r + (2*r + d)*i) (r + (2*r + d)*j) gr.g.(i).(j).tag r
|
|
done
|
|
done ;
|
|
|
|
let draw_tile i j =
|
|
set_line_width 5;
|
|
set_color (rgb 48 48 48) ;
|
|
fill_circle (r + (2*r + d)*i) (r + (2*r + d)*j) r ;
|
|
set_color black;
|
|
draw_circle (r + (2*r + d)*i) (r + (2*r + d)*j) r ;
|
|
set_color colors.(i).(j);
|
|
draw_integer (r + (2*r + d)*i) (r + (2*r + d)*j) gr.g.(i).(j).tag r ;
|
|
in
|
|
|
|
(* Actual BFS *)
|
|
|
|
let pq = Queue.create () in
|
|
|
|
Queue.add (0, gr.width/2, gr.height/2, gr.width/2, gr.height/2, [||], [||]) pq ;
|
|
|
|
let visited = Array.make_matrix gr.width gr.height false in
|
|
|
|
try
|
|
while true do
|
|
let (depth, i0, j0, i, j, path_arr, bigpath_arr) = Queue.take pq in
|
|
|
|
if visited.(i).(j) = false then begin
|
|
set_line_width 4;
|
|
set_color black;
|
|
draw_poly_line path_arr ;
|
|
set_color colors.(i).(j);
|
|
set_line_width 8;
|
|
draw_poly_line bigpath_arr ;
|
|
|
|
draw_tile i j;
|
|
|
|
set_color colors.(i0).(j0) ;
|
|
draw_tile i0 j0;
|
|
|
|
visited.(i).(j) <- true;
|
|
|
|
set_color white;
|
|
fill_circle (1200-r) (800-r) r;
|
|
set_color black;
|
|
draw_integer (1200-r) (800-r) depth r;
|
|
|
|
Unix.sleepf 0.5;
|
|
|
|
let node_xy = ((r + (2*r + d)*i), (r + (2*r + d)*j)) in
|
|
|
|
if (i > 0 && j > 0) && gr.g.(i).(j).edges.(0) <> (-1) && (visited.(i-1).(j-1) = false) then begin (* SO *)
|
|
Queue.add (depth+1, i, j, i-1, j-1, [|node_xy; (r + (2*r + d)*(i-1)), (r + (2*r + d)*(j-1))|], [|node_xy; (2 * (fst node_xy) + r + (2*r + d)*(i-1))/3, (2 * (snd node_xy) + r + (2*r + d)*(j-1))/3|]) pq;
|
|
end;
|
|
|
|
if (i > 0) && gr.g.(i).(j).edges.(1) <> (-1) && (visited.(i-1).(j) = false) then begin (* O *)
|
|
Queue.add (depth+1, i, j, i-1, j, [|node_xy; (r + (2*r + d)*(i-1)), (r + (2*r + d)*j)|], [|node_xy; (2 * (fst node_xy) + r + (2*r + d)*(i-1))/3, (2 * (snd node_xy) + r + (2*r + d)*j)/3|]) pq;
|
|
end;
|
|
|
|
if (i > 0 && j < gr.height -1) && gr.g.(i).(j).edges.(2) <> (-1) && (visited.(i-1).(j+1) = false) then begin (* NO *)
|
|
Queue.add (depth+1, i, j, i-1, j+1, [|node_xy; (r + (2*r + d)*(i-1)), (r + (2*r + d)*(j+1))|], [|node_xy; (2 * (fst node_xy) + r + (2*r + d)*(i-1))/3, (2 * (snd node_xy) + r + (2*r + d)*(j+1))/3|]) pq;
|
|
end;
|
|
|
|
if (j < gr.height -1) && gr.g.(i).(j).edges.(3) <> (-1) && (visited.(i).(j+1) = false) then begin (* N *)
|
|
Queue.add (depth+1, i, j, i, j+1, [|node_xy; (r + (2*r + d)*i), (r + (2*r + d)*(j+1))|], [|node_xy; (2 * (fst node_xy) + r + (2*r + d)*i)/3, (2 * (snd node_xy) + r + (2*r + d)*(j+1))/3|]) pq;
|
|
end;
|
|
|
|
if (i < gr.width-1 && j < gr.height -1) && gr.g.(i).(j).edges.(4) <> (-1) && (visited.(i+1).(j+1) = false) then begin (* NE *)
|
|
Queue.add (depth+1, i, j, i+1, j+1, [|node_xy; (r + (2*r + d)*(i+1)), (r + (2*r + d)*(j+1))|], [|node_xy; (2 * (fst node_xy) + r + (2*r + d)*(i+1))/3, (2 * (snd node_xy) + r + (2*r + d)*(j+1))/3|]) pq;
|
|
end;
|
|
|
|
if (i < gr.width-1) && gr.g.(i).(j).edges.(5) <> (-1) && (visited.(i+1).(j) = false) then begin (* E *)
|
|
Queue.add (depth+1, i, j, i+1, j, [|node_xy; (r + (2*r + d)*(i+1)), (r + (2*r + d)*j)|], [|node_xy; (2 * (fst node_xy) + r + (2*r + d)*(i+1))/3, (2 * (snd node_xy) + r + (2*r + d)*j)/3|]) pq;
|
|
end;
|
|
|
|
if (i < gr.width-1 && j > 0) && gr.g.(i).(j).edges.(6) <> (-1) && (visited.(i+1).(j-1) = false) then begin (* SE *)
|
|
Queue.add (depth+1, i, j, i+1, j-1, [|node_xy; (r + (2*r + d)*(i+1)), (r + (2*r + d)*(j-1))|], [|node_xy; (2 * (fst node_xy) + r + (2*r + d)*(i+1))/3, (2 * (snd node_xy) + r + (2*r + d)*(j-1))/3|]) pq;
|
|
end;
|
|
|
|
if (j > 0) && gr.g.(i).(j).edges.(7) <> (-1) && (visited.(i).(j-1) = false) then begin (* S *)
|
|
Queue.add (depth+1, i, j, i, j-1, [|node_xy; (r + (2*r + d)*i), (r + (2*r + d)*(j-1))|], [|node_xy; (2 * (fst node_xy) + r + (2*r + d)*i)/3, (2 * (snd node_xy) + r + (2*r + d)*(j-1))/3|]) pq;
|
|
end
|
|
end;
|
|
done;
|
|
()
|
|
with
|
|
| Stdlib.Queue.Empty -> ignore (Scanf.bscanf Scanf.Scanning.stdin "%d\n" identity) ;;
|
|
|
|
(* ------------------------------------------------------------*)
|
|
(* ------------------------------------------------------------*)
|
|
(* ------------------------------------------------------------*)
|
|
|
|
(* ----------------------- Tests --------------------------- *)
|
|
|
|
open_graph " 1200x800" ;;
|
|
set_window_title "Graphs" ;;
|
|
|
|
let type2 = generate_type2_graph 8 6 40 1 1 ;;
|
|
|
|
(*another_type_of_graph_printing type2 35 75 ;;*)
|
|
(*another_type_of_dfs type2 35 75 ;;*)
|
|
another_type_of_bfs type2 35 75 ;;
|
|
|
|
close_graph () ;;
|
|
|
|
(* ----------------------- Tests --------------------------- *)
|
|
|
|
open_graph " 1200x800" ;;
|
|
set_window_title "Graphs" ;;
|
|
|
|
let generate_full_graph k =
|
|
let res = Array.make k [||] in
|
|
for i = 0 to k-1 do
|
|
res.(i) <- Array.make (k-1) 0
|
|
done;
|
|
|
|
for x = 0 to k-1 do
|
|
for y = 0 to k-1 do
|
|
if x < y then
|
|
res.(x).(y-1) <- y
|
|
else if x > y then
|
|
res.(x).(y) <- y
|
|
done
|
|
done;
|
|
res ;;
|
|
|
|
let generate_random_graph k freq =
|
|
let res = Array.make k [||] in
|
|
for i = 0 to k-1 do
|
|
res.(i) <- Array.make (k-1) (-1)
|
|
done;
|
|
|
|
for x = 0 to k-1 do
|
|
for y = 0 to k-1 do
|
|
if (Random.int 100) < freq then
|
|
if x < y then
|
|
res.(x).(y-1) <- y
|
|
else if x > y then
|
|
res.(x).(y) <- y
|
|
done
|
|
done;
|
|
res ;;
|
|
|
|
let gr = [|[|3; 5; 7|]; [|0|]; [|1; 7; 8|]; [|2; 6; 9; 10|]; [|0; 1; 3|]; [|6; 7|]; [|0; 1; 2|]; [|8|]; [|0; 7; 6|]; [|10; 11|]; [|3; 5; 7|]; [|0; 9|]|] ;;
|
|
let fulg = generate_full_graph 16 ;;
|
|
let rang = generate_random_graph 9 50 ;;
|
|
|
|
(*improved_pretty_printing gr 1200 800 50*) ;;
|
|
(*improved_pretty_printing fulg 1200 800 25 ;;*)
|
|
improved_pretty_printing rang 1200 800 45 ;;
|
|
|
|
close_graph () ;;
|
|
|
|
(* compilation command : ocamlfind ocamlc -linkpkg -package unix -linkpkg -package graphics graphs.ml *) |