From 507ca674cdd4db00cdd4d54df76d0a2874146bcc Mon Sep 17 00:00:00 2001
From: ilya-krivtsov <180809461+ilya-krivtsov@users.noreply.github.com>
Date: Sun, 4 May 2025 23:26:56 +0300
Subject: [PATCH] MyLinq (hw10 - mylinq)
---
MyLinq/MyLinq.Tests/GlobalSuppressions.cs | 11 +++
MyLinq/MyLinq.Tests/MyLinq.Tests.csproj | 28 +++++++
MyLinq/MyLinq.Tests/MyLinqTests.cs | 94 +++++++++++++++++++++++
MyLinq/MyLinq.sln | 53 +++++++++++++
MyLinq/MyLinq/MyLinq.cs | 83 ++++++++++++++++++++
MyLinq/MyLinq/MyLinq.csproj | 10 +++
6 files changed, 279 insertions(+)
create mode 100644 MyLinq/MyLinq.Tests/GlobalSuppressions.cs
create mode 100644 MyLinq/MyLinq.Tests/MyLinq.Tests.csproj
create mode 100644 MyLinq/MyLinq.Tests/MyLinqTests.cs
create mode 100644 MyLinq/MyLinq.sln
create mode 100644 MyLinq/MyLinq/MyLinq.cs
create mode 100644 MyLinq/MyLinq/MyLinq.csproj
diff --git a/MyLinq/MyLinq.Tests/GlobalSuppressions.cs b/MyLinq/MyLinq.Tests/GlobalSuppressions.cs
new file mode 100644
index 0000000..909e036
--- /dev/null
+++ b/MyLinq/MyLinq.Tests/GlobalSuppressions.cs
@@ -0,0 +1,11 @@
+//
+// Copyright (c) Ilya Krivtsov. All rights reserved.
+//
+
+// This file is used by Code Analysis to maintain SuppressMessage
+// attributes that are applied to this project.
+// Project-level suppressions either have no target or are given
+// a specific target and scoped to a namespace, type, member, etc.
+using System.Diagnostics.CodeAnalysis;
+
+[assembly: SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1600:Elements should be documented", Justification = "This is tests project")]
diff --git a/MyLinq/MyLinq.Tests/MyLinq.Tests.csproj b/MyLinq/MyLinq.Tests/MyLinq.Tests.csproj
new file mode 100644
index 0000000..8c176c4
--- /dev/null
+++ b/MyLinq/MyLinq.Tests/MyLinq.Tests.csproj
@@ -0,0 +1,28 @@
+
+
+
+ net9.0
+ latest
+ enable
+ enable
+
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/MyLinq/MyLinq.Tests/MyLinqTests.cs b/MyLinq/MyLinq.Tests/MyLinqTests.cs
new file mode 100644
index 0000000..f970e0d
--- /dev/null
+++ b/MyLinq/MyLinq.Tests/MyLinqTests.cs
@@ -0,0 +1,94 @@
+//
+// Copyright (c) Ilya Krivtsov. All rights reserved.
+//
+
+namespace MyLinq.Tests;
+
+public class MyLinqTests
+{
+ [Test]
+ public void GetPrimes_Yields_PrimeNumbers()
+ {
+ int iterations = 100;
+
+ foreach (var (index, prime) in MyLinq.GetPrimes().Index())
+ {
+ if (index >= iterations)
+ {
+ break;
+ }
+
+ for (uint i = 2; i < prime; i++)
+ {
+ Assert.That(prime % i, Is.Not.EqualTo(0));
+ }
+ }
+ }
+
+ [Test]
+ public void Take_ReturnsSequence_With_First_N_Elements()
+ {
+ int takeCount = 47;
+ Assert.That(
+ MyLinq.Take(Enumerable.Range(0, 100), takeCount)
+ .SequenceEqual(Enumerable.Range(0, takeCount)),
+ Is.True);
+ }
+
+ [Test]
+ public void Take_ReturnsSameSequence_If_CountIsGreaterThanOrEqualTo_SourceCount()
+ {
+ int count = 100;
+ var range = Enumerable.Range(0, count);
+ Assert.Multiple(() =>
+ {
+ Assert.That(MyLinq.Take(range, count).SequenceEqual(range), Is.True);
+ Assert.That(MyLinq.Take(range, count + 1).SequenceEqual(range), Is.True);
+ });
+ }
+
+ [Test]
+ public void Take_ReturnsEmptySequence_If_CountIs_LessThanOrEqualTo_Zero()
+ {
+ var range = Enumerable.Range(0, 100);
+ Assert.Multiple(() =>
+ {
+ Assert.That(MyLinq.Take(range, 0).Any(), Is.False);
+ Assert.That(MyLinq.Take(range, -1).Any(), Is.False);
+ });
+ }
+
+ [Test]
+ public void Skip_ReturnsSequence_Without_First_N_Elements()
+ {
+ int takeCount = 53;
+ Assert.That(
+ MyLinq.Skip(Enumerable.Range(0, 100), takeCount)
+ .SequenceEqual(Enumerable.Range(takeCount, 100 - takeCount)),
+ Is.True);
+ }
+
+ [Test]
+ public void Skip_ReturnsSameSequence_If_CountIsLessThanOrEqualTo_Zero()
+ {
+ int count = 100;
+ var range = Enumerable.Range(0, count);
+ Assert.Multiple(() =>
+ {
+ Assert.That(MyLinq.Skip(range, 0).SequenceEqual(range), Is.True);
+ Assert.That(MyLinq.Skip(range, -1).SequenceEqual(range), Is.True);
+ });
+ }
+
+ [Test]
+ public void Skip_ReturnsEmptySequence_If_CountIsGreaterThanOrEqualTo_SourceCount()
+ {
+ int count = 100;
+ var range = Enumerable.Range(0, count);
+ Assert.Multiple(() =>
+ {
+ Assert.That(MyLinq.Skip(range, count).Any(), Is.False);
+ Assert.That(MyLinq.Skip(range, count + 1).Any(), Is.False);
+ });
+ }
+}
diff --git a/MyLinq/MyLinq.sln b/MyLinq/MyLinq.sln
new file mode 100644
index 0000000..4082121
--- /dev/null
+++ b/MyLinq/MyLinq.sln
@@ -0,0 +1,53 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 17
+VisualStudioVersion = 17.0.31903.59
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MyLinq", "MyLinq\MyLinq.csproj", "{29852F1B-EA67-4A5F-921D-52E576AB1D21}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "MyLinq.Tests", "MyLinq.Tests", "{57E4A64D-212E-B59A-67DA-DA99F8ED86A3}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MyLinq.Tests", "MyLinq.Tests\MyLinq.Tests.csproj", "{69B64B70-96AF-4C17-8F62-95FCA2604676}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Debug|x64 = Debug|x64
+ Debug|x86 = Debug|x86
+ Release|Any CPU = Release|Any CPU
+ Release|x64 = Release|x64
+ Release|x86 = Release|x86
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {29852F1B-EA67-4A5F-921D-52E576AB1D21}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {29852F1B-EA67-4A5F-921D-52E576AB1D21}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {29852F1B-EA67-4A5F-921D-52E576AB1D21}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {29852F1B-EA67-4A5F-921D-52E576AB1D21}.Debug|x64.Build.0 = Debug|Any CPU
+ {29852F1B-EA67-4A5F-921D-52E576AB1D21}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {29852F1B-EA67-4A5F-921D-52E576AB1D21}.Debug|x86.Build.0 = Debug|Any CPU
+ {29852F1B-EA67-4A5F-921D-52E576AB1D21}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {29852F1B-EA67-4A5F-921D-52E576AB1D21}.Release|Any CPU.Build.0 = Release|Any CPU
+ {29852F1B-EA67-4A5F-921D-52E576AB1D21}.Release|x64.ActiveCfg = Release|Any CPU
+ {29852F1B-EA67-4A5F-921D-52E576AB1D21}.Release|x64.Build.0 = Release|Any CPU
+ {29852F1B-EA67-4A5F-921D-52E576AB1D21}.Release|x86.ActiveCfg = Release|Any CPU
+ {29852F1B-EA67-4A5F-921D-52E576AB1D21}.Release|x86.Build.0 = Release|Any CPU
+ {69B64B70-96AF-4C17-8F62-95FCA2604676}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {69B64B70-96AF-4C17-8F62-95FCA2604676}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {69B64B70-96AF-4C17-8F62-95FCA2604676}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {69B64B70-96AF-4C17-8F62-95FCA2604676}.Debug|x64.Build.0 = Debug|Any CPU
+ {69B64B70-96AF-4C17-8F62-95FCA2604676}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {69B64B70-96AF-4C17-8F62-95FCA2604676}.Debug|x86.Build.0 = Debug|Any CPU
+ {69B64B70-96AF-4C17-8F62-95FCA2604676}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {69B64B70-96AF-4C17-8F62-95FCA2604676}.Release|Any CPU.Build.0 = Release|Any CPU
+ {69B64B70-96AF-4C17-8F62-95FCA2604676}.Release|x64.ActiveCfg = Release|Any CPU
+ {69B64B70-96AF-4C17-8F62-95FCA2604676}.Release|x64.Build.0 = Release|Any CPU
+ {69B64B70-96AF-4C17-8F62-95FCA2604676}.Release|x86.ActiveCfg = Release|Any CPU
+ {69B64B70-96AF-4C17-8F62-95FCA2604676}.Release|x86.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(NestedProjects) = preSolution
+ {69B64B70-96AF-4C17-8F62-95FCA2604676} = {57E4A64D-212E-B59A-67DA-DA99F8ED86A3}
+ EndGlobalSection
+EndGlobal
diff --git a/MyLinq/MyLinq/MyLinq.cs b/MyLinq/MyLinq/MyLinq.cs
new file mode 100644
index 0000000..7dbea2d
--- /dev/null
+++ b/MyLinq/MyLinq/MyLinq.cs
@@ -0,0 +1,83 @@
+//
+// Copyright (c) Ilya Krivtsov. All rights reserved.
+//
+
+namespace MyLinq;
+
+///
+/// Utility class with GetPrimes, Take and Skip functions.
+///
+public static class MyLinq
+{
+ ///
+ /// Practically infinite sequence of prime numbers.
+ ///
+ /// Sequence of prime numbers.
+ public static IEnumerable GetPrimes()
+ {
+ yield return 2;
+ yield return 3;
+ ulong lastPrime = 3;
+ while (true)
+ {
+ lastPrime += 2;
+ bool isPrime = true;
+ for (ulong i = 2; i * i <= lastPrime; i++)
+ {
+ if (lastPrime % i == 0)
+ {
+ isPrime = false;
+ break;
+ }
+ }
+
+ if (isPrime)
+ {
+ yield return lastPrime;
+ }
+ }
+ }
+
+ ///
+ /// Sequence with first items from .
+ ///
+ /// Item type.
+ /// Sequence to take first items from.
+ /// How many items to take.
+ /// Subsequence of .
+ public static IEnumerable Take(this IEnumerable sequence, int count)
+ {
+ int index = 0;
+ foreach (var item in sequence)
+ {
+ if (index >= count)
+ {
+ yield break;
+ }
+
+ yield return item;
+ index++;
+ }
+ }
+
+ ///
+ /// Sequence without first items from .
+ ///
+ /// Item type.
+ /// Sequence to skip first items from.
+ /// How many items to skip.
+ /// Subsequence of .
+ public static IEnumerable Skip(this IEnumerable sequence, int count)
+ {
+ int index = 0;
+ foreach (var item in sequence)
+ {
+ if (index >= count)
+ {
+ yield return item;
+ }
+
+ index++;
+ }
+ }
+}
diff --git a/MyLinq/MyLinq/MyLinq.csproj b/MyLinq/MyLinq/MyLinq.csproj
new file mode 100644
index 0000000..bf05b58
--- /dev/null
+++ b/MyLinq/MyLinq/MyLinq.csproj
@@ -0,0 +1,10 @@
+
+
+
+ Library
+ net9.0
+ enable
+ enable
+
+
+