open Graphics ;; (* SOMMAIRE - misc functions : 20 - main function : 68 - type 2 printing: 122 - DFS : 373 - BFS : 630 - Dijkstra : *) 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*11/7)/2 in for i = 0 to size do let x = x0 + offset - i*(len*11/7) 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 try (inf + Random.int (sup-inf)) with | Invalid_argument _ -> inf 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 dx dy is_weighted = 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 + dx)*i), (r + (2*r + dy)*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 + dx)*(i-1)), (r + (2*r + dy)*(j-1))|] ; end; if (i > 0) && gr.g.(i).(j).edges.(1) <> (-1) then begin (* O *) draw_poly_line [|node_xy; (r + (2*r + dx)*(i-1)), (r + (2*r + dy)*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 + dx)*(i-1)), (r + (2*r + dy)*(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 + dx)*i), (r + (2*r + dy)*(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 + dx)*(i+1)), (r + (2*r + dy)*(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 + dx)*(i+1)), (r + (2*r + dy)*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 + dx)*(i+1)), (r + (2*r + dy)*(j-1))|] ; end; if (j > 0) && gr.g.(i).(j).edges.(7) <> (-1) then begin (* S *) draw_poly_line [|node_xy; (r + (2*r + dx)*i), (r + (2*r + dy)*(j-1))|] ; end; done done; let roff = (9*r)/8 in let roff2 = (7*r)/5 in let rsize = (3*r)/4 in let wcolor = rgb 255 255 255 in let bcolor = rgb 0 0 0 in 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 + dx)*i), (r + (2*r + dy)*j)) in if (i > 0 && j > 0) && gr.g.(i).(j).edges.(0) <> (-1) then begin (* SO *) if is_weighted then begin set_color bcolor; fill_circle (fst node_xy - roff) (snd node_xy - roff) (3*rsize/4) ; set_color wcolor; set_line_width 3; draw_integer (fst node_xy - roff) (snd node_xy - roff) gr.g.(i).(j).edges.(0) rsize; end else begin set_line_width 8; set_color colors.(i).(j) ; draw_poly_line [|node_xy; (2 * (fst node_xy) + r + (2*r + dx)*(i-1))/3, (2 * (snd node_xy) + r + (2*r + dy)*(j-1))/3|] ; end end; if (i > 0) && gr.g.(i).(j).edges.(1) <> (-1) then begin (* O *) if is_weighted then begin set_color bcolor; fill_circle (fst node_xy - roff2) (snd node_xy) (3*rsize/4) ; set_color wcolor; set_line_width 3; draw_integer (fst node_xy - roff2) (snd node_xy) gr.g.(i).(j).edges.(1) rsize; end else begin set_line_width 8; set_color colors.(i).(j) ; draw_poly_line [|node_xy; (2 * (fst node_xy) + r + (2*r + dx)*(i-1))/3, (2 * (snd node_xy) + r + (2*r + dy)*j)/3|] ; end end; if (i > 0 && j < gr.height -1) && gr.g.(i).(j).edges.(2) <> (-1) then begin (* NO *) if is_weighted then begin set_color bcolor; fill_circle (fst node_xy - roff) (snd node_xy + roff) (3*rsize/4) ; set_color wcolor; set_line_width 3; draw_integer (fst node_xy - roff) (snd node_xy + roff) gr.g.(i).(j).edges.(2) rsize; end else begin set_line_width 8; set_color colors.(i).(j) ; draw_poly_line [|node_xy; (2 * (fst node_xy) + r + (2*r + dx)*(i-1))/3, (2 * (snd node_xy) + r + (2*r + dy)*(j+1))/3|] ; end end; if (j < gr.height -1) && gr.g.(i).(j).edges.(3) <> (-1) then begin (* N *) if is_weighted then begin set_color bcolor; fill_circle (fst node_xy) (snd node_xy + roff2) (3*rsize/4) ; set_color wcolor; set_line_width 3; draw_integer (fst node_xy) (snd node_xy + roff2) gr.g.(i).(j).edges.(3) rsize; end else begin set_line_width 8; set_color colors.(i).(j) ; draw_poly_line [|node_xy; (2 * (fst node_xy) + r + (2*r + dx)*i)/3, (2 * (snd node_xy) + r + (2*r + dy)*(j+1))/3|] ; end end; if (i < gr.width-1 && j < gr.height -1) && gr.g.(i).(j).edges.(4) <> (-1) then begin (* NE *) if is_weighted then begin set_color bcolor; fill_circle (fst node_xy + roff) (snd node_xy + roff) (3*rsize/4) ; set_color wcolor; set_line_width 3; draw_integer (fst node_xy + roff) (snd node_xy + roff) gr.g.(i).(j).edges.(4) rsize; end else begin set_line_width 8; set_color colors.(i).(j) ; draw_poly_line [|node_xy; (2 * (fst node_xy) + r + (2*r + dx)*(i+1))/3, (2 * (snd node_xy) + r + (2*r + dy)*(j+1))/3|] ; end end; if (i < gr.width-1) && gr.g.(i).(j).edges.(5) <> (-1) then begin (* E *) if is_weighted then begin set_color bcolor; fill_circle (fst node_xy + roff2) (snd node_xy) (3*rsize/4) ; set_color wcolor; set_line_width 3; draw_integer (fst node_xy + roff2) (snd node_xy) gr.g.(i).(j).edges.(5) rsize; end else begin set_line_width 8; set_color colors.(i).(j) ; draw_poly_line [|node_xy; (2 * (fst node_xy) + r + (2*r + dx)*(i+1))/3, (2 * (snd node_xy) + r + (2*r + dy)*j)/3|] ; end end; if (i < gr.width-1 && j > 0) && gr.g.(i).(j).edges.(6) <> (-1) then begin (* SE *) if is_weighted then begin set_color bcolor; fill_circle (fst node_xy + roff) (snd node_xy - roff) (3*rsize/4) ; set_color wcolor; set_line_width 3; draw_integer (fst node_xy + roff) (snd node_xy - roff) gr.g.(i).(j).edges.(6) rsize; end else begin set_line_width 8; set_color colors.(i).(j) ; draw_poly_line [|node_xy; (2 * (fst node_xy) + r + (2*r + dx)*(i+1))/3, (2 * (snd node_xy) + r + (2*r + dy)*(j-1))/3|] ; end end; if (j > 0) && gr.g.(i).(j).edges.(7) <> (-1) then begin (* S *) if is_weighted then begin set_color bcolor; fill_circle (fst node_xy) (snd node_xy - roff2) (3*rsize/4) ; set_color wcolor; set_line_width 3; draw_integer (fst node_xy) (snd node_xy - roff2) gr.g.(i).(j).edges.(7) rsize; end else begin set_line_width 8; set_color colors.(i).(j) ; draw_poly_line [|node_xy; (2 * (fst node_xy) + r + (2*r + dx)*i)/3, (2 * (snd node_xy) + r + (2*r + dy)*(j-1))/3|] ; end 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 + dx)*i) (r + (2*r + dy)*j) r ; set_color black ; draw_circle (r + (2*r + dx)*i) (r + (2*r + dy)*j) r ; set_color colors.(i).(j) ; draw_integer (r + (2*r + dx)*i) (r + (2*r + dy)*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 dx dy dt = 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 + dx)*i), (r + (2*r + dy)*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 + dx)*(i-1)), (r + (2*r + dy)*(j-1))|] ; end; if (i > 0) && gr.g.(i).(j).edges.(1) <> (-1) then begin (* O *) draw_poly_line [|node_xy; (r + (2*r + dx)*(i-1)), (r + (2*r + dy)*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 + dx)*(i-1)), (r + (2*r + dy)*(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 + dx)*i), (r + (2*r + dy)*(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 + dx)*(i+1)), (r + (2*r + dy)*(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 + dx)*(i+1)), (r + (2*r + dy)*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 + dx)*(i+1)), (r + (2*r + dy)*(j-1))|] ; end; if (j > 0) && gr.g.(i).(j).edges.(7) <> (-1) then begin (* S *) draw_poly_line [|node_xy; (r + (2*r + dx)*i), (r + (2*r + dy)*(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 + dx)*i), (r + (2*r + dy)*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 + dx)*(i-1))/3, (2 * (snd node_xy) + r + (2*r + dy)*(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 + dx)*(i-1))/3, (2 * (snd node_xy) + r + (2*r + dy)*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 + dx)*(i-1))/3, (2 * (snd node_xy) + r + (2*r + dy)*(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 + dx)*i)/3, (2 * (snd node_xy) + r + (2*r + dy)*(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 + dx)*(i+1))/3, (2 * (snd node_xy) + r + (2*r + dy)*(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 + dx)*(i+1))/3, (2 * (snd node_xy) + r + (2*r + dy)*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 + dx)*(i+1))/3, (2 * (snd node_xy) + r + (2*r + dy)*(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 + dx)*i)/3, (2 * (snd node_xy) + r + (2*r + dy)*(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 + dx)*i) (r + (2*r + dy)*j) r ; set_color (rgb 100 100 100) ; draw_circle (r + (2*r + dx)*i) (r + (2*r + dy)*j) r ; draw_integer (r + (2*r + dx)*i) (r + (2*r + dy)*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 + dx)*i) (r + (2*r + dy)*j) r ; set_color black; draw_circle (r + (2*r + dx)*i) (r + (2*r + dy)*j) r ; set_color colors.(i).(j); draw_integer (r + (2*r + dx)*i) (r + (2*r + dy)*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 (r + (2*r + dx)*(gr.width/2)) (r + (2*r + dy)*(gr.height/2)) r; set_color black; draw_integer (r + (2*r + dx)*(gr.width/2)) (r + (2*r + dy)*(gr.height/2)) depth r; Unix.sleepf dt; let node_xy = ((r + (2*r + dx)*i), (r + (2*r + dy)*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 + dx)*(i-1)), (r + (2*r + dy)*(j-1))|] ; set_color colors.(i).(j); set_line_width 8; draw_poly_line [|node_xy; (2 * (fst node_xy) + r + (2*r + dx)*(i-1))/3, (2 * (snd node_xy) + r + (2*r + dy)*(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 + dx)*(i-1)), (r + (2*r + dy)*j)|] ; set_color colors.(i).(j); set_line_width 8; draw_poly_line [|node_xy; (2 * (fst node_xy) + r + (2*r + dx)*(i-1))/3, (2 * (snd node_xy) + r + (2*r + dy)*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 + dx)*(i-1)), (r + (2*r + dy)*(j+1))|] ; set_color colors.(i).(j); set_line_width 8; draw_poly_line [|node_xy; (2 * (fst node_xy) + r + (2*r + dx)*(i-1))/3, (2 * (snd node_xy) + r + (2*r + dy)*(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 + dx)*i), (r + (2*r + dy)*(j+1))|] ; set_color colors.(i).(j); set_line_width 8; draw_poly_line [|node_xy; (2 * (fst node_xy) + r + (2*r + dx)*i)/3, (2 * (snd node_xy) + r + (2*r + dy)*(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 + dx)*(i+1)), (r + (2*r + dy)*(j+1))|] ; set_color colors.(i).(j); set_line_width 8; draw_poly_line [|node_xy; (2 * (fst node_xy) + r + (2*r + dx)*(i+1))/3, (2 * (snd node_xy) + r + (2*r + dy)*(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 + dx)*(i+1)), (r + (2*r + dy)*j)|] ; set_color colors.(i).(j); set_line_width 8; draw_poly_line [|node_xy; (2 * (fst node_xy) + r + (2*r + dx)*(i+1))/3, (2 * (snd node_xy) + r + (2*r + dy)*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 + dx)*(i+1)), (r + (2*r + dy)*(j-1))|] ; set_color colors.(i).(j); set_line_width 8; draw_poly_line [|node_xy; (2 * (fst node_xy) + r + (2*r + dx)*(i+1))/3, (2 * (snd node_xy) + r + (2*r + dy)*(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 + dx)*i), (r + (2*r + dy)*(j-1))|] ; set_color colors.(i).(j); set_line_width 8; draw_poly_line [|node_xy; (2 * (fst node_xy) + r + (2*r + dx)*i)/3, (2 * (snd node_xy) + r + (2*r + dy)*(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 dx dy gwd ght dt = 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 + dx)*i), (r + (2*r + dy)*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 + dx)*(i-1)), (r + (2*r + dy)*(j-1))|] ; end; if (i > 0) && gr.g.(i).(j).edges.(1) <> (-1) then begin (* O *) draw_poly_line [|node_xy; (r + (2*r + dx)*(i-1)), (r + (2*r + dy)*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 + dx)*(i-1)), (r + (2*r + dy)*(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 + dx)*i), (r + (2*r + dy)*(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 + dx)*(i+1)), (r + (2*r + dy)*(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 + dx)*(i+1)), (r + (2*r + dy)*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 + dx)*(i+1)), (r + (2*r + dy)*(j-1))|] ; end; if (j > 0) && gr.g.(i).(j).edges.(7) <> (-1) then begin (* S *) draw_poly_line [|node_xy; (r + (2*r + dx)*i), (r + (2*r + dy)*(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 + dx)*i), (r + (2*r + dy)*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 + dx)*(i-1))/3, (2 * (snd node_xy) + r + (2*r + dy)*(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 + dx)*(i-1))/3, (2 * (snd node_xy) + r + (2*r + dy)*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 + dx)*(i-1))/3, (2 * (snd node_xy) + r + (2*r + dy)*(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 + dx)*i)/3, (2 * (snd node_xy) + r + (2*r + dy)*(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 + dx)*(i+1))/3, (2 * (snd node_xy) + r + (2*r + dy)*(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 + dx)*(i+1))/3, (2 * (snd node_xy) + r + (2*r + dy)*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 + dx)*(i+1))/3, (2 * (snd node_xy) + r + (2*r + dy)*(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 + dx)*i)/3, (2 * (snd node_xy) + r + (2*r + dy)*(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 + dx)*i) (r + (2*r + dy)*j) r ; set_color (rgb 100 100 100) ; draw_circle (r + (2*r + dx)*i) (r + (2*r + dy)*j) r ; draw_integer (r + (2*r + dx)*i) (r + (2*r + dy)*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 + dx)*i) (r + (2*r + dy)*j) r ; set_color black; draw_circle (r + (2*r + dx)*i) (r + (2*r + dy)*j) r ; set_color colors.(i).(j); draw_integer (r + (2*r + dx)*i) (r + (2*r + dy)*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 (r + (2*r + dx)*(gr.width/2)) (r + (2*r + dy)*(gr.height/2)) r; set_color black; draw_integer (r + (2*r + dx)*(gr.width/2)) (r + (2*r + dy)*(gr.height/2)) depth r; Unix.sleepf dt; let node_xy = ((r + (2*r + dx)*i), (r + (2*r + dy)*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 + dx)*(i-1)), (r + (2*r + dy)*(j-1))|], [|node_xy; (2 * (fst node_xy) + r + (2*r + dx)*(i-1))/3, (2 * (snd node_xy) + r + (2*r + dy)*(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 + dx)*(i-1)), (r + (2*r + dy)*j)|], [|node_xy; (2 * (fst node_xy) + r + (2*r + dx)*(i-1))/3, (2 * (snd node_xy) + r + (2*r + dy)*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 + dx)*(i-1)), (r + (2*r + dy)*(j+1))|], [|node_xy; (2 * (fst node_xy) + r + (2*r + dx)*(i-1))/3, (2 * (snd node_xy) + r + (2*r + dy)*(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 + dx)*i), (r + (2*r + dy)*(j+1))|], [|node_xy; (2 * (fst node_xy) + r + (2*r + dx)*i)/3, (2 * (snd node_xy) + r + (2*r + dy)*(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 + dx)*(i+1)), (r + (2*r + dy)*(j+1))|], [|node_xy; (2 * (fst node_xy) + r + (2*r + dx)*(i+1))/3, (2 * (snd node_xy) + r + (2*r + dy)*(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 + dx)*(i+1)), (r + (2*r + dy)*j)|], [|node_xy; (2 * (fst node_xy) + r + (2*r + dx)*(i+1))/3, (2 * (snd node_xy) + r + (2*r + dy)*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 + dx)*(i+1)), (r + (2*r + dy)*(j-1))|], [|node_xy; (2 * (fst node_xy) + r + (2*r + dx)*(i+1))/3, (2 * (snd node_xy) + r + (2*r + dy)*(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 + dx)*i), (r + (2*r + dy)*(j-1))|], [|node_xy; (2 * (fst node_xy) + r + (2*r + dx)*i)/3, (2 * (snd node_xy) + r + (2*r + dy)*(j-1))/3|]) pq; end end; done; () with | Stdlib.Queue.Empty -> ignore (Scanf.bscanf Scanf.Scanning.stdin "%d\n" identity) ;; (* --------------------------------------------------------------- *) (* ---AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA--- *) (* --------------------------------------------------------------- *) type 'a dyna = {mutable memlen : int ; mutable len : int ; a : ('a * int) array} ;; let create_d n i = let res = {memlen = n; len = 0; a = Array.make n (i, 0)} in res ;; let is_empty_d da = da.len = 0 ;; let add_elt_d da elt p = if da.len = da.memlen then failwith "Not yet" else da.a.(da.len) <- (elt, p); da.len <- da.len + 1;; let swap da i j = let temp = da.a.(i) in da.a.(i) <- da.a.(j); da.a.(j) <- temp ;; let get_min_d da = let cmin = ref (snd da.a.(0)) in let idmin = ref 0 in for i = 1 to da.len -1 do if !cmin > snd da.a.(i) then begin cmin := snd da.a.(i); idmin := i end done; (!idmin, !cmin) ;; let remove_min_d da = if da.len <= 0 then failwith "Nothing to pop"; let (i, p) = get_min_d da in let x = fst da.a.(i) in swap da i (da.len -1); da.len <- da.len - 1; (x, p) ;; let get_p da elt = let cp = ref (-1) in let break = ref false in for i = 0 to da.len -1 do if !break = false && fst da.a.(i) = elt then begin cp := snd da.a.(i); break := true end done; !cp ;; let update_p da elt newp = let break = ref false in for i = 0 to da.len -1 do if !break = false && fst da.a.(i) = elt then begin da.a.(i) <- (elt, newp); break := true end done;; let me_out_of_this_thing (gr : type2graph) r dx dy dt = 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; let roff = (9*r)/8 in let roff2 = (7*r)/5 in let rsize = (3*r)/4 in let wcolor = rgb 255 255 255 in let bcolor = rgb 150 150 150 in let ncolor = rgb 150 150 150 in let xdists = [|-roff ; -roff2; -roff; 0; roff; roff2; roff; 0|] in let ydists = [|-roff; 0; roff ; roff2; roff; 0; -roff ;-roff2|] in set_line_width 4; set_color (rgb 122 122 122) ; for i = 0 to gr.width -1 do for j = 0 to gr.height -1 do let node_xy = ((r + (2*r + dx)*i), (r + (2*r + dy)*j)) in if (i > 0 && j > 0) && gr.g.(i).(j).edges.(0) <> (-1) then begin (* SO *) draw_poly_line [|(fst node_xy + xdists.(0), snd node_xy + ydists.(0)); (xdists.(4) + r + (2*r + dx)*(i-1)), (ydists.(4) + r + (2*r + dy)*(j-1))|] ; end; if (i > 0) && gr.g.(i).(j).edges.(1) <> (-1) then begin (* O *) draw_poly_line [|(fst node_xy + xdists.(1), snd node_xy + ydists.(1)); (xdists.(5) + r + (2*r + dx)*(i-1)), (ydists.(5) + r + (2*r + dy)*j)|] ; end; if (i > 0 && j < gr.height -1) && gr.g.(i).(j).edges.(2) <> (-1) then begin (* NO *) draw_poly_line [|(fst node_xy + xdists.(2), snd node_xy + ydists.(2)); (xdists.(6) + r + (2*r + dx)*(i-1)), (ydists.(6) + r + (2*r + dy)*(j+1))|] ; end; if (j < gr.height -1) && gr.g.(i).(j).edges.(3) <> (-1) then begin (* N *) draw_poly_line [|(fst node_xy + xdists.(3), snd node_xy + ydists.(3)); (xdists.(7) + r + (2*r + dx)*i), (ydists.(7) + r + (2*r + dy)*(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 [|(fst node_xy + xdists.(4), snd node_xy + ydists.(4)); (xdists.(0) + r + (2*r + dx)*(i+1)), (ydists.(0) + r + (2*r + dy)*(j+1))|] ; end; if (i < gr.width-1) && gr.g.(i).(j).edges.(5) <> (-1) then begin (* E *) draw_poly_line [|(fst node_xy + xdists.(5), snd node_xy + ydists.(5)); (xdists.(1) + r + (2*r + dx)*(i+1)), (ydists.(1) + r + (2*r + dy)*j)|] ; end; if (i < gr.width-1 && j > 0) && gr.g.(i).(j).edges.(6) <> (-1) then begin (* SE *) draw_poly_line [|(fst node_xy + xdists.(6), snd node_xy + ydists.(6)); (xdists.(2) + r + (2*r + dx)*(i+1)), (ydists.(2) + r + (2*r + dy)*(j-1))|] ; end; if (j > 0) && gr.g.(i).(j).edges.(7) <> (-1) then begin (* S *) draw_poly_line [|(fst node_xy + xdists.(7), snd node_xy + ydists.(7)); (xdists.(3) + r + (2*r + dx)*i), (ydists.(3) + r + (2*r + dy)*(j-1))|] ; end; done done; set_line_width 4; for i = 0 to gr.width -1 do for j = 0 to gr.height -1 do let node_xy = ((r + (2*r + dx)*i), (r + (2*r + dy)*j)) in if (i > 0 && j > 0) && gr.g.(i).(j).edges.(0) <> (-1) then begin (* SO *) set_color bcolor; end else begin set_color ncolor ; end; fill_circle (fst node_xy - roff) (snd node_xy - roff) (3*rsize/4) ; if (i > 0 && j > 0) && gr.g.(i).(j).edges.(0) <> (-1) then begin (* SO *) set_color wcolor; set_line_width 3; draw_integer (fst node_xy - roff) (snd node_xy - roff) gr.g.(i).(j).edges.(0) rsize; end; if (i > 0) && gr.g.(i).(j).edges.(1) <> (-1) then begin (* O *) set_color bcolor; end else begin set_color ncolor ; end; fill_circle (fst node_xy - roff2) (snd node_xy) (3*rsize/4) ; if (i > 0) && gr.g.(i).(j).edges.(1) <> (-1) then begin (* O *) set_color wcolor; set_line_width 3; draw_integer (fst node_xy - roff2) (snd node_xy) gr.g.(i).(j).edges.(1) rsize; end; if (i > 0 && j < gr.height -1) && gr.g.(i).(j).edges.(2) <> (-1) then begin (* NO *) set_color bcolor; end else begin set_color ncolor ; end; fill_circle (fst node_xy - roff) (snd node_xy + roff) (3*rsize/4) ; if (i > 0 && j < gr.height -1) && gr.g.(i).(j).edges.(2) <> (-1) then begin (* NO *) set_color wcolor; set_line_width 3; draw_integer (fst node_xy - roff) (snd node_xy + roff) gr.g.(i).(j).edges.(2) rsize; end; if (j < gr.height -1) && gr.g.(i).(j).edges.(3) <> (-1) then begin (* N *) set_color bcolor; end else begin set_color ncolor ; end; fill_circle (fst node_xy) (snd node_xy + roff2) (3*rsize/4) ; if (j < gr.height -1) && gr.g.(i).(j).edges.(3) <> (-1) then begin (* N *) set_color wcolor; set_line_width 3; draw_integer (fst node_xy) (snd node_xy + roff2) gr.g.(i).(j).edges.(3) rsize; end; if (i < gr.width-1 && j < gr.height -1) && gr.g.(i).(j).edges.(4) <> (-1) then begin (* NE *) set_color bcolor; end else begin set_color ncolor ; end; fill_circle (fst node_xy + roff) (snd node_xy + roff) (3*rsize/4) ; if (i < gr.width-1 && j < gr.height -1) && gr.g.(i).(j).edges.(4) <> (-1) then begin (* NE *) set_color wcolor; set_line_width 3; draw_integer (fst node_xy + roff) (snd node_xy + roff) gr.g.(i).(j).edges.(4) rsize; end; if (i < gr.width-1) && gr.g.(i).(j).edges.(5) <> (-1) then begin (* E *) set_color bcolor; end else begin set_color ncolor ; end; fill_circle (fst node_xy + roff2) (snd node_xy) (3*rsize/4) ; if (i < gr.width-1) && gr.g.(i).(j).edges.(5) <> (-1) then begin (* E *) set_color wcolor; set_line_width 3; draw_integer (fst node_xy + roff2) (snd node_xy) gr.g.(i).(j).edges.(5) rsize; end; if (i < gr.width-1 && j > 0) && gr.g.(i).(j).edges.(6) <> (-1) then begin (* SE *) set_color bcolor; end else begin set_color ncolor ; end; fill_circle (fst node_xy + roff) (snd node_xy - roff) (3*rsize/4) ; if (i < gr.width-1 && j > 0) && gr.g.(i).(j).edges.(6) <> (-1) then begin (* SE *) set_color wcolor; set_line_width 3; draw_integer (fst node_xy + roff) (snd node_xy - roff) gr.g.(i).(j).edges.(6) rsize; end; if (j > 0) && gr.g.(i).(j).edges.(7) <> (-1) then begin (* S *) set_color bcolor; end else begin set_color ncolor ; end; fill_circle (fst node_xy) (snd node_xy - roff2) (3*rsize/4) ; if (j > 0) && gr.g.(i).(j).edges.(7) <> (-1) then begin (* S *) set_color wcolor; set_line_width 3; draw_integer (fst node_xy) (snd node_xy - roff2) gr.g.(i).(j).edges.(7) rsize; 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 32 32 32) ; fill_circle (r + (2*r + dx)*i) (r + (2*r + dy)*j) r ; set_color (rgb 100 100 100) ; draw_circle (r + (2*r + dx)*i) (r + (2*r + dy)*j) r ; done done ; let draw_tile i j p = set_line_width 5; set_color colors.(i).(j); draw_integer (r + (2*r + dx)*i) (r + (2*r + dy)*j) p r ; in let offx = [|-1; -1; -1; 0; 1; 1; 1; 0|] in let offy = [|-1; 0; 1; 1; 1; 0; -1; -1|] in let w = gr.width and h = gr.height in let is_valid i j = (i >= 0) && (j >= 0) && (i < w) && (j < h) in let draw_path i j side = let node_xy = ((r + (2*r + dx)*i), (r + (2*r + dy)*j)) in set_color (rgb 32 220 32); if side = 0 then begin (* SO *) draw_poly_line [|(fst node_xy + xdists.(0), snd node_xy + ydists.(0)); (xdists.(4) + r + (2*r + dx)*(i-1)), (ydists.(4) + r + (2*r + dy)*(j-1))|] ; end; if side = 1 then begin (* O *) draw_poly_line [|(fst node_xy + xdists.(1), snd node_xy + ydists.(1)); (xdists.(5) + r + (2*r + dx)*(i-1)), (ydists.(5) + r + (2*r + dy)*j)|] ; end; if side = 2 then begin (* NO *) draw_poly_line [|(fst node_xy + xdists.(2), snd node_xy + ydists.(2)); (xdists.(6) + r + (2*r + dx)*(i-1)), (ydists.(6) + r + (2*r + dy)*(j+1))|] ; end; if side = 3 then begin (* N *) draw_poly_line [|(fst node_xy + xdists.(3), snd node_xy + ydists.(3)); (xdists.(7) + r + (2*r + dx)*i), (ydists.(7) + r + (2*r + dy)*(j+1))|] ; end; if side = 4 then begin (* NE *) draw_poly_line [|(fst node_xy + xdists.(4), snd node_xy + ydists.(4)); (xdists.(0) + r + (2*r + dx)*(i+1)), (ydists.(0) + r + (2*r + dy)*(j+1))|] ; end; if side = 5 then begin (* E *) draw_poly_line [|(fst node_xy + xdists.(5), snd node_xy + ydists.(5)); (xdists.(1) + r + (2*r + dx)*(i+1)), (ydists.(1) + r + (2*r + dy)*j)|] ; end; if side = 6 then begin (* SE *) draw_poly_line [|(fst node_xy + xdists.(6), snd node_xy + ydists.(6)); (xdists.(2) + r + (2*r + dx)*(i+1)), (ydists.(2) + r + (2*r + dy)*(j-1))|] ; end; if side = 7 then begin (* S *) draw_poly_line [|(fst node_xy + xdists.(7), snd node_xy + ydists.(7)); (xdists.(3) + r + (2*r + dx)*i), (ydists.(3) + r + (2*r + dy)*(j-1))|] ; end; if (i > 0 && j > 0) && gr.g.(i).(j).edges.(0) <> (-1) then begin (* SO *) set_color bcolor; end ; if side >= 0 then begin set_color black; fill_circle (fst node_xy + xdists.(side)) (snd node_xy + ydists.(side)) (3*rsize/4) ; set_color (rgb 32 255 32); set_line_width 3; draw_integer (fst node_xy + xdists.(side)) (snd node_xy + ydists.(side)) gr.g.(i).(j).edges.(side) rsize; let side2 = (side + 4) mod 8 in let node_xy2 = ((r + (2*r + dx)*(i + offx.(side))), (r + (2*r + dy)*(j + offy.(side)))) in set_color black; fill_circle (fst node_xy2 + xdists.(side2)) (snd node_xy2 + ydists.(side2)) (3*rsize/4) ; set_color (rgb 255 32 32); set_line_width 3; if is_valid (i + offx.(side)) (j + offy.(side)) then let reversepond = gr.g.(i + offx.(side)).(j + offy.(side)).edges.(side2) in if reversepond <> -1 then draw_integer (fst node_xy2 + xdists.(side2)) (snd node_xy2 + ydists.(side2)) reversepond rsize end in (* Actual algo *) let disttab = Array.make_matrix w h (-1) in let pq = create_d (w*h) (0, 0) in for i = 0 to w-1 do for j = 0 to h-1 do add_elt_d pq (i, j) 999999 done done; let dirtab = Array.make_matrix w h (-1) in let origintab = Array.make_matrix w h (0, 0) in update_p pq (w/2, h/2) 0; let out_of_connex = ref false in let srci = ref (w/2) and srcj = ref (h/2) in while !out_of_connex = false && (is_empty_d pq) = false do let ((i, j), p) = remove_min_d pq in disttab.(i).(j) <- p; draw_path (fst origintab.(i).(j)) (snd origintab.(i).(j)) dirtab.(i).(j); if p <> -1 then begin for nb = 0 to 7 do let ni = i + offx.(nb) in let nj = j + offy.(nb) in if is_valid ni nj then if disttab.(ni).(nj) = (-1) && gr.g.(i).(j).edges.(nb) > 0 then begin let newdist = p + gr.g.(i).(j).edges.(nb) in let oldp = get_p pq (ni, nj) in if oldp > newdist then begin update_p pq (ni, nj) newdist; dirtab.(ni).(nj) <- nb; origintab.(ni).(nj) <- (i, j) end end done; draw_tile i j p; srci := i; srcj := j; Unix.sleepf dt ; end else out_of_connex := true; done; (*for j = h-1 downto 0 do for i = 0 to w-1 do Printf.printf "{[%d %d] : %d} " i j disttab.(i).(j) done; print_char '\n' done ; Stdlib.print_endline "--";*) ignore (Scanf.bscanf Scanf.Scanning.stdin "%d\n" identity) ;; (* ------------------------------------------------------------*) (* ------------------------------------------------------------*) (* ------------------------------------------------------------*) (* ----------------------- Tests --------------------------- *) let main r = Stdlib.print_endline "Enter the width of the graph (use 8 for weighted): "; let wd = Scanf.bscanf Scanf.Scanning.stdin "%d\n" identity in if wd <= 0 then failwith "Error : invalid input"; Stdlib.print_endline "Enter the height of the graph (use 6 for weighted): "; let ht = Scanf.bscanf Scanf.Scanning.stdin "%d\n" identity in Stdlib.print_endline "Enter the density of the graph (0 ~ 100): "; let density = ref (Scanf.bscanf Scanf.Scanning.stdin "%d\n" identity) in if(!density < 0 || !density > 100) then begin Stdlib.print_endline "Invalid input, will use 50 instead"; density := 50; end; if ht <= 0 then failwith "Error : invalid input"; Stdlib.print_endline "Is the grap weighted ? (0/1)"; let is_weighted = Scanf.bscanf Scanf.Scanning.stdin "%d\n" identity in let weighted = ref false in if is_weighted = 1 then weighted := true; Stdlib.print_endline "Enter the mode :\n0 for display\n1 for BFS\n2 for DFS\n3 for (BROKEN) Dijkstra\n"; let choice = Scanf.bscanf Scanf.Scanning.stdin "%d\n" identity in open_graph " 1500x1000" ; set_window_title "Graphs" ; let gwd = 1500-r and ght = 1000-r in let offset_x = (gwd - r)/(wd-1) - 2*r in let offset_y = (ght - r)/(ht-1) - 2*r in let type2 = generate_type2_graph wd ht !density 1 10 in let dt = 0.3 in if choice = 0 then begin another_type_of_graph_printing type2 r offset_x offset_y !weighted; close_graph () end else if choice = 1 then begin another_type_of_dfs type2 r offset_x offset_y dt ; close_graph () end else if choice = 2 then begin another_type_of_bfs type2 r offset_x offset_y gwd ght dt ; close_graph () end else if choice = 3 then begin me_out_of_this_thing type2 r offset_x offset_y dt ; close_graph () end else failwith "Error : invalid input"; ignore (Scanf.bscanf Scanf.Scanning.stdin "%d\n" identity);; main 35;; (* ----------------------- 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 *)