open Graphics ;; 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 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 12 ; 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) ;; (* ----------------------- Tests --------------------------- *) Random.self_init ;; Random.self_init ;; 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 () ;;