open AppTools open Graph (* Prompts the user to enter all activities and stores them in a (id, name) list*) let enterAllChoices () = let rec inner xs i = let str = read_line () in if str = "" (*means the user hit enter twice --> end of input, we return the list*) then xs else (*gets a line input, splits it and removes any remaining empty string *) let inputs = List.filter (fun s -> s <> "") (String.split_on_char ' ' str) in (*checks for the right number of elements*) if (List.length inputs) = 2 then try (*extracts the name and capacity of said activity*) let name = List.hd inputs in let capa = int_of_string (List.nth inputs 1) in (*adds them to the list*) inner ((name,i,capa) :: xs) (i+1) with (*in case of an error : prompts to retry*) | _ -> let () = (print_string "\nPlease enter a string followed by a number\n") in (); inner xs i else (*in case of a wrong number of arguments : prompts to retry*) let () = (print_string "\nPlease enter a string followed by a number\n") in (); inner xs i in let _ = Sys.command "clear" in print_string "Enter the possible choices for the children separated \ by new lines and followed by their capacity, hit enter twice to finish \n"; inner [] 1 (* Displays all of the activities alongside their id*) let displayAllChoices xs = let rec inner i acc = function | [] -> acc | x :: xs -> inner (i+1) ( acc ^ (string_of_int i) ^ " : " ^ x ^ "\n") xs in let _ = Sys.command "clear" in print_string (inner 1 "" xs) (* Prompts the user to enter all children's names the activities they are interested in and returns a (id, name, id list) list. Takes in input the number of the previously assigned nodes' maximum id and the list of activities) *) let enterChildren idPrev listActivities = let rec inner xs i = let str = read_line () in if str = "" (*means the user hit enter twice --> end of input, we return the list*) then xs (*in case of help : prompts to retry*) else (*checks if the input is not the keyword for help*) if str = "HELP" then let () = (print_string "\n=========\n"); displayAllChoices (List.map (fun x -> (fst3 x)) listActivities); (print_string "=========\n") in () ; inner xs i else (*gets a line input, splits it and removes any remaining empty string *) let inputs = List.filter (fun s -> s <> "") (String.split_on_char ' ' str) in try (*get all the choices (i.e. the tail of the input list and the converts them to ints before sorting them)*) let choices = List.sort_uniq (-) (List.map (fun x -> int_of_string x) (List.tl inputs)) in (*checks for invalid activities (i.e. ones that do not have a node in the graph)*) if List.exists (fun x -> x > idPrev) choices then let () = (print_string "\n=========\n Please only enter digits that match activities\n=========\n"); displayAllChoices (List.map (fun x -> (fst3 x)) listActivities); in () ; (*in case of an error : prompts to retry*) inner xs i else inner ((i, (List.hd inputs), choices) :: xs) (i+1) with (*in case of an error : prompts to retry*) | _ -> (print_string "=========\n"); (print_string "Usage : name id1 id2 id3"); (print_string "\n=========\n"); inner xs i in print_string "Enter the name of the child followed by the ids of the \ activities they are interested in. type \'HELP\' to list the activities\n"; inner [] (idPrev+1) (*starts at the next available node*) (*Prints on the screen which children have nothing to do and what the others have*) let outputData g childrenList choicesList = (*lists the children that will not have an activity i.e. the nodes that do have a path from the source to them*) let listIdleChildren = let rec inner3 acc = function (*goes over all edges out of the sources's node*) | [] -> acc | x :: xs -> inner3 (acc ^ let childNodeId = fst x in snd3 (List.find (fun a -> fst3 a = childNodeId) childrenList) ^ "/" ) xs in inner3 "" (out_arcs g (getMaximumNodeId g)) in (*lists the children that have an activity i.e. the nodes that do have a path from said activity to them*) let findAssignedChildren activity = let rec inner2 acc = function (*goes over all edges out of the activity's node*) | [] -> acc | x :: xs -> inner2 (acc ^ (if fst x <> 0 then let childNodeId = fst x in snd3 (List.find (fun a -> fst3 a = childNodeId) childrenList) ^ "/" else "" ) ) xs in inner2 "" (out_arcs g (snd3 activity)) in (*goes over all activities and gets the string to print for each activity*) let rec inner acc g = function | [] -> print_string acc | x :: xs -> (inner (acc ^ (fst3 x) ^ " : " ^ (findAssignedChildren x) ^ "\n") g xs ) in let _ = Sys.command "clear" in inner "" g choicesList; print_string("The children that did not appear above (if any) could \ not be assigned any activity : " ^ listIdleChildren)