Advertisement
Guest User

Worm War 2

a guest
Aug 17th, 2018
84
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
F# 3.87 KB | None | 0 0
  1. open System
  2.  
  3. type Network = {id:char; hosts:int; infected:int  }
  4.  
  5. type Link = { n1:char; n2:char; capacity:int }
  6.  
  7. type Rate = {S:float ; I:float; R:float}
  8.  
  9. //Natural number
  10. let (|Nat|_|) str =
  11.    match System.Int32.TryParse(str) with
  12.    | (true,int) when int > 0 -> Some(int)
  13.    | _ -> None
  14. //Integer greater then 0
  15. let (|ZeroNAT|_|) str =
  16.    match System.Int32.TryParse(str) with
  17.    | (true,int) when int >= 0 -> Some(int)
  18.    | _ -> None
  19.  
  20. let (|Float|_|) str =
  21.     match Double.TryParse(str) with
  22.     | (true,v)  when v > 0.0 ->  Some(v)
  23.     | _ -> None
  24.  
  25. let (|Char|_|) (str:string) =
  26.     match str |> String.length with
  27.     | 1 -> Some (str |> Seq.head)
  28.     | _ -> None
  29.  
  30. let getNumberItems () =
  31.     match Console.ReadLine() with
  32.     | Nat v -> Ok v
  33.     | _ -> Error "invalid number, must be greater then 0"
  34. let tryRead() =
  35.     match Console.ReadLine() with
  36.     | null -> Error "not Expecting empty input"
  37.     | v -> Ok v
  38. let maybeNetwork (str:string) =
  39.     match str.Split(' ', StringSplitOptions.RemoveEmptyEntries) with
  40.     | [|Char c; Nat h; ZeroNAT i |] -> Ok {id = c; hosts = h; infected = i }
  41.     | _ -> Error "Invalid network"
  42. let maybeLink (str:string) =
  43.    match str.Split(' ', StringSplitOptions.RemoveEmptyEntries) with
  44.    | [|Char c1; Char c2; Nat cap  |] -> Ok { n1=c1; n2=c2; capacity= cap}
  45.    | _ -> Error "Invalid Link"
  46.  
  47. let maybeRate (str:string) =
  48.     match str.Split(' ', StringSplitOptions.RemoveEmptyEntries) with
  49.     | [|Float spread; Float infected; Float rate |] -> Ok {S = spread; I = infected; R = rate;}
  50.     | _ -> Error "Invalid Rate"
  51.  
  52. let getNetworks n =
  53.     //Some kind of sequence or list to replace this?
  54.    let rec tryNewnetwork lis =
  55.  
  56.        printfn "enter network ID(char) hosts(integer greater then 0 ) infected(integer greater then 0)"
  57.        tryRead()
  58.        |> Result.bind(maybeNetwork)
  59.        |> Result.bind(fun x -> if not ( lis |> List.exists(fun y -> x.id = y.id)) then Ok x else Error "A network with that ID already exists")
  60.        |>function
  61.        | Ok  newNet -> match (newNet::lis) |> List.length with
  62.                         | v when v = n -> lis
  63.                         | _ -> tryNewnetwork lis
  64.        | Error e ->  printfn "%s" e
  65.                      tryNewnetwork lis
  66.    tryNewnetwork []
  67.  
  68. let identicalLink l1 l2 =
  69.     ((l1.n1 = l2.n1 && l1.n2 = l2.n2 )||(l1.n1 = l2.n2 && l1.n2 = l2.n1))
  70.  
  71. let linkHasNetworks networkLis l1  =
  72.     List.exists(fun y -> l1.n1 = y.id) networkLis && List.exists(fun y -> l1.n2 = y.id) networkLis
  73.  
  74. let getLinks n networkLis =
  75.      //Some kind of sequence or list to replace this?
  76.    let rec trylistofLinks lis =
  77.        tryRead()
  78.        |> Result.bind(maybeLink)
  79.        |> Result.bind(fun x -> match x.n1 = x.n2 with
  80.                               | false -> Ok x
  81.                               | true -> Error "can't connect to the same network")
  82.        |> Result.bind(fun x -> if not ( lis |> List.exists(fun y -> identicalLink x y )) then Ok x else Error "A Link connecting these two networks already exists")
  83.        |> Result.bind(fun x ->  match linkHasNetworks networkLis x with
  84.                                | true -> Ok x
  85.                                | false -> Error "Both networks need to exist")
  86.        |>function
  87.        | Ok  newNet -> match (newNet::lis) |> List.length with
  88.                         | v when v = n -> lis
  89.                         | _ -> trylistofLinks lis
  90.        | Error e ->  printfn "%s" e
  91.                      trylistofLinks lis
  92.    trylistofLinks []
  93.  
  94. let getRate () =
  95.     tryRead() |>
  96.     Result.bind maybeRate
  97.  
  98. let simulate = ignore
  99.  
  100. [<EntryPoint>]
  101. let main argv =
  102.     printfn "Enter Number of networks"
  103.     getNumberItems()
  104.     |> Result.map(fun x ->  getNetworks x)
  105.     |> function //output
  106.     | Ok result -> result
  107.                    |> printfn "%A"
  108.     | Error e -> printfn "%s" e
  109.     0 // return an integer exit code
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement