diff --git a/Brackets/Brackets.sln b/Brackets/Brackets.sln new file mode 100644 index 0000000..576a161 --- /dev/null +++ b/Brackets/Brackets.sln @@ -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 diff --git a/Brackets/Brackets/Brackets.fsproj b/Brackets/Brackets/Brackets.fsproj new file mode 100644 index 0000000..05d5068 --- /dev/null +++ b/Brackets/Brackets/Brackets.fsproj @@ -0,0 +1,12 @@ + + + + net7.0 + true + + + + + + + diff --git a/Brackets/Brackets/BracketsChecker.fs b/Brackets/Brackets/BracketsChecker.fs new file mode 100644 index 0000000..dc67553 --- /dev/null +++ b/Brackets/Brackets/BracketsChecker.fs @@ -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 \ No newline at end of file diff --git a/Brackets/BracketsChecker.Tests/BracketsChecker.Tests.fsproj b/Brackets/BracketsChecker.Tests/BracketsChecker.Tests.fsproj new file mode 100644 index 0000000..4f1b4aa --- /dev/null +++ b/Brackets/BracketsChecker.Tests/BracketsChecker.Tests.fsproj @@ -0,0 +1,30 @@ + + + + net7.0 + + false + false + true + + + + + + + + + + + + + + + + + + + + + + diff --git a/Brackets/BracketsChecker.Tests/Program.fs b/Brackets/BracketsChecker.Tests/Program.fs new file mode 100644 index 0000000..5da7e48 --- /dev/null +++ b/Brackets/BracketsChecker.Tests/Program.fs @@ -0,0 +1,5 @@ +module Program = + + [] + let main _ = 0 + diff --git a/Brackets/BracketsChecker.Tests/UnitTest.fs b/Brackets/BracketsChecker.Tests/UnitTest.fs new file mode 100644 index 0000000..6467b9a --- /dev/null +++ b/Brackets/BracketsChecker.Tests/UnitTest.fs @@ -0,0 +1,27 @@ +module BracketsChecker.Tests + +open FsUnit +open NUnit.Framework +open Brackets.Brackets +let testCasesTrue = + seq { + yield (TestCaseData("[][{}([][(){()()}])]")) + } + +let testCasesFalse = + seq { + yield (TestCaseData("[]{{}}}")) + yield (TestCaseData("[{(})]")) + yield (TestCaseData("))((")) + yield (TestCaseData(")")) + yield (TestCaseData("(")) + } +[] +let ``Test cases true`` (sequence : string) = + let res = checkSequence sequence + Assert.That(checkSequence sequence) + +[] +let ``Test cases false`` (sequence : string) = + let res = checkSequence sequence + Assert.That(not (checkSequence sequence)) \ No newline at end of file diff --git a/PhoneBook/PhoneBook.Tests/PhoneBook.Tests.fsproj b/PhoneBook/PhoneBook.Tests/PhoneBook.Tests.fsproj new file mode 100644 index 0000000..0c6aa75 --- /dev/null +++ b/PhoneBook/PhoneBook.Tests/PhoneBook.Tests.fsproj @@ -0,0 +1,35 @@ + + + + net7.0 + + false + false + true + + + + + + + + + + + + runtime; build; native; contentfiles; analyzers; buildtransitive +all + + + + + + + + + + + + + + diff --git a/PhoneBook/PhoneBook.Tests/Program.fs b/PhoneBook/PhoneBook.Tests/Program.fs new file mode 100644 index 0000000..5da7e48 --- /dev/null +++ b/PhoneBook/PhoneBook.Tests/Program.fs @@ -0,0 +1,5 @@ +module Program = + + [] + let main _ = 0 + diff --git a/PhoneBook/PhoneBook.Tests/UnitTests.fs b/PhoneBook/PhoneBook.Tests/UnitTests.fs new file mode 100644 index 0000000..8bc5e85 --- /dev/null +++ b/PhoneBook/PhoneBook.Tests/UnitTests.fs @@ -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 + +[] +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)) + +[] +let ``test find name by phone`` () = + (findByPhone "82839281789" data).Value |> should equal "John" + findByPhone "82839281780" data |> should equal None + +[] +let ``test find name by name`` () = + (findByName "Sara" data).Value |> should equal "81278918789" + findByName "Kat" data |> should equal None + +[] +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) \ No newline at end of file diff --git a/PhoneBook/PhoneBook.Tests/readTest.txt b/PhoneBook/PhoneBook.Tests/readTest.txt new file mode 100644 index 0000000..2788c19 --- /dev/null +++ b/PhoneBook/PhoneBook.Tests/readTest.txt @@ -0,0 +1,6 @@ +Tom 89019892909 +Alice 83890198101 +John 82839281789 +Bob +72898271890 +Hanna +71289019813 +Sara 81278918789 \ No newline at end of file diff --git a/PhoneBook/PhoneBook.sln b/PhoneBook/PhoneBook.sln new file mode 100644 index 0000000..6a2a1a4 --- /dev/null +++ b/PhoneBook/PhoneBook.sln @@ -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 diff --git a/PhoneBook/PhoneBook/PhoneBook.fs b/PhoneBook/PhoneBook/PhoneBook.fs new file mode 100644 index 0000000..0a6bea1 --- /dev/null +++ b/PhoneBook/PhoneBook/PhoneBook.fs @@ -0,0 +1,55 @@ +namespace PhoneBook + +open System.Text.RegularExpressions + +module PhoneBook = + + 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 + 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) 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 \ No newline at end of file diff --git a/PhoneBook/PhoneBook/PhoneBook.fsproj b/PhoneBook/PhoneBook/PhoneBook.fsproj new file mode 100644 index 0000000..fd14933 --- /dev/null +++ b/PhoneBook/PhoneBook/PhoneBook.fsproj @@ -0,0 +1,21 @@ + + + + Exe + net7.0 + + + + + + + + + + PreserveNewest + + + PreserveNewest + + + diff --git a/PhoneBook/PhoneBook/Program.fs b/PhoneBook/PhoneBook/Program.fs new file mode 100644 index 0000000..4da44e7 --- /dev/null +++ b/PhoneBook/PhoneBook/Program.fs @@ -0,0 +1,114 @@ +open System +open System.IO +open PhoneBook.PhoneBook + +printfn "To exit press 0 +To add record press 1 +To find a person's phone by name press 2 +To find a person's name by phone press 3 +To see all saved data press 4 +To save all existed data to file press 5 +To read data from file and save it to phone book press 6:\n" + +///Parse comand code and check if the value is appropriate +let parseCommandCode () = + printfn "enter a command code:\n" + let mutable code = 0 + let mutable isCorrect = Int32.TryParse(Console.ReadLine(), &code) + while ((not isCorrect || code > 6)) do + printfn "incorrect comand, try again\n" + isCorrect <- Int32.TryParse(Console.ReadLine(), &code) + + Some code + +///Add record to the existed records +let rec addNewRecord data = + printfn "Enter name & phone: \n" + let personData = Console.ReadLine().Split() + if not (personData.Length = 2) then + printfn "incorrect data, should be 2 items, try again\n" + addNewRecord data + + else if not (phoneRegex().IsMatch(personData.[1])) then + printfn "incorrect phone number, try again\n" + addNewRecord data + else if not (nameRegex().IsMatch(personData.[0])) then + printfn "incorrect name, try again\n" + addNewRecord data + else + let person = {Name = personData.[0]; Number = personData.[1]} + match (addRecord person data) with + | (d, Some v) -> d + | (d, None) -> + printf "the number already exists" + d + +///Find name by existed number +let rec findName data = + printfn "enter the phone:\n" + let phone = Console.ReadLine() + if not(phoneRegex().IsMatch(phone)) then + printfn "incorrect data, try again\n" + findName data + else + match findByName phone data with + | None -> printfn "%s" "there is no such name\n" + | Some name -> printfn "%s" (name.ToString()) + +///Find phone by name, return first coinsidence +let rec findPhone data = + printfn "enter the name:\n" + let name = Console.ReadLine() + if not(nameRegex().IsMatch(name)) then + printfn "incorrect data, try again\n" + findPhone data + else + match findByPhone name data with + | None -> printfn "%s" "there is no such name\n" + | Some name -> printfn "%s" (name.ToString()) + +///Write all the data to file +let writeFile data = + let path = "dataWrite.txt" + use fileWriter = new StreamWriter(path) + let dataToWrite = convertDataToString data + fileWriter.Write(dataToWrite) + +///Read the data from file +let readFile data = + let path = "dataRead.txt" + use fileReader = new StreamReader(path) + let readData = fileReader.ReadToEnd() + fill readData data + +///Process the continious loop of commands +let rec runLoop data = + + match parseCommandCode() with + | None | Some 0 -> Some data + | Some 1 -> + runLoop (addNewRecord data) + | Some 2 -> + findPhone data + runLoop data + | Some 3 -> + findName data + runLoop data + | Some 4 -> + printfn "%s" (convertDataToString data) + runLoop data + | Some 5 -> + writeFile data + runLoop data + | Some 6 -> + match (readFile data) with + | None -> + printf "incorrect data format in input file\n" + None + | Some data -> + runLoop data + | _ -> + printfn "incorrect command code:\n" + runLoop data + +runLoop [] |> ignore \ No newline at end of file diff --git a/PhoneBook/PhoneBook/dataRead.txt b/PhoneBook/PhoneBook/dataRead.txt new file mode 100644 index 0000000..2788c19 --- /dev/null +++ b/PhoneBook/PhoneBook/dataRead.txt @@ -0,0 +1,6 @@ +Tom 89019892909 +Alice 83890198101 +John 82839281789 +Bob +72898271890 +Hanna +71289019813 +Sara 81278918789 \ No newline at end of file diff --git a/PhoneBook/PhoneBook/dataWrite.txt b/PhoneBook/PhoneBook/dataWrite.txt new file mode 100644 index 0000000..5f28270 --- /dev/null +++ b/PhoneBook/PhoneBook/dataWrite.txt @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/PointFree/PointFree.Tests/PointFree.Tests.fsproj b/PointFree/PointFree.Tests/PointFree.Tests.fsproj new file mode 100644 index 0000000..bccf8d8 --- /dev/null +++ b/PointFree/PointFree.Tests/PointFree.Tests.fsproj @@ -0,0 +1,30 @@ + + + + net7.0 + + false + false + true + + + + + + + + + + + + + + + + + + + + + + diff --git a/PointFree/PointFree.Tests/Program.fs b/PointFree/PointFree.Tests/Program.fs new file mode 100644 index 0000000..5da7e48 --- /dev/null +++ b/PointFree/PointFree.Tests/Program.fs @@ -0,0 +1,5 @@ +module Program = + + [] + let main _ = 0 + diff --git a/PointFree/PointFree.Tests/UnitTests.fs b/PointFree/PointFree.Tests/UnitTests.fs new file mode 100644 index 0000000..41ded1b --- /dev/null +++ b/PointFree/PointFree.Tests/UnitTests.fs @@ -0,0 +1,17 @@ +module PointFree.Tests + +open FsUnit +open FsCheck +open NUnit.Framework + +let funcInitial x l = List.map (fun y -> y * x) l +let funcWithoutL1 x = List.map (fun y -> y * x) +let funcWithoutL2 x = List.map (fun y -> (*) y x) +let funcWithoutL3 x = List.map << (fun y -> (*) y) <| x +let funcWithoutLX = List.map << (fun y -> (*) y) +let funcPointFree = List.map << (*) + +[] +let ``Ckeck if the funcs the same`` () = + let isTheSame x l = funcInitial x l = funcPointFree x l + Check.QuickThrowOnFailure isTheSame \ No newline at end of file diff --git a/PointFree/PointFree.sln b/PointFree/PointFree.sln new file mode 100644 index 0000000..75d3be5 --- /dev/null +++ b/PointFree/PointFree.sln @@ -0,0 +1,25 @@ + +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}") = "PointFree.Tests", "PointFree.Tests\PointFree.Tests.fsproj", "{54197351-7BAD-4A2B-BD17-2D60D1E7D057}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {54197351-7BAD-4A2B-BD17-2D60D1E7D057}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {54197351-7BAD-4A2B-BD17-2D60D1E7D057}.Debug|Any CPU.Build.0 = Debug|Any CPU + {54197351-7BAD-4A2B-BD17-2D60D1E7D057}.Release|Any CPU.ActiveCfg = Release|Any CPU + {54197351-7BAD-4A2B-BD17-2D60D1E7D057}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {A307D023-04B6-4BEC-B3D7-8CF53BE730E3} + EndGlobalSection +EndGlobal diff --git a/PointFree/PointFree/PointFree.fs b/PointFree/PointFree/PointFree.fs new file mode 100644 index 0000000..d98f4ab --- /dev/null +++ b/PointFree/PointFree/PointFree.fs @@ -0,0 +1,5 @@ +namespace PointFree + +module PointFree = + + \ No newline at end of file diff --git a/PointFree/PointFree/PointFree.fsproj b/PointFree/PointFree/PointFree.fsproj new file mode 100644 index 0000000..d49e68a --- /dev/null +++ b/PointFree/PointFree/PointFree.fsproj @@ -0,0 +1,12 @@ + + + + net7.0 + true + + + + + + +