FordFulkersonLeChameau/src/ioApp.ml

152 lines
6.3 KiB
OCaml

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)