Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sem4 problem 5 #64

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions Semester-4/Homework-5/Network.Tests/LogBFS.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
namespace Network

/// Logger for computers with 100% infection chance
type LogBFS() =
let mutable stepNumber = 0
let mutable isSomeoneHealthy = true
let mutable isBFS = true

member this.IsSomeoneHealthy = isSomeoneHealthy
member this.IsBFS = isBFS

interface ILog with
member this.LogState state =

if (state.[2 - stepNumber] = false || state.[2 + stepNumber] = false) then
isBFS <- false

if stepNumber >= 500 then
failwith "Simulation was not stopped, but probability is 1!"
else
isSomeoneHealthy <- Array.contains false <| state
stepNumber <- stepNumber + 1


stepNumber
11 changes: 11 additions & 0 deletions Semester-4/Homework-5/Network.Tests/LogZeroChance.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
namespace Network

/// Logger for network of uninfectable computers
type LogZeroChance() =
let mutable stepNumber = 0

interface ILog with
member this.LogState state =

stepNumber <- stepNumber + 1
stepNumber
27 changes: 27 additions & 0 deletions Semester-4/Homework-5/Network.Tests/Network.Tests.fsproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>

<IsPackable>false</IsPackable>
<GenerateProgramFile>false</GenerateProgramFile>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="FsUnit" Version="3.8.1" />
<PackageReference Include="nunit" Version="3.12.0" />
<PackageReference Include="NUnit3TestAdapter" Version="3.15.1" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.2.0" />
</ItemGroup>

<ItemGroup>
<Compile Include="LogZeroChance.fs" />
<Compile Include="LogBFS.fs" />
<Compile Include="UnitTests.fs" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\Network\Network.fsproj" />
</ItemGroup>

</Project>
64 changes: 64 additions & 0 deletions Semester-4/Homework-5/Network.Tests/UnitTests.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
namespace Network

module Tests =
open NUnit.Framework
open FsUnit

[<Test>]
let ``Simulator should work correctly with overall chance = 1`` () =
let computers = [| for i in 1..6 -> ({new IOperatingSystem with
member this.InfectionChance = 1.0}) |]
let graph =
[|
[1]
[0; 2]
[3; 1]
[2; 4; 5]
[3; 5]
[3; 4]
|]

let logger = new LogBFS()
let simulator = new Simulator(computers, graph, logger)
simulator.Start [|false; false; true; false; false; false|] |> ignore

logger.IsSomeoneHealthy |> should be False

[<Test>]
let ``Simulator should work correctly with overall chance = 0`` () =
let computers = [| for i in 1..6 -> ({new IOperatingSystem with
member this.InfectionChance = 0.0}) |]
let graph =
[|
[1]
[0; 2]
[1; 3]
[2; 4; 5]
[3; 5]
[3; 4]
|]
let expectedState = Array.concat[ [|true|]; [| for i in 1..5 -> false |] ]
let log = new LogZeroChance()

let simulator = new Simulator(computers, graph, log)
let resultingNetwork = simulator.Start(expectedState)
resultingNetwork |> should equal expectedState

[<Test>]
let ``Infection should work like BFS with infection chance == 1`` () =
let computers = [| for i in 1..6 -> ({new IOperatingSystem with
member this.InfectionChance = 1.0}) |]
let graph =
[|
[1]
[0; 2]
[1; 3]
[2; 4]
[3]
|]

let logger = new LogBFS()
let simulator = new Simulator(computers, graph, logger)
simulator.Start [|false; false; true; false; false|] |> ignore

logger.IsBFS |> should be True
17 changes: 17 additions & 0 deletions Semester-4/Homework-5/Network/Log/ConsoleLog.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
namespace Network

/// Network state logger
type ConsoleLog() =
let mutable step = 0

interface ILog with
/// Prints current network state
member this.LogState state =
printfn "Step №%d. " step
state |> Array.iteri (fun i item ->
match item with
| true -> printfn "Computer #%d: Infected" i
| false -> printfn "Computer #%d: Healthy" i)

step <- step + 1
step
6 changes: 6 additions & 0 deletions Semester-4/Homework-5/Network/Log/ILog.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
namespace Network

/// Network state logger interface
type ILog =
/// Prints current network state
abstract member LogState : bool array -> int
16 changes: 16 additions & 0 deletions Semester-4/Homework-5/Network/Network.fsproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp3.1</TargetFramework>
</PropertyGroup>

<ItemGroup>
<Compile Include="Log\ILog.fs" />
<Compile Include="Log\ConsoleLog.fs" />
<Compile Include="OperatingSystem\IOperatingSystem.fs" />
<Compile Include="Simulation.fs" />
<Compile Include="Program.fs" />
</ItemGroup>

</Project>
31 changes: 31 additions & 0 deletions Semester-4/Homework-5/Network/Network.sln
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.29613.14
MinimumVisualStudioVersion = 10.0.40219.1
Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "Network", "Network.fsproj", "{608891F1-5F7C-4773-95FF-9563686EDE0C}"
EndProject
Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "Network.Tests", "..\Network.Tests\Network.Tests.fsproj", "{8C57BEC3-20B6-4158-BDD8-B2454D45DA76}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{608891F1-5F7C-4773-95FF-9563686EDE0C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{608891F1-5F7C-4773-95FF-9563686EDE0C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{608891F1-5F7C-4773-95FF-9563686EDE0C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{608891F1-5F7C-4773-95FF-9563686EDE0C}.Release|Any CPU.Build.0 = Release|Any CPU
{8C57BEC3-20B6-4158-BDD8-B2454D45DA76}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{8C57BEC3-20B6-4158-BDD8-B2454D45DA76}.Debug|Any CPU.Build.0 = Debug|Any CPU
{8C57BEC3-20B6-4158-BDD8-B2454D45DA76}.Release|Any CPU.ActiveCfg = Release|Any CPU
{8C57BEC3-20B6-4158-BDD8-B2454D45DA76}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {6055F841-A110-4496-B204-4862CD75557F}
EndGlobalSection
EndGlobal
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
namespace Network

/// Describes the operating system interface
type IOperatingSystem =
/// Chance of the computer getting infected
abstract member InfectionChance : float
20 changes: 20 additions & 0 deletions Semester-4/Homework-5/Network/Program.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
namespace Network

module Main =
open System

let computers = [| for i in 1..5 -> ( {new IOperatingSystem with
member this.InfectionChance = 1.0}) |]

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Интересное решение, но я имел в виду сделать IOperatingSystem конкрентым классом, а вероятность заражения принимать в конструктор просто

let graph =
[|
[1]
[0; 2]
[1; 3]
[2; 4]
[3]
|]

let logger = new ConsoleLog()
let simulator = new Simulator(computers, graph, logger)

simulator.Start [|true; false; true; false; true|] |> ignore
56 changes: 56 additions & 0 deletions Semester-4/Homework-5/Network/Simulation.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
namespace Network

/// Simulates network infection process
type Simulator(
computers : IOperatingSystem array,
graph : int list array,
log : ILog) =

let random = System.Random()


/// Starts the simulation
member this.Start (startState : bool array) =

/// Carries out the simulation steps
let rec nextStep (handlingQueue : int list) (used : bool array) (newQueue : int list) =
match handlingQueue with

/// Computer gets infected
| head :: tail when
not used.[head] &&
(random.NextDouble() < computers.[head].InfectionChance) ->
used.[head] <- true
nextStep tail used (newQueue @ graph.[head])

/// Computer does not get infected
/// Keeps trying to infect it
| head :: tail when not used.[head] ->

/// If the computer is invincible...
if (computers.[head].InfectionChance = 0.0) then
/// ...there's no need in trying to infect it
nextStep tail used newQueue
else
nextStep tail used (newQueue @ [head])

/// Already infected computer
| head :: tail ->
nextStep tail used newQueue

/// Empty queue
| [] ->
(newQueue, used)

/// Launches the virus into the network
let rec virusJump queue states =
match queue with
| [] -> states
| virusQueue ->

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Можно было просто | _ ->

states |> log.LogState |> ignore
let newNetwork = nextStep virusQueue states List.Empty
virusJump (fst newNetwork) (snd newNetwork)

let infected = startState |> Array.indexed |> Array.filter (fun (i, x) -> x = true)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Мм, они же не infected, а соседи инфицированных?

|> Array.map (fun (i, x) -> graph.[i]) |> List.concat
virusJump infected startState
1 change: 1 addition & 0 deletions appveyor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ environment:
- solution_name: Semester-4/Homework-4/BracketSeq/BracketSeq.sln
- solution_name: Semester-4/Homework-4/PointFree/PointFree.sln
- solution_name: Semester-4/Homework-4/Phonebook/Phonebook.sln
- solution_name: Semester-4/Homework-5/Network/Network.sln
- solution_name: Semester-4/Homework-6/Workflows/Workflows.sln

before_build:
Expand Down