diff --git a/hw5/LocalNetworkGraph/LocalNetworkGraph.sln b/hw5/LocalNetworkGraph/LocalNetworkGraph.sln
new file mode 100644
index 0000000..7f7828b
--- /dev/null
+++ b/hw5/LocalNetworkGraph/LocalNetworkGraph.sln
@@ -0,0 +1,31 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 16
+VisualStudioVersion = 16.0.30114.105
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "LocalNetworkGraph", "LocalNetworkGraph\LocalNetworkGraph.fsproj", "{3DD18E22-393F-4B15-ACD5-AF3DA21A5CC2}"
+EndProject
+Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "LocalNetworkGraphTests", "LocalNetworkGraphTests\LocalNetworkGraphTests.fsproj", "{61D8FBF7-9B8A-461B-A27F-0416A7085DB3}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {3DD18E22-393F-4B15-ACD5-AF3DA21A5CC2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {3DD18E22-393F-4B15-ACD5-AF3DA21A5CC2}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {3DD18E22-393F-4B15-ACD5-AF3DA21A5CC2}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {3DD18E22-393F-4B15-ACD5-AF3DA21A5CC2}.Release|Any CPU.Build.0 = Release|Any CPU
+ {61D8FBF7-9B8A-461B-A27F-0416A7085DB3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {61D8FBF7-9B8A-461B-A27F-0416A7085DB3}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {61D8FBF7-9B8A-461B-A27F-0416A7085DB3}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {61D8FBF7-9B8A-461B-A27F-0416A7085DB3}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {70F6F8E0-B63F-4D25-9686-6ACC16C8D9F5}
+ EndGlobalSection
+EndGlobal
diff --git a/hw5/LocalNetworkGraph/LocalNetworkGraph/LocalNetwork.fs b/hw5/LocalNetworkGraph/LocalNetworkGraph/LocalNetwork.fs
new file mode 100644
index 0000000..d05e288
--- /dev/null
+++ b/hw5/LocalNetworkGraph/LocalNetworkGraph/LocalNetwork.fs
@@ -0,0 +1,82 @@
+module LocalNetwork
+
+open System
+
+
+/// Local network working process model.
+type LocalNetwork(computersCommunication: int list list, OSOfComputers: string list, probabilityInfectionForOS: float list) =
+
+ /// Number of computers in local network.
+ let numberOfComputers () = List.length computersCommunication
+
+ /// Random number sensor for computers. On every step check if the computer is infected.
+ let rndSensorValue = new Random()
+
+ /// Returns the probability to be infected for computer with specific OS.
+ let probabylityOfInfectionForOS operSys = probabilityInfectionForOS.[List.findIndex (fun x -> x = operSys) OSOfComputers] * 100.0
+
+ /// Finds probabylity of infection for computer.
+ let probabilityOfInfection vertex = probabylityOfInfectionForOS <| OSOfComputers.[vertex]
+
+ /// Checks if the current step infects computer.
+ let isInfectedThisStep vertex =
+ probabilityOfInfection vertex >= double(rndSensorValue.Next(0, 100))
+
+ /// Checks if the network can be infected.
+ let networkCanBeInfected = List.exists (fun x -> abs(x) > 0.001) probabilityInfectionForOS
+
+ /// Checks if the neighbours of the computer can be infected.
+ let neighboursCanBeInfected vertex infected =
+ List.exists (fun x -> not (List.contains x infected) && abs(probabilityOfInfection x) > 0.001) computersCommunication.[vertex]
+
+ /// Tries to infect neighbours.
+ let tryInfectNeighbours infected vertex =
+ let rec tryInfectNeighboursRec infected vertex currVrtx =
+ if currVrtx = numberOfComputers() then infected
+ elif isInfectedThisStep currVrtx && not (List.contains currVrtx infected) && List.contains currVrtx computersCommunication.[vertex] then
+ tryInfectNeighboursRec (currVrtx :: infected) vertex (currVrtx + 1)
+ else tryInfectNeighboursRec infected vertex (currVrtx + 1)
+ tryInfectNeighboursRec infected vertex 0
+
+ /// Tries to infect all the vertexes that are connected with infected.
+ let tryInfectNeighboursOfInfected infected =
+ let rec tryInfectNeighboursOfInfectedRec infected leftVrtxs =
+ match leftVrtxs with
+ | [] -> infected
+ | h :: t -> tryInfectNeighboursOfInfectedRec (tryInfectNeighbours infected h) t
+ tryInfectNeighboursOfInfectedRec infected infected
+
+
+ /// Infects first computer.
+ let infectFirst () =
+ let rec infectFirstRec acc =
+ if isInfectedThisStep acc then acc
+ else infectFirstRec <| (acc + 1) % numberOfComputers()
+ infectFirstRec 0
+
+ /// Prints the information about the state of the network.
+ let printInf infected =
+ let rec printRec infected currVertex =
+ if currVertex < numberOfComputers() then
+ if List.contains currVertex infected then printfn "%s%d" "INFECTED: " currVertex
+ else printfn "%s%d" "Not infected: " currVertex
+ printRec infected (currVertex + 1)
+ printf "%s" "\n"
+ printRec infected 0
+
+ /// Infects all the vertexes that are possible to infect.
+ let rec infectAll =
+ if not networkCanBeInfected then []
+ else
+ let rec infectAllRec infected =
+ if List.length infected = 0 then
+ printInf infected
+ infectAllRec (infectFirst () :: infected)
+ elif (List.length infected = numberOfComputers () || List.forall (fun x -> not (neighboursCanBeInfected x infected)) infected) then infected
+ else
+ printInf infected
+ infectAllRec (tryInfectNeighboursOfInfected infected)
+ infectAllRec []
+
+ /// Infects all the computers with virus. Returns infected computers.
+ member public this.Infected = infectAll
diff --git a/hw5/LocalNetworkGraph/LocalNetworkGraph/LocalNetworkGraph.fsproj b/hw5/LocalNetworkGraph/LocalNetworkGraph/LocalNetworkGraph.fsproj
new file mode 100644
index 0000000..cf05dbe
--- /dev/null
+++ b/hw5/LocalNetworkGraph/LocalNetworkGraph/LocalNetworkGraph.fsproj
@@ -0,0 +1,13 @@
+
+
+
+ Exe
+ netcoreapp3.1
+
+
+
+
+
+
+
+
diff --git a/hw5/LocalNetworkGraph/LocalNetworkGraph/Program.fs b/hw5/LocalNetworkGraph/LocalNetworkGraph/Program.fs
new file mode 100644
index 0000000..23c15b9
--- /dev/null
+++ b/hw5/LocalNetworkGraph/LocalNetworkGraph/Program.fs
@@ -0,0 +1,11 @@
+// Learn more about F# at http://fsharp.org
+
+open System
+open LocalNetwork
+
+[]
+let main argv =
+ printfn "%A" <| LocalNetwork([[1; 3]; [0]; [3]; [2; 1]], ["Windows"; "Linux"; "Linux"; "Mac OS"],
+ [0.7; 0.1; 0.1; 0.9]).Infected
+
+ 0 // return an integer exit code
diff --git a/hw5/LocalNetworkGraph/LocalNetworkGraphTests/LocalNetworkGraphTests.fsproj b/hw5/LocalNetworkGraph/LocalNetworkGraphTests/LocalNetworkGraphTests.fsproj
new file mode 100644
index 0000000..c8c48fb
--- /dev/null
+++ b/hw5/LocalNetworkGraph/LocalNetworkGraphTests/LocalNetworkGraphTests.fsproj
@@ -0,0 +1,32 @@
+
+
+
+ netcoreapp3.1
+
+ false
+ true
+
+
+
+
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/hw5/LocalNetworkGraph/LocalNetworkGraphTests/LocalNetworkTests.fs b/hw5/LocalNetworkGraph/LocalNetworkGraphTests/LocalNetworkTests.fs
new file mode 100644
index 0000000..3d58e6d
--- /dev/null
+++ b/hw5/LocalNetworkGraph/LocalNetworkGraphTests/LocalNetworkTests.fs
@@ -0,0 +1,39 @@
+module LocalNetworkGraphTests
+
+open NUnit.Framework
+open LocalNetwork
+open FsUnit
+
+let testCases1 =
+ [
+ [[1]; [0]], ["Linux"; "Windows"], [0.3; 0.7], [0; 1]
+ [[1]; [0]], ["Linux"; "Windows"], [1.0; 1.0], [0; 1]
+ [[1]; [0]], ["Mac OS"; "Linux"], [0.7; 0.0], [0]
+ [[1; 3]; [0]; [3]; [2; 1]], ["Windows"; "Linux"; "Linux"; "Mac OS"], [0.7; 0.1; 0.1; 0.9], [0; 1; 2; 3]
+ [[1; 2; 3; 4]; [0; 2; 3; 4]; [0; 1; 3; 4]; [0; 1; 2; 3]; [0; 1; 2; 3; 4]],
+ ["WIndows"; "Windows"; "Linux"; "Linux"; "Mac OS"], [0.5; 0.5; 0.2; 0.2; 1.0], [0; 1; 2; 3; 4]
+ ] |> List.map (fun (communicationComputers, operSys, probabOfInf, infected) ->
+ TestCaseData(communicationComputers, operSys, probabOfInf, infected))
+
+let testCases2 =
+ [
+ [[1]; [0]], ["Linux"; "Windows"], [0.0; 0.0]
+ [[1; 2; 3; 4]; [0; 2; 3; 4]; [0; 1; 3; 4]; [0; 1; 2; 3]; [0; 1; 2; 3; 4]],
+ ["WIndows"; "Windows"; "Linux"; "Linux"; "Mac OS"], [0.0; 0.0; 0.0; 0.0; 0.0]
+ ] |> List.map (fun (communicationComputers, operSys, probabOfInf) ->
+ TestCaseData(communicationComputers, operSys, probabOfInf))
+
+[]
+[]
+let ``Checks if contains vertexes that should be infected`` communication operSys probabOfInf infected =
+ LocalNetwork(communication, operSys, probabOfInf).Infected |> List.forall (fun x -> List.contains x infected) |> should equal true
+
+[]
+[]
+let ``Checks if vertexes that should be infected are contained in result`` communication operSys probabOfInf infected =
+ List.forall (fun x -> LocalNetwork(communication, operSys, probabOfInf).Infected |> List.contains x) infected |> should equal true
+
+[]
+[]
+let ``Checks if the algorithm works correctly when probabylity of infection is 0 for all computers`` communication operSys probabOfInf =
+ LocalNetwork(communication, operSys, probabOfInf).Infected |> List.length = 0 |> should equal true
\ No newline at end of file