exception PT of int * int ;; Random.self_init () ;; (* parsing output.txt *) type player = { chx : int; (* X chunk, is in [0, lines[ *) chy : int; (* Y chunk, is in [0, cols[ *) posx : float; (* X coord, is in [0, roomSize[ *) posy : float; (* Y coord, is in [0, roomSize[ *) } ;; let rec ln b = function | k when k < b -> 0 | k -> 1+ln b (k/b) in let isDigit c = match (Char.code c) with | k when k >= 48 && k <= 57 -> true | _ -> false in let rec pw x = function | 0 -> 1 | 1 -> x | n when n mod 2 = 0 -> pw (x*x) (n/2) | n -> x*pw (x*x) ((n-1)/2) in let read_int (str : string) (i : int ref) = let buf = ref 0 in while !i < String.length str && not (isDigit str.[!i]) do incr i; done; while !i < String.length str && isDigit str.[!i] do buf := 10 * !buf + (Char.code str.[!i] - 48); incr i done; !buf in let read_float (str : string) (i : int ref) = let ent = read_int str i in let frac = read_int str i in (*Printf.printf "-> %d %d <-\n" ent frac;*) (float_of_int ent +. (float_of_int frac) /. (float_of_int (pw 10 (1+ ln 10 frac)))) in let file = open_in "output.txt" in let nPlayers = int_of_string (input_line file) in (*Printf.printf "np : %d\n" nPlayers;*) let players = Array.make nPlayers {chx=0;chy=0;posx=0.;posy=0.} in for i = 0 to nPlayers -1 do let data = input_line file in let i = ref 0 in let idPlayer = read_int data i in let chy = read_int data i in let chx = read_int data i in let posx = read_float data i in let posy = read_float data i in players.(idPlayer) <- {chx = chx; chy = chy; posx = posx; posy = posy} done; (*Printf.printf "players done\n";*) let you = int_of_string (input_line file) in ignore (input_line file); let wdht = input_line file in let whi = ref 0 in let lines = read_int wdht whi in let cols = read_int wdht whi in (*Printf.printf "dims : %d %d\n" lines cols;*) let map = Array.make_matrix lines cols '.' in for i= 0 to lines-1 do String.iteri (fun j ch -> map.(i).(j) <- ch) (input_line file) done; ignore (input_line file); let meta = input_line file in let metai = ref 0 in (* metadata (constants relative to the map) *) let roomSize = read_int meta metai in (* integer (meters) *) let maximumSpeed = read_int meta metai in (* integer (meters/seconds) *) let playerRadius = read_int meta metai in (* integer *) let friction = read_float meta metai in (* float (between 0.0 and 1.0) *) let restitutionFactor = read_float meta metai in (* float (between 0.0 and 1.0) *) let trackDistance = read_float meta metai in (* float (between 0.0 and 0.5) - this is the width of the black area on both side of the tracks in other words, the width of the track is (except for start and finish) roomSize*(1-2*trackDistance) *) let magneticField = read_float meta metai in (* workd just like in induction : v ^ B is added to the speed each tick *) close_in file ; (*Printf.printf "%d %d %d %f %f %f\n" roomSize maximumSpeed playerRadius friction restitutionFactor trackDistance ;;*) (* VARIABLES : nPlayers : number of players in the match players : list containing data relative to all players (struct is defined at the top of the code) you : integer telling you who you are (lines, cols) : the dimension of the map map : a char array array containing each tile as an integer metadata : see above *) let getDirs = function | '0' -> 5 | '1' -> 10 | '2' -> 3 | '3' -> 6 | '4' -> 12 | '5' -> 9 | 'S' -> 15 | _ -> 0 in let getS () = try for i = 0 to lines -1 do for j = 0 to cols -1 do if map.(i).(j) = 'S' then raise (PT (i,j)) done done; failwith "no start ?" with | PT (x,y) -> (x,y) in let getPath mp = let path = Array.make_matrix lines cols '.' in let vstd = Hashtbl.create 100 in let halt = ref false in let rec aux (i,j) = if i >= 0 && j >= 0 && i < lines && j < cols then begin if mp.(i).(j) = 'E' then halt := true else if not !halt && path.(i).(j) <> ',' && Hashtbl.find_opt vstd (i,j) = None then begin Hashtbl.add vstd (i,j) 1; let ds = getDirs mp.(i).(j) in if not !halt && ds mod 2 = 1 then begin path.(i).(j) <- '^'; aux (i-1,j); end; if not !halt && (ds/2) mod 2 = 1 then begin path.(i).(j) <- '>'; aux (i,j+1); end; if not !halt && (ds/4) mod 2 = 1 then begin path.(i).(j) <- 'v'; aux (i+1,j); end; if not !halt && (ds/8) mod 2 = 1 then begin path.(i).(j) <- '<'; aux (i,j-1); end; if not !halt then path.(i).(j) <- ',' end end in aux (getS ()); path in let pth = getPath map in (* Array.iter ( fun ln -> Array.iter ( fun c -> print_char c; ) ln; print_endline "" ) pth; *) let ans = open_out "answer.txt" in match pth.(players.(you).chx).(players.(you).chy) with | '>' -> Printf.fprintf ans "0 100\n" | 'v' -> Printf.fprintf ans "90 100\n" | '<' -> Printf.fprintf ans "180 100\n" | '^' -> Printf.fprintf ans "270 100\n" | _ -> Printf.fprintf ans "%d 100\n" (Random.int 360) ; close_out ans ;; (* write two integers (angle (0-360, integer) and power (0-100, integer)) to answer.txt *)