Skip to content
Open
31 changes: 31 additions & 0 deletions Brackets/Brackets.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 = 25.0.1706.10
MinimumVisualStudioVersion = 10.0.40219.1
Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "Brackets", "Brackets\Brackets.fsproj", "{B26871CD-3266-4D15-A5D9-E56EF988A7EF}"
EndProject
Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "BracketsChecker.Tests", "BracketsChecker.Tests\BracketsChecker.Tests.fsproj", "{38386C22-13A1-4BFF-B58C-A23812F7FDD0}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{B26871CD-3266-4D15-A5D9-E56EF988A7EF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B26871CD-3266-4D15-A5D9-E56EF988A7EF}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B26871CD-3266-4D15-A5D9-E56EF988A7EF}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B26871CD-3266-4D15-A5D9-E56EF988A7EF}.Release|Any CPU.Build.0 = Release|Any CPU
{38386C22-13A1-4BFF-B58C-A23812F7FDD0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{38386C22-13A1-4BFF-B58C-A23812F7FDD0}.Debug|Any CPU.Build.0 = Debug|Any CPU
{38386C22-13A1-4BFF-B58C-A23812F7FDD0}.Release|Any CPU.ActiveCfg = Release|Any CPU
{38386C22-13A1-4BFF-B58C-A23812F7FDD0}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {5AFD0F68-0793-4F4E-8C8D-6924AFE7632C}
EndGlobalSection
EndGlobal
12 changes: 12 additions & 0 deletions Brackets/Brackets/Brackets.fsproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
</PropertyGroup>

<ItemGroup>
<Compile Include="BracketsChecker.fs" />
</ItemGroup>

</Project>
24 changes: 24 additions & 0 deletions Brackets/Brackets/BracketsChecker.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
namespace Brackets

module Brackets =

let bracketPairs = Map['(', ')'; '{', '}'; '[', ']']

let checkSequence (sequence : string) =
let rec checkRec (sequence : string) stack position counter =
if (position = sequence.Length) then if (counter = 0) then true else false

else
let bracket = sequence.[position]
if bracketPairs.ContainsKey bracket then
checkRec sequence (bracket :: stack) (position + 1) (counter + 1)
else
if (bracketPairs.Values.Contains bracket) then
match stack with
| [] -> false
| head :: tail ->
if (bracket = bracketPairs.[head]) then
checkRec sequence tail (position + 1) (counter - 1)
else false
else checkRec sequence stack (position + 1) counter
checkRec sequence [] 0 0
30 changes: 30 additions & 0 deletions Brackets/BracketsChecker.Tests/BracketsChecker.Tests.fsproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>

<IsPackable>false</IsPackable>
<GenerateProgramFile>false</GenerateProgramFile>
<IsTestProject>true</IsTestProject>
</PropertyGroup>

<ItemGroup>
<Compile Include="UnitTest.fs" />
<Compile Include="Program.fs" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.5.0" />
<PackageReference Include="NUnit" Version="3.13.3" />
<PackageReference Include="NUnit3TestAdapter" Version="4.4.2" />
<PackageReference Include="NUnit.Analyzers" Version="3.6.1" />
<PackageReference Include="coverlet.collector" Version="3.2.0" />
<PackageReference Include="FsUnit" Version="6.0.0">
<GeneratePathProperty></GeneratePathProperty>
</PackageReference>
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\Brackets\Brackets.fsproj" />
</ItemGroup>
</Project>
5 changes: 5 additions & 0 deletions Brackets/BracketsChecker.Tests/Program.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
module Program =

[<EntryPoint>]
let main _ = 0

27 changes: 27 additions & 0 deletions Brackets/BracketsChecker.Tests/UnitTest.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
module BracketsChecker.Tests

open FsUnit
open NUnit.Framework
open Brackets.Brackets
let testCasesTrue =
seq {
yield (TestCaseData("[][{}([][(){()()}])]"))
}

let testCasesFalse =
seq {

Choose a reason for hiding this comment

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

нужны тесты на "", ")", "("

yield (TestCaseData("[]{{}}}"))
yield (TestCaseData("[{(})]"))
yield (TestCaseData("))(("))
yield (TestCaseData(")"))
yield (TestCaseData("("))
}
[<TestCaseSource("testCasesTrue")>]
let ``Test cases true`` (sequence : string) =
let res = checkSequence sequence
Assert.That(checkSequence sequence)

[<TestCaseSource("testCasesFalse")>]
let ``Test cases false`` (sequence : string) =
let res = checkSequence sequence
Assert.That(not (checkSequence sequence))
35 changes: 35 additions & 0 deletions PhoneBook/PhoneBook.Tests/PhoneBook.Tests.fsproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>

<IsPackable>false</IsPackable>
<GenerateProgramFile>false</GenerateProgramFile>
<IsTestProject>true</IsTestProject>
</PropertyGroup>

<ItemGroup>
<Compile Include="UnitTests.fs" />
<Compile Include="Program.fs" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.5.0" />
<PackageReference Include="NUnit" Version="4.1.0" />
<PackageReference Include="NUnit3TestAdapter" Version="4.5.0" />
<PackageReference Include="NUnit.Analyzers" Version="4.1.0"><IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="coverlet.collector" Version="3.2.0" />
<PackageReference Include="FsUnit" Version="6.0.0">
<GeneratePathProperty></GeneratePathProperty>
</PackageReference>
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\PhoneBook\PhoneBook.fsproj" />
</ItemGroup>
<ItemGroup>
<None Include="readTest.txt" />
</ItemGroup>
</Project>
5 changes: 5 additions & 0 deletions PhoneBook/PhoneBook.Tests/Program.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
module Program =

[<EntryPoint>]
let main _ = 0

55 changes: 55 additions & 0 deletions PhoneBook/PhoneBook.Tests/UnitTests.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
module PhoneBookTests

open FsUnit
open NUnit.Framework
open PhoneBook.PhoneBook

let data =
[
{Name = "Tom"; Number = "89019892909"};
{Name = "Alice"; Number = "83890198101"};
{Name = "John"; Number = "82839281789"};
{Name = "Bob"; Number = "+72898271890"};
{Name = "Hanna"; Number = "+71289019813"};
{Name = "Sara"; Number = "81278918789"}
]

let comparePersons (p1 : Person) (p2 : Person) =
if p1 < p2 then -1 else
if p1 = p2 then
if p1 < p2 then -1
else 1
else 1

[<Test>]
let ``test add record basic`` () =
let person = {Name = "Julia"; Number = "+79110606382"}
let newData = fst (addRecord person data)
let correctResult = List.sortWith comparePersons [{Name = "Tom"; Number = "89019892909"};
{Name = "Alice"; Number = "83890198101"};
{Name = "John"; Number = "82839281789"};
{Name = "Bob"; Number = "+72898271890"};
{Name = "Hanna"; Number = "+71289019813"};
{Name = "Sara"; Number = "81278918789"};
{Name = "Julia"; Number = "+79110606382"}]
let actual = List.sortWith comparePersons newData
Assert.That(actual, Is.EqualTo(correctResult))

[<Test>]
let ``test find name by phone`` () =
(findByPhone "82839281789" data).Value |> should equal "John"
findByPhone "82839281780" data |> should equal None

[<Test>]
let ``test find name by name`` () =
(findByName "Sara" data).Value |> should equal "81278918789"
findByName "Kat" data |> should equal None

[<Test>]
let ``test read from file`` () =
let dataWrite = "Tom 89019892909\nAlice 83890198101\nJohn 82839281789\nBob +72898271890\nHanna +71289019813\nSara 81278918789"
let dataEmpty = []
match fill dataWrite dataEmpty with
| None -> Assert.Fail()
| Some data ->
List.sortWith comparePersons data |> should equal (List.sortWith comparePersons data)
6 changes: 6 additions & 0 deletions PhoneBook/PhoneBook.Tests/readTest.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
Tom 89019892909
Alice 83890198101
John 82839281789
Bob +72898271890
Hanna +71289019813
Sara 81278918789
31 changes: 31 additions & 0 deletions PhoneBook/PhoneBook.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 = 25.0.1706.10
MinimumVisualStudioVersion = 10.0.40219.1
Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "PhoneBook", "PhoneBook\PhoneBook.fsproj", "{6505FB31-C578-46DB-BA5D-4EC7EE43949E}"
EndProject
Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "PhoneBook.Tests", "PhoneBook.Tests\PhoneBook.Tests.fsproj", "{ECE029B1-5E76-4E6D-B1D3-A810FCA77DA6}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{6505FB31-C578-46DB-BA5D-4EC7EE43949E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{6505FB31-C578-46DB-BA5D-4EC7EE43949E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{6505FB31-C578-46DB-BA5D-4EC7EE43949E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{6505FB31-C578-46DB-BA5D-4EC7EE43949E}.Release|Any CPU.Build.0 = Release|Any CPU
{ECE029B1-5E76-4E6D-B1D3-A810FCA77DA6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{ECE029B1-5E76-4E6D-B1D3-A810FCA77DA6}.Debug|Any CPU.Build.0 = Debug|Any CPU
{ECE029B1-5E76-4E6D-B1D3-A810FCA77DA6}.Release|Any CPU.ActiveCfg = Release|Any CPU
{ECE029B1-5E76-4E6D-B1D3-A810FCA77DA6}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {977DFA75-7185-40AB-8D5A-13BB914B801E}
EndGlobalSection
EndGlobal
55 changes: 55 additions & 0 deletions PhoneBook/PhoneBook/PhoneBook.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
namespace PhoneBook

open System.Text.RegularExpressions

module PhoneBook =

Choose a reason for hiding this comment

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

Я бы ещё сказал, что надо комментарии


type Person = { Name: string; Number: string }

let phoneRegex () = Regex(@"(\+7|7|8)+\d{10}", RegexOptions.Compiled)
let nameRegex () = Regex(@"[A-Z][a-z]+", RegexOptions.Compiled)

///Add new record to the data

Choose a reason for hiding this comment

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

Suggested change
///Add new record to the data
/// Add new record to the data

let addRecord (person : Person) data =
if List.exists(fun (p : Person) -> p.Number = person.Number) data
then
(data, None)
else (person :: data, Some 1)

///Find by phone a name of a person
let findByPhone phone data =
let result = List.tryFind(fun (p : Person) -> p.Number = phone) data

match result with
| Some p -> Some p.Name
| None -> None

///Find a phone by name
let findByName name data =
let result = List.tryFind(fun (p : Person) -> p.Name = name) data

match result with
| Some p -> Some p.Number
| None -> None

///Convert all the data to string
let convertDataToString data =
data
|> List.fold (fun acc person ->
acc + $"{person.Name} {person.Number}\n") ""

///Parse data from string and create list of records
let fill (personsString : string) data =

let persons = personsString.Split('\n')
let rec addPersons (persons : list<string>) data =
match persons with
| [] -> Some data
| head :: tail ->
let personData = (head.ToString()).Split([|' '|])
let newPerson = {Name = personData.[0]; Number = personData.[1]}
if not (phoneRegex().IsMatch(personData.[1]) && nameRegex().IsMatch(personData.[0])) then
None
else if (personData.Length) = 2 then addPersons tail (newPerson :: data)
else None
addPersons (Seq.toList persons) data
21 changes: 21 additions & 0 deletions PhoneBook/PhoneBook/PhoneBook.fsproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net7.0</TargetFramework>
</PropertyGroup>

<ItemGroup>
<Compile Include="PhoneBook.fs" />
<Compile Include="Program.fs" />
</ItemGroup>

<ItemGroup>
<None Include="dataWrite.txt">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="dataRead.txt">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
</Project>
Loading