Advertisement
Guest User

Worm War 2

a guest
Aug 18th, 2018
83
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
F# 4.79 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. type IOWorkFlow() =
  31.  
  32.     member this.Bind(x, f) = Result.bind f x
  33.  
  34.  
  35.     member this.Return(x) =
  36.         Ok x
  37.  
  38. let createdWorkflow = new IOWorkFlow()
  39.  
  40. let getNaturalNumber () =
  41.     match Console.ReadLine() with
  42.     | Nat v -> Ok v
  43.     | _ -> Error "invalid number, must be greater then 0"
  44.  
  45. let tryRead() =
  46.     match Console.ReadLine() with
  47.     | null -> Error "not Expecting empty input"
  48.     | v -> Ok v
  49. let maybeNetwork (str:string) =
  50.     match str.Split(' ', StringSplitOptions.RemoveEmptyEntries) with
  51.     | [|Char c; Nat h; ZeroNAT i |] -> Ok {id = c; hosts = h; infected = i }
  52.     | _ -> Error "Invalid network"
  53.  
  54. let maybeLink (str:string) =
  55.    match str.Split(' ', StringSplitOptions.RemoveEmptyEntries) with
  56.    | [|Char c1; Char c2; Nat cap  |] -> Ok { n1=c1; n2=c2; capacity= cap}
  57.    | _ -> Error "Invalid Link networkID1(char) networkID2(char) capacity(int greater then 0)"
  58.  
  59. let maybeRate (str:string) =
  60.     match str.Split(' ', StringSplitOptions.RemoveEmptyEntries) with
  61.     | [|Float spread; Float infected; Float rate |] -> Ok {S = spread; I = infected; R = rate;}
  62.     | _ -> Error "Invalid Rate spread(float) infected(float) rate(float)"
  63.  
  64. let getNetworks n =
  65.     //Some kind of sequence or list to replace this?
  66.    let rec tryNewnetwork lis =
  67.  
  68.        printfn "enter network ID(char) hosts(integer greater then 0 ) infected(integer greater or equal to 0)"
  69.  
  70.        tryRead()
  71.        |> Result.bind(maybeNetwork)
  72.        |> 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")
  73.        |>function
  74.        | Ok  newNet -> match (newNet::lis)  with
  75.                         | v when List.length v  = n -> v
  76.                         | v -> tryNewnetwork v
  77.        | Error e ->  printfn "%s" e
  78.                      tryNewnetwork lis
  79.    tryNewnetwork []
  80.  
  81. let identicalLink l1 l2 =
  82.     ((l1.n1 = l2.n1 && l1.n2 = l2.n2 )||(l1.n1 = l2.n2 && l1.n2 = l2.n1))
  83.  
  84. let linkHasNetworks networkLis l1  =
  85.     List.exists(fun y -> l1.n1 = y.id) networkLis && List.exists(fun y -> l1.n2 = y.id) networkLis
  86.  
  87. let getLinks n networkLis =
  88.      //Some kind of sequence or list to replace this?
  89.    let rec trylistofLinks lis =
  90.  
  91.        printfn "enter Link networkID1(char) networkID2(char) capacity(int greater then 0)"
  92.  
  93.        tryRead()
  94.        |> Result.bind(maybeLink)
  95.        |> Result.bind(fun x -> match x.n1 = x.n2 with
  96.                                | false -> Ok x
  97.                                | true -> Error "can't connect to the same network")
  98.        |> 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")
  99.        |> Result.bind(fun x ->  match linkHasNetworks networkLis x with
  100.                                 | true -> Ok x
  101.                                 | false -> Error "Both networks need to exist")
  102.        |>function
  103.        | Ok  newNet -> match (newNet::lis) |> List.length with
  104.                         | v when v = n -> lis
  105.                         | _ -> trylistofLinks lis
  106.        | Error e ->  printfn "%s" e
  107.                      trylistofLinks lis
  108.    trylistofLinks []
  109.  
  110. let getRate () =
  111.     printfn "Enter rate spread(float) infected(float) rate(float)"
  112.     tryRead() |>
  113.     Result.bind maybeRate
  114.  
  115. let simulate networks links rate packetSize = ignore
  116.  
  117.  
  118. let inputAll() =
  119.     createdWorkflow
  120.         {
  121.            printfn "Enter Number of networks"
  122.            let! networks = getNaturalNumber()
  123.                            |> Result.map getNetworks
  124.            printfn "Enter Number of Links"
  125.            let! links = getNaturalNumber()
  126.                         |> Result.map (fun n -> getLinks n networks)
  127.                        
  128.            let! rate = getRate()
  129.  
  130.            printfn "Enter packet size"
  131.            let! packetSize = getNaturalNumber()
  132.            
  133.            return simulate networks links rate packetSize
  134.         }
  135.  
  136. [<EntryPoint>]
  137. let main argv =
  138.     inputAll()
  139.     |>function
  140.     | Ok v -> printfn "yay"
  141.     | Error e -> printfn "%s" e
  142.     0 // return an integer exit code
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement