├── 456px-.NET_Logo.svg.png ├── ArrayExtensions.cs ├── ArrayPoolCustomImplementation.cs ├── ArrayPoolSingletonDesign.cs ├── AsyncAggregateException.cs ├── AsyncDelegate.cs ├── CustomCollection.cs ├── DeadlockControl.cs ├── DefaultInterfaceImplementation.cs ├── EasyClonePattern.cs ├── EffectiveAsyncLoadWithSemaphoreslim.cs ├── EnumHasFlag.cs ├── EnumToString.cs ├── EqualityBenchmark.cs ├── EqualityComparer.cs ├── ExternUnmanagedHeap.cs ├── FibonacciMemoization.cs ├── FibonacciSeriesGenWithSpan.cs ├── FindMinMax.cs ├── ForeachExtension.cs ├── FunctionPointer.cs ├── HasDuplicate.cs ├── IAsyncDisposableIDisposable.cs ├── IDisposableSafeHandle.cs ├── ImplicitOperatorMathPow.cs ├── JobSequencingDeadline.cs ├── JsonDOMExtension.cs ├── JsonNodeSummary.cs ├── JsonSerializerSummary.cs ├── JsonWriterSummary.cs ├── KestrelWebHostBuilder.cs ├── KnapsackAlgorithm.cs ├── KnuthMorrisPratAlgorithm.cs ├── LICENSE ├── LINQEqualityComparer.cs ├── LazyFibonacciList.cs ├── LongestCommonSubsequence.cs ├── MagicSquareForOddSizes.cs ├── MarshallBenchmark.cs ├── MarshallString.cs ├── ModuleInitializer.cs ├── MonitorTryEnter.cs ├── NQueenProblemInDetail.cs ├── OperatorOverloadingFull.cs ├── ParallelAggregation.cs ├── ParallelFactorialCalc.cs ├── ParallelForEachAsync.cs ├── ParallelLetterFrequency.cs ├── ParallelPrimeNumbers.cs ├── PointerChunk.cs ├── README.md ├── RabinKarpStringMatchingHashTechnique.cs ├── RecordCalculatedProperty.cs ├── RecordOverrideEquals.cs ├── SafeHandleExample.cs ├── ShallowAndDeepCopy.cs ├── StructBigSizeFlags.cs ├── StructDefensiveCopy.cs ├── SubsetSumMax.cs ├── TailRecursion.cs ├── TravellingSalesmanAlgorithm.cs ├── ValueEqualityImplementation.cs └── ValueTaskBenchmark.cs /456px-.NET_Logo.svg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sabitkondakci/DynamicProgramming/643da9c301e20359560cde0a596167dad1c77a0b/456px-.NET_Logo.svg.png -------------------------------------------------------------------------------- /ArrayExtensions.cs: -------------------------------------------------------------------------------- 1 | // LinqPad 6 2 | 3 | void Main() 4 | { 5 | int[] arr = { 1, 2, 3, 4, 2}; 6 | 7 | /* 8 | var sameArr = arr.Fill(9,3); 9 | sameArr.Dump(); // 1, 2, 3, 9, 9 10 | arr.Dump(); // 1, 2, 3, 9, 9 11 | */ 12 | 13 | /* 14 | var copyArr = arr.FillAndCopy(9,3); 15 | copyArr.Dump(); // 1, 2, 3, 9, 9 16 | arr.Dump(); // 1, 2, 3, 4, 2 17 | */ 18 | 19 | /* 20 | var sameMappedArr = arr.Map(a => (int)Math.Pow(a,3),2); 21 | sameMappedArr.Dump(); // 1, 2, 27, 64, 8 22 | arr.Dump(); // 1, 2, 27, 64, 8 23 | */ 24 | 25 | /* 26 | var copyMappedArr = arr.MapAndCopy(a => (int)Math.Pow(a, 3), 2); 27 | copyMappedArr.Dump(); // 1, 2, 27, 64, 8 28 | arr.Dump(); // 1, 2, 3, 4, 2 29 | */ 30 | } 31 | 32 | 33 | public static class ArrayExtensions 34 | { 35 | public static int[] FillAndCopy(this int[] array,int value,int startIndex = 0) 36 | { 37 | var tempArray = array.ToArray(); 38 | foreach (ref int item in tempArray.AsSpan(startIndex)) 39 | item = value; 40 | 41 | return tempArray; 42 | } 43 | 44 | public static int[] Fill(this int[] array, int value, int startIndex = 0) 45 | { 46 | foreach (ref int item in array.AsSpan(startIndex)) 47 | item = value; 48 | 49 | return array; 50 | } 51 | 52 | public static int[] Map(this int[] array, Func func, int startIndex = 0) 53 | { 54 | foreach (ref int item in array.AsSpan(startIndex)) 55 | item = func(item); 56 | 57 | return array; 58 | } 59 | 60 | public static int[] MapAndCopy(this int[] array, Func func, int startIndex = 0) 61 | { 62 | var tempArray = array.ToArray(); 63 | foreach (ref int item in tempArray.AsSpan(startIndex)) 64 | item = func(item); 65 | 66 | return tempArray; 67 | } 68 | } 69 | 70 | 71 | -------------------------------------------------------------------------------- /ArrayPoolCustomImplementation.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Buffers; 3 | using System.Threading; 4 | using System.Threading.Tasks; 5 | namespace APCustomImplementation; 6 | 7 | public class APCustom 8 | { 9 | static async Task Main() 10 | { 11 | int taskListSize = 100; 12 | var tasks = new Task[taskListSize]; 13 | using (var semaphore_10 = new SemaphoreSlim(10)) 14 | { 15 | for (int i = 0; i < tasks.Length; i++) 16 | 17 | { 18 | // this will be released in SharedMemory(int, SemaphoreSlim) 19 | semaphore_10.Wait(); 20 | 21 | tasks[i] = Task.Run(() => 22 | { ReturnWith(list); SharedMemory(bufferSize, semaphore_10); }); 23 | } 24 | } 25 | 26 | await Task.WhenAll(tasks); 27 | Console.Read(); 28 | } 29 | 30 | #region ArrayPoolAsync 31 | 32 | static int bufferSize = 30_000; 33 | readonly static WisconsinDriverLicenseInfo[] list; 34 | static APCustom() 35 | { 36 | list = GenerateLicenceObjects(bufferSize); 37 | } 38 | 39 | public static void SharedMemory(int nItemAtATime,SemaphoreSlim semaphore) 40 | { 41 | WisconsinDLPool wisPoolObject = new(); 42 | var pooledList = wisPoolObject.Rent(nItemAtATime).AsSpan(); // WisconsinDriverLicenseInfo[] 43 | 44 | for (int i = 0; i < Size; i++) 45 | { 46 | pooledList[i].address = "Rize"; 47 | pooledList[i].dateOfBirth = DateTime.Now; 48 | pooledList[i].expirationDate = 49 | DateTime.Now.Add(TimeSpan.FromDays(100)); 50 | pooledList[i].eyeColor = EyeColor.Gray; 51 | pooledList[i].hairColor = HairColor.PaintedMi; 52 | pooledList[i].heightInch = 243; 53 | pooledList[i].weightPound = 443; 54 | pooledList[i].IsDonor = true; 55 | pooledList[i].ISS = DateTime.Now.Add(TimeSpan.FromDays(-100)); 56 | pooledList[i].licenceClass = 'D'; 57 | pooledList[i].licenceId = "4433"; 58 | pooledList[i].sex = 'F'; 59 | } 60 | 61 | for (int i = 0; i < nItemAtATime; i++) 62 | { 63 | var listItem = pooledList[i]; 64 | if (listItem is not null) 65 | Console.WriteLine(listItem); 66 | } 67 | 68 | semaphore.Release(); 69 | } 70 | 71 | public static WisconsinDriverLicenseInfo[] GenerateLicenceObjects(int nItemAtATime) 72 | { 73 | HairColor[] hairColors = Enum.GetValues(); 74 | EyeColor[] eyeColors = Enum.GetValues(); 75 | Random randomHairColor = new(); 76 | Random randomEyeColor = new(); 77 | 78 | WisconsinDLPool wisPoolObject = new(); 79 | var wisconsinDLInfoArray = wisPoolObject.Rent(nItemAtATime); 80 | 81 | for (int i = 0; i < nItemAtATime; i++) 82 | { 83 | int randomHCNext = randomHairColor.Next(1, hairColors.Length); 84 | int randomECNext = randomEyeColor.Next(1, eyeColors.Length); 85 | 86 | wisconsinDLInfoArray[i] = 87 | new WisconsinDriverLicenseInfo() 88 | { 89 | licenceId = "licenseId", 90 | licenceClass = '#', 91 | sex = '#', 92 | address = "address", 93 | weightPound = 1, 94 | heightInch = 1, 95 | dateOfBirth = DateTime.UtcNow, 96 | expirationDate = DateTime.UtcNow, 97 | hairColor = hairColors[randomHCNext], 98 | eyeColor = eyeColors[randomECNext], 99 | IsDonor = true, 100 | ISS = DateTime.UtcNow 101 | }; 102 | } 103 | 104 | wisPoolObject.Return(wisconsinDLInfoArray); 105 | return wisconsinDLInfoArray; 106 | } 107 | 108 | public static void ReturnWith(in WisconsinDriverLicenseInfo[] wisconsinInfo) 109 | { 110 | WisconsinDLPool pool = new(); 111 | pool.Return(wisconsinInfo); 112 | } 113 | 114 | #endregion 115 | } 116 | 117 | 118 | #region ArrayPoolAsync2 119 | 120 | sealed class SingletonArrayPool 121 | { 122 | private static readonly Lazy> _singleton = 123 | new Lazy>(() => ArrayPool.Shared); 124 | private SingletonArrayPool() { } 125 | public static ArrayPool Shared => _singleton.Value; 126 | } 127 | public record WisconsinDriverLicenseInfo 128 | { 129 | public string licenceId { get; set; } 130 | public char licenceClass { get; set; } 131 | public char sex { get; set; } 132 | public string address { get; set; } 133 | public ushort weightPound { get; set; } 134 | public ushort heightInch { get; set; } 135 | public DateTime dateOfBirth { get; set; } 136 | public DateTime expirationDate { get; set; } 137 | public HairColor hairColor { get; set; } 138 | public EyeColor eyeColor { get; set; } 139 | public bool IsDonor { get; set; } 140 | public DateTime ISS { get; set; } 141 | } 142 | public class WisconsinDLPool : ArrayPool 143 | { 144 | private int length; 145 | public override WisconsinDriverLicenseInfo[] Rent(int minimumLength) 146 | { 147 | length = minimumLength; 148 | return SingletonArrayPool. 149 | Shared.Rent(minimumLength); 150 | } 151 | public override void Return(WisconsinDriverLicenseInfo[] array, 152 | bool clearArray = false) 153 | { 154 | if (clearArray) 155 | { 156 | for (int i = 0; i < length; i++) 157 | { 158 | array[i] = 159 | new WisconsinDriverLicenseInfo() 160 | { 161 | licenceId = "#", 162 | licenceClass = '#', 163 | sex = '#', 164 | address = "#", 165 | weightPound = 0, 166 | heightInch = 0, 167 | dateOfBirth = DateTime.MinValue, 168 | expirationDate = DateTime.MaxValue, 169 | hairColor = HairColor.None, 170 | eyeColor = EyeColor.None, 171 | IsDonor = false, 172 | ISS = DateTime.MinValue 173 | }; 174 | } 175 | 176 | } 177 | 178 | SingletonArrayPool. 179 | Shared.Return(array); 180 | } 181 | } 182 | 183 | #region Enum_Hair&Eye_Color 184 | public enum HairColor : byte 185 | { 186 | None, 187 | Black, 188 | Yellow, 189 | White, 190 | Red, 191 | Brown, 192 | PaintedMi 193 | } 194 | 195 | public enum EyeColor : byte 196 | { 197 | None, 198 | Black, 199 | Blue, 200 | Green, 201 | Brown, 202 | Brown_Amber, 203 | Gray, 204 | Hazel 205 | } 206 | #endregion 207 | 208 | 209 | #endregion 210 | -------------------------------------------------------------------------------- /ArrayPoolSingletonDesign.cs: -------------------------------------------------------------------------------- 1 | void Main() 2 | { 3 | InvokeLicencePool(); 4 | ReinvokeLicencePool(); 5 | } 6 | 7 | sealed class SingletonArrayPool 8 | { 9 | private static readonly Lazy> _singleton = 10 | new Lazy>(() => ArrayPool.Shared); 11 | private SingletonArrayPool() { } 12 | public static ArrayPool Shared => _singleton.Value; 13 | } 14 | 15 | public record Licence 16 | { 17 | public int Id { get; init; } 18 | public string HairColor { get; init; } 19 | public string EyeColor { get; init; } 20 | public ushort WeightInPound { get; init; } 21 | public byte Age { get; init; } 22 | // 20 more properties ... 23 | } 24 | 25 | public void InvokeLicencePool() 26 | { 27 | var licencePool = SingletonArrayPool.Shared; 28 | var licenceArr = licencePool.Rent(10); 29 | for (int i = 0; i < 10; i++) 30 | { 31 | licenceArr[i] = new() 32 | { 33 | Id = 0, 34 | EyeColor = "Black", 35 | HairColor = "Black", 36 | WeightInPound = 155, 37 | Age = 33 38 | }; 39 | } 40 | 41 | licenceArr.Dump(); 42 | licencePool.Return(licenceArr); 43 | } 44 | 45 | public void ReinvokeLicencePool() 46 | { 47 | var licencePool = SingletonArrayPool.Shared; 48 | var licenceArr = licencePool.Rent(10); 49 | licenceArr.Dump(); 50 | } 51 | -------------------------------------------------------------------------------- /AsyncAggregateException.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Threading.Tasks; 3 | 4 | class TaskException 5 | { 6 | public static async Task> WhenAll(params Task[] tasks) 7 | { 8 | var taskList = Task.WhenAll(tasks); 9 | 10 | try 11 | { 12 | return await taskList; 13 | } 14 | catch (System.Exception){/*ignore exception*/} 15 | 16 | throw taskList.Exception ?? throw new System.Exception("Task list is null"); 17 | } 18 | } -------------------------------------------------------------------------------- /AsyncDelegate.cs: -------------------------------------------------------------------------------- 1 | 2 | 3 | class Program 4 | { 5 | 6 | 7 | public record User(string FirstName, string LastName, string Email, int? Age); 8 | 9 | // async delegates give us a good degree of freedom & flexibility 10 | // without corrupting the application 11 | 12 | public static async Task GetUserInfoByEmail(string Email, 13 | Func> searchAlgorithm = null) 14 | { 15 | searchAlgorithm ??= DefaultEmailSearchingAlgorithm; 16 | return await searchAlgorithm(Email); 17 | } 18 | 19 | public static async Task> GetUserListByFirstName( string FirstName, 20 | Func>> searchAlgorithm = null) 21 | { 22 | searchAlgorithm ??=DefaultFirstNameSearchingAlgorithm; 23 | return await searchAlgorithm(FirstName); 24 | } 25 | 26 | public static async Task DefaultEmailSearchingAlgorithm(string email) 27 | { 28 | if(email == null || email == string.Empty) 29 | return await Task.Run (() => new User(string.Empty,string.Empty,string.Empty,0)); 30 | 31 | return await Task.Run(() => userList.First(l => l.Email == email)); 32 | } 33 | 34 | public static async Task> CustomFirstNameSearchingAlgorithm(string firstName) 35 | { 36 | if (firstName == null || firstName == string.Empty) 37 | return await Task.Run (() => userList.DefaultIfEmpty()); 38 | 39 | return await Task.Run(() => userList.Where(l => l.FirstName == firstName)); 40 | } 41 | 42 | public static async Task> DefaultFirstNameSearchingAlgorithm(string firstName) 43 | { 44 | return await Task.Run(() => userList.Where(l => l.FirstName == firstName).OrderBy(l => l.Age)); 45 | } 46 | 47 | static IEnumerable userList = new List() 48 | { 49 | new User("Halil","Sezai","sezaihalil@outlook.com",32), 50 | new User("Onur","Kocabiyil","onurkocabiyil@outlook.com",27), 51 | new User("Emin","Otlak","eminotlak@outlook.com",16), 52 | new User("Sehtap","Ikildi","sehtapikildi@gmail.com",43), 53 | new User("Sehtap","Adali","gamzeardali@gmail.com",36), 54 | }; 55 | 56 | static async Task Main(string[] args) 57 | { 58 | User userByEmailDefault = await GetUserInfoByEmail(""); 59 | IEnumerable userByFirstNameDefault = await GetUserListByFirstName("Sehtap"); 60 | 61 | User userByEmail = await GetUserInfoByEmail("eminotlak@outlook.com"); 62 | IEnumerable userByFirstNameCustom = await GetUserListByFirstName("Sehtap", 63 | CustomFirstNameSearchingAlgorithm); 64 | 65 | userByEmail.Dump(); 66 | userByFirstNameCustom.Dump(); 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /CustomCollection.cs: -------------------------------------------------------------------------------- 1 | interface IReadOnlyArray : IEnumerable, IEnumerable ,IEnumerator,IEnumerator 2 | { 3 | // your custom implementations 4 | T this[int index] { get; } 5 | } 6 | 7 | public struct ReadOnlyArray : IReadOnlyArray 8 | { 9 | private readonly T[] _array; 10 | 11 | public int Length => _array.Length; 12 | 13 | // Enumerators are positioned before the first element 14 | // until the first MoveNext() call 15 | int position; // Enumerator 16 | 17 | public ReadOnlyArray(T[] array) 18 | { 19 | position = -1; 20 | _array = array; 21 | } 22 | 23 | // such a nice pointer shot! 24 | public ref readonly T IndexReference(int index) 25 | { 26 | return ref this._array[index]; 27 | } 28 | 29 | 30 | public static implicit operator ReadOnlyArray(T[]? array) => 31 | new ReadOnlyArray(array ?? new T[1]); 32 | 33 | 34 | // IEnumerable 35 | public IEnumerator GetEnumerator() 36 | { 37 | return new ReadOnlyArray(_array); 38 | } 39 | IEnumerator IEnumerable.GetEnumerator() 40 | { 41 | return GetEnumerator(); 42 | } 43 | 44 | 45 | // IEnumerator 46 | 47 | public bool MoveNext() 48 | { 49 | position++; 50 | return (position < _array.Length); 51 | } 52 | 53 | public void Reset() 54 | { 55 | position = -1; 56 | } 57 | 58 | public void Dispose() 59 | { 60 | // extra disposing! 61 | } 62 | 63 | object IEnumerator.Current => Current; 64 | 65 | public T Current 66 | { 67 | get 68 | { 69 | try 70 | { 71 | return _array[position]; 72 | } 73 | catch (IndexOutOfRangeException) 74 | { 75 | throw new InvalidOperationException(); 76 | } 77 | } 78 | } 79 | 80 | public readonly T this[int index] => _array[index]; 81 | } 82 | 83 | LoopInForEach list = new(); 84 | foreach (var item in list) 85 | { 86 | Console.WriteLine(item); // valid 87 | } 88 | 89 | var refCheck = new int[] { 1, 2, 3 }; 90 | IReadOnlyArray readOnlyArray = (ReadOnlyArray) refCheck; // valid 91 | ReadOnlyArray roArray = refCheck; // valid 92 | 93 | public class LoopInForEach 94 | { 95 | private readonly List internalList = new List() { "hello", "world" }; 96 | public List.Enumerator GetEnumerator() => internalList.GetEnumerator(); 97 | } 98 | 99 | 100 | -------------------------------------------------------------------------------- /DeadlockControl.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Threading; 3 | 4 | namespace ThreadDeadlockControl 5 | { 6 | class Program 7 | { 8 | 9 | static void Main(string[] args) 10 | { 11 | Console.WriteLine("Main Thread Started"); 12 | Account A = new Account(10000, 101); 13 | Account B = new Account(5000, 102); 14 | 15 | AccountManager managerFromAtoB = new AccountManager(A, B, 3000); 16 | Thread firstThread = new Thread(managerFromAtoB.Transfer); 17 | firstThread.Name = "T1"; 18 | 19 | AccountManager managerFromBtoA = new AccountManager(B, A, 4000); 20 | Thread secondThread = new Thread(managerFromBtoA.Transfer); 21 | secondThread.Name = "T2"; 22 | 23 | firstThread.Start(); secondThread.Start(); 24 | firstThread.Join(); secondThread.Join(); 25 | 26 | Console.WriteLine($"Balance A:{A.Balance}"); 27 | Console.WriteLine($"Balance B:{B.Balance}"); 28 | Console.WriteLine("Main Thread Ended"); 29 | 30 | } 31 | } 32 | 33 | class Account 34 | { 35 | public double Balance { get; set; } 36 | public long ID { get; set; } 37 | 38 | public Account(double balance, int id) 39 | { 40 | this.Balance = balance; 41 | this.ID = id; 42 | } 43 | 44 | public long GetID => ID; 45 | 46 | public void WithDraw(double amount) 47 | { 48 | Balance -= amount; 49 | } 50 | 51 | public void Deposit(double amount) 52 | { 53 | Balance += amount; 54 | } 55 | } 56 | 57 | class AccountManager 58 | { 59 | private Account _fromAccount; 60 | private Account _toAccount; 61 | private double amountToTransfer; 62 | public AccountManager(Account fromAccount, Account toAccount, double amountToTransfer) 63 | { 64 | this._fromAccount = fromAccount; 65 | this._toAccount = toAccount; 66 | this.amountToTransfer = amountToTransfer; 67 | } 68 | 69 | public void Transfer() 70 | { 71 | object lock1, lock2; 72 | if (_fromAccount.ID > _toAccount.ID) 73 | { 74 | lock1 = _fromAccount; 75 | lock2 = _toAccount; 76 | } 77 | else 78 | { 79 | lock1 = _toAccount; 80 | lock2 = _fromAccount; 81 | } 82 | 83 | lock (lock1) 84 | { 85 | Console.WriteLine($"In _fromAccount lock, for :{Thread.CurrentThread.Name}"); 86 | Thread.Sleep(1000); 87 | 88 | lock (lock2) 89 | { 90 | Console.WriteLine($"Thread:{Thread.CurrentThread.Name}!"); 91 | _fromAccount.WithDraw(amountToTransfer); 92 | _toAccount.Deposit(amountToTransfer); 93 | 94 | } 95 | 96 | } 97 | 98 | } 99 | 100 | } 101 | 102 | } 103 | -------------------------------------------------------------------------------- /DefaultInterfaceImplementation.cs: -------------------------------------------------------------------------------- 1 | void Main() 2 | { 3 | ICustomer guess = new Guess(); 4 | ICustomer.SetLoyaltyThresholds(TimeSpan.FromDays(10),20,0.3m); 5 | guess.ComputeLoyaltyDiscount().Dump(); 6 | } 7 | 8 | interface ICustomer : IOrder 9 | { 10 | IEnumerable PreviousOrders { get;} 11 | 12 | DateTime DateJoined { get;} 13 | DateTime? LastOrder { get;} 14 | string Name { get;} 15 | IDictionary Reminders { get;} 16 | 17 | public static void SetLoyaltyThresholds( 18 | TimeSpan ago, 19 | int minimumOrders = 10, 20 | decimal percentageDiscount = 0.10m) 21 | { 22 | length = ago; 23 | orderCount = minimumOrders; 24 | discountPercent = percentageDiscount; 25 | } 26 | private static TimeSpan length = new TimeSpan(365 * 2, 0, 0, 0); // two years 27 | private static int orderCount = 10; 28 | private static decimal discountPercent = 0.10m; 29 | 30 | public decimal ComputeLoyaltyDiscount() => DefaultLoyaltyDiscount(this); 31 | protected static decimal DefaultLoyaltyDiscount(ICustomer c) 32 | { 33 | DateTime start = DateTime.Now - length; 34 | 35 | if ((c.DateJoined < start) && (c.PreviousOrders.Count() > orderCount)) 36 | { 37 | return discountPercent; 38 | } 39 | return 0; 40 | } 41 | } 42 | 43 | interface IOrder 44 | { 45 | DateTime Purchased {get;} 46 | float Cost {get;} 47 | } 48 | 49 | class Guess : ICustomer 50 | { 51 | 52 | public IEnumerable PreviousOrders 53 | { 54 | get 55 | { 56 | var dummyList = new List(); 57 | dummyList.Add(new Cupcake()); 58 | dummyList.Add(new Beer()); 59 | return dummyList; 60 | } 61 | } 62 | 63 | public DateTime DateJoined => DateTime.Now.AddYears(-4); 64 | 65 | public DateTime? LastOrder => DateTime.UtcNow.AddDays(-6); 66 | 67 | public string Name => "Daniel Sutto"; 68 | 69 | public IDictionary Reminders => 70 | new Dictionary(); 71 | 72 | public DateTime Purchased => DateTime.UtcNow; 73 | 74 | public float Cost => 122.4f; 75 | 76 | public decimal ComputeLoyaltyDiscount() 77 | { 78 | if (PreviousOrders.Any() == false) 79 | return 0.50m; 80 | else 81 | return ICustomer.DefaultLoyaltyDiscount(this); 82 | } 83 | 84 | } 85 | 86 | class Cupcake : IOrder 87 | { 88 | public DateTime Purchased => default(DateTime); 89 | 90 | public float Cost => default(float); 91 | } 92 | 93 | class Beer : IOrder 94 | { 95 | public DateTime Purchased => default(DateTime); 96 | 97 | public float Cost => default(float); 98 | } 99 | -------------------------------------------------------------------------------- /EasyClonePattern.cs: -------------------------------------------------------------------------------- 1 | // .NET6 , LINQPad 7 2 | 3 | void Main() 4 | { 5 | var model = new Model { Date = DateTime.Now, Name = "Joe" }; 6 | 7 | model.Dump("model"); 8 | 9 | var easyClone = model.CloneWith(x => { x.Date = DateTime.Today; }); 10 | 11 | easyClone.Dump("easyClone"); 12 | } 13 | 14 | public class Model : ICloneable 15 | { 16 | public string Name { get; set; } 17 | public DateTime Date { get; set; } 18 | 19 | public int Id { get; set; } 20 | public int[] RefTest { get; set; } 21 | 22 | public Model() { } 23 | 24 | private Model(Model model) 25 | { 26 | Name = model.Name; 27 | Date = model.Date; 28 | Id = model.Id; 29 | RefTest = model.RefTest; 30 | } 31 | 32 | object ICloneable.Clone() => new Model(this); 33 | } 34 | 35 | 36 | public static class CloneHelper 37 | { 38 | public static T CloneWith(this T model, Action action = default) 39 | where T : ICloneable 40 | { 41 | var tempT = (T)model?.Clone(); 42 | 43 | if (tempT != null && action != null) 44 | action(tempT); 45 | 46 | return tempT; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /EffectiveAsyncLoadWithSemaphoreslim.cs: -------------------------------------------------------------------------------- 1 | using System.Net; 2 | using System.Net.NetworkInformation; 3 | using System.Runtime.CompilerServices; 4 | namespace DummyConsole; 5 | 6 | class EffectiveLoad 7 | { 8 | static async Task Main() 9 | { 10 | #region string[] list 11 | string[] list = { 12 | "www.youtube.com", 13 | "www.facebook.com ", 14 | "www.baidu.com ", 15 | "www.yahoo.com ", 16 | "www.amazon.com ", 17 | "www.wikipedia.org ", 18 | "www.qq.com ", 19 | "www.google.co.in ", 20 | "www.twitter.com ", 21 | "www.live.com ", 22 | "www.taobao.com ", 23 | "www.bing.com ", 24 | "www.instagram.com ", 25 | "www.weibo.com ", 26 | "www.sina.com.cn ", 27 | "www.linkedin.com ", 28 | "www.yahoo.co.jp ", 29 | "www.msn.com ", 30 | "www.vk.com ", 31 | "www.google.de ", 32 | "www.yandex.ru ", 33 | "www.hao123.com ", 34 | "www.google.co.uk ", 35 | "www.reddit.com ", 36 | "www.ebay.com ", 37 | "www.google.fr ", 38 | "www.t.co ", 39 | "www.tmall.com ", 40 | "www.google.com.br ", 41 | "www.360.cn ", 42 | "www.sohu.com ", 43 | "www.amazon.co.jp ", 44 | "www.pinterest.com ", 45 | "www.netflix.com ", 46 | "www.google.it ", 47 | "www.google.ru ", 48 | "www.microsoft.com ", 49 | "www.google.es ", 50 | "www.wordpress.com ", 51 | "www.gmw.cn ", 52 | "www.tumblr.com ", 53 | "www.paypal.com ", 54 | "www.blogspot.com ", 55 | "www.imgur.com ", 56 | "www.stackoverflow.com ", 57 | "www.aliexpress.com ", 58 | "www.naver.com ", 59 | "www.ok.ru ", 60 | "www.apple.com ", 61 | "www.github.com ", 62 | "www.chinadaily.com.cn ", 63 | "www.imdb.com ", 64 | "www.google.co.kr ", 65 | "www.fc2.com ", 66 | "www.jd.com ", 67 | "www.blogger.com ", 68 | "www.163.com ", 69 | "www.google.ca ", 70 | "www.whatsapp.com ", 71 | "www.amazon.in ", 72 | "www.office.com ", 73 | "www.tianya.cn ", 74 | "www.google.co.id ", 75 | "www.youku.com ", 76 | "www.rakuten.co.jp ", 77 | "www.craigslist.org ", 78 | "www.amazon.de ", 79 | "www.nicovideo.jp ", 80 | "www.google.pl ", 81 | "www.soso.com ", 82 | "www.bilibili.com ", 83 | "www.dropbox.com ", 84 | "www.xinhuanet.com ", 85 | "www.outbrain.com ", 86 | "www.pixnet.net ", 87 | "www.alibaba.com ", 88 | "www.alipay.com ", 89 | "www.microsoftonline.com ", 90 | "www.booking.com ", 91 | "www.googleusercontent.com", 92 | "www.google.com.au ", 93 | "www.popads.net ", 94 | "www.cntv.cn ", 95 | "www.zhihu.com ", 96 | "www.amazon.co.uk ", 97 | "www.diply.com ", 98 | "www.coccoc.com ", 99 | "www.cnn.com ", 100 | "www.bbc.co.uk ", 101 | "www.twitch.tv ", 102 | "www.wikia.com ", 103 | "www.google.co.th ", 104 | "www.go.com ", 105 | "www.google.com.ph ", 106 | "www.doubleclick.net ", 107 | "www.onet.pl ", 108 | "www.googleadservices.com ", 109 | "www.accuweather.com ", 110 | "www.googleweblight.com ", 111 | "www.answers.yahoo.com " 112 | }; 113 | 114 | list = list.Select(l => l.Trim()).ToArray(); 115 | list = list.Concat(list).ToArray(); 116 | #endregion 117 | 118 | // pass a timeout accordingly 119 | await PrintPingList(list); 120 | } 121 | 122 | public readonly struct NetworkInfo 123 | { 124 | public string Website { get; init; } 125 | public IPAddress Address { get; init; } 126 | public IPStatus Status { get; init; } 127 | public long RoundTripTime { get; init; } 128 | } 129 | 130 | public static async Task PrintPingList(string[] sites, int timeout = -1) 131 | { 132 | using CancellationTokenSource source = new(timeout); 133 | 134 | try 135 | { 136 | // PingAsync(sites,source.Token) is to cancel running tasks 137 | // pingResultList.WithCancellation(source.Token) is to cancel IAsyncEnumerable's enumerator ==> IAsyncEnumerable .GetAsyncEnumerator(CancellationToken) 138 | 139 | var pingResultList = PingAsync(sites, source.Token); 140 | await Print(pingResultList, source.Token); 141 | } 142 | catch (OperationCanceledException) 143 | { 144 | Console.WriteLine("Operation has been cancelled!"); 145 | // log it! 146 | } 147 | } 148 | 149 | public static async Task Print(IAsyncEnumerable pingResultList, 150 | CancellationToken token = default) 151 | { 152 | await foreach (var pingResult in pingResultList 153 | .WithCancellation(token).ConfigureAwait(false)) 154 | { 155 | Console.WriteLine($"Website:{pingResult.Website}\n" 156 | + $"Address:{pingResult.Address}\nStatus:{pingResult.Status}\n" 157 | + $"RoundTripTime: {pingResult.RoundTripTime}"); 158 | 159 | Console.WriteLine(); 160 | 161 | // catch the cancellation quicker 162 | if (token.IsCancellationRequested) 163 | throw new OperationCanceledException(); 164 | } 165 | } 166 | public static async IAsyncEnumerable PingAsync(string[] websites, [EnumeratorCancellation] CancellationToken cancellationToken = default) 167 | { 168 | var length = websites.Length; 169 | var taskNetworkInfo = new Queue>(); 170 | 171 | // allow 20 worker thread in at a time, this will prevent the thread exhaustion. 172 | using (var semaphore_20 = new SemaphoreSlim(20)) 173 | { 174 | for (int i = 0; i < length; i++) 175 | { 176 | var k = i; 177 | NetworkInfo info = new(); 178 | await semaphore_20.WaitAsync(cancellationToken); 179 | 180 | taskNetworkInfo.Enqueue(Task.Run(async () => 181 | { 182 | 183 | Ping ping = new(); 184 | 185 | try 186 | { 187 | var pingResult = await ping.SendPingAsync(websites[k], 500); 188 | 189 | info = new NetworkInfo 190 | { 191 | Address = pingResult.Address, 192 | Website = websites[k], 193 | RoundTripTime = pingResult.RoundtripTime, 194 | Status = pingResult.Status 195 | }; 196 | } 197 | catch { /* log the errors */} 198 | finally 199 | { 200 | ping.Dispose(); 201 | } 202 | 203 | return info; 204 | 205 | }, cancellationToken)); 206 | 207 | // flush 10 items to IAsyncEnumerable at a time 208 | // other 10 items in queue will be completed in the meantime 209 | // this will create a nice throughput. 210 | int qFlush = (i + 1) % 10; 211 | if (qFlush == 0 || i >= length - 10) 212 | { 213 | while (taskNetworkInfo.TryDequeue(out var networkInfo)) 214 | { 215 | if (!cancellationToken.IsCancellationRequested) 216 | semaphore_20.Release(); 217 | 218 | yield return await networkInfo; 219 | } 220 | } 221 | } 222 | } 223 | } 224 | } 225 | 226 | -------------------------------------------------------------------------------- /EnumHasFlag.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | 4 | class Example 5 | { 6 | 7 | 8 | [Flags] 9 | enum Color 10 | { 11 | None = 1, 12 | Blue = 2, 13 | Green = 4, 14 | Yellow = 8, 15 | Purple = 16, 16 | Red = 32, 17 | Orange = 64, 18 | Pink = 128, 19 | Cyan = 256, 20 | Magenta = 512 21 | } 22 | 23 | 24 | private static readonly Color[] colors = Enum.GetValues(); 25 | 26 | static void Main() 27 | { 28 | 29 | var randomColors = Color.Red | Color.Magenta | Color.Cyan | Color.Blue | Color.Orange | Color.Purple; 30 | var (primaryColors, secondaryColors, otherColors) = Filter(randomColors); 31 | 32 | Console.WriteLine(); 33 | 34 | 35 | } 36 | 37 | static (Color[] primary, Color[] secondary, Color[] other) Filter(Color color) 38 | { 39 | var primaryList = new Color[3]; 40 | var secondaryList = new Color[3]; 41 | var mixList = new Color[3]; 42 | int i = 0, j = 0, k = 0; 43 | var primaryColors = Color.Yellow | Color.Red | Color.Blue; 44 | var secondaryColors = Color.Purple | Color.Orange | Color.Green; 45 | foreach (var item in colors) 46 | { 47 | if (color.HasFlag(item)) 48 | { 49 | if (primaryColors.HasFlag(item)) 50 | primaryList[i++] = item; 51 | else if (secondaryColors.HasFlag(item)) 52 | secondaryList[j++] = item; 53 | else 54 | mixList[k++] = item; 55 | } 56 | } 57 | return (primaryList, secondaryList, mixList); 58 | } 59 | 60 | } 61 | -------------------------------------------------------------------------------- /EnumToString.cs: -------------------------------------------------------------------------------- 1 | 2 | void Main() 3 | { 4 | string result = EnumToString(Color.Blue); 5 | Console.WriteLine(result); 6 | } 7 | 8 | enum Color { 9 | Blue, 10 | Green, 11 | Yellow 12 | } 13 | 14 | private static string EnumToString(Color enumerator) 15 | { 16 | switch (enumerator) 17 | { 18 | case Color.Blue: 19 | return nameof(Color.Blue); 20 | case Color.Green: 21 | return nameof(Color.Green); 22 | case Color.Yellow: 23 | return nameof(Color.Yellow); 24 | default: 25 | throw new ArgumentOutOfRangeException(nameof(enumerator),enumerator,null); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /EqualityBenchmark.cs: -------------------------------------------------------------------------------- 1 | using BenchmarkDotNet.Attributes; 2 | using BenchmarkDotNet.Running; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | 7 | namespace ConsoleDemo 8 | { 9 | class Program 10 | { 11 | static void Main() 12 | { 13 | var a = BenchmarkRunner.Run(); 14 | } 15 | } 16 | 17 | [MemoryDiagnoser] 18 | public class EqualityBenchmark 19 | { 20 | public int[] arr1; 21 | public int[] arr2; 22 | 23 | [GlobalSetup] 24 | public void Setup() 25 | { 26 | arr1 = Enumerable.Range(0, 1_000).ToArray(); 27 | arr2 = Enumerable.Range(0, 1_000).ToArray(); 28 | } 29 | 30 | public static bool LinqEquality(T[] firstArray, T[] secondArray) 31 | { 32 | return firstArray.SequenceEqual(secondArray); 33 | } 34 | 35 | public static bool BitwiseEquality(int[] x, int[] y) 36 | { 37 | if (x == null && y == null) 38 | return true; 39 | 40 | if (x == null || y == null || x.Length != y.Length) 41 | return false; 42 | 43 | int diff = 0; 44 | 45 | for (int i = 0; i < x.Length; i++) 46 | { 47 | diff |= x[i] ^ y[i]; 48 | } 49 | 50 | return diff == 0; 51 | } 52 | 53 | public static bool EqComparerEquality(T[] firstArray, T[] secondArray) 54 | { 55 | if (ReferenceEquals(firstArray, secondArray)) 56 | return true; 57 | 58 | if ( firstArray == null || secondArray == null || firstArray.Length != secondArray.Length ) 59 | return false; 60 | 61 | EqualityComparer comparer = EqualityComparer.Default; 62 | 63 | for (int i = 0; i < firstArray.Length; i++) 64 | { 65 | if (!comparer.Equals(firstArray[i], secondArray[i])) 66 | return false; 67 | } 68 | 69 | return true; 70 | } 71 | 72 | [Benchmark] 73 | public void LinqArrEqual() // 948 ms 74 | { 75 | int conditionalCount = 0; 76 | 77 | for (int i = 0; i < 100_000; i++) 78 | { 79 | if (LinqEquality(arr1, arr2)) 80 | conditionalCount++; 81 | } 82 | } 83 | 84 | [Benchmark] 85 | public void BitwiseArrEqual() // 77 ms 86 | { 87 | int conditionalCount = 0; 88 | 89 | for (int i = 0; i < 100_000; i++) 90 | { 91 | if (BitwiseEquality(arr1, arr2)) 92 | conditionalCount++; 93 | } 94 | } 95 | 96 | [Benchmark] 97 | public void EqualityComparerCheck() // 243 ms 98 | { 99 | int conditionalCount = 0; 100 | 101 | for (int i = 0; i < 100_000; i++) 102 | { 103 | if (EqComparerEquality(arr1, arr2)) 104 | conditionalCount++; 105 | } 106 | } 107 | } 108 | 109 | } 110 | 111 | 112 | -------------------------------------------------------------------------------- /EqualityComparer.cs: -------------------------------------------------------------------------------- 1 | using BenchmarkDotNet.Attributes; 2 | using BenchmarkDotNet.Running; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Diagnostics.CodeAnalysis; 6 | using System.Linq; 7 | using System.Text; 8 | using System.Threading; 9 | using System.Threading.Tasks; 10 | 11 | namespace ShallowDeepCopy 12 | { 13 | 14 | public class PrimaryColorComparer : EqualityComparer 15 | { 16 | public override bool Equals(PrimaryColor x, PrimaryColor y) 17 | { 18 | return Default.Equals(x, y); // direct comparison "==" is of same execution time in .Net 5 + 19 | } 20 | 21 | public override int GetHashCode([DisallowNull] PrimaryColor obj) 22 | { 23 | return Default.GetHashCode(obj); // obj.GetHashCode() is of same execution time in .Net 5 + 24 | } 25 | } 26 | 27 | public enum PrimaryColor { Red, Yellow, Blue } 28 | 29 | 30 | [MemoryDiagnoser] 31 | public class CompareEnum 32 | { 33 | public PrimaryColor firstPrimaryColor => PrimaryColor.Blue; 34 | public PrimaryColor secondPrimaryColor => PrimaryColor.Blue; 35 | 36 | public bool GenericBoxing(T firstEnum, T secondEnum) where T : Enum 37 | { 38 | return firstEnum.Equals(secondEnum); 39 | } 40 | 41 | public bool GenericBoxingEnumEquals(T firstEnum, T secondEnum) where T : Enum 42 | { 43 | return Enum.Equals(firstEnum,secondEnum); 44 | } 45 | 46 | public bool GenericEqualityComparer(T firstEnum, T secondEnum) where T : Enum 47 | { 48 | return EqualityComparer.Default.Equals(firstEnum,secondEnum); 49 | } 50 | 51 | [Benchmark] 52 | public void GenericBoxingTest() 53 | { 54 | for (int i = 0; i < 10_000; i++) 55 | { 56 | bool arePrimaryColorsEqualBoxing = GenericBoxing(firstPrimaryColor, secondPrimaryColor); // ~ 160 micro seconds 57 | } 58 | } 59 | 60 | [Benchmark] 61 | public void GenericBoxingEnumEqualsTest() 62 | { 63 | for (int i = 0; i < 10_000; i++) 64 | { 65 | bool arePrimaryColorsEqualEnum = GenericBoxingEnumEquals(firstPrimaryColor, secondPrimaryColor); // ~ 180 micro seconds 66 | } 67 | } 68 | 69 | [Benchmark] 70 | public void GenericEqualityComparerTest() 71 | { 72 | 73 | for (int i = 0; i < 10_000; i++) 74 | { 75 | bool arePrimaryColorsEqComparer = GenericEqualityComparer(firstPrimaryColor, secondPrimaryColor); // ~ 3 micro seconds 76 | } 77 | } 78 | 79 | [Benchmark] 80 | public void PrimaryColorComparerEqualsTest() 81 | { 82 | PrimaryColorComparer comparer = new(); 83 | for (int i = 0; i < 10_000; i++) 84 | { 85 | bool arePrimaryColorsEqualDerived = comparer.Equals(firstPrimaryColor, secondPrimaryColor); // ~ 3 micro seconds 86 | } 87 | } 88 | } 89 | 90 | class Program 91 | { 92 | 93 | static void Main(string[] args) 94 | { 95 | 96 | var a = BenchmarkRunner.Run(); 97 | 98 | } 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /ExternUnmanagedHeap.cs: -------------------------------------------------------------------------------- 1 | class UnmanagedHeap 2 | { 3 | static unsafe void Main() 4 | { 5 | byte* buffer = null; 6 | try 7 | { 8 | const int Size = 256; 9 | buffer = (byte*)Memory.Alloc(Size); 10 | for (int i = 0; i < Size; i++) buffer[i] = (byte)i; 11 | byte[] array = new byte[Size]; 12 | fixed (byte* p = array) Memory.Copy(buffer, p, Size); 13 | for (int i = 0; i < Size; i++) Console.WriteLine(array[i]); 14 | } 15 | finally 16 | { 17 | if (buffer != null) Memory.Free(buffer); 18 | } 19 | } 20 | } 21 | 22 | public static unsafe class Memory 23 | { 24 | // Handle for the process heap. This handle is used in all calls to the 25 | // HeapXXX APIs in the methods below. 26 | private static readonly IntPtr s_heap = GetProcessHeap(); 27 | 28 | // Allocates a memory block of the given size. The allocated memory is 29 | // automatically initialized to zero. 30 | public static void* Alloc(int size) 31 | { 32 | void* result = HeapAlloc(s_heap, HEAP_ZERO_MEMORY, (UIntPtr)size); 33 | if (result == null) throw new OutOfMemoryException(); 34 | return result; 35 | } 36 | 37 | // Copies count bytes from src to dst. The source and destination 38 | // blocks are permitted to overlap. 39 | public static void Copy(void* src, void* dst, int count) 40 | { 41 | byte* ps = (byte*)src; 42 | byte* pd = (byte*)dst; 43 | 44 | Console.WriteLine((long)ps); 45 | Console.WriteLine((long)pd); 46 | if (ps > pd) 47 | { 48 | for (; count != 0; count--) *pd++ = *ps++; 49 | } 50 | else if (ps < pd) 51 | { 52 | for (ps += count, pd += count; count != 0; count--) *--pd = *--ps; 53 | } 54 | } 55 | 56 | // Frees a memory block. 57 | public static void Free(void* block) 58 | { 59 | if (!HeapFree(s_heap, 0, block)) throw new InvalidOperationException(); 60 | } 61 | 62 | // Re-allocates a memory block. If the reallocation request is for a 63 | // larger size, the additional region of memory is automatically 64 | // initialized to zero. 65 | public static void* ReAlloc(void* block, int size) 66 | { 67 | void* result = HeapReAlloc(s_heap, HEAP_ZERO_MEMORY, block, (UIntPtr)size); 68 | if (result == null) throw new OutOfMemoryException(); 69 | return result; 70 | } 71 | 72 | // Returns the size of a memory block. 73 | public static int SizeOf(void* block) 74 | { 75 | int result = (int)HeapSize(s_heap, 0, block); 76 | if (result == -1) throw new InvalidOperationException(); 77 | return result; 78 | } 79 | 80 | // Heap API flags 81 | private const int HEAP_ZERO_MEMORY = 0x00000008; 82 | 83 | // Heap API functions 84 | [DllImport("kernel32")] 85 | private static extern IntPtr GetProcessHeap(); 86 | 87 | [DllImport("kernel32")] 88 | private static extern void* HeapAlloc(IntPtr hHeap, int flags, UIntPtr size); 89 | 90 | [DllImport("kernel32")] 91 | private static extern bool HeapFree(IntPtr hHeap, int flags, void* block); 92 | 93 | [DllImport("kernel32")] 94 | private static extern void* HeapReAlloc(IntPtr hHeap, int flags, void* block, UIntPtr size); 95 | 96 | [DllImport("kernel32")] 97 | private static extern UIntPtr HeapSize(IntPtr hHeap, int flags, void* block); 98 | } 99 | -------------------------------------------------------------------------------- /FibonacciMemoization.cs: -------------------------------------------------------------------------------- 1 | public int FibonacciWithMemo(int n) 2 | { 3 | if (n < 0) 4 | throw new ArgumentException("n >= 0", nameof(n)); 5 | if (n <= 1) 6 | return n; 7 | 8 | var dictMemo = new Dictionary() { { 0, 0 }, { 1, 1 } }; 9 | 10 | int LocalMemoFibonacci(int key) 11 | { 12 | if (dictMemo.ContainsKey(key)) 13 | return dictMemo[key]; 14 | 15 | int value = LocalMemoFibonacci(key - 1) + LocalMemoFibonacci(key - 2); 16 | 17 | dictMemo[key] = value; 18 | 19 | return value; 20 | } 21 | 22 | return LocalMemoFibonacci(n); 23 | } 24 | -------------------------------------------------------------------------------- /FibonacciSeriesGenWithSpan.cs: -------------------------------------------------------------------------------- 1 | public List FibonacciSeries(int firstNItem) 2 | { 3 | 4 | List store = new(); 5 | const int stackArrSize = 25; 6 | Span fibo = stackalloc double[stackArrSize]; 7 | 8 | fibo[0] = fibo[1] = 1; 9 | store.Add(1); store.Add(1); 10 | 11 | for (int i = 2; i < firstNItem; i++) 12 | { 13 | int k = i; 14 | k %= stackArrSize; // loop in an array of 25 elements stored in stack 15 | 16 | if (k == 0) 17 | { 18 | fibo[0] = fibo[^2] + fibo[^1]; 19 | fibo[1] = fibo[^1] + fibo[0]; 20 | store.Add(fibo[0]) ; store.Add(fibo[1]); 21 | k = 2; // skip first two elements 22 | i += 2; // skip two steps 23 | } 24 | 25 | fibo[k] = fibo[k - 1] + fibo[k - 2]; 26 | store.Add(fibo[k]); 27 | } 28 | 29 | 30 | return store; 31 | } 32 | 33 | // asynchronous version with Memory as an argument 34 | public async Task> FibonacciSeriesAsync(int firstNItem,Memory fibo) 35 | => await Task.Run (() => FibonacciSeries(firstNItem,fibo.Span)); 36 | 37 | -------------------------------------------------------------------------------- /FindMinMax.cs: -------------------------------------------------------------------------------- 1 | public static Main(string[] args) 2 | { 3 | //int32 minimum , int32 maximum 4 | var (minimum,maximum) = FindMinMax(-1,2,33,4,-10,6); 5 | System.Console.WriteLine($"Min:{minimum} Max:{maximum}"); 6 | } 7 | 8 | 9 | static (int min, int max) FindMinMax(params int[] input) 10 | { 11 | if (input is null || input.Length == 0) 12 | { 13 | throw new ArgumentException("Cannot find minimum and maximum of a null or empty array."); 14 | } 15 | 16 | var min = int.MaxValue; 17 | var max = int.MinValue; 18 | 19 | foreach(var i in input) 20 | { 21 | if(i < min) 22 | min = i; 23 | 24 | if(i > max) 25 | max = i; 26 | } 27 | 28 | return (min, max) 29 | } 30 | -------------------------------------------------------------------------------- /ForeachExtension.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | void Main() 4 | { 5 | foreach (var element in (1.4,10.4,0.5)) 6 | { 7 | Console.WriteLine(element); 8 | } 9 | } 10 | 11 | static class Extensions 12 | { 13 | public static IEnumerator GetEnumerator (this int x) => 14 | Enumerable.Range (0, x).GetEnumerator(); 15 | 16 | public static IEnumerator GetEnumerator(this (double start,double end, double step) loop) 17 | { 18 | List list = new(); 19 | for (double i = loop.start; i <= loop.end; i+=loop.step) 20 | list.Add(i); 21 | 22 | return list.GetEnumerator(); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /FunctionPointer.cs: -------------------------------------------------------------------------------- 1 | 2 | void Main() 3 | { 4 | unsafe 5 | { 6 | int outputUnsafe = CalculateUnsafe(&Sum, 3, 4); // calli IL instruction 7 | // output -> 7 8 | } 9 | 10 | int outputDemo = Demo(Sum, 5, 6); 11 | // output -> 11 12 | } 13 | 14 | static int Sum(int x, int y) => x + y; 15 | 16 | //C# provides delegate types to define safe function pointer objects. 17 | //Invoking a delegate involves instantiating a type derived from System.Delegate 18 | //and making a virtual method call to its Invoke method. 19 | //This virtual call uses the callvirt IL instruction. 20 | //In performance critical code paths, using the calli IL instruction is more efficient. 21 | static T Demo(Func calculate, T x, T y) => 22 | calculate(x, y); 23 | 24 | //You can define a function pointer using the delegate* syntax. 25 | //delegate* -> calli IL instruction , Func -> callvirt IL instruction 26 | static unsafe T CalculateUnsafe(delegate* calculate, T x, T y) => 27 | calculate(x, y); 28 | -------------------------------------------------------------------------------- /HasDuplicate.cs: -------------------------------------------------------------------------------- 1 | public static class ExtentionCollection 2 | { 3 | public static bool HasDuplicate(this ICollection collection, out int indexOfDuplicateValue) 4 | where T : struct 5 | { 6 | var localCollection = collection; 7 | 8 | if(localCollection is null) 9 | throw new NullReferenceException(); 10 | if(localCollection.Count == 0) 11 | throw new Exception("Collection is empty"); 12 | 13 | HashSet list = new(); 14 | var result = !localCollection.All(c => list.Add(c) ); 15 | indexOfDuplicateValue = result ? list.Count : -1; 16 | 17 | return result; 18 | } 19 | 20 | public static bool HasDuplicate(this ICollection collection, 21 | out int indexOfDuplicateValue, bool isCaseSensitive = false) 22 | { 23 | var localCollection = collection; 24 | 25 | if (localCollection is null) 26 | throw new NullReferenceException(); 27 | if (localCollection.Count == 0) 28 | throw new Exception("Collection is empty"); 29 | 30 | localCollection = !isCaseSensitive ? 31 | collection.Select(c => c?.ToLower() ).ToArray() : localCollection ; 32 | 33 | HashSet list = new(); 34 | var result = !localCollection.All(c => list.Add(c)); 35 | indexOfDuplicateValue = result ? list.Count : -1; 36 | 37 | return result; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /IAsyncDisposableIDisposable.cs: -------------------------------------------------------------------------------- 1 | public class ExampleAsyncDisposable : IAsyncDisposable, IDisposable 2 | { 3 | private Utf8JsonWriter _jsonWriter; 4 | 5 | public ExampleAsyncDisposable() 6 | { 7 | _jsonWriter = new(new MemoryStream()); 8 | } 9 | 10 | public void Dispose() 11 | { 12 | Dispose(true); 13 | GC.SuppressFinalize(this); 14 | } 15 | 16 | public async ValueTask DisposeAsync() 17 | { 18 | await DisposeAsyncCore(); 19 | 20 | Dispose(false); // dispose unmanaged objects 21 | GC.SuppressFinalize(this); 22 | } 23 | 24 | protected virtual void Dispose(bool disposing) 25 | { 26 | if (disposing) 27 | { 28 | _jsonWriter?.Dispose(); 29 | } 30 | 31 | _jsonWriter = null; 32 | } 33 | 34 | protected virtual async ValueTask DisposeAsyncCore() 35 | { 36 | if (_jsonWriter is not null) 37 | { 38 | await _jsonWriter.DisposeAsync().ConfigureAwait(false); 39 | } 40 | 41 | _jsonWriter = null; 42 | } 43 | } 44 | 45 | 46 | 47 | // second approach 48 | 49 | class ExampleConjunctiveDisposableusing : IDisposable, IAsyncDisposable 50 | { 51 | IDisposable _disposableResource = new MemoryStream(); 52 | IAsyncDisposable _asyncDisposableResource = new MemoryStream(); 53 | 54 | public void Dispose() 55 | { 56 | Dispose(true); 57 | GC.SuppressFinalize(this); 58 | } 59 | 60 | public async ValueTask DisposeAsync() 61 | { 62 | await DisposeAsyncCore(); 63 | 64 | Dispose(disposing: false); 65 | GC.SuppressFinalize(this); 66 | } 67 | 68 | protected virtual void Dispose(bool disposing) 69 | { 70 | if (disposing) 71 | { 72 | _disposableResource?.Dispose(); 73 | (_asyncDisposableResource as IDisposable)?.Dispose(); 74 | } 75 | 76 | _disposableResource = null; 77 | _asyncDisposableResource = null; 78 | } 79 | 80 | protected virtual async ValueTask DisposeAsyncCore() 81 | { 82 | if (_asyncDisposableResource is not null) 83 | { 84 | await _asyncDisposableResource.DisposeAsync().ConfigureAwait(false); 85 | } 86 | 87 | if (_disposableResource is IAsyncDisposable disposable) 88 | { 89 | await disposable.DisposeAsync().ConfigureAwait(false); 90 | } 91 | else 92 | { 93 | _disposableResource?.Dispose(); 94 | } 95 | 96 | _asyncDisposableResource = null; 97 | _disposableResource = null; 98 | } 99 | } 100 | 101 | // using await in main 102 | 103 | class ExampleConfigureAwaitProgram 104 | { 105 | static async Task Main() 106 | { 107 | var exampleAsyncDisposable = new ExampleAsyncDisposable(); 108 | await using (exampleAsyncDisposable.ConfigureAwait(false)) 109 | { 110 | // Interact with the exampleAsyncDisposable instance. 111 | } 112 | 113 | Console.ReadLine(); 114 | } 115 | } 116 | -------------------------------------------------------------------------------- /IDisposableSafeHandle.cs: -------------------------------------------------------------------------------- 1 | void Main() 2 | { 3 | string[] websites = { "http://www.olay53.com", "http://www.bilecikolay.com/"}; 4 | DownloadWebsiteContent d = new(websites); 5 | foreach (var content in d.Download()) 6 | content.Dump(); 7 | 8 | d.Dispose(); 9 | } 10 | // SafeHandle provides built-in finalizer, it's recommended to use this approach 11 | // it's a abstratc wrapper class for operating system handles which must be inherited. 12 | // SafeHandle class provides critical finalization of handle resources, 13 | // preventing handles from being reclaimed prematurely by garbage collection and from 14 | // being recycled by Windows to reference unintended unmanaged objects. 15 | public class SafeUnmanagedClass : SafeHandle 16 | { 17 | public SafeUnmanagedClass() : base(IntPtr.Zero,false){ } 18 | public override bool IsInvalid => false; 19 | protected override bool ReleaseHandle() => base.ReleaseHandle(); 20 | } 21 | 22 | public class DownloadWebsiteContent : IDisposable 23 | { 24 | WebClient client; 25 | string[] urlList; 26 | bool disposed = false; 27 | SafeUnmanagedClass safeClass ; 28 | 29 | public DownloadWebsiteContent(string[] urls) 30 | { 31 | safeClass = new(); 32 | urlList = urls; 33 | client = new(); 34 | } 35 | 36 | public IEnumerable Download() 37 | { 38 | if (urlList is not null) 39 | { 40 | for (int i = 0; i < urlList.Length; i++) 41 | { 42 | yield return client.DownloadString(urlList[i]); 43 | } 44 | } 45 | } 46 | 47 | public void Dispose() 48 | { 49 | Dispose(true); // true : release managed and unmanaged objects. 50 | } 51 | 52 | protected virtual void Dispose ( bool disposeManagedObjects) 53 | { 54 | if (!disposed) 55 | { 56 | if (disposeManagedObjects) 57 | { 58 | urlList = null; // GC will collect this array earlier. 59 | safeClass.Dispose(); // safeHandle is a safe unmanaged object wrapper. 60 | } 61 | 62 | client.Dispose(); // unmanaged objects got released 63 | disposed = true; 64 | } 65 | 66 | // if there's a base class that also impements IDisposable 67 | // base.Dispose(disposeManagedObjects); 68 | } 69 | 70 | // SafeHandle is recommended! 71 | ~DownloadWebsiteContent() { Dispose(false);} // false : release unmanaged objects 72 | } 73 | -------------------------------------------------------------------------------- /ImplicitOperatorMathPow.cs: -------------------------------------------------------------------------------- 1 | 2 | 3 | void Main() 4 | { 5 | pint64 a = 12; // --> implicit operator pint64(long number) => new pint64(number); 6 | pint64 b = 2; // --> implicit operator pint64(long number) => new pint64(number); 7 | nuint s =3; 8 | double t = a^b; // t = 144 --> double operator ^(pint64 first, pint64 second) => Math.Pow(first._x,second._x); 9 | 10 | long k = a; // k = 12 --> implicit operator long(pint64 p) => p._x; 11 | 12 | } 13 | 14 | struct pint64 15 | { 16 | private long _x; 17 | public pint64(long x) 18 | { 19 | this._x = x; 20 | } 21 | public static double operator ^(pint64 first, pint64 second) => Math.Pow(first._x,second._x); 22 | public static implicit operator long(pint64 p) => p._x; 23 | public static implicit operator pint64(long number) => new pint64(number); 24 | } 25 | -------------------------------------------------------------------------------- /JobSequencingDeadline.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace DynamicProgrammingAlgorithms 8 | { 9 | class JobSequencingDeadline 10 | { 11 | //List> DateTime stands for deadline and double for profit 12 | //Accepting all the jobs have 1 unit of work to finish 13 | //key corresponds to deadline and value to profit 14 | public KeyValuePair, double>[] JobSequencingWithDeadlines( 15 | List> jobListWithDeadlines) 16 | { 17 | //Jobs and their profit enlisted in descending order , on profit base 18 | List> tempList = jobListWithDeadlines.OrderByDescending(x => x.Value).ToList(); 19 | //Distinct datetime values are filtered out 20 | List deadLineList = jobListWithDeadlines.Select(x => x.Key.Date).Distinct().ToList(); 21 | deadLineList.Insert(0, DateTime.UtcNow.Date);// today's date is added 22 | deadLineList.Sort(); // Datetime list sorted, values will be inserted according to this order 23 | 24 | int count = 0; 25 | int sizeOfArray = deadLineList.Count - 1; 26 | int repeat = tempList.Count() - 1; 27 | //Array for keeping high profit values 28 | KeyValuePair, double>[] deadLineSequence = 29 | new KeyValuePair, double>[sizeOfArray]; 30 | 31 | for (int i = 0; i < repeat; i++) 32 | { 33 | for (int k = deadLineList.IndexOf(tempList[i].Key.Date); k > 0; k--) 34 | { 35 | if (deadLineSequence[k - 1].Key.Value == null) 36 | { 37 | deadLineSequence[k - 1] = new KeyValuePair, double>( 38 | new KeyValuePair(deadLineList[k - 1].ToString("d") 39 | , deadLineList[k].ToString("d")), tempList[i].Value); 40 | count++; 41 | break; 42 | } 43 | } 44 | 45 | if (count + 1 == deadLineList.Count()) 46 | break; 47 | } 48 | 49 | return deadLineSequence; 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /JsonDOMExtension.cs: -------------------------------------------------------------------------------- 1 | 2 | 3 | async Task Main() 4 | { 5 | await using var sampleFileOpen = 6 | File.OpenRead(@"C:\Users\fenko\Desktop\sampleJson.json"); 7 | 8 | sampleFileOpen.Seek(0,SeekOrigin.Begin); 9 | 10 | using (JsonDocument jsonDocument = await JsonDocument.ParseAsync(sampleFileOpen)) 11 | { 12 | var root = jsonDocument.RootElement; 13 | var releaseList = root.Pull("releases"); 14 | 15 | var enumeratedList = releaseList?.EnumerateArray().Where(jsonElement => 16 | { 17 | if (jsonElement.TryGetProperty("release-date", out JsonElement date)) 18 | { 19 | var dateTime = date.TryGetDateTime(out DateTime outputDateTime) ? 20 | outputDateTime : new DateTime(0, 0, 0); 21 | 22 | // get JsonElements whose release-date year >= 2019; 23 | if (dateTime.Year >= 2019) 24 | return true; 25 | } 26 | 27 | return false; 28 | }); 29 | 30 | var jsonWriterOptions = new JsonWriterOptions 31 | { 32 | Indented = true, 33 | SkipValidation = true 34 | }; 35 | 36 | await using (var stream = new MemoryStream()) 37 | { 38 | var streamReader = new StreamReader(stream); 39 | var jsonWriter = new Utf8JsonWriter(stream, jsonWriterOptions); 40 | 41 | foreach (var jsonElement in enumeratedList) 42 | { 43 | 44 | 45 | jsonElement.WriteTo(jsonWriter); 46 | 47 | 48 | string result = string.Empty; 49 | 50 | streamReader.BaseStream.Position = 0; 51 | result = await streamReader.ReadToEndAsync(); 52 | 53 | 54 | result.OnDemand().Dump(); 55 | 56 | var runtimeFiles = jsonElement. 57 | Pull("sdk:files")?. 58 | EnumerateArray() ?? default(JsonElement.ArrayEnumerator); 59 | 60 | await jsonWriter.FlushAsync(); 61 | foreach (JsonElement file in runtimeFiles) 62 | { 63 | var script = file.Pull("name")?.GetString(); 64 | script.Dump(); 65 | } 66 | 67 | } 68 | 69 | await jsonWriter.DisposeAsync(); 70 | streamReader.Dispose(); 71 | } 72 | 73 | } 74 | } 75 | 76 | 77 | public static class JsonDOMExtensions 78 | { 79 | public static JsonElement? Pull(this JsonElement jsonElement, string jsonPath) 80 | { 81 | if (jsonPath is null || 82 | jsonElement.ValueKind is JsonValueKind.Undefined or JsonValueKind.Null) 83 | return default(JsonElement?); 84 | 85 | var filter = new char[] { '.', ':' }; 86 | 87 | string[] slicedList = 88 | jsonPath.Split(filter, StringSplitOptions.RemoveEmptyEntries); 89 | 90 | for (int i = 0; i < slicedList.Length; i++) 91 | { 92 | if (jsonElement.ValueKind is JsonValueKind.Undefined or JsonValueKind.Null) 93 | return default(JsonElement?); 94 | 95 | jsonElement = 96 | jsonElement.TryGetProperty(slicedList[i], out JsonElement output) ? 97 | output : default(JsonElement); 98 | } 99 | 100 | return jsonElement; 101 | } 102 | } 103 | 104 | //sampleJson.json content: 105 | /* { 106 | "channel-version": "2.2", 107 | "latest-release": "2.2.8", 108 | "latest-release-date": "2019-11-19", 109 | "latest-runtime": "2.2.8", 110 | "latest-sdk": "2.2.207", 111 | "support-phase": "eol", 112 | "eol-date": "2019-12-23", 113 | "lifecycle-policy": "https://www.microsoft.com/net/support/policy", 114 | "releases": [ 115 | { 116 | "release-date": "2019-11-19", 117 | "release-version": "2.2.8", 118 | "security": false, 119 | "release-notes": "https://github.com/dotnet/core/blob/master/release-notes/2.2/2.2.8/2.2.8.md", 120 | "runtime": { 121 | "version": "2.2.8", 122 | "version-display": "2.2.8", 123 | "vs-version": "", 124 | "files": [ 125 | { 126 | "name": "1dotnet-runtime-linux-arm.tar.gz", 127 | "rid": "linux-arm", 128 | "url": "https://download.visualstudio.microsoft.com/download/pr/97595553-470b-45bc-842d-aff8da46d4c4/46ee25ac85e4844df0e7f0fb9229755c/dotnet-runtime-2.2.8-linux-arm.tar.gz", 129 | "hash": "a3fb720504821eca64ec507e4ae2e321b3119c90f7b14844db85026d386047e1cfdf6f24b07f5fae6f19af9ed7ccbe49e46a39ad16d0c3838d9e9589bf2d5ef9" 130 | }, 131 | { 132 | "name": "1dotnet-runtime-linux-arm64.tar.gz", 133 | "rid": "linux-arm64", 134 | "url": "https://download.visualstudio.microsoft.com/download/pr/8595cc08-1588-4e28-b765-1201b447c99b/342cf07ff5e3adb396d17da2de0d359b/dotnet-runtime-2.2.8-linux-arm64.tar.gz", 135 | "hash": "097e94db6a7cf2d78588825aea663ebbe6fdd51275bcb9cee4d6d00c8274532a3474f95d506267e38b1b45bf1fa3fa2d255ba532afffe9f5bce17c8092c24766" 136 | }, 137 | { 138 | "name": "1dotnet-runtime-linux-musl-x64.tar.gz", 139 | "rid": "linux-musl-x64", 140 | "url": "https://download.visualstudio.microsoft.com/download/pr/f5e25e07-9934-4323-9f8b-164e2a829063/d95bd8e5f1dd52168ebf4fb9594507b1/dotnet-runtime-2.2.8-linux-musl-x64.tar.gz", 141 | "hash": "d0f8e7ac385e7fcaca2a70b1081625be88289e06f031ce12955f0d6df0b6ff2f13e6d93287e30439bb19932b2a06a9d1162577579c9c85da435c4036c609659a" 142 | }, 143 | { 144 | "name": "1dotnet-runtime-linux-x64.tar.gz", 145 | "rid": "linux-x64", 146 | "url": "https://download.visualstudio.microsoft.com/download/pr/3fbca771-e7d3-45bf-8e77-cfc1c5c41810/e118d44f5a6df21714abd8316e2e042b/dotnet-runtime-2.2.8-linux-x64.tar.gz", 147 | "hash": "b818557b0090ec047be0fb2e5ffee212e23e8417e1b0164f455e3a880bf5b94967dc4c86d6ed82397af9acc1f7415674904f6225a1abff85d28d2a6d5de8073b" 148 | }, 149 | { 150 | "name": "1dotnet-runtime-osx-x64.pkg", 151 | "rid": "osx-x64", 152 | "url": "https://download.visualstudio.microsoft.com/download/pr/fcec560f-0ae9-4d60-8528-13a11150805a/97c10e386a0cb1a7c2312fcf7bf87823/dotnet-runtime-2.2.8-osx-x64.pkg", 153 | "hash": "ae5d06c54fb0126d87abfb30cc372f8b56f6ed2ddb3d0762fb05b39714c42535ea47298f3ed85f687dfea42d670acdb19bc3009dc79fab39d1a339d5708ca360" 154 | }, 155 | { 156 | "name": "1dotnet-runtime-osx-x64.tar.gz", 157 | "rid": "osx-x64", 158 | "url": "https://download.visualstudio.microsoft.com/download/pr/bbd4e493-6eed-45e8-90ed-7be0f1270c7a/2d19adb63887d3b02301361117bbe4f5/dotnet-runtime-2.2.8-osx-x64.tar.gz", 159 | "hash": "dcd38ac8c6093eacd6b649b6416dc6af0053003441d1182ccf0b9584e04805b82c51381139ee76de1788ffa3ff576e7310dd4bc24318412a0fe47a0982cfc0fb" 160 | }, 161 | { 162 | "name": "1dotnet-runtime-rhel.6-x64.tar.gz", 163 | "rid": "rhel.6-x64", 164 | "url": "https://download.visualstudio.microsoft.com/download/pr/fcefad8a-38da-4f06-8039-8b6053cd5d84/4548d460aac1744ad6ddd253bbb4422d/dotnet-runtime-2.2.8-rhel.6-x64.tar.gz", 165 | "hash": "5016f53948514bee22f4d7646ebc03784e86eb45d1d19bcec0f2ef2957f3f9374c512b9fff34686c597d4c0640cd208ed07df9298c0ff0f50a44a2c4b774beeb" 166 | }, 167 | { 168 | "name": "1dotnet-runtime-win-arm.zip", 169 | "rid": "win-arm", 170 | "url": "https://download.visualstudio.microsoft.com/download/pr/584be079-dde5-465d-9f9b-04183458dd07/a666047a3ae292cb97d74e466320e600/dotnet-runtime-2.2.8-win-arm.zip", 171 | "hash": "21f34cafd5e3661017f1bc92f39d250f162f9d3832404125c73473250157d25cd74d7afe959749c4cc2fc418439d20f521626f4505e254f42ef857c5c10904c5" 172 | }, 173 | { 174 | "name": "1dotnet-runtime-win-x64.exe", 175 | "rid": "win-x64", 176 | "url": "https://download.visualstudio.microsoft.com/download/pr/4e14a32d-cf57-42ce-964f-fa40c7d11dde/95cf2d91312fc495bc25ad9137d42698/dotnet-runtime-2.2.8-win-x64.exe", 177 | "hash": "963742eb79d51807444d871cd57acc1c2b37a199eeecc97f3d47715fe73dcc7d2b7015bb2b7e6f7497726de67a44f936c1ebbc2c9ea728cf47e66aa4cbacc191" 178 | }, 179 | { 180 | "name": "1dotnet-runtime-win-x64.zip", 181 | "rid": "win-x64", 182 | "url": "https://download.visualstudio.microsoft.com/download/pr/79365951-b51b-487e-a03c-6ffeb3a5f3ad/ce9eb59ba8a76621d5e76614b0c9e97d/dotnet-runtime-2.2.8-win-x64.zip", 183 | "hash": "5864a40f662388761bc108510df9540b0b6672ae0f5a04cac71112ef0d1aa5781ffa3c856e919eed68eba6161f21a38c52f0e8850e8ecdf22609c42d2387d848" 184 | }, 185 | { 186 | "name": "1dotnet-runtime-win-x86.exe", 187 | "rid": "win-x86", 188 | "url": "https://download.visualstudio.microsoft.com/download/pr/930685bc-ac92-4149-b4f0-b0b26d480418/c03bbed24f87e66281b5ff99ceecbb0b/dotnet-runtime-2.2.8-win-x86.exe", 189 | "hash": "75de2107f0798add2f67f773451a779b051bf6898936f8fbd82ce7347e7471bb5310831844e3868610bc1fb8cc6ef780c5b4fa7ec4419b81b574fb5085881de2" 190 | }, 191 | { 192 | "name": "1dotnet-runtime-win-x86.zip", 193 | "rid": "win-x86", 194 | "url": "https://download.visualstudio.microsoft.com/download/pr/33751b42-f854-4d55-b2ff-3f0d09a88cf7/0c268c32f7730e90bd0a370be6699bf6/dotnet-runtime-2.2.8-win-x86.zip", 195 | "hash": "66fca0a5b9b801fea1972b87d99ecf9f9904edf948139df495e7696c6a02a417371c4632a9232c76e3832f6161a3dd172a0d799acf66db0dc43a7719776c90d7" 196 | } 197 | ] 198 | }, 199 | "sdk": { 200 | "version": "2.2.207", 201 | "version-display": "2.2.207", 202 | "runtime-version": "2.2.8", 203 | "vs-version": "", 204 | "vs-support": "Visual Studio 2019 (v16.0)", 205 | "csharp-version": "7.3", 206 | "fsharp-version": "4.5", 207 | "files": [ 208 | { 209 | "name": "dotnet-sdk-linux-arm.tar.gz", 210 | "rid": "linux-arm", 211 | "url": "https://download.visualstudio.microsoft.com/download/pr/fca1c415-b70c-4134-8844-ea947f410aad/901a86c12be90a67ec37cd0cc59d5070/dotnet-sdk-2.2.207-linux-arm.tar.gz", 212 | "hash": "a922b87fc1e433d489d6863fa3faca5a5eeb33f68104c5c4733ca8fbd187230715f6ce384ddbdaca501b1f42c87f590a9299b525be405214803bb1da3c4bbd1c" 213 | }, 214 | { 215 | "name": "dotnet-sdk-linux-arm64.tar.gz", 216 | "rid": "linux-arm64", 217 | "url": "https://download.visualstudio.microsoft.com/download/pr/18738093-b024-4353-96c2-4e1d2285a5e4/5e86ebbca79e71486aa2b18af0214ae9/dotnet-sdk-2.2.207-linux-arm64.tar.gz", 218 | "hash": "565fe5cbc2c388e54b3ee548d5b98e1fd85d920ceeeb5475a2bf2daa7f090fc925d8afef19b2b76973af439fbb749c6996711790287eafd588e4d916a016e84c" 219 | }, 220 | { 221 | "name": "dotnet-sdk-linux-musl-x64.tar.gz", 222 | "rid": "linux-musl-x64", 223 | "url": "https://download.visualstudio.microsoft.com/download/pr/c72122bd-38f5-4c98-b585-b8aaf57ecc6e/c89d7774a430e163d801753654f33972/dotnet-sdk-2.2.207-linux-musl-x64.tar.gz", 224 | "hash": "231118ba205b5d609263fc790851c65900aabf5830d492425849de89b7103f02012a302ce21960cb062426c5b8fd480e1316176a927bd287b08b7d19445f7224" 225 | }, 226 | { 227 | "name": "dotnet-sdk-linux-x64.tar.gz", 228 | "rid": "linux-x64", 229 | "url": "https://download.visualstudio.microsoft.com/download/pr/022d9abf-35f0-4fd5-8d1c-86056df76e89/477f1ebb70f314054129a9f51e9ec8ec/dotnet-sdk-2.2.207-linux-x64.tar.gz", 230 | "hash": "9d70b4a8a63b66da90544087199a0f681d135bf90d43ca53b12ea97cc600a768b0a3d2f824cfe27bd3228e058b060c63319cd86033be8b8d27925283f99de958" 231 | }, 232 | { 233 | "name": "dotnet-sdk-osx-gs-x64.pkg", 234 | "rid": "osx-x64", 235 | "url": "https://download.visualstudio.microsoft.com/download/pr/837aa87a-8160-4297-b6b7-eceb56b3ce48/74c42db19f2784ab172e27598eae7f4f/dotnet-sdk-2.2.207-osx-gs-x64.pkg", 236 | "hash": "3cf91804f2d0b7beb0830450f98cbd18125d1df72354b6a57668cca11a871a68d234f2d8a8a5fe86215b1f71584c22b9f75fc057365c55026da2979195894278" 237 | }, 238 | { 239 | "name": "dotnet-sdk-osx-x64.pkg", 240 | "rid": "osx-x64", 241 | "url": "https://download.visualstudio.microsoft.com/download/pr/cb2d65e1-ad90-4416-8e6a-3755f92ba39f/f498aca4950a038d6fc55cca75eca630/dotnet-sdk-2.2.207-osx-x64.pkg", 242 | "hash": "3cf91804f2d0b7beb0830450f98cbd18125d1df72354b6a57668cca11a871a68d234f2d8a8a5fe86215b1f71584c22b9f75fc057365c55026da2979195894278" 243 | }, 244 | { 245 | "name": "dotnet-sdk-osx-x64.tar.gz", 246 | "rid": "osx-x64", 247 | "url": "https://download.visualstudio.microsoft.com/download/pr/5b8d25c1-85e1-4b18-8d96-b14115586319/78ff638656c3a90324e810f8dd157422/dotnet-sdk-2.2.207-osx-x64.tar.gz", 248 | "hash": "d60d683851ba08a8f30acac8c635219223a6f11e1efe5ec7e64c4b1dca44f7e3d6122ecc0a4e97b8b57c2035e22be5e09f5f1642db6227bb8898654da057a7ae" 249 | }, 250 | { 251 | "name": "dotnet-sdk-rhel.6-x64.tar.gz", 252 | "rid": "rhel.6-x64", 253 | "url": "https://download.visualstudio.microsoft.com/download/pr/2b9ec838-2e6e-40cd-a57a-885e56904329/959135d11fd608afea316c01f73e9490/dotnet-sdk-2.2.207-rhel.6-x64.tar.gz", 254 | "hash": "64decac610d7fdda90e7a1236e155ddcc8bb35ee5fda8f1ebd7c97380eddff9638e08cf8d439bbc52bdedb223c70049441b448bda0b687b744b34b159630ef4b" 255 | }, 256 | { 257 | "name": "dotnet-sdk-win-arm.zip", 258 | "rid": "win-arm", 259 | "url": "https://download.visualstudio.microsoft.com/download/pr/4ce7496a-fa96-4fbd-9259-f5ad6f9fbcd4/7a4176c05032d8b28cb3a7e830876c22/dotnet-sdk-2.2.207-win-arm.zip", 260 | "hash": "263aa3de231de97268d75dadee94031f26ee0c3ed0da18ee87c53eba42138cf1384ff0869caee13f8a57441c4c5d415d8abe388bb3dee3294f5af2a9e7620ecb" 261 | }, 262 | { 263 | "name": "dotnet-sdk-win-gs-x64.exe", 264 | "rid": "", 265 | "url": "https://download.visualstudio.microsoft.com/download/pr/dfa5fe58-1542-4b4c-84bf-2aa44743c925/170740c73015a8c621bedab256fd8431/dotnet-sdk-2.2.207-win-gs-x64.exe", 266 | "hash": "721882a80632fb113dcd3b82a80f4be968a08b6f09a9c0513cef7464e5fae836b60b601e570289fc6a31d3765f6f66d81ec32d6e98e58098acb74d0a714eabb6" 267 | }, 268 | { 269 | "name": "dotnet-sdk-win-gs-x86.exe", 270 | "rid": "", 271 | "url": "https://download.visualstudio.microsoft.com/download/pr/d23f0125-64e3-4132-97c0-5beb671228f9/e68a5a74a1dbf73059efe007ae56a456/dotnet-sdk-2.2.207-win-gs-x86.exe", 272 | "hash": "ce0a50585881d0345a232a3f40d99d4248c455157472525ade558bb93f222358ee79dde0786dcdf75b4923f55935d9d6aa8785c0129f44d713c8dee3f97c4195" 273 | }, 274 | { 275 | "name": "dotnet-sdk-win-x64.exe", 276 | "rid": "win-x64", 277 | "url": "https://download.visualstudio.microsoft.com/download/pr/279de74e-f7e3-426b-94d8-7f31d32a129c/e83e8c4c49bcb720def67a5c8fe0d8df/dotnet-sdk-2.2.207-win-x64.exe", 278 | "hash": "721882a80632fb113dcd3b82a80f4be968a08b6f09a9c0513cef7464e5fae836b60b601e570289fc6a31d3765f6f66d81ec32d6e98e58098acb74d0a714eabb6" 279 | }, 280 | { 281 | "name": "dotnet-sdk-win-x64.zip", 282 | "rid": "win-x64", 283 | "url": "https://download.visualstudio.microsoft.com/download/pr/e0d4bd70-9dd2-40a3-9e6e-64af9721f3e3/2324e93d2152efd009f242a1723685c3/dotnet-sdk-2.2.207-win-x64.zip", 284 | "hash": "726f60e2cf82b7fbea97066dda318d468774bcd830c7244aac16610f4a2bbd879cfb89a93dd7983a8b424babe8201d62845e2b904ed698455f1082655dd00286" 285 | }, 286 | { 287 | "name": "dotnet-sdk-win-x86.exe", 288 | "rid": "win-x86", 289 | "url": "https://download.visualstudio.microsoft.com/download/pr/982e7a87-d652-4db0-b64b-cb14eaf17564/f920534ef0bfac0f0e2553b0428e45fd/dotnet-sdk-2.2.207-win-x86.exe", 290 | "hash": "ce0a50585881d0345a232a3f40d99d4248c455157472525ade558bb93f222358ee79dde0786dcdf75b4923f55935d9d6aa8785c0129f44d713c8dee3f97c4195" 291 | }, 292 | { 293 | "name": "dotnet-sdk-win-x86.zip", 294 | "rid": "win-x86", 295 | "url": "https://download.visualstudio.microsoft.com/download/pr/1d1cc3a2-efb5-4810-8fcf-e6413945b4ad/e335d27e9ab47de259aa2f22db7a4e60/dotnet-sdk-2.2.207-win-x86.zip", 296 | "hash": "3f8d76e44a4f236d2c38b79620d4c4ab8e98f768774bf00ce3b3fad32762991f9c65bd16b5811218605b7f959a7fc7d492e17879370f4a58e0f7c15e0e603a56" 297 | } 298 | ] 299 | }, 300 | "sdks": [ 301 | { 302 | "version": "2.2.207", 303 | "version-display": "2.2.207", 304 | "runtime-version": "2.2.8", 305 | "vs-version": "", 306 | "vs-support": "Visual Studio 2019 (v16.0)", 307 | "csharp-version": "7.3", 308 | "fsharp-version": "4.5", 309 | "files": [ 310 | { 311 | "name": "dotnet-sdk-linux-arm.tar.gz", 312 | "rid": "linux-arm", 313 | "url": "https://download.visualstudio.microsoft.com/download/pr/fca1c415-b70c-4134-8844-ea947f410aad/901a86c12be90a67ec37cd0cc59d5070/dotnet-sdk-2.2.207-linux-arm.tar.gz", 314 | "hash": "a922b87fc1e433d489d6863fa3faca5a5eeb33f68104c5c4733ca8fbd187230715f6ce384ddbdaca501b1f42c87f590a9299b525be405214803bb1da3c4bbd1c" 315 | }, 316 | { 317 | "name": "dotnet-sdk-linux-arm64.tar.gz", 318 | "rid": "linux-arm64", 319 | "url": "https://download.visualstudio.microsoft.com/download/pr/18738093-b024-4353-96c2-4e1d2285a5e4/5e86ebbca79e71486aa2b18af0214ae9/dotnet-sdk-2.2.207-linux-arm64.tar.gz", 320 | "hash": "565fe5cbc2c388e54b3ee548d5b98e1fd85d920ceeeb5475a2bf2daa7f090fc925d8afef19b2b76973af439fbb749c6996711790287eafd588e4d916a016e84c" 321 | }, 322 | { 323 | "name": "dotnet-sdk-linux-musl-x64.tar.gz", 324 | "rid": "linux-musl-x64", 325 | "url": "https://download.visualstudio.microsoft.com/download/pr/c72122bd-38f5-4c98-b585-b8aaf57ecc6e/c89d7774a430e163d801753654f33972/dotnet-sdk-2.2.207-linux-musl-x64.tar.gz", 326 | "hash": "231118ba205b5d609263fc790851c65900aabf5830d492425849de89b7103f02012a302ce21960cb062426c5b8fd480e1316176a927bd287b08b7d19445f7224" 327 | }, 328 | { 329 | "name": "dotnet-sdk-linux-x64.tar.gz", 330 | "rid": "linux-x64", 331 | "url": "https://download.visualstudio.microsoft.com/download/pr/022d9abf-35f0-4fd5-8d1c-86056df76e89/477f1ebb70f314054129a9f51e9ec8ec/dotnet-sdk-2.2.207-linux-x64.tar.gz", 332 | "hash": "9d70b4a8a63b66da90544087199a0f681d135bf90d43ca53b12ea97cc600a768b0a3d2f824cfe27bd3228e058b060c63319cd86033be8b8d27925283f99de958" 333 | }, 334 | { 335 | "name": "dotnet-sdk-osx-gs-x64.pkg", 336 | "rid": "osx-x64", 337 | "url": "https://download.visualstudio.microsoft.com/download/pr/837aa87a-8160-4297-b6b7-eceb56b3ce48/74c42db19f2784ab172e27598eae7f4f/dotnet-sdk-2.2.207-osx-gs-x64.pkg", 338 | "hash": "3cf91804f2d0b7beb0830450f98cbd18125d1df72354b6a57668cca11a871a68d234f2d8a8a5fe86215b1f71584c22b9f75fc057365c55026da2979195894278" 339 | }, 340 | { 341 | "name": "dotnet-sdk-osx-x64.pkg", 342 | "rid": "osx-x64", 343 | "url": "https://download.visualstudio.microsoft.com/download/pr/cb2d65e1-ad90-4416-8e6a-3755f92ba39f/f498aca4950a038d6fc55cca75eca630/dotnet-sdk-2.2.207-osx-x64.pkg", 344 | "hash": "3cf91804f2d0b7beb0830450f98cbd18125d1df72354b6a57668cca11a871a68d234f2d8a8a5fe86215b1f71584c22b9f75fc057365c55026da2979195894278" 345 | }, 346 | { 347 | "name": "dotnet-sdk-osx-x64.tar.gz", 348 | "rid": "osx-x64", 349 | "url": "https://download.visualstudio.microsoft.com/download/pr/5b8d25c1-85e1-4b18-8d96-b14115586319/78ff638656c3a90324e810f8dd157422/dotnet-sdk-2.2.207-osx-x64.tar.gz", 350 | "hash": "d60d683851ba08a8f30acac8c635219223a6f11e1efe5ec7e64c4b1dca44f7e3d6122ecc0a4e97b8b57c2035e22be5e09f5f1642db6227bb8898654da057a7ae" 351 | }, 352 | { 353 | "name": "dotnet-sdk-rhel.6-x64.tar.gz", 354 | "rid": "rhel.6-x64", 355 | "url": "https://download.visualstudio.microsoft.com/download/pr/2b9ec838-2e6e-40cd-a57a-885e56904329/959135d11fd608afea316c01f73e9490/dotnet-sdk-2.2.207-rhel.6-x64.tar.gz", 356 | "hash": "64decac610d7fdda90e7a1236e155ddcc8bb35ee5fda8f1ebd7c97380eddff9638e08cf8d439bbc52bdedb223c70049441b448bda0b687b744b34b159630ef4b" 357 | }, 358 | { 359 | "name": "dotnet-sdk-win-arm.zip", 360 | "rid": "win-arm", 361 | "url": "https://download.visualstudio.microsoft.com/download/pr/4ce7496a-fa96-4fbd-9259-f5ad6f9fbcd4/7a4176c05032d8b28cb3a7e830876c22/dotnet-sdk-2.2.207-win-arm.zip", 362 | "hash": "263aa3de231de97268d75dadee94031f26ee0c3ed0da18ee87c53eba42138cf1384ff0869caee13f8a57441c4c5d415d8abe388bb3dee3294f5af2a9e7620ecb" 363 | }, 364 | { 365 | "name": "dotnet-sdk-win-gs-x64.exe", 366 | "rid": "", 367 | "url": "https://download.visualstudio.microsoft.com/download/pr/dfa5fe58-1542-4b4c-84bf-2aa44743c925/170740c73015a8c621bedab256fd8431/dotnet-sdk-2.2.207-win-gs-x64.exe", 368 | "hash": "721882a80632fb113dcd3b82a80f4be968a08b6f09a9c0513cef7464e5fae836b60b601e570289fc6a31d3765f6f66d81ec32d6e98e58098acb74d0a714eabb6" 369 | }, 370 | { 371 | "name": "dotnet-sdk-win-gs-x86.exe", 372 | "rid": "", 373 | "url": "https://download.visualstudio.microsoft.com/download/pr/d23f0125-64e3-4132-97c0-5beb671228f9/e68a5a74a1dbf73059efe007ae56a456/dotnet-sdk-2.2.207-win-gs-x86.exe", 374 | "hash": "ce0a50585881d0345a232a3f40d99d4248c455157472525ade558bb93f222358ee79dde0786dcdf75b4923f55935d9d6aa8785c0129f44d713c8dee3f97c4195" 375 | }, 376 | { 377 | "name": "dotnet-sdk-win-x64.exe", 378 | "rid": "win-x64", 379 | "url": "https://download.visualstudio.microsoft.com/download/pr/279de74e-f7e3-426b-94d8-7f31d32a129c/e83e8c4c49bcb720def67a5c8fe0d8df/dotnet-sdk-2.2.207-win-x64.exe", 380 | "hash": "721882a80632fb113dcd3b82a80f4be968a08b6f09a9c0513cef7464e5fae836b60b601e570289fc6a31d3765f6f66d81ec32d6e98e58098acb74d0a714eabb6" 381 | }, 382 | { 383 | "name": "dotnet-sdk-win-x64.zip", 384 | "rid": "win-x64", 385 | "url": "https://download.visualstudio.microsoft.com/download/pr/e0d4bd70-9dd2-40a3-9e6e-64af9721f3e3/2324e93d2152efd009f242a1723685c3/dotnet-sdk-2.2.207-win-x64.zip", 386 | "hash": "726f60e2cf82b7fbea97066dda318d468774bcd830c7244aac16610f4a2bbd879cfb89a93dd7983a8b424babe8201d62845e2b904ed698455f1082655dd00286" 387 | }, 388 | { 389 | "name": "dotnet-sdk-win-x86.exe", 390 | "rid": "win-x86", 391 | "url": "https://download.visualstudio.microsoft.com/download/pr/982e7a87-d652-4db0-b64b-cb14eaf17564/f920534ef0bfac0f0e2553b0428e45fd/dotnet-sdk-2.2.207-win-x86.exe", 392 | "hash": "ce0a50585881d0345a232a3f40d99d4248c455157472525ade558bb93f222358ee79dde0786dcdf75b4923f55935d9d6aa8785c0129f44d713c8dee3f97c4195" 393 | }, 394 | { 395 | "name": "dotnet-sdk-win-x86.zip", 396 | "rid": "win-x86", 397 | "url": "https://download.visualstudio.microsoft.com/download/pr/1d1cc3a2-efb5-4810-8fcf-e6413945b4ad/e335d27e9ab47de259aa2f22db7a4e60/dotnet-sdk-2.2.207-win-x86.zip", 398 | "hash": "3f8d76e44a4f236d2c38b79620d4c4ab8e98f768774bf00ce3b3fad32762991f9c65bd16b5811218605b7f959a7fc7d492e17879370f4a58e0f7c15e0e603a56" 399 | } 400 | ] 401 | }, 402 | { 403 | "version": "2.2.110", 404 | "version-display": "2.2.110", 405 | "runtime-version": "2.2.8", 406 | "vs-version": "", 407 | "vs-support": "Visual Studio 2017 (v15.9)", 408 | "csharp-version": "7.3", 409 | "fsharp-version": "4.5", 410 | "files": [ 411 | { 412 | "name": "dotnet-sdk-linux-arm.tar.gz", 413 | "rid": "linux-arm", 414 | "url": "https://download.visualstudio.microsoft.com/download/pr/8cbe9c20-2e88-43dc-8d9a-27da95e5a1e7/d580d095fc8d236d7db15336668d9173/dotnet-sdk-2.2.110-linux-arm.tar.gz", 415 | "hash": "7a4c26448216d8e4e1433c4070972f5314fe69c8f7b8f66993b0a60465282fbd6b6a9cd8de9da251982f55f24a5853bd400c6cbf5e4ed40213b80b62e541d8c5" 416 | }, 417 | { 418 | "name": "dotnet-sdk-linux-arm64.tar.gz", 419 | "rid": "linux-arm64", 420 | "url": "https://download.visualstudio.microsoft.com/download/pr/06413d6a-e12b-41fc-91cf-d88a6f97a5c1/5a32f67fe5ad0457309cf8e0fa52f2b8/dotnet-sdk-2.2.110-linux-arm64.tar.gz", 421 | "hash": "921ee8b9409a36ccc0d49fa90af68aa387bb0a7fbe7eea06c10b76cb2c53b81e08ce7767f4b18afdd4ce46194ca5e0de787b105a906f4da6c03dd5b284518063" 422 | }, 423 | { 424 | "name": "dotnet-sdk-linux-musl-x64.tar.gz", 425 | "rid": "linux-musl-x64", 426 | "url": "https://download.visualstudio.microsoft.com/download/pr/17b53621-992d-4805-9feb-93cc34662c5f/c83ef9c56200b4d333b18c48f9054437/dotnet-sdk-2.2.110-linux-musl-x64.tar.gz", 427 | "hash": "1dd6bedfa2151bb518eaaba8621035ddae94fc69a1053c3247de3aab044252e2d0979984520bd11dee4922cd58a03f6ba99b652fb1602b5cff9a6d3d22034fa5" 428 | }, 429 | { 430 | "name": "dotnet-sdk-linux-x64.tar.gz", 431 | "rid": "linux-x64", 432 | "url": "https://download.visualstudio.microsoft.com/download/pr/42f39f2f-3f24-4340-8c57-0a3133620c21/0a353696275b00cbddc9f60069867cfc/dotnet-sdk-2.2.110-linux-x64.tar.gz", 433 | "hash": "cd3bc601ccc45edf38cdcc254831b88539dd51f26bdafa2d74eebb09d20d19d745fe319a93c4290e3b74a7a5d8fe851773a748ef0f23f7997c76b26e74d0d94f" 434 | }, 435 | { 436 | "name": "dotnet-sdk-osx-gs-x64.pkg", 437 | "rid": "osx-x64", 438 | "url": "https://download.visualstudio.microsoft.com/download/pr/701d2e3d-4e06-44e1-a364-88772d946ddb/fe84d8921516ac6c7c2f6b039611ac29/dotnet-sdk-2.2.110-osx-gs-x64.pkg", 439 | "hash": "4cd219e117c642955a553fd3c2bd78b6e1163d4bd773bfdc2bd2e8f1fc9a0b90b6243edb2d9c13298e18900394522284961d9e9204a4a9913c91bd15cf6de206" 440 | }, 441 | { 442 | "name": "dotnet-sdk-osx-x64.pkg", 443 | "rid": "osx-x64", 444 | "url": "https://download.visualstudio.microsoft.com/download/pr/7db9e4c2-7118-4c13-8689-4193e4c91aed/a783f5cad3c017097bc123b478eee2a3/dotnet-sdk-2.2.110-osx-x64.pkg", 445 | "hash": "4cd219e117c642955a553fd3c2bd78b6e1163d4bd773bfdc2bd2e8f1fc9a0b90b6243edb2d9c13298e18900394522284961d9e9204a4a9913c91bd15cf6de206" 446 | }, 447 | { 448 | "name": "dotnet-sdk-osx-x64.tar.gz", 449 | "rid": "osx-x64", 450 | "url": "https://download.visualstudio.microsoft.com/download/pr/f2d70b94-7b76-49c7-917f-758e71135305/24dc05dad28e067500762516d4a8d514/dotnet-sdk-2.2.110-osx-x64.tar.gz", 451 | "hash": "866512de8a387d66b9518620ca1449bef61fcd8ca4978f2286d3d44de09670ba418bdb9d0a6d821f61e3f753996db66841e8ddaf53e5859ed0b767b6451534d6" 452 | }, 453 | { 454 | "name": "dotnet-sdk-rhel.6-x64.tar.gz", 455 | "rid": "rhel.6-x64", 456 | "url": "https://download.visualstudio.microsoft.com/download/pr/c7a67baf-9c6b-4fdf-8b58-c3e554c6802f/87fbc4a569b2c5ddca8c4933346ff56d/dotnet-sdk-2.2.110-rhel.6-x64.tar.gz", 457 | "hash": "25d68910b75aec0ba8fd038264aa641a8b8b89c1c6cb8871a69081d40ebfe9f79473e3d3efe64c75cdab7b50a4518da131a04e685c1c91b95f1c7ceac48216dd" 458 | }, 459 | { 460 | "name": "dotnet-sdk-win-arm.zip", 461 | "rid": "win-arm", 462 | "url": "https://download.visualstudio.microsoft.com/download/pr/c466f96a-d612-4f1c-9b4f-5bb3f658d5a7/38f300421101aa06bb58de9f8651de7e/dotnet-sdk-2.2.110-win-arm.zip", 463 | "hash": "3b938d4b46807fd84e62f1d8b20ecd3e89280e2f7867a4a510ef298b9eb29cfd524f332525ccd442a9d40c9bac438291e2601b305ac23f9f8fdcc2a023652009" 464 | }, 465 | { 466 | "name": "dotnet-sdk-win-gs-x64.exe", 467 | "rid": "", 468 | "url": "https://download.visualstudio.microsoft.com/download/pr/3e380085-9346-4710-9079-a7292981b1fd/3aeba734cf4d9d44e0fd8eea4af0673f/dotnet-sdk-2.2.110-win-gs-x64.exe", 469 | "hash": "d36edc2cc36e3f1a673cfddc4c5ccfd70806f56604995015678e17ab3ece7cc5a530b4f1dbb9e03f916c5cd0eabd13005219c25259d29528cb4efc3a03425623" 470 | }, 471 | { 472 | "name": "dotnet-sdk-win-gs-x86.exe", 473 | "rid": "", 474 | "url": "https://download.visualstudio.microsoft.com/download/pr/005b25fa-1626-4ea0-9605-c72d0a1786c7/6735c99bc12178f2db721b883582986c/dotnet-sdk-2.2.110-win-gs-x86.exe", 475 | "hash": "365de8c85f22977d3fda98fe02d15fc3c847b43ce1b447fb9028c062a86c541fd668a48d50633b1ce8e3469b7d219ac68cff33d8b3b064325c66d021d30f4b3e" 476 | }, 477 | { 478 | "name": "dotnet-sdk-win-x64.exe", 479 | "rid": "win-x64", 480 | "url": "https://download.visualstudio.microsoft.com/download/pr/78969d24-673f-4515-9544-1dd5bcda5411/beda84891a9a085cecd9bff855fdd082/dotnet-sdk-2.2.110-win-x64.exe", 481 | "hash": "d36edc2cc36e3f1a673cfddc4c5ccfd70806f56604995015678e17ab3ece7cc5a530b4f1dbb9e03f916c5cd0eabd13005219c25259d29528cb4efc3a03425623" 482 | }, 483 | { 484 | "name": "dotnet-sdk-win-x64.zip", 485 | "rid": "win-x64", 486 | "url": "https://download.visualstudio.microsoft.com/download/pr/246c4b65-5a51-4294-8ce3-181aefd60e94/5169a50a00d4c56abe20ef1c1325ceff/dotnet-sdk-2.2.110-win-x64.zip", 487 | "hash": "4b702194aa19a3e9659733cae3e32ae1db595924ddeb4d7fb81736242b30c91ed2444b7bc2b588ff4e6a79ec184fd476e0c9a49b37b09bc93085a5b5dcdadeef" 488 | }, 489 | { 490 | "name": "dotnet-sdk-win-x86.exe", 491 | "rid": "win-x86", 492 | "url": "https://download.visualstudio.microsoft.com/download/pr/1af1c7ed-74dc-4772-8e8c-146e54a47b2f/162c9a7e45ea5080a3f4085d8684b7b9/dotnet-sdk-2.2.110-win-x86.exe", 493 | "hash": "365de8c85f22977d3fda98fe02d15fc3c847b43ce1b447fb9028c062a86c541fd668a48d50633b1ce8e3469b7d219ac68cff33d8b3b064325c66d021d30f4b3e" 494 | }, 495 | { 496 | "name": "dotnet-sdk-win-x86.zip", 497 | "rid": "win-x86", 498 | "url": "https://download.visualstudio.microsoft.com/download/pr/513e3f1e-2ff8-48d9-bc2a-0e60b19eca72/4a780ab4d4fe4ce5e7777d25d973e1b7/dotnet-sdk-2.2.110-win-x86.zip", 499 | "hash": "77072d6eabe0181e7f1ad2dbf95b4d37ffdb8189049785df24d2842e28ce950c9ab52f08b45aa0443c553cb67aa0ef1ed139ba0c4a8364671574a8166d6af482" 500 | } 501 | ] 502 | } 503 | ], 504 | "aspnetcore-runtime": { 505 | "version": "2.2.8", 506 | "version-display": "2.2.8", 507 | "version-aspnetcoremodule": [ 508 | "12.2.19109.5" 509 | ], 510 | "vs-version": "", 511 | "files": [ 512 | { 513 | "name": "aspnetcore-runtime-linux-arm.tar.gz", 514 | "rid": "linux-arm", 515 | "url": "https://download.visualstudio.microsoft.com/download/pr/9fcb0171-11d7-40e6-a2e8-2357813bf6bd/becdd52523d5a6782ded8febd2c487a0/aspnetcore-runtime-2.2.8-linux-arm.tar.gz", 516 | "hash": "fab9a1d9d101716337bb153af2ac36429fc387230c0c0bf2d639b31fb7f787bc8dbaaa31f28f9cbe69f117ffc78d8ddb5a5968da0e77785d3c12c6814ef50f7b" 517 | }, 518 | { 519 | "name": "aspnetcore-runtime-linux-musl-x64.tar.gz", 520 | "rid": "linux-musl-x64", 521 | "url": "https://download.visualstudio.microsoft.com/download/pr/981063ac-98de-4622-9da7-c9df5a2547b5/ebc5edcac0759ad87f478c92f36a9a0c/aspnetcore-runtime-2.2.8-linux-musl-x64.tar.gz", 522 | "hash": "139d13a067d91b13f90f488cbb36517a0c629e803e15edbb4fb85443641184c4efd8c83110e32c1a1cc578b95f25e38056e680830288665491b568ea3944db3f" 523 | }, 524 | { 525 | "name": "aspnetcore-runtime-linux-x64.tar.gz", 526 | "rid": "linux-x64", 527 | "url": "https://download.visualstudio.microsoft.com/download/pr/e716faa4-345c-45a7-bd1f-860cdf422b75/fa8e57167f3bd4bf20b8b60992cf184f/aspnetcore-runtime-2.2.8-linux-x64.tar.gz", 528 | "hash": "954072376698be69acb7e277df2c243f931e10529def21dcbf9ce277609b30d462126bf8b8b3cab36476bec3d63a927b8e44e59e4d4cade23eef45956fba1ffd" 529 | }, 530 | { 531 | "name": "aspnetcore-runtime-osx-x64.tar.gz", 532 | "rid": "osx-x64", 533 | "url": "https://download.visualstudio.microsoft.com/download/pr/e73aa371-90fd-488c-805a-649a324ea853/611a4a5bd4da4a950387eea27e0b588a/aspnetcore-runtime-2.2.8-osx-x64.tar.gz", 534 | "hash": "1c969c6cbad8276ae19a64448105d627a43b97f26d4bc65165afecbea684f9f370969be00070fda065e0cd88842f4280e54b181bb32c608f307e68507fd4607c" 535 | }, 536 | { 537 | "name": "aspnetcore-runtime-win-arm.zip", 538 | "rid": "win-arm", 539 | "url": "https://download.visualstudio.microsoft.com/download/pr/344af0cd-5fd8-427b-a438-b94d1973fdcc/54291ccaa6049a63a811bb52d0eb94e6/aspnetcore-runtime-2.2.8-win-arm.zip", 540 | "hash": "ed0152644d9270010c0470c32e5774c8f542f70bdf09f66665c4c1640c379b3cc4ba38d33ef170e16f606257faa5b696562e3575eb6f372865780b851b39e59f" 541 | }, 542 | { 543 | "name": "aspnetcore-runtime-win-x64.exe", 544 | "rid": "win-x64", 545 | "url": "https://download.visualstudio.microsoft.com/download/pr/068d05e8-a0cf-4584-9422-b77f34f1e98e/de70e92721a05c6148619993cbf1376b/aspnetcore-runtime-2.2.8-win-x64.exe", 546 | "hash": "18e3b7fcb645aa5d476d9b06491013b533ba1653015d8dbf90001c917ce48a8a6e93b3d5cea25e38965f5a024f836ef8b99e04892b043b4da850316111d60514" 547 | }, 548 | { 549 | "name": "aspnetcore-runtime-win-x64.zip", 550 | "rid": "win-x64", 551 | "url": "https://download.visualstudio.microsoft.com/download/pr/acf18dce-9e6a-4a39-a1c7-e503c09e4086/f2c6e01ef9bb44c4beb905d82bb7ebac/aspnetcore-runtime-2.2.8-win-x64.zip", 552 | "hash": "990c1c0e1db6f59b213f4d94c81c212dc39cbbe6a9ae2a0183c1f7947b447e614ac266d78785d0f0fc0451d32e3d3f0b3e5f7415a52d5c7f2e58db38aedda1d0" 553 | }, 554 | { 555 | "name": "aspnetcore-runtime-win-x86.exe", 556 | "rid": "win-x86", 557 | "url": "https://download.visualstudio.microsoft.com/download/pr/53eefcbe-83a9-42ce-b529-9ef7672c5508/b3e9c4afc183b447044703dbc8edf71d/aspnetcore-runtime-2.2.8-win-x86.exe", 558 | "hash": "34c648e841ec8a016990d9dab30eac3bf26b0bca1ba2f16b807cb15abd028d951db61be8b1a5f1278ad6a63469908aa7e37dc75717556b660e2fe07c5d4d6cc7" 559 | }, 560 | { 561 | "name": "aspnetcore-runtime-win-x86.zip", 562 | "rid": "win-x86", 563 | "url": "https://download.visualstudio.microsoft.com/download/pr/295249c5-35e1-4688-a9f4-9096989d70c1/c6cd5d342e754d2cff6f61645c4e84ae/aspnetcore-runtime-2.2.8-win-x86.zip", 564 | "hash": "a82014bc9ec924668115351d96c1c64754ffdd31ae3bc080ab7b18fd072dc4c127256cb2442b7977cc13014208793bcb2340e575d4af5ac9d12f0c12fe275892" 565 | }, 566 | { 567 | "name": "dotnet-hosting-win.exe", 568 | "rid": "win-x86_x64", 569 | "url": "https://download.visualstudio.microsoft.com/download/pr/ba001109-03c6-45ef-832c-c4dbfdb36e00/e3413f9e47e13f1e4b1b9cf2998bc613/dotnet-hosting-2.2.8-win.exe", 570 | "hash": "1b3177fc65ec343f641b8ffdc2a0e925e322e90ed44dcb5c6d3982a370dd7b56f7fcc362dad3a4b7e2db4f0fe6878b7e7448fc7f41dfe01302c7484434691f6b" 571 | } 572 | ] 573 | }, 574 | "windowsdesktop": { 575 | "version": "2.2.8", 576 | "version-display": "2.2.8", 577 | "files": [] 578 | }, 579 | "symbols": { 580 | "version": "2.2.8", 581 | "files": [] 582 | } 583 | } 584 | } 585 | } */ 586 | -------------------------------------------------------------------------------- /JsonNodeSummary.cs: -------------------------------------------------------------------------------- 1 | // .Net6 Console Template 2 | string jsonString = 3 | @" 4 | { 5 | ""Date"": ""2019-08-01T00:00:00"", 6 | ""Temperature"": 25, 7 | ""Summary"": ""Hot"", 8 | ""DatesAvailable"": [ 9 | ""2019-08-01T00:00:00"", 10 | ""2019-08-02T00:00:00"" 11 | ], 12 | ""TemperatureRanges"": { 13 | ""Cold"": { 14 | ""High"": 20, 15 | ""Low"": -10 16 | }, 17 | ""Hot"": { 18 | ""High"": 60, 19 | ""Low"": 20 20 | } 21 | } 22 | } 23 | "; 24 | 25 | var options = new JsonSerializerOptions 26 | { 27 | WriteIndented = true, 28 | PropertyNamingPolicy = JsonNamingPolicy.CamelCase, 29 | DictionaryKeyPolicy = JsonNamingPolicy.CamelCase, 30 | }; 31 | 32 | JsonNode? jsonNode = 33 | await Task.Run( () => JsonNode.Parse(jsonString)); 34 | 35 | // Console.WriteLine(jsonNode?.ToJsonString(options)); 36 | // JsonNode is mutable! 37 | jsonNode!["TemperatureRanges"] = new JsonObject() 38 | { 39 | ["Chill"] = new JsonObject() 40 | { 41 | ["High"] = 22, 42 | ["Low"] = 5 43 | } 44 | }; 45 | 46 | JsonNode? temperature = jsonNode?["TemperatureRanges"]; 47 | // Console.WriteLine(temperature?.ToJsonString()); 48 | 49 | JsonNode? datesAvalilable = jsonNode?["DatesAvailable"]; 50 | JsonNode? firstElement = 51 | datesAvalilable!.GetType() == typeof(JsonArray) ? datesAvalilable?[0] : default(JsonNode) ; 52 | // Console.WriteLine(firstElement?.GetValue()); 53 | 54 | var jsonNodeOptions = new JsonNodeOptions() 55 | { 56 | PropertyNameCaseInsensitive = true 57 | }; 58 | 59 | var jObject = new JsonObject(jsonNodeOptions) 60 | { 61 | ["Date"] = new DateTime(2022, 1, 1), 62 | ["RoomTemperature"] = 21, 63 | ["Summary"] = "Moist", 64 | ["DatesAvailable"] = 65 | new JsonArray(new DateTime(2019, 5, 5), new DateTime(2020, 4, 4)), 66 | ["TemperatureRanges"] = new JsonObject 67 | { 68 | ["Cold"] = new JsonObject 69 | { 70 | ["High"] = 20, 71 | ["Low"] = -10 72 | }, 73 | 74 | ["Warm"] = new JsonObject 75 | { 76 | ["High"] = 40, 77 | ["Low"] = 20 78 | } 79 | }, 80 | 81 | ["Location"] = new JsonObject 82 | { 83 | ["HighAltitude"] = new JsonArray(435,22,11), 84 | ["LowAltitude"] = new JsonArray(322,32,11) 85 | }, 86 | 87 | ["KeyWords"] = new JsonArray("Cool", "Windy", "Moist") 88 | }; 89 | 90 | // add a new value to TemperatureRanges 91 | jObject["TemperatureRanges"]!["HeatWave"] = new JsonObject 92 | { 93 | ["High"] = 100, 94 | ["Low"] = 40 95 | }; 96 | 97 | jObject.Remove("Date"); 98 | //Console.WriteLine(jObject.ToJsonString(options)); 99 | 100 | 101 | await using (var stream = new MemoryStream()) 102 | { 103 | await using (var jsonWriter = new Utf8JsonWriter(stream)) 104 | { 105 | JsonObject? tempRangesObject = jObject["TemperatureRanges"]?.AsObject(); 106 | 107 | // write a small portion of jObject to stream 108 | tempRangesObject?.WriteTo(jsonWriter); 109 | await jsonWriter.FlushAsync(); 110 | 111 | stream.Seek(0, SeekOrigin.Begin); 112 | 113 | TemperatureRanges temperatureRanges = 114 | (await JsonSerializer. 115 | DeserializeAsync(stream))!; 116 | 117 | 118 | Console.WriteLine($"Hot.High = {temperatureRanges["Warm"].High}"); 119 | 120 | JsonArray? jArray = jObject["DatesAvailable"]?.AsArray(); 121 | Console.WriteLine($"First Date = {jArray?[0]?.GetValue()}"); 122 | 123 | } 124 | } 125 | 126 | 127 | 128 | public class TemperatureRanges : Dictionary 129 | { 130 | } 131 | 132 | public class HighLowTemps 133 | { 134 | public int High { get; set; } 135 | public int Low { get; set; } 136 | } 137 | -------------------------------------------------------------------------------- /JsonSerializerSummary.cs: -------------------------------------------------------------------------------- 1 | async Task Main() 2 | { 3 | var store = new WareHouse() 4 | { 5 | BrandName = @"Muggy\", 6 | Amount = 1200, 7 | 8 | Price = new Dictionary 9 | { 10 | ["Max"] = 1244.33442, 11 | ["Min"] = 988.4323 12 | }, 13 | 14 | // Fahrenheit or Celsius 15 | Temp = new Temperature(80,celsius:false), 16 | 17 | PurchaseDate = new DateTime(2021,10,29), 18 | TemperatureRanges = new Dictionary 19 | { 20 | ["Cold"] = new HighLowTempCelcius { High = 20, Low = -10 }, 21 | ["Hot"] = new HighLowTempCelcius { High = 35, Low = 21 }, 22 | ["Humid"] = new HighLowTempCelcius { High = 60, Low = 36 }, 23 | }, 24 | 25 | // JsonElement issue has been solved by 26 | // new DictionaryStringObjectJsonConverter() implementation 27 | DummyElement = new Dictionary 28 | { 29 | ["Bool"] = true, 30 | ["Null"] = null, 31 | ["Text"] = "String", 32 | ["Double"] = 332.44, 33 | ["Integer"] = 342 34 | }, 35 | 36 | ItemCategory = Category.Home_Gadget 37 | }; 38 | 39 | var jsonOptions = new JsonSerializerOptions(JsonSerializerDefaults.Web) 40 | { 41 | WriteIndented = true, 42 | IgnoreReadOnlyProperties = true, 43 | 44 | //Custom Property Naming Policy 45 | PropertyNamingPolicy = new LowerCaseNamingPolicy(), 46 | 47 | // PropertyNamingPolicy = JsonNamingPolicy.CamelCase: built-in policy 48 | 49 | // The camel case naming policy for dictionary keys 50 | // applies to serialization only. 51 | // If you deserialize a dictionary, the keys will match the JSON file 52 | // even if you specify JsonNamingPolicy.CamelCase for the DictionaryKeyPolicy. 53 | DictionaryKeyPolicy = new UpperCaseNamingPolicy(), 54 | 55 | //Allows comments within the JSON input and ignores them. 56 | //The Utf8JsonReader behaves as if no comments are present. 57 | ReadCommentHandling = JsonCommentHandling.Skip, 58 | AllowTrailingCommas = true, 59 | DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingDefault, 60 | 61 | // Writes numbers in string notation as "12" 62 | NumberHandling = 63 | JsonNumberHandling.AllowReadingFromString | 64 | JsonNumberHandling.WriteAsString, 65 | 66 | Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping, 67 | // by default enums are serialized as numbers 68 | // by the help of JsonStringEnumConverter() 69 | // this behaviour may change. 70 | Converters = 71 | { 72 | new JsonStringEnumConverter(), //JsonNamingPolicy is optional 73 | new DateTimeOnlyDateConverter_Turkey(), 74 | new DictionaryStringObjectJsonConverter() 75 | } 76 | }; 77 | 78 | await using (var stream = new MemoryStream()) 79 | { 80 | 81 | // Serialize 82 | await JsonSerializer. 83 | SerializeAsync(stream, store, jsonOptions); 84 | 85 | stream.Seek(0,SeekOrigin.Begin); 86 | 87 | using var streamReader = new StreamReader(stream,Encoding.UTF8, 88 | false,stream.Capacity); 89 | 90 | var script = await streamReader.ReadToEndAsync(); 91 | script.Dump(); 92 | 93 | //Deserialize 94 | stream.Seek(0,SeekOrigin.Begin); 95 | 96 | WareHouse wareObject = await JsonSerializer. 97 | DeserializeAsync(stream,jsonOptions); 98 | 99 | wareObject.Dump(); 100 | } 101 | } 102 | 103 | 104 | public class WareHouse : IStorage, ITempConditions 105 | { 106 | [JsonIgnore] 107 | public int ItemId { get; } 108 | public string BrandName { get; set; } 109 | public double Amount { get; set; } 110 | 111 | [JsonConverter(typeof(RoundFractionConverter))] 112 | public Dictionary Price {get;set;} 113 | 114 | public Dictionary DummyElement {get;set;} 115 | 116 | public DateTime PurchaseDate { get; set; } 117 | public Dictionary TemperatureRanges {get;set;} 118 | 119 | [JsonPropertyName("KeyWords")] // overrides JsonNamingPolicy.CamelCase 120 | public string[] TempKeyWords => ITempConditions.DefaultTempKeyWords; 121 | 122 | [JsonInclude] // include fields, except static, const ones 123 | public byte OptimalTemp = 22; 124 | public Category ItemCategory {get;set;} 125 | public string ItemCategoryString(Category category) 126 | { 127 | return category switch 128 | { 129 | Category.Tool => nameof(Category.Tool), 130 | Category.Hygene => nameof(Category.Hygene), 131 | Category.Home_Gadget => nameof(Category.Home_Gadget), 132 | Category.Food => nameof(Category.Food), 133 | Category.Electronic_Material => nameof(Category.Electronic_Material), 134 | Category.Car_Spare_Part => nameof(Category.Car_Spare_Part), 135 | Category.Bike_Spare_Part => nameof(Category.Bike_Spare_Part), 136 | _ => nameof(Category.None) 137 | }; 138 | } 139 | 140 | public Temperature Temp {get;set;} 141 | } 142 | 143 | public enum Category 144 | { 145 | None, 146 | Food, 147 | Home_Gadget, 148 | Tool, 149 | Electronic_Material, 150 | Car_Spare_Part, 151 | Bike_Spare_Part, 152 | Hygene 153 | } 154 | 155 | interface IStorage 156 | { 157 | protected static readonly short SmallSize = 30_000; 158 | protected static readonly int MidSize = 500_000; 159 | protected static readonly int LargeSize = 1_000_000; 160 | 161 | public int ItemId { get; } 162 | public string BrandName { get; set; } 163 | public double Amount { get; set; } 164 | public DateTime PurchaseDate { get; set; } 165 | } 166 | 167 | interface ITempConditions 168 | { 169 | public Dictionary TemperatureRanges { get; set; } 170 | public Temperature Temp {get;set;} 171 | protected static string[] DefaultTempKeyWords => new[] { "Cold", "Humid", "Hot"}; 172 | } 173 | 174 | public struct HighLowTempCelcius 175 | { 176 | public int High { get; init; } 177 | public int Low { get; init; } 178 | } 179 | 180 | //Adding a Custom Property Naming Policy 181 | public class LowerCaseNamingPolicy : JsonNamingPolicy 182 | { 183 | public override string ConvertName(string name) => name.ToLower(); 184 | } 185 | 186 | // Dictionay Key Policy 187 | public class UpperCaseNamingPolicy : JsonNamingPolicy 188 | { 189 | public override string ConvertName(string name) => name.ToUpper(); 190 | } 191 | 192 | // [JsonConverter] applied to a property. 193 | // A converter added to the Converters collection. 194 | // [JsonConverter] applied to a custom value type or POCO. 195 | [JsonConverter(typeof(TemperatureConverter))] 196 | public struct Temperature 197 | { 198 | public Temperature(double degrees, bool celsius) 199 | { 200 | Degrees = degrees; 201 | IsCelsius = celsius; 202 | Celcius = celsius ? degrees : Math.Round((degrees - 32)/1.8,2); 203 | } 204 | 205 | public double Degrees { get;} 206 | public double Celcius { get;} 207 | public bool IsCelsius { get; } 208 | public bool IsFahrenheit => !IsCelsius; 209 | 210 | public override string ToString() => 211 | $"{Degrees}{(IsCelsius ? "C" : "F")}"; 212 | 213 | public static Temperature Parse(string input) 214 | { 215 | double degrees = int.Parse(input[..^1]); 216 | bool celsius = input[^1] == 'C'; 217 | 218 | return new Temperature(degrees, celsius); 219 | } 220 | } 221 | 222 | public class TemperatureConverter : JsonConverter 223 | { 224 | public override Temperature Read( 225 | ref Utf8JsonReader reader, 226 | Type typeToConvert, 227 | JsonSerializerOptions options) => 228 | Temperature.Parse(reader.GetString()); 229 | 230 | 231 | public override void Write( 232 | Utf8JsonWriter writer, 233 | Temperature temperature, 234 | JsonSerializerOptions options) => 235 | writer.WriteStringValue(temperature.ToString()); 236 | } 237 | 238 | public class DateTimeOnlyDateConverter_Turkey : JsonConverter 239 | { 240 | public override DateTime 241 | Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) 242 | { 243 | // struct can be assigned by assignment 244 | 245 | CultureInfo culture = new CultureInfo("tr-TR"); 246 | 247 | if (typeToConvert == typeof(DateTime)) 248 | { 249 | return DateTime.Parse(reader.GetString(), culture); 250 | } 251 | 252 | return new DateTime(); 253 | } 254 | 255 | public override void 256 | Write(Utf8JsonWriter writer, DateTime value, JsonSerializerOptions options) 257 | { 258 | var year = value.Year; 259 | var month = value.Month; 260 | var day = value.Day; 261 | 262 | var date = $"{day}/{month}/{year}"; // DateTime format in Turkey 263 | writer.WriteStringValue(date); 264 | } 265 | } 266 | 267 | public class RoundFractionConverter : JsonConverter> 268 | { 269 | public override Dictionary 270 | Read(ref Utf8JsonReader reader, 271 | Type typeToConvert, JsonSerializerOptions options) 272 | { 273 | 274 | if (reader.TokenType != JsonTokenType.StartObject) 275 | { 276 | throw new JsonException($"JsonTokenType was of type {reader.TokenType}, only objects are supported"); 277 | } 278 | 279 | var dictionary = new Dictionary(); 280 | 281 | while (reader.Read()) 282 | { 283 | if (reader.TokenType == JsonTokenType.EndObject) 284 | { 285 | return dictionary; 286 | } 287 | 288 | if (reader.TokenType != JsonTokenType.PropertyName) 289 | { 290 | throw new JsonException("JsonTokenType was not PropertyName"); 291 | } 292 | 293 | var propertyName = reader.GetString(); 294 | 295 | if (string.IsNullOrWhiteSpace(propertyName)) 296 | { 297 | throw new JsonException("Failed to get property name"); 298 | } 299 | 300 | reader.Read(); 301 | dictionary.Add(propertyName, GetRoundDictValue(ref reader, options)); 302 | } 303 | 304 | return dictionary; 305 | } 306 | 307 | public override void 308 | Write(Utf8JsonWriter writer, 309 | Dictionary value, JsonSerializerOptions options) 310 | { 311 | writer.WriteStartObject(); 312 | writer.WriteNumber("Max",Math.Round(value["Max"],2)); 313 | writer.WriteNumber("Min",Math.Round(value["Min"],2)); 314 | writer.WriteEndObject(); 315 | 316 | } 317 | 318 | private double 319 | GetRoundDictValue(ref Utf8JsonReader reader, JsonSerializerOptions options) 320 | { 321 | Utf8JsonReader readerClone = reader; 322 | 323 | if(readerClone.TokenType == JsonTokenType.Number) 324 | { 325 | double value = readerClone.GetDouble(); 326 | return Math.Round(value,2); 327 | } 328 | 329 | return default(double); 330 | } 331 | } 332 | 333 | public class DictionaryStringObjectJsonConverter : JsonConverter> 334 | { 335 | public override Dictionary 336 | Read(ref Utf8JsonReader reader, 337 | Type typeToConvert, JsonSerializerOptions options) 338 | { 339 | 340 | if (reader.TokenType != JsonTokenType.StartObject) 341 | { 342 | throw new JsonException($"JsonTokenType was of type {reader.TokenType}, only objects are supported"); 343 | } 344 | 345 | var dictionary = new Dictionary(); 346 | 347 | while (reader.Read()) 348 | { 349 | if (reader.TokenType == JsonTokenType.EndObject) 350 | { 351 | return dictionary; 352 | } 353 | 354 | if (reader.TokenType != JsonTokenType.PropertyName) 355 | { 356 | throw new JsonException("JsonTokenType was not PropertyName"); 357 | } 358 | 359 | var propertyName = reader.GetString(); 360 | 361 | if (string.IsNullOrWhiteSpace(propertyName)) 362 | { 363 | throw new JsonException("Failed to get property name"); 364 | } 365 | 366 | reader.Read(); 367 | dictionary.Add(propertyName, ExtractValue(ref reader, options)); 368 | } 369 | 370 | return dictionary; 371 | } 372 | 373 | public override void Write(Utf8JsonWriter writer, Dictionary value, JsonSerializerOptions options) 374 | { 375 | writer.WriteStartObject(); 376 | 377 | foreach (var key in value.Keys) 378 | { 379 | HandleValue(writer, key, value[key]); 380 | } 381 | 382 | writer.WriteEndObject(); 383 | } 384 | 385 | private static void HandleValue(Utf8JsonWriter writer, string key, object objectValue) 386 | { 387 | if (key != null) 388 | writer.WritePropertyName(key); 389 | 390 | switch (objectValue) 391 | { 392 | case string stringValue: 393 | writer.WriteStringValue(stringValue); 394 | break; 395 | case DateTime dateTime: 396 | writer.WriteStringValue(dateTime); 397 | break; 398 | case long longValue: 399 | writer.WriteNumberValue(longValue); 400 | break; 401 | case int intValue: 402 | writer.WriteNumberValue(intValue); 403 | break; 404 | case float floatValue: 405 | writer.WriteNumberValue(floatValue); 406 | break; 407 | case double doubleValue: 408 | writer.WriteNumberValue(doubleValue); 409 | break; 410 | case decimal decimalValue: 411 | writer.WriteNumberValue(decimalValue); 412 | break; 413 | case bool boolValue: 414 | writer.WriteBooleanValue(boolValue); 415 | break; 416 | case Dictionary dict: 417 | writer.WriteStartObject(); 418 | foreach (var item in dict) 419 | { 420 | HandleValue(writer, item.Key, item.Value); 421 | } 422 | writer.WriteEndObject(); 423 | break; 424 | case object[] array: 425 | writer.WriteStartArray(); 426 | foreach (var item in array) 427 | { 428 | HandleValue(writer, item); 429 | } 430 | writer.WriteEndArray(); 431 | break; 432 | default: 433 | writer.WriteNullValue(); 434 | break; 435 | } 436 | } 437 | 438 | private static void HandleValue(Utf8JsonWriter writer, object value) 439 | { 440 | HandleValue(writer, null, value); 441 | } 442 | 443 | private object ExtractValue(ref Utf8JsonReader reader, JsonSerializerOptions options) 444 | { 445 | Utf8JsonReader readerClone = reader; 446 | 447 | switch (readerClone.TokenType) 448 | { 449 | case JsonTokenType.String: 450 | 451 | if (readerClone.TryGetDateTime(out var date)) 452 | return date; 453 | 454 | return readerClone.GetString(); 455 | 456 | case JsonTokenType.False: 457 | return false; 458 | case JsonTokenType.True: 459 | return true; 460 | case JsonTokenType.Null: 461 | return null; 462 | case JsonTokenType.Number: 463 | 464 | if (readerClone.TryGetInt64(out var result)) 465 | return result; 466 | 467 | return readerClone.GetDecimal(); 468 | 469 | case JsonTokenType.StartObject: 470 | return Read(ref readerClone, null, options); 471 | case JsonTokenType.StartArray: 472 | 473 | var list = new List(); 474 | while (readerClone.Read() && readerClone.TokenType != JsonTokenType.EndArray) 475 | list.Add(ExtractValue(ref readerClone, options)); 476 | 477 | return list; 478 | 479 | default: 480 | throw new JsonException($"'{readerClone.TokenType}' is not supported"); 481 | } 482 | } 483 | } 484 | 485 | 486 | 487 | 488 | // HttpClient GetFromJsonAsync(requestUri) 489 | namespace HttpClientExtensionMethods 490 | { 491 | public class User 492 | { 493 | public int Id { get; set; } 494 | public string Name { get; set; } 495 | public string Username { get; set; } 496 | public string Email { get; set; } 497 | } 498 | 499 | public class Program 500 | { 501 | public static async Task Main() 502 | { 503 | using HttpClient client = new() 504 | { 505 | BaseAddress = new Uri("https://jsonplaceholder.typicode.com") 506 | }; 507 | 508 | // Get the user information. 509 | User user = await client.GetFromJsonAsync("users/7"); 510 | Console.WriteLine($"Id: {user.Id}"); 511 | Console.WriteLine($"Name: {user.Name}"); 512 | Console.WriteLine($"Username: {user.Username}"); 513 | Console.WriteLine($"Email: {user.Email}"); 514 | 515 | // Post a new user. 516 | HttpResponseMessage response = 517 | await client.PostAsJsonAsync("users", user); 518 | Console.WriteLine( 519 | $"{(response.IsSuccessStatusCode ? "Success" : "Error")}" 520 | + $"- {response.StatusCode}"); 521 | } 522 | } 523 | } 524 | -------------------------------------------------------------------------------- /JsonWriterSummary.cs: -------------------------------------------------------------------------------- 1 | async Task Main() 2 | { 3 | 4 | var encodeSettings = new TextEncoderSettings(); 5 | encodeSettings.AllowCharacters('\u0436', '\u0430'); 6 | encodeSettings.AllowRange(UnicodeRanges.BasicLatin); 7 | 8 | var options = new JsonWriterOptions 9 | { 10 | Indented = true, 11 | Encoder = JavaScriptEncoder.Create(UnicodeRanges.BasicLatin,UnicodeRanges.Arabic) 12 | 13 | //To minimize escaping you can use JavaScriptEncoder.UnsafeRelaxedJsonEscaping 14 | //Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping 15 | 16 | // An alternative is to specify individual characters that 17 | // you want to allow through without being escaped. 18 | // The following example serializes only the first two characters of жарко: 19 | //Encoder = JavaScriptEncoder.Create(encodeSettings) 20 | }; 21 | 22 | // Provides methods to transform UTF-8 23 | // or UTF-16 encoded text into a form that is suitable for JSON. 24 | var jsonEncodedText = JsonEncodedText. 25 | Encode("sampleArray",JavaScriptEncoder.UnsafeRelaxedJsonEscaping); 26 | 27 | 28 | await using (var stream = new MemoryStream()) 29 | { 30 | await using (var writer = new Utf8JsonWriter(stream, options)) 31 | { 32 | writer.WriteStartObject(); 33 | writer.WriteString("start-date", DateTimeOffset.UtcNow); 34 | writer.WriteNumber("array-length", 2); 35 | writer.WriteBoolean("is-still-valid",true); 36 | 37 | writer.WriteCommentValue("sample arrays are great!"); 38 | writer.WriteStartArray(jsonEncodedText.EncodedUtf8Bytes); 39 | writer.WriteStartObject(); 40 | writer.WriteString("name", "Ahmet"); 41 | writer.WriteNumber("age", 14); 42 | writer.WriteEndObject(); 43 | 44 | writer.WriteStartObject(); 45 | writer.WriteString("name", "Elif"); 46 | writer.WriteNumber("age", 11); 47 | writer.WriteEndObject(); 48 | 49 | writer.WriteCommentValue("Array Values"); 50 | // boolean in a json array 51 | writer.WriteBooleanValue(false); 52 | // null in a json array 53 | writer.WriteNullValue(); 54 | // string value in a json array 55 | writer.WriteStringValue("test string value"); 56 | // number value in a json array 57 | writer.WriteNumberValue(999); 58 | 59 | writer.WriteEndArray(); 60 | 61 | writer.WriteNull("nullProperty"); 62 | 63 | writer.WriteEndObject(); 64 | await writer.FlushAsync(); 65 | } 66 | 67 | // store it to a file 68 | using var fileStream = File.Create(@"C:\Users\fenko\Desktop\sample.json"); 69 | await fileStream.WriteAsync(stream.ToArray()); 70 | } 71 | } 72 | 73 | // OUTPUT: 74 | 75 | //{ 76 | // "start-date": "2021-11-10T12:38:21.2030153+00:00", 77 | // "array-length": 2, 78 | // "is-still-valid": true 79 | // /*sample arrays are great!*/, 80 | // "sampleArray": [ 81 | // { 82 | // "name": "Ahmet", 83 | // "age": 14 84 | // }, 85 | // { 86 | // "name": "Elif", 87 | // "age": 11 88 | // 89 | // } 90 | // /*Array Values*/, 91 | // false, 92 | // null, 93 | // "test string value", 94 | // 999 95 | // ], 96 | // "nullProperty": null 97 | //} 98 | 99 | 100 | 101 | -------------------------------------------------------------------------------- /KestrelWebHostBuilder.cs: -------------------------------------------------------------------------------- 1 | public class Program 2 | { 3 | public static void Main(string[] args) 4 | { 5 | new WebHostBuilder() 6 | .UseContentRoot(Directory.GetCurrentDirectory()) 7 | .UseKestrel() 8 | .UseIISIntegration() 9 | .UseStartup() 10 | .ConfigureKestrel((context, serverOptions) => 11 | { 12 | // setup for HTTP/2 13 | serverOptions.ConfigureHttpsDefaults(conAdapter => conAdapter.SslProtocols = System.Security.Authentication.SslProtocols.Tls12); 14 | 15 | /* 16 | serverOptions.Limits.MaxConcurrentConnections = 100; 17 | serverOptions.Limits.MaxConcurrentUpgradedConnections = 100; 18 | serverOptions.Limits.MaxRequestBodySize = 10 * 1024; 19 | serverOptions.Limits.MinRequestBodyDataRate = 20 | new MinDataRate(bytesPerSecond: 100, gracePeriod: TimeSpan.FromSeconds(10)); 21 | serverOptions.Limits.MinResponseDataRate = 22 | new MinDataRate(bytesPerSecond: 100, gracePeriod: TimeSpan.FromSeconds(10)); 23 | serverOptions.Listen(IPAddress.Loopback, 5000); 24 | serverOptions.Listen(IPAddress.Loopback, 5001, listenOptions => 25 | { 26 | listenOptions.UseHttps("testCert.pfx", "testPassword"); 27 | }); 28 | serverOptions.Limits.KeepAliveTimeout = TimeSpan.FromMinutes(2); 29 | serverOptions.Limits.RequestHeadersTimeout = TimeSpan.FromMinutes(1); 30 | */ 31 | 32 | // visit the link for more detailed information: 33 | // https://docs.microsoft.com/en-us/aspnet/core/fundamentals/servers/kestrel?view=aspnetcore-2.2#listenoptionsprotocols 34 | 35 | }).Build().Run(); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /KnapsackAlgorithm.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace DynamicProgrammingAlgorithms 8 | { 9 | class KnapsackAlgorithm 10 | { 11 | // Formulation V[i,w] = Max{ V[ i-1 , w] , V[ i-1 , w - W[i] ] + P[i] } 12 | // W[] {} weight matrix and P[] {} profit matrix 13 | // Linearly it has O(2^n) time complexity , with table method it has O(n*m) time and space complexity 14 | // This is the algorithm for undivisable objects, if you pick a phone as an example you can't split it physically 15 | 16 | /// 17 | /// Method returns a List<KeyValuePair<int,double>>> , which contains weight,profit data. 18 | /// 19 | /// Maximum weight to be desired 20 | /// List<KeyValuePair<int,double>>> a List which contains weight,profit pair data 21 | /// 22 | public List> ZeroOneKnapsacMethod(int m, List> profitWeight) 23 | { 24 | //For the sake of algorithmic convenience a weight-profit of [0 , 0] object is inserted into profitWeight list. 25 | profitWeight.Insert(0,new KeyValuePair(0,0)); 26 | List> tempList=new List>(); // A temporaryList in which proper values are inserted 27 | int n = profitWeight.Count(); //row 28 | double[,] valMatrix=new double[n,m+1];//the table [nxm] 29 | for (int i = 0; i < n; i++) 30 | { 31 | for (int j = 0; j <= m; j++) 32 | { 33 | if (i==0||j==0) 34 | { 35 | valMatrix[i,j] = 0; 36 | } 37 | else if(profitWeight[i].Key<=j) 38 | { 39 | valMatrix[i, j] = 40 | Math.Max(profitWeight[i].Value + valMatrix[i - 1, j - profitWeight[i].Key],valMatrix[i-1,j]); 41 | } 42 | else 43 | { 44 | valMatrix[i, j] = valMatrix[i - 1, j]; 45 | } 46 | } 47 | } 48 | 49 | int k = n-1, l = m; // k is "row" and l is "column" 50 | 51 | while (k>0 && l>0) 52 | { 53 | if (valMatrix[k, l] == valMatrix[k - 1, l] ) //Check the object above current index, if the both are same , move up. 54 | { 55 | k--; 56 | } 57 | else 58 | { 59 | tempList.Add(profitWeight[k]); 60 | l = l - profitWeight[k].Key; //Go to the remaining weight's column index 61 | k--; // move up on the table 62 | } 63 | } 64 | 65 | return tempList; 66 | } 67 | 68 | public List> KnapsackGreedyMethod(double m,List> profitWeight) 69 | { 70 | List> tempList = new List>(); 71 | List> myContainer = profitWeight.OrderByDescending(x => x.Value / x.Key).ToList(); 72 | 73 | foreach (var keyValuePair in myContainer) 74 | { 75 | if (m>=keyValuePair.Key) 76 | { 77 | tempList.Add(keyValuePair); 78 | m -= keyValuePair.Key; 79 | } 80 | else 81 | { 82 | tempList.Add(new KeyValuePair(m,(keyValuePair.Value)*(m/keyValuePair.Key))); 83 | break; 84 | } 85 | } 86 | 87 | return tempList; 88 | } 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /KnuthMorrisPratAlgorithm.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Text.RegularExpressions; 7 | using System.Threading.Tasks; 8 | 9 | namespace DynamicProgrammingAlgorithms 10 | { 11 | class KnuthMorrisPratAlgorithm 12 | { 13 | //this is a form of pattern matching algorithm 14 | public bool StringPatternMatchController(string pattern, StringBuilder sampleString,bool caseInsensitive=false) 15 | { 16 | // if case insensitive search is desired or not 17 | if (caseInsensitive) 18 | { 19 | pattern = pattern.ToLower(); 20 | sampleString = sampleString.Replace(sampleString.ToString(),sampleString.ToString().ToLower()); 21 | } 22 | 23 | //a list to add and check chars 24 | List indexPatternChars = new List(); 25 | //for the sake of simplicity a word-space char is added at zero index 26 | indexPatternChars.Insert(0, ' '); 27 | 28 | //to prevent a constant index call from pattern[] , a patternChar variable is created 29 | char[] patternChar = pattern.ToCharArray(); 30 | 31 | //char indexes which repeat itself at specific locations [ ,a,b,a,b,a,d] => IndexPatternChars 32 | // storedIndexes => [0,0,0,1,2,3,0] 33 | int[] storedIndexes = new int[patternChar.Length+1]; 34 | 35 | //a loop to create stored indexes and indexPatterChars 36 | for (int i = 0; i < patternChar.Length; i++) 37 | { 38 | if (indexPatternChars.Contains(patternChar[i])) 39 | { 40 | // for a pattern of [a,b,a,b,c] 41 | // indexPatternChars => [ ,a,b,a,b,c] 42 | // storedIndexes => [0,0,0,1,2,0] 43 | 44 | int lastIndex = indexPatternChars.LastIndexOf(patternChar[i]); 45 | //the key part! take the lastIndex of repating char into consideration. 46 | storedIndexes[i+1] = lastIndex; 47 | } 48 | 49 | indexPatternChars.Add(patternChar[i]); 50 | } 51 | 52 | int k = 0, j = 0; 53 | 54 | //traverse whole sampleString 55 | while (k 0 condition is provided 71 | j = storedIndexes[j]; 72 | 73 | //if a char matches, then j++ ,break the loop, k++ 74 | if (sampleString[k] == indexPatternChars[j+1]) 75 | { 76 | j++; 77 | break; 78 | } 79 | 80 | 81 | } while ((sampleString[k] != indexPatternChars[j+1] && j > 0)); 82 | 83 | k++; 84 | } 85 | } 86 | 87 | //if k reaches to end with no return true interruption, return false 88 | return false; 89 | } 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Sabit 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /LINQEqualityComparer.cs: -------------------------------------------------------------------------------- 1 | // LinqPad Environment 2 | 3 | void Main() 4 | { 5 | var itemList = new List() 6 | { 7 | new Tool(){ ID = 1, Name = "Pump", ProductionDate = DateTime.Today }, 8 | new Tool() { ID = 2, Name = "Toy", ProductionDate = DateTime.Today.AddDays(-63) }, 9 | new Tool() { ID = 2, Name = "Toy", ProductionDate = DateTime.Today.AddDays(-63) }, 10 | null, 11 | new Tool() { ID = 3, Name = "Faucet", ProductionDate = DateTime.Today.AddDays(-3) }, 12 | null, 13 | null 14 | }; 15 | 16 | var comparer = new ToolComparer(); 17 | 18 | var distList = itemList.Distinct(comparer); 19 | distList.Dump(); 20 | 21 | } 22 | 23 | public class Tool 24 | { 25 | public int ID { get; set; } 26 | public string Name { get; set; } 27 | public DateTime ProductionDate { get; set; } 28 | } 29 | 30 | public class ToolComparer : IEqualityComparer 31 | { 32 | // Second, once a similar GetHashCode returns, Eqauls() is checked. 33 | public bool Equals(Tool x, Tool y) 34 | { 35 | 36 | if(ReferenceEquals(x,y)) 37 | return true; 38 | 39 | return 40 | x.Name == y.Name && 41 | x.ProductionDate == y.ProductionDate; 42 | } 43 | 44 | // First, itemList element is compared against GetHasCode of ToolComparer 45 | public int GetHashCode(Tool obj) 46 | { 47 | if(obj is null) 48 | return -1; 49 | 50 | return obj.ID; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /LazyFibonacciList.cs: -------------------------------------------------------------------------------- 1 | void Main() 2 | { 3 | var fiboList = new LazyFibonacciList(); 4 | 5 | var list = new List(); 6 | 7 | // if you don't use Take(), it'll loop infinitely. 8 | foreach (var element in fiboList.Take(10)) 9 | { 10 | Console.WriteLine(element); 11 | } 12 | } 13 | 14 | public class LazyFibonacciList : IEnumerable 15 | { 16 | 17 | public IEnumerator GetEnumerator() => new Enumerator(); 18 | 19 | IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); 20 | 21 | struct Enumerator : IEnumerator 22 | { 23 | public long Current { get; private set; } 24 | 25 | private long Last { get; set; } 26 | 27 | object IEnumerator.Current => Current; 28 | 29 | public void Dispose() { } 30 | 31 | public bool MoveNext() 32 | { 33 | if (Current == -1) 34 | Current = 0; 35 | else if (Current == 0) 36 | Current = 1; 37 | else 38 | { 39 | long next = Current + Last; 40 | Last = Current; 41 | Current = next; 42 | } 43 | 44 | return true; 45 | } 46 | 47 | public void Reset() 48 | { 49 | Current = -1; 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /LongestCommonSubsequence.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace DynamicProgrammingAlgorithms 8 | { 9 | class LongestCommonSubsequence 10 | { 11 | //the method has O(m.n) time complexity 12 | public string LongestSubsequence(string pattern, string strSample,bool caseInsensitive=false) 13 | { 14 | if (caseInsensitive) 15 | { 16 | pattern = pattern.ToLower(); 17 | strSample = strSample.ToLower(); 18 | } 19 | 20 | StringBuilder longestPattern=new StringBuilder(); 21 | List charPattern = pattern.ToList(); 22 | List strPattern = strSample.ToList(); 23 | 24 | charPattern.Insert(0,' ');//for mapTable compability 25 | strPattern.Insert(0,' ');//for mapTable compability 26 | 27 | int[,] mapTable=new int[charPattern.Count,strPattern.Count]; 28 | 29 | for (int i = 1; i < charPattern.Count; i++) 30 | { 31 | for (int j = 1; j < strPattern.Count; j++) 32 | { 33 | //if element at charPattern matches, add 1 to mapTable[i-1,j-1] 34 | if (charPattern[i] == strPattern[j]) 35 | mapTable[i, j] = 1 + mapTable[i - 1, j - 1]; 36 | else 37 | mapTable[i, j] = Math.Max(mapTable[i - 1, j], mapTable[i, j - 1]); 38 | //check out previous and upper section, take the big value 39 | } 40 | } 41 | 42 | int k = charPattern.Count - 1, l = strPattern.Count - 1; 43 | //k :row counter , l:column counter 44 | while (k>0 && l>0) 45 | { 46 | //traverse the mapTable , form end to first 47 | //if previous column is similar to current then decrease column counter "l" 48 | if (mapTable[k, l] == mapTable[k, l - 1]) 49 | l--; 50 | else 51 | { 52 | //mapTable is traversed from end to first so that insertion method is used 53 | longestPattern.Insert(0,strPattern[l--]); 54 | k--; 55 | } 56 | 57 | } 58 | 59 | return longestPattern.ToString(); 60 | } 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /MagicSquareForOddSizes.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using Microsoft.CSharp.RuntimeBinder; 7 | 8 | namespace DynamicProgrammingAlgorithms 9 | { 10 | //Magic Sum = n(n^2+1)/2 11 | class MagicSquareForOddSizes 12 | { 13 | // method returns magicSum according to size 14 | public int MagicSquare(int[,] magicArray) 15 | { 16 | int n = magicArray.GetLength(0); 17 | int magicSum = n * (n * n + 1) / 2; 18 | 19 | if (n % 2 == 0) 20 | throw new RuntimeBinderInternalCompilerException("n must be odd"); 21 | 22 | int row = n - 1; 23 | int col = n / 2; 24 | magicArray[row,col] = 1; 25 | 26 | for (int i = 2; i <= n * n; i++) 27 | { 28 | if (magicArray[(row + 1) % n,(col + 1) % n] == 0) 29 | { 30 | row = (row + 1) % n; 31 | col = (col + 1) % n; 32 | } 33 | else 34 | row = (row - 1) % n; 35 | 36 | magicArray[row,col] = i; 37 | } 38 | 39 | return magicSum; 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /MarshallBenchmark.cs: -------------------------------------------------------------------------------- 1 | using BenchmarkDotNet.Attributes; 2 | using BenchmarkDotNet.Running; 3 | using System; 4 | using System.Linq; 5 | using System.Runtime.InteropServices; 6 | using System.Text; 7 | 8 | class NotTooSafeStringReverse 9 | { 10 | 11 | public static void Main() 12 | { 13 | var a = BenchmarkRunner.Run(); 14 | } 15 | 16 | public static string GetLargeString() 17 | { 18 | string insanOlmak = "Bu konularda kafa yoran ve bir türlü taşı yerine oturtamayan arkadaşlarla zaman, zaman “neden” diye tartışıp, fikir teatisinde bulunuruz.. Ne yazık ki, sonuçta konu hüsranla kapanır çoğunlukla.. Çünkü toplumun büyük bir kesiminde dostlukları, iyilikleri, güzellikleri, hizmetleri unutma ya hastalık olmuş, ya da işlerine geliyor, kararına varırız.. Maneviyata dönmek isteriz.. Ama nerde.. Aramak faydasız.. Manevi değerler dünyamıza gözümüzü kapattığımız ölçüde vefadan, minnet duygusundan, kadirbilir olmaktan kopup uzaklaşılmış olduğunu görürüz.. Anlarız ki, insanlık için önce insan olmak gerekir.. Aslında bize şöyle öğretmişti atalarımız.. “Aman haaa, bir fincan kahvenin kırk yıl hatırı vardır”.. “Komşu komşunun külüne muhtaçtır, iyi geçinin çevrenizdekilerle, sayın, sevin” derlerdi..Hatta bizlerin beyinlerine kazınacağına inandıkları hikayelerle nasihatte bulunurlardı.. Demek gerçekten başarılı olmuşlar, nasıl hayatımda beklentisiz hizmet aşkı coşkusu hiç eksilmediyse, her şeye rağmen anlatılan hikayeler de unutulmadı şükürler olsun.. Hem de tüm etkisiyle beynimde koruyor yerini.. Mesela bakın bir tanesi şöyleydi ve bu hikayenin insan üstüne hassasiyetini şimdi çok daha iyi anlıyorum.Küçük bir kız çocuğu çimenlerin üzerinde yürürken bir kelebeğin dikene takılıp kalmış olduğunu görür..Hemen koşar ve çok dikkatli bir şekilde kelebeği dikenden kurtarır..Kelebek sevinçle uçmaya başlar..Ve az sonra çok güzel ve iyi kalpli bir peri olarak geri döner..Küçük kıza “Güzel kız, bu iyiliğine karşı bende sana en çok istediğin şeyi vermek istiyorum” der..Küçük kız bir an düşünür ve cevap verir “Hayat boyu mutlu olmak istiyorum” Onun üzerine peri ona doğru eğilir ve kulağına bir şeyler fısıldar..Ardından birden bire gözden kaybolur..Kız büyür..Çevresindeki hiç kimse ondan daha mutlu değildir..Bu mutluluğun sırrını ona her sorduklarında yalnızca gülümser ve “iyi bir perinin sözünü dinledim” der..Seneler geçer ve bu mutlu yaşlının sırrının onunla birlikte öleceğinden korkan komşuları “Lütfen bu sırrı artık bize de söyle” diye yalvarırlar. “Perinin sana ne "; 19 | string largeString = string.Empty; 20 | 21 | for (int i = 0; i < 15; i++) 22 | { 23 | largeString += insanOlmak; 24 | } 25 | 26 | return largeString; 27 | } 28 | } 29 | 30 | [MemoryDiagnoser] 31 | public class ReverseBench 32 | { 33 | string largeString; 34 | 35 | [GlobalSetup] 36 | public void CreateLargeString() 37 | { 38 | largeString = NotTooSafeStringReverse.GetLargeString(); 39 | } 40 | 41 | [Benchmark] 42 | public void CustomReverseTest() 43 | { 44 | var a = largeString.CustomReverse(); 45 | } 46 | [Benchmark] 47 | public void LinqReverseTest() 48 | { 49 | var b = largeString.LinqReverse(); 50 | } 51 | [Benchmark] 52 | public void SpanReverseTest() 53 | { 54 | var c = largeString.SpanReverse(); 55 | } 56 | [Benchmark] 57 | public void MemoryReverseTest() 58 | { 59 | var d = largeString.MemoryReverse(); 60 | } 61 | 62 | [Benchmark] 63 | public void StringCreateReverseTest() 64 | { 65 | var d = largeString.StringCreateReverse(); 66 | } 67 | 68 | } 69 | 70 | public static class ExtensionString 71 | { 72 | public static string CustomReverse(this string script) 73 | { 74 | string result = null; 75 | string strValue = script; 76 | int strLength = strValue.Length; 77 | 78 | 79 | // Allocate HGlobal memory for source and destination strings 80 | IntPtr sourcePtr = Marshal.StringToHGlobalUni(strValue); 81 | IntPtr destPtr = Marshal.StringToHGlobalUni(strValue); 82 | 83 | // The unsafe section where byte pointers are used. 84 | try 85 | { 86 | if (sourcePtr != IntPtr.Zero && destPtr != IntPtr.Zero) 87 | { 88 | unsafe 89 | { 90 | ushort* src = (ushort*)sourcePtr.ToPointer(); 91 | ushort* dst = (ushort*)destPtr.ToPointer(); 92 | 93 | if (strLength > 0) 94 | { 95 | // set the source pointer to the end of the string 96 | // to do a reverse copy. 97 | src += strLength - 1; 98 | while (strLength-- > 0) 99 | { 100 | *dst++ = *src--; 101 | } 102 | 103 | *dst = 0; 104 | } 105 | } 106 | 107 | result = Marshal.PtrToStringUni(destPtr); 108 | } 109 | 110 | return result; 111 | } 112 | finally 113 | { 114 | Marshal.FreeHGlobal(sourcePtr); 115 | Marshal.FreeHGlobal(destPtr); 116 | } 117 | 118 | } 119 | 120 | public static string LinqReverse(this string script) 121 | { 122 | var tmpString = new StringBuilder(); 123 | var reversedStr = script.Reverse(); 124 | foreach (var c in reversedStr) 125 | { 126 | tmpString.Append(c); 127 | } 128 | 129 | return tmpString.ToString(); 130 | } 131 | 132 | public static string SpanReverse(this string script) 133 | { 134 | Span spnStr = new Span(script.ToCharArray()); 135 | spnStr.Reverse(); 136 | return spnStr.ToString(); 137 | } 138 | 139 | public static string MemoryReverse(this string script) 140 | { 141 | Memory spnStr = new Memory(script.ToCharArray()); 142 | spnStr.Span.Reverse(); 143 | return spnStr.ToString(); 144 | } 145 | 146 | public static string StringCreateReverse(this string script) 147 | { 148 | var text = script; 149 | 150 | if (text == null) 151 | throw new NullReferenceException(); 152 | 153 | if (text == string.Empty) 154 | return text; 155 | 156 | return string.Create(text.Length, text, (output, context) => 157 | { 158 | int length = context.Length - 1; 159 | for (int i = length; i >= 0; i--) 160 | { 161 | output[length - i] = context[i]; 162 | } 163 | }); 164 | 165 | } 166 | } 167 | -------------------------------------------------------------------------------- /MarshallString.cs: -------------------------------------------------------------------------------- 1 | public static class ExtensionString 2 | { 3 | public static string CustomReverse(this string script) 4 | { 5 | string result = null; 6 | string strValue = script; 7 | int strLength = strValue.Length; 8 | 9 | // Allocate HGlobal memory for source and destination strings 10 | IntPtr sourcePtr = Marshal.StringToHGlobalAnsi(strValue); 11 | IntPtr destPtr = Marshal.AllocHGlobal(strLength + 1); 12 | 13 | // The unsafe section where byte pointers are used. 14 | if (sourcePtr != IntPtr.Zero && destPtr != IntPtr.Zero) 15 | { 16 | unsafe 17 | { 18 | byte *src = (byte *)sourcePtr.ToPointer(); 19 | byte *dst = (byte *)destPtr.ToPointer(); 20 | 21 | if (strLength > 0) 22 | { 23 | // set the source pointer to the end of the string 24 | // to do a reverse copy. 25 | src += strLength - 1; 26 | while (strLength-- > 0) 27 | { 28 | *dst++ = *src--; 29 | } 30 | 31 | *dst = 0; 32 | } 33 | } 34 | 35 | result = Marshal.PtrToStringAnsi(destPtr); 36 | } 37 | 38 | 39 | Marshal.FreeHGlobal(sourcePtr); 40 | Marshal.FreeHGlobal(destPtr); 41 | 42 | return result; 43 | } 44 | 45 | public static string LinqReverse(this string script) 46 | { 47 | var tmpString = new StringBuilder(); 48 | var reversedStr = script.Reverse(); 49 | foreach (var c in reversedStr) 50 | { 51 | tmpString.Append(c); 52 | } 53 | 54 | return tmpString.ToString(); 55 | } 56 | } 57 | 58 | 59 | 60 | // Unicode & try-finally 61 | public static class ExtensionString 62 | { 63 | public static string CustomReverse(this string script) 64 | { 65 | string result = null; 66 | string strValue = script; 67 | int strLength = strValue.Length; 68 | 69 | 70 | // Allocate HGlobal memory for source and destination strings 71 | IntPtr sourcePtr = Marshal.StringToHGlobalUni(strValue); 72 | IntPtr destPtr = Marshal.StringToHGlobalUni(strValue); 73 | 74 | // The unsafe section where byte pointers are used. 75 | try 76 | { 77 | if (sourcePtr != IntPtr.Zero && destPtr != IntPtr.Zero) 78 | { 79 | unsafe 80 | { 81 | ushort* src = (ushort*)sourcePtr.ToPointer(); 82 | ushort* dst = (ushort*)destPtr.ToPointer(); 83 | 84 | if (strLength > 0) 85 | { 86 | // set the source pointer to the end of the string 87 | // to do a reverse copy. 88 | src += strLength - 1; 89 | while (strLength-- > 0) 90 | { 91 | *dst++ = *src--; 92 | } 93 | 94 | *dst = 0; 95 | } 96 | } 97 | 98 | result = Marshal.PtrToStringUni(destPtr); 99 | } 100 | 101 | return result; 102 | } 103 | finally 104 | { 105 | Marshal.FreeHGlobal(sourcePtr); 106 | Marshal.FreeHGlobal(destPtr); 107 | } 108 | 109 | } 110 | 111 | public static string LinqReverse(this string script) 112 | { 113 | var tmpString = new StringBuilder(); 114 | var reversedStr = script.Reverse(); 115 | foreach (var c in reversedStr) 116 | { 117 | tmpString.Append(c); 118 | } 119 | 120 | return tmpString.ToString(); 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /ModuleInitializer.cs: -------------------------------------------------------------------------------- 1 | class Program 2 | { 3 | // This method runs automatically when the containing assembly is first loaded. 4 | // public or internal 5 | [System.Runtime.CompilerServices.ModuleInitializer] 6 | public static void Initializer() 7 | { 8 | Console.WriteLine("This runs only once throughout application's lifetime"); 9 | // Module initializers have less overhead than static constructors. 10 | // This feature requires .NET 5 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /MonitorTryEnter.cs: -------------------------------------------------------------------------------- 1 | void Main() 2 | { 3 | object locker1 = new object(); 4 | object locker2 = new object(); 5 | 6 | new Thread(() => 7 | { 8 | bool lockTaken = false; 9 | try 10 | { 11 | Monitor.Enter(locker1, ref lockTaken); 12 | Console.WriteLine("1"); 13 | Thread.Sleep(1000); 14 | bool lockTaken2 = false; 15 | try 16 | { 17 | Monitor.TryEnter(locker2,10000, ref lockTaken2); 18 | Console.WriteLine("2"); 19 | } 20 | finally 21 | { 22 | if (lockTaken2) 23 | { 24 | Monitor.Exit(locker2); 25 | } 26 | } 27 | } 28 | finally 29 | { 30 | if (lockTaken) 31 | { 32 | Monitor.Exit(locker1); 33 | } 34 | } 35 | }).Start(); 36 | 37 | 38 | bool lockTaken = false; 39 | try 40 | { 41 | Monitor.Enter(locker2, ref lockTaken); 42 | Console.WriteLine("3"); 43 | Thread.Sleep(1000); 44 | bool lockTaken2 = false; 45 | try 46 | { 47 | Monitor.Enter(locker1, ref lockTaken2); 48 | Console.WriteLine("4"); 49 | } 50 | finally 51 | { 52 | if (lockTaken2) 53 | { 54 | Monitor.Exit(locker1); 55 | } 56 | } 57 | } 58 | finally 59 | { 60 | if (lockTaken) 61 | { 62 | Monitor.Exit(locker2); 63 | } 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /NQueenProblemInDetail.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace DynamicProgrammingAlgorithms 8 | { 9 | class NQueenProblem 10 | { 11 | private int item = 1; 12 | 13 | private int[,] firstDiagonal; 14 | private int[,] secondDiagonal; 15 | private int[,] copyOfChestBoard; 16 | private int[,] Rotation90; 17 | private int[,] Rotation180; 18 | private int[,] Rotation270; 19 | private List checkList; 20 | 21 | //N is dimention of board where queens are positioned 22 | public NQueenProblem(int N) 23 | { 24 | firstDiagonal=new int[N,N]; 25 | secondDiagonal=new int[N,N]; 26 | Rotation90=new int[N,N]; 27 | Rotation180=new int[N,N]; 28 | Rotation270=new int[N,N]; 29 | 30 | checkList =new List(); 31 | } 32 | 33 | //Fundemantal Solutions, it returns double amount of desired result 34 | //the reason that it doesn't include first and second reflections for every rotation 35 | //for rotational reflexions it's made by firstDiagonal refection, it can be done by second 36 | //diagonal either 37 | public void FundamentalSolution(int[,] chestBoard) 38 | { 39 | if (FundamentalSolveTheProblem(chestBoard) == false) 40 | { 41 | Console.Write("No solution"); 42 | } 43 | checkList.Clear(); 44 | item = 1; 45 | } 46 | 47 | public void FullSolution(int[,] chestBoard) 48 | { 49 | if (SolveTheProblem(chestBoard) == false) 50 | { 51 | Console.Write("No solution"); 52 | } 53 | 54 | item = 1; 55 | } 56 | 57 | //Display method to print possible solutions 58 | private void Display(int[,] chestBoard) 59 | { 60 | Console.Write($"{item++}"); 61 | Console.WriteLine(); 62 | for (int i = 0; i < chestBoard.GetLength(0); i++) 63 | { 64 | for (int j = 0; j < chestBoard.GetLength(1); j++) 65 | Console.Write( $"{chestBoard[i, j]} "); 66 | 67 | Console.Write("\n"); 68 | } 69 | 70 | Console.WriteLine(); 71 | } 72 | 73 | //Method checks the place , if it's proper for certain row and column then place it 74 | private bool IsProper(int[,] chestBoard, int row, int column) 75 | { 76 | 77 | // check the left side of this column 78 | for (int i = 0; i < column; i++) 79 | { 80 | if (chestBoard[row, i] == 1) 81 | return false; 82 | } 83 | 84 | 85 | // Check upper diagonal on left side 86 | for (int i = row, j = column; i >= 0 && j >= 0; i--, j--) 87 | { 88 | if (chestBoard[i, j] == 1) 89 | return false; 90 | } 91 | 92 | 93 | // Check lower diagonal on left side 94 | for (int i = row, j = column; j >= 0 && i < chestBoard.GetLength(0); i++, j--) 95 | { 96 | if (chestBoard[i, j] == 1) 97 | return false; 98 | } 99 | 100 | return true; 101 | } 102 | 103 | //A recursive function to solve the problem 104 | private bool SolveTheProblem(int[,] chestBoard, int column=0) 105 | { 106 | bool decision = false; 107 | int N = chestBoard.GetLength(0); 108 | //if it reaches to last index of column Display and return true 109 | if (column == N) 110 | { 111 | Display(chestBoard); 112 | return true; 113 | } 114 | 115 | 116 | for (int r = 0; r < N; r++) 117 | { 118 | // \ 119 | // ---- IsProper checks three places! Up-Left ,Down-Left ,Left 120 | // / 121 | if (IsProper(chestBoard, r, column)) 122 | { 123 | // put the value in position 124 | chestBoard[r, column] = 1; 125 | 126 | // Make result true if any placement is possible 127 | // Recursion follows the row , till N 128 | decision = SolveTheProblem(chestBoard, column + 1) || decision; 129 | 130 | //this is placed in stack in every cycle, beware! 131 | //this is also called as backtracking 132 | //if column+1 can't reach to the value of N , 0 is placed back in place of 1 133 | chestBoard[r, column] = 0; 134 | } 135 | } 136 | 137 | //If queen can not be placed in any row in this column then return false 138 | return decision; 139 | } 140 | 141 | //this method shows fundamental solutions of NQueen problem 142 | //fundemantal solution excludes rotations if they are somehow alike 143 | //this method does't inclue diagonal reflections fro every rotation 144 | //includes norotational reflexions 145 | private bool FundamentalSolveTheProblem(int[,] chestBoard, int column = 0) 146 | { 147 | 148 | bool decision = false; 149 | int N = chestBoard.GetLength(0); 150 | 151 | copyOfChestBoard = new int[N, N]; 152 | //if it reaches to last index of column Display and return true 153 | if (column == N) 154 | { 155 | for (int i = 0; i < N; i++) 156 | { 157 | for (int j = 0; j < N; j++) 158 | { 159 | firstDiagonal[i, j] = chestBoard[i, j]; 160 | secondDiagonal[i, j] = chestBoard[i, j]; 161 | Rotation90[i, j] = chestBoard[i, j]; 162 | Rotation180[i, j] = chestBoard[i, j]; 163 | Rotation270[i, j] = chestBoard[i, j]; 164 | 165 | } 166 | } 167 | 168 | FirstDiagonalReflectionSwap(firstDiagonal); 169 | SecondDiagonalReflectionSwap(secondDiagonal); 170 | RotateMatrix90(N,Rotation90); 171 | RotateMatrix180(N, Rotation180); 172 | RotateMatrix270(N,Rotation270); 173 | 174 | bool outCheck = true; 175 | //check if rotations and diagonal reflections are similar 176 | outCheck = OutCheck(N, outCheck); 177 | 178 | //if outCheck returns as true it means that there is a similar matrix in the list 179 | if (outCheck) 180 | { 181 | for (int i = 0; i < N; i++) 182 | { 183 | for (int j = 0; j < N; j++) 184 | { 185 | copyOfChestBoard[i, j] = chestBoard[i, j]; 186 | } 187 | } 188 | checkList.Add(copyOfChestBoard); 189 | Display(copyOfChestBoard); 190 | } 191 | 192 | return true; 193 | } 194 | 195 | for (int r = 0; r < N; r++) 196 | { 197 | 198 | if (IsProper(chestBoard, r, column)) 199 | { 200 | // put the value in position 201 | chestBoard[r, column] = 1; 202 | 203 | // Make result true if any placement 204 | // is possible 205 | decision = FundamentalSolveTheProblem(chestBoard, column + 1) || decision; 206 | 207 | //this is placed in stack in every cycle, beware! 208 | //this is also called as backtracking 209 | chestBoard[r, column] = 0; 210 | } 211 | } 212 | 213 | //If queen can not be placed in any row in this column then return false 214 | return decision; 215 | } 216 | private void FirstDiagonalReflectionSwap(int[,] chestBoard) 217 | { 218 | int N = chestBoard.GetLength(0); 219 | for (int i = 0; i < N; i++) 220 | { 221 | for (int j = 0; j < i; j++) 222 | { 223 | int temp = chestBoard[i, j]; 224 | chestBoard[i, j] = chestBoard[j, i]; 225 | chestBoard[j, i] = temp; 226 | } 227 | } 228 | } 229 | private void SecondDiagonalReflectionSwap(int[,] chestBoard) 230 | { 231 | int N = chestBoard.GetLength(0); 232 | 233 | for (int i = 0, j = N - 1; i < N && j >= 0; i++, j--) 234 | { 235 | for (int k = 0; k < j; k++) 236 | { 237 | int temp = chestBoard[i, k]; 238 | chestBoard[i, k] = chestBoard[(N - 1) - k, j]; 239 | chestBoard[(N - 1) - k, j] = temp; 240 | } 241 | } 242 | } 243 | private bool OutCheck(int N, bool outCheck) 244 | { 245 | // checking the firstDiogonal, if there is one it returns false so that no need for extra availablity check 246 | foreach (var arr in checkList) 247 | { 248 | for (int i = 0; i < N; i++) 249 | { 250 | for (int j = 0; j < N; j++) 251 | { 252 | //if one element pops up as different, outCheck is true , break the loop 253 | if (arr[i, j] == firstDiagonal[i, j]) 254 | outCheck = false; 255 | else 256 | { 257 | outCheck = true; 258 | break; 259 | } 260 | } 261 | //if loop is cut off by break it will come out as true, so that get out of second inner loop 262 | if (outCheck) break; 263 | } 264 | //if all elements are similar then outCheck gets false, which means there is a similar object in list 265 | //so that get out of foreach loop, we are done 266 | if (!outCheck) break; 267 | } 268 | //if first foreach traverse returns true , it means that there is no similar matrix in current list 269 | //so that check for others, -secondDiagonal and rotations- 270 | if (outCheck) 271 | { 272 | foreach (var arr in checkList) 273 | { 274 | for (int i = 0; i < N; i++) 275 | { 276 | for (int j = 0; j < N; j++) 277 | { 278 | if (arr[i, j] == secondDiagonal[i, j]) 279 | outCheck = false; 280 | else 281 | { 282 | outCheck = true; 283 | break; 284 | } 285 | } 286 | 287 | if (outCheck) break; 288 | } 289 | 290 | if (!outCheck) break; 291 | } 292 | } 293 | 294 | //check similarities after diagonal reflection of rotations 295 | if (outCheck) 296 | { 297 | foreach (var arr in checkList) 298 | { 299 | for (int i = 0; i < N; i++) 300 | { 301 | for (int j = 0; j < N; j++) 302 | { 303 | if (arr[i, j] == Rotation90[i, j]) 304 | outCheck = false; 305 | else 306 | { 307 | outCheck = true; 308 | break; 309 | } 310 | } 311 | 312 | if (outCheck) break; 313 | } 314 | 315 | if (!outCheck) break; 316 | } 317 | } 318 | FirstDiagonalReflectionSwap(Rotation90); 319 | if (outCheck) 320 | { 321 | foreach (var arr in checkList) 322 | { 323 | for (int i = 0; i < N; i++) 324 | { 325 | for (int j = 0; j < N; j++) 326 | { 327 | if (arr[i, j] == Rotation90[i, j]) 328 | outCheck = false; 329 | else 330 | { 331 | outCheck = true; 332 | break; 333 | } 334 | } 335 | 336 | if (outCheck) break; 337 | } 338 | 339 | if (!outCheck) break; 340 | } 341 | } 342 | 343 | if (outCheck) 344 | { 345 | foreach (var arr in checkList) 346 | { 347 | for (int i = 0; i < N; i++) 348 | { 349 | for (int j = 0; j < N; j++) 350 | { 351 | if (arr[i, j] == Rotation180[i, j]) 352 | outCheck = false; 353 | else 354 | { 355 | outCheck = true; 356 | break; 357 | } 358 | } 359 | 360 | if (outCheck) break; 361 | } 362 | 363 | if (!outCheck) break; 364 | } 365 | } 366 | FirstDiagonalReflectionSwap(Rotation180); 367 | if (outCheck) 368 | { 369 | foreach (var arr in checkList) 370 | { 371 | for (int i = 0; i < N; i++) 372 | { 373 | for (int j = 0; j < N; j++) 374 | { 375 | if (arr[i, j] == Rotation180[i, j]) 376 | outCheck = false; 377 | else 378 | { 379 | outCheck = true; 380 | break; 381 | } 382 | } 383 | 384 | if (outCheck) break; 385 | } 386 | 387 | if (!outCheck) break; 388 | } 389 | } 390 | 391 | if (outCheck) 392 | { 393 | foreach (var arr in checkList) 394 | { 395 | for (int i = 0; i < N; i++) 396 | { 397 | for (int j = 0; j < N; j++) 398 | { 399 | if (arr[i, j] == Rotation270[i, j]) 400 | outCheck = false; 401 | else 402 | { 403 | outCheck = true; 404 | break; 405 | } 406 | } 407 | 408 | if (outCheck) break; 409 | } 410 | 411 | if (!outCheck) break; 412 | } 413 | } 414 | FirstDiagonalReflectionSwap(Rotation270); 415 | if (outCheck) 416 | { 417 | foreach (var arr in checkList) 418 | { 419 | for (int i = 0; i < N; i++) 420 | { 421 | for (int j = 0; j < N; j++) 422 | { 423 | if (arr[i, j] == Rotation270[i, j]) 424 | outCheck = false; 425 | else 426 | { 427 | outCheck = true; 428 | break; 429 | } 430 | } 431 | 432 | if (outCheck) break; 433 | } 434 | 435 | if (!outCheck) break; 436 | } 437 | } 438 | 439 | return outCheck; 440 | } 441 | //Clockwise Rotation! 442 | private void RotateMatrix90(int N, int[,] rotation) 443 | { 444 | // Consider all squares one by one 445 | for (int x = 0; x < N / 2; x++) 446 | { 447 | // Consider elements in group of 4 in current square 448 | for (int y = x; y < N - x - 1; y++) 449 | { 450 | // store current cell in temp variable 451 | int temp = rotation[x, y]; 452 | 453 | // move values from right to top 454 | rotation[x, y] = rotation[y, N - 1 - x]; 455 | 456 | // move values from bottom to right 457 | rotation[y, N - 1 - x] = rotation[N - 1 - x, 458 | N - 1 - y]; 459 | 460 | // move values from left to bottom 461 | rotation[N - 1 - x, 462 | N - 1 - y] 463 | = rotation[N - 1 - y, x]; 464 | 465 | // assign temp to left 466 | rotation[N - 1 - y, x] = temp; 467 | } 468 | } 469 | } 470 | private void RotateMatrix180(int N, int[,] rotation) 471 | { 472 | RotateMatrix90(N,rotation); 473 | RotateMatrix90(N,rotation); 474 | } 475 | private void RotateMatrix270(int N, int[,] rotation) 476 | { 477 | RotateMatrix90(N, rotation); 478 | RotateMatrix90(N, rotation); 479 | RotateMatrix90(N, rotation); 480 | } 481 | } 482 | } 483 | -------------------------------------------------------------------------------- /OperatorOverloadingFull.cs: -------------------------------------------------------------------------------- 1 | 2 | 3 | public class Coordinate 4 | { 5 | public int X { get; private set; } 6 | public int Y { get; private set; } 7 | public int Z { get; private set; } 8 | 9 | public Coordinate(int x, int y, int z) 10 | { 11 | this.X = x; 12 | this.Y = y; 13 | this.Z = z; 14 | } 15 | 16 | public static Coordinate operator +(in Coordinate a, in Coordinate b) => 17 | new Coordinate (a.X + b.X , a.Y + b.Y , a.Z + b.Z); 18 | 19 | public static Coordinate operator -(in Coordinate a, in Coordinate b) => 20 | new Coordinate(a.X - b.X, a.Y - b.Y, a.Z - b.Z); 21 | 22 | public static Coordinate operator *(in Coordinate a, in Coordinate b) => 23 | new Coordinate(a.X * b.X, a.Y * b.Y, a.Z * b.Z); 24 | 25 | public static bool operator ==(in Coordinate a, in Coordinate b) 26 | { 27 | if(a.X == b.X && a.Y == b.Y && a.Z == b.Z) 28 | return true; 29 | 30 | return false; 31 | } 32 | 33 | public static bool operator !=(in Coordinate a, in Coordinate b) => !(a == b); 34 | 35 | public static Coordinate operator ++(Coordinate a) => 36 | new Coordinate(++a.X,++a.Y,++a.Z); 37 | 38 | public static Coordinate operator --(Coordinate a) => 39 | new Coordinate(--a.X, --a.Y, --a.Z); 40 | 41 | public static Coordinate operator %(in Coordinate a, in Coordinate b) 42 | { 43 | if( b.X != 0 && b.Y != 0 && b.Z != 0) 44 | return new Coordinate(a.X % b.X, a.Y % b.Y, a.Z % b.Z); 45 | else 46 | throw new DivideByZeroException(); 47 | } 48 | 49 | public static Coordinate operator /(in Coordinate a, in Coordinate b) 50 | { 51 | if( b.X != 0 && b.Y != 0 && b.Z != 0) 52 | return new Coordinate(a.X / b.X, a.Y / b.Y, a.Z / b.Z); 53 | else 54 | throw new DivideByZeroException(); 55 | } 56 | 57 | public static (double X, double Y, double Z) operator 58 | ^(in Coordinate a, in Coordinate b) 59 | { 60 | double x = Math.Pow(a.X, b.X); 61 | double y = Math.Pow(a.Y, b.Y); 62 | double z = Math.Pow(a.Z, b.Z); 63 | 64 | return (x,y,z); 65 | } 66 | 67 | public override bool Equals(object obj) 68 | { 69 | if(obj is not null) 70 | { 71 | Coordinate coordinate = (Coordinate)obj; 72 | return this == coordinate; 73 | } 74 | return false; 75 | } 76 | 77 | public override int GetHashCode() 78 | { 79 | string hash = $"{X}+{Y}+{Z}"; 80 | return hash.GetHashCode(); 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /ParallelAggregation.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Diagnostics; 4 | using System.Diagnostics.CodeAnalysis; 5 | using System.Linq; 6 | using System.Net.NetworkInformation; 7 | using System.Threading; 8 | using System.Threading.Tasks; 9 | 10 | namespace ParallelAggregation 11 | { 12 | class Program 13 | { 14 | 15 | public static void Main() 16 | { 17 | Stopwatch timer = new Stopwatch(); 18 | IEnumerable nums = ParallelEnumerable.Range(0, int.MaxValue); 19 | long sum = 0; 20 | 21 | timer.Start(); 22 | sum = nums.AsParallel().Aggregate( 23 | () => 0, // seedFactory: first value of localTotal 24 | (localTotal, n) => localTotal + n, // updateAccumulatorFunc:adding values to local total 25 | (mainTotal, localTotal) => mainTotal + localTotal, // combineAccumulatorFunc:interlock add at mainTotal 26 | finalResult => finalResult); // resultSelector:last return value, sum 27 | timer.Stop(); 28 | 29 | //less than 9 secs 30 | Console.WriteLine(timer.Elapsed.TotalMilliseconds); 31 | Console.WriteLine(sum); 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /ParallelFactorialCalc.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Diagnostics; 4 | using System.Diagnostics.CodeAnalysis; 5 | using System.Linq; 6 | using System.Net.NetworkInformation; 7 | using System.Threading; 8 | using System.Threading.Tasks; 9 | 10 | namespace ParallelFactorialCalculaion 11 | { 12 | class Program 13 | { 14 | public static double Factorial(int num) 15 | { 16 | IEnumerable numbers = ParallelEnumerable.Range(1, num); 17 | 18 | double sum = numbers.AsParallel().Aggregate( 19 | () => 1, 20 | (localTotal, n) => localTotal * n, 21 | (mainTotal, localTotal) => mainTotal * localTotal, 22 | finalResult => finalResult); 23 | 24 | return sum; 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /ParallelForEachAsync.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.CompilerServices; 2 | 3 | async IAsyncEnumerable GetInfoAsync(string[] users, 4 | [EnumeratorCancellation]CancellationToken cancellationToken = default) 5 | { 6 | if (users is not null) 7 | { 8 | for (int i = 0; i < users.Length; i++) 9 | { 10 | var userHandler = users[i]; 11 | if (!cancellationToken.IsCancellationRequested) 12 | yield return await Task.FromResult(userHandler); 13 | else 14 | { 15 | // throw new TaskCancelledException() 16 | await Task.FromCanceled(cancellationToken); 17 | } 18 | } 19 | } 20 | } 21 | 22 | using HttpClient httpClient = new() 23 | { 24 | BaseAddress = new Uri("https://api.github.com"), 25 | }; 26 | 27 | httpClient.DefaultRequestHeaders. 28 | UserAgent.Add(new ProductInfoHeaderValue("Trying_Net6", "GitAPI")); 29 | 30 | // GitHub provides OAuth token for 30 days, 31 | // which is capable of recieving and sending 5000 respose/request per minute 32 | httpClient.DefaultRequestHeaders.Authorization = 33 | new AuthenticationHeaderValue("token", 34 | "Setttings > Developer Settings > Personal Access Tokens "); 35 | 36 | 37 | ParallelOptions prlOptions = new() 38 | { 39 | MaxDegreeOfParallelism = 5 40 | }; 41 | 42 | using var cancTokenSource = new CancellationTokenSource(5000); 43 | 44 | try 45 | { 46 | await RunTasksParallelAsync(cancTokenSource.Token); 47 | } 48 | catch (TaskCanceledException) 49 | { 50 | Console.WriteLine("Request has been cancelled!"); 51 | } 52 | 53 | async Task RunTasksParallelAsync(CancellationToken cancellationToken = default) 54 | { 55 | for (int i = 2000; i < 2025; i++) 56 | { 57 | string uri = $"https://api.github.com/users?since={i}&per_page=100"; 58 | var all_users = 59 | await httpClient.GetStringAsync(uri,cancellationToken); 60 | 61 | 62 | var filter_users = all_users.Split(","); 63 | 64 | // creation of "users/{username}" string[] list; 65 | var username_list = 66 | filter_users.Where(x => 67 | { 68 | int index = x.IndexOf("login"); 69 | 70 | if (index != -1) 71 | return x.Substring(index, 5) == "login"; 72 | else 73 | return false; 74 | }). 75 | Select(l => "users/" + l.Substring(l.IndexOf(":") + 1). 76 | Replace("\"", String.Empty)).ToArray(); 77 | 78 | var userAsync = GetInfoAsync(username_list, cancellationToken); 79 | 80 | await Parallel. 81 | ForEachAsync(userAsync, prlOptions, async (uri, token) => 82 | { 83 | 84 | var user = 85 | await httpClient.GetFromJsonAsync(uri, token); 86 | 87 | Console.WriteLine( 88 | $"Name: {user?.Name}\n" + 89 | $"Bio: {user?.Bio}\n" + 90 | $"Twitter-UserName: {user?.Twitter_UserName}\n" + 91 | $"Location: {user?.Location}\n" + 92 | $"Blog: {user?.Blog}\n" + 93 | $"Company: {user?.Company}\n"); 94 | }); 95 | } 96 | } 97 | 98 | public record GithubAccount(string Name, 99 | string Bio, string Twitter_UserName, 100 | string Location, string Blog, 101 | string Company, string Email); 102 | -------------------------------------------------------------------------------- /ParallelLetterFrequency.cs: -------------------------------------------------------------------------------- 1 | public static int[] FrequencyOfLetters(StringBuilder stringBuilder) 2 | { 3 | string text = stringBuilder.ToString(); 4 | int[] result = 5 | text.AsParallel().Aggregate( 6 | () => new int[26], // new localFrequencies 7 | 8 | (localFrequencies, c) => 9 | { 10 | int index = char.ToUpper(c) - 'A'; 11 | if (index >= 0 && index <= 26) localFrequencies[index]++; 12 | return localFrequencies; 13 | }, 14 | 15 | (mainFreq, localFreq) => 16 | mainFreq.Zip(localFreq, (f1, f2) => f1 + f2).ToArray(), 17 | 18 | finalResult => finalResult 19 | ); 20 | return result; 21 | } 22 | -------------------------------------------------------------------------------- /ParallelPrimeNumbers.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Diagnostics; 4 | using System.Linq; 5 | using System.Threading; 6 | using System.Threading.Tasks; 7 | 8 | namespace ParallelPrimeNumbers 9 | { 10 | class Program 11 | { 12 | public static void Main() 13 | { 14 | IEnumerable numbers = Enumerable.Range(3, 100000000 - 3); 15 | 16 | Stopwatch timer = new Stopwatch(); 17 | 18 | timer.Start(); 19 | var parallelQuery = 20 | from n in numbers.AsParallel() 21 | where IsNPrime(n) 22 | select n; 23 | timer.Stop(); 24 | //less than 3 secs 25 | Console.WriteLine(timer.Elapsed.TotalMilliseconds); 26 | } 27 | 28 | 29 | private static bool IsNPrime(int n) 30 | { 31 | if (n == 1) return false; 32 | if (n == 2) return true; 33 | if (n > 2 && n % 2 == 0) return false; 34 | 35 | int divisor = (int)Math.Floor(Math.Sqrt(n)); 36 | for (int i = 3; i <= divisor; i+=2) 37 | if (n % i == 0) return false; 38 | 39 | return true; 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /PointerChunk.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Runtime.InteropServices; 5 | using BenchmarkDotNet.Attributes; 6 | using BenchmarkDotNet.Running; 7 | 8 | class BestPractices 9 | { 10 | public static void Main() 11 | { 12 | 13 | var a = BenchmarkRunner.Run(); 14 | 15 | } 16 | 17 | } 18 | 19 | public static class ArrayExtensions 20 | { 21 | public static IEnumerable Chunk(this int[] array, int size) 22 | { 23 | while (array.Any()) 24 | { 25 | yield return array.Take(size).ToArray(); 26 | array = array.Skip(size).ToArray(); 27 | } 28 | } 29 | } 30 | 31 | [MemoryDiagnoser] 32 | public class ChunkBenchmark 33 | { 34 | public int[] array; 35 | public Random random; 36 | [GlobalSetup] 37 | public void InitializeArray() 38 | { 39 | array = Enumerable.Range(1, 10_000_000).Where(x => x % 2 == 0).ToArray(); 40 | random = new Random(); 41 | } 42 | 43 | [Benchmark] 44 | public void PointerChunkTest() 45 | { 46 | var pointerChunk = new PointerChunk(array, 1_000); 47 | for (int i = 0; i < 3; i++) 48 | { 49 | var a = pointerChunk[random.Next(1,100)]; 50 | } 51 | } 52 | 53 | [Benchmark] 54 | public void LinqChunkTest() 55 | { 56 | var chunk = array.Chunk(1_000); 57 | for (int i = 0; i < 3; i++) 58 | { 59 | var a = chunk.ElementAt(random.Next(1,100)); 60 | } 61 | } 62 | } 63 | 64 | [SkipLocalsInit] 65 | // int64, int32, int16, byte, IntPtr 66 | public sealed class PointerChunk 67 | { 68 | private IntPtr[] _chunkList; 69 | private int[] _partialList; 70 | private int _chunkSize; 71 | private int _lastLoopSize; 72 | private int _chunkListSize { get; } 73 | private int _sizeofInt = sizeof(int); 74 | 75 | public PointerChunk(int[] largeArray,int chunkSize) 76 | { 77 | _chunkSize = chunkSize; 78 | _chunkList = Chunk(largeArray, chunkSize); // Chunk method handles exceptions. 79 | _chunkListSize = _chunkList.Length; // so that _chunkList won't be null. 80 | } 81 | 82 | public int Length => _chunkListSize; 83 | 84 | public int[] this[int i] 85 | { 86 | get 87 | { 88 | if (i == _chunkListSize - 1) 89 | _chunkSize = _lastLoopSize; 90 | 91 | if (i > _chunkListSize - 1) 92 | throw new IndexOutOfRangeException(); 93 | else 94 | { 95 | _partialList = new int[_chunkSize]; 96 | var tempPtr = _chunkList[i]; 97 | 98 | for (int j = 0; j < _chunkSize; j++) 99 | { 100 | var value = Marshal.ReadInt32(tempPtr, _sizeofInt * j); 101 | _partialList[j] = value; 102 | } 103 | 104 | return _partialList; 105 | } 106 | } 107 | } 108 | 109 | public IntPtr[] Chunk(int[] largeArray,int chunkSize) 110 | { 111 | if (largeArray is null) 112 | throw new NullReferenceException("Array can't be null"); 113 | if (largeArray.Length == 0) 114 | throw new ArgumentException("You can't chunk an empty array"); 115 | 116 | IntPtr[] list; // thread safe IntPtr list. 117 | int[] tempArr = largeArray; 118 | int arrLength = tempArr.Length; 119 | 120 | int remainder = arrLength % chunkSize; 121 | int noReminderSize = arrLength / chunkSize; 122 | int remainderSize = arrLength / chunkSize + 1; 123 | 124 | int loopSize = remainder == 0 ? noReminderSize : remainderSize; 125 | _lastLoopSize = remainder == 0 ? chunkSize : remainder; 126 | 127 | list = new IntPtr[loopSize]; 128 | 129 | unsafe 130 | { 131 | fixed (int* ptr = tempArr) 132 | { 133 | IntPtr iPtr = new IntPtr(ptr); 134 | for (int i = 0; i < loopSize; i++) 135 | { 136 | IntPtr tempPtr = iPtr + i * _sizeofInt * chunkSize; 137 | list[i] = tempPtr; 138 | } 139 | } 140 | } 141 | 142 | return list; 143 | } 144 | } 145 | 146 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 |
3 | DeckDeckGo logo 4 | 5 |
6 | 7 |

DynamicProgramming Repo - contains handy algorithms, spanning from travelling salesman to async-semaphoreSlim

8 | 9 |

Designed via C# .NET5+

10 | 11 |
12 | 13 | ![Website](https://img.shields.io/website?label=Editor&url=https://docs.microsoft.com/en-us/dotnet/csharp/) 14 | ![npm-license] 15 | [![Tweet](https://img.shields.io/twitter/url?url=https%3A%2F%2Fdeckdeckgo.com)](https://twitter.com/sabitk) 16 | 17 |
18 | 19 | [npm-license]: https://img.shields.io/npm/l/@stencil/core.svg 20 | 21 | --- 22 | 23 | ## Table of Contents 24 | - [Array Extensions](https://github.com/SabitKondakci/DynamicProgramming/blob/main/ArrayExtensions.cs) 25 | - [Asynchronous ArrayPool Implementation](https://github.com/SabitKondakci/DynamicProgramming/blob/main/ArrayPoolCustomImplementation.cs) 26 | - [ArrayPool Singleton Design](https://github.com/SabitKondakci/DynamicProgramming/blob/main/ArrayPoolSingletonDesign.cs) 27 | - [Asynchronous Aggregate Exceptions](https://github.com/SabitKondakci/DynamicProgramming/blob/main/AsyncAggregateException.cs) 28 | - [Async Delegate Implementation](https://github.com/SabitKondakci/DynamicProgramming/blob/main/AsyncDelegate.cs) 29 | - [Custom Collection Implementation](https://github.com/SabitKondakci/DynamicProgramming/blob/main/CustomCollection.cs) 30 | - [Deadlock Control via Locks](https://github.com/SabitKondakci/DynamicProgramming/blob/main/DeadlockControl.cs) 31 | - [Default Interface Implementation](https://github.com/SabitKondakci/DynamicProgramming/blob/main/DefaultInterfaceImplementation.cs) 32 | - [Easy Clone Pattern](https://github.com/sabitkondakci/DynamicProgramming/blob/main/EasyClonePattern.cs) 33 | - [Effective Async Load with SemaphoreSlim](https://github.com/SabitKondakci/DynamicProgramming/blob/main/EffectiveAsyncLoadWithSemaphoreslim.cs) 34 | - [Enum HasFlag Method Implementation](https://github.com/SabitKondakci/DynamicProgramming/blob/main/EnumHasFlag.cs) 35 | - [Enum ToString via Switch & nameof()](https://github.com/SabitKondakci/DynamicProgramming/blob/main/EnumToString.cs) 36 | - [Equality Comparison Benchmark](https://github.com/SabitKondakci/DynamicProgramming/blob/main/EqualityBenchmark.cs) 37 | - [EqualityComparer.Default.Equals() Benchmark](https://github.com/SabitKondakci/DynamicProgramming/blob/main/EqualityComparer.cs) 38 | - [Extern Unmanaged Heap Allocation](https://github.com/SabitKondakci/DynamicProgramming/blob/main/ExternUnmanagedHeap.cs) 39 | - [Fibonacci via Memoization](https://github.com/SabitKondakci/DynamicProgramming/blob/main/FibonacciMemoization.cs) 40 | - [Fibonacci via Span & stackalloc](https://github.com/SabitKondakci/DynamicProgramming/blob/main/FibonacciSeriesGenWithSpan.cs) 41 | - [Find Min-Max via Tuples](https://github.com/SabitKondakci/DynamicProgramming/blob/main/FindMinMax.cs) 42 | - [Foreach Extensions via Tuples](https://github.com/SabitKondakci/DynamicProgramming/blob/main/ForeachExtension.cs) 43 | - [Function Pointer delegate*](https://github.com/SabitKondakci/DynamicProgramming/blob/main/FunctionPointer.cs) 44 | - [Has Duplicate? via HasSet](https://github.com/SabitKondakci/DynamicProgramming/blob/main/HasDuplicate.cs) 45 | - [IAsyncDisposable, IDisposable Implementation](https://github.com/SabitKondakci/DynamicProgramming/blob/main/IAsyncDisposableIDisposable.cs) 46 | - [IDisposable with SafeHandle Implementation](https://github.com/SabitKondakci/DynamicProgramming/blob/main/IDisposableSafeHandle.cs) 47 | - [Implicit Operator for Math.Pow(2,3) -> 2^3 = 8 ](https://github.com/SabitKondakci/DynamicProgramming/blob/main/ImplicitOperatorMathPow.cs) 48 | - [Job Sequencing & Deadline](https://github.com/SabitKondakci/DynamicProgramming/blob/main/JobSequencingDeadline.cs) 49 | - [JsonDOMExtension](https://github.com/SabitKondakci/DynamicProgramming/blob/main/JsonDOMExtension.cs) 50 | - [JsonNode, Topic Summary](https://github.com/SabitKondakci/DynamicProgramming/blob/main/JsonNodeSummary.cs) 51 | - [JsonSerializer, All Subjects](https://github.com/SabitKondakci/DynamicProgramming/blob/main/JsonSerializerSummary.cs) 52 | - [JsonWriter, Topic Summary](https://github.com/SabitKondakci/DynamicProgramming/blob/main/JsonWriterSummary.cs) 53 | - [Kestrel WebHostBuilder HTTP/2 Setting](https://github.com/SabitKondakci/DynamicProgramming/blob/main/KestrelWebHostBuilder.cs) 54 | - [Knapsack](https://github.com/SabitKondakci/DynamicProgramming/blob/main/KnapsackAlgorithm.cs) 55 | - [Knuth - Morris - Prat ](https://github.com/SabitKondakci/DynamicProgramming/blob/main/KnuthMorrisPratAlgorithm.cs) 56 | - [LINQ Equality Comparer](https://github.com/sabitkondakci/DynamicProgramming/blob/main/LINQEqualityComparer.cs) 57 | - [Lazy Fibonacci List](https://github.com/sabitkondakci/DynamicProgramming/blob/main/LazyFibonacciList.cs) 58 | - [Longest Common Subsequence](https://github.com/SabitKondakci/DynamicProgramming/blob/main/LongestCommonSubsequence.cs) 59 | - [Magic Square - Odd Size](https://github.com/SabitKondakci/DynamicProgramming/blob/main/MagicSquareForOddSizes.cs) 60 | - [Marshalling - Reverse Benchmark](https://github.com/SabitKondakci/DynamicProgramming/blob/main/MarshallBenchmark.cs) 61 | - [Marshalling - String Implementation](https://github.com/SabitKondakci/DynamicProgramming/blob/main/MarshallString.cs) 62 | - [Module Initializer & Static Constructor Alternative](https://github.com/SabitKondakci/DynamicProgramming/blob/main/ModuleInitializer.cs) 63 | - [MonitorTryEnter via Lock](https://github.com/SabitKondakci/DynamicProgramming/blob/main/MonitorTryEnter.cs) 64 | - [NQueen Problem In Detail](https://github.com/SabitKondakci/DynamicProgramming/blob/main/NQueenProblemInDetail.cs) 65 | - [Operator Overloading Full Implementation](https://github.com/SabitKondakci/DynamicProgramming/blob/main/OperatorOverloadingFull.cs) 66 | - [Parallel Aggregation Technique](https://github.com/SabitKondakci/DynamicProgramming/blob/main/ParallelAggregation.cs) 67 | - [Parallel Factorial Calculation](https://github.com/SabitKondakci/DynamicProgramming/blob/main/ParallelFactorialCalc.cs) 68 | - [Parallel Letter Frequency](https://github.com/SabitKondakci/DynamicProgramming/blob/main/ParallelLetterFrequency.cs) 69 | - [Parallel Foreach Async, OAuth Token](https://github.com/SabitKondakci/DynamicProgramming/blob/main/ParallelForEachAsync.cs) 70 | - [Parallel Prime Numbers](https://github.com/SabitKondakci/DynamicProgramming/blob/main/ParallelPrimeNumbers.cs) 71 | - [Pointer Chunk](https://github.com/SabitKondakci/DynamicProgramming/blob/main/PointerChunk.cs) 72 | - [Rabin & Karp String Matching](https://github.com/SabitKondakci/DynamicProgramming/blob/main/RabinKarpStringMatchingHashTechnique.cs) 73 | - [Record Protected Constructor](https://github.com/SabitKondakci/DynamicProgramming/blob/main/RecordCalculatedProperty.cs) 74 | - [Record Overriding Equals](https://github.com/SabitKondakci/DynamicProgramming/blob/main/RecordOverrideEquals.cs) 75 | - [SafeHandle Example](https://github.com/sabitkondakci/DynamicProgramming/blob/main/SafeHandleExample.cs) 76 | - [Shallow & Deep Copy](https://github.com/SabitKondakci/DynamicProgramming/blob/main/ShallowAndDeepCopy.cs) 77 | - [Struct Big Size Flags](https://github.com/sabitkondakci/DynamicProgramming/blob/main/StructBigSizeFlags.cs) 78 | - [Struct Defensive Copy](https://github.com/sabitkondakci/DynamicProgramming/blob/main/StructDefensiveCopy.cs) 79 | - [Subset Sum Max](https://github.com/SabitKondakci/DynamicProgramming/blob/main/SubsetSumMax.cs) 80 | - [Tail Recursion](https://github.com/SabitKondakci/DynamicProgramming/blob/main/TailRecursion.cs) 81 | - [Travelling Salesman](https://github.com/SabitKondakci/DynamicProgramming/blob/main/TravellingSalesmanAlgorithm.cs) 82 | - [Value Equality , Class -> Record Implementation](https://github.com/SabitKondakci/DynamicProgramming/blob/main/ValueEqualityImplementation.cs) 83 | - [ValueTask Benchmark -1_000_000 call-](https://github.com/SabitKondakci/DynamicProgramming/blob/main/ValueTaskBenchmark.cs) 84 | -------------------------------------------------------------------------------- /RabinKarpStringMatchingHashTechnique.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace DynamicProgrammingAlgorithms 8 | { 9 | class RabinKarpStringMatchingHashTechnique 10 | { 11 | // the method made use of hashing technique 12 | public bool RabinCarpMatchingCheck(string pattern, StringBuilder sampleString, bool caseInsensitive = false) 13 | { 14 | // if case insensitiveness is desired or not 15 | if (caseInsensitive) 16 | { 17 | pattern = pattern.ToLower(); 18 | sampleString = sampleString.Replace(sampleString.ToString(), sampleString.ToString().ToLower()); 19 | } 20 | 21 | int N = pattern.Length; 22 | //traverse the sampleString 23 | for (int i = 0; i < sampleString.Length; i++) 24 | { 25 | //if i+N reaches the max limit then break the loop, it simlpy means there is no match 26 | if (i + N > sampleString.Length) 27 | break; 28 | //compare hash codes of substrings which are size of N 29 | if (pattern.GetHashCode() == sampleString.ToString().Substring(i, N).GetHashCode()) 30 | return true; 31 | } 32 | 33 | return false; 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /RecordCalculatedProperty.cs: -------------------------------------------------------------------------------- 1 | void Main() 2 | { 3 | var point = new Point (1, 1); 4 | point.DistanceFromOrigin.Dump(); 5 | 6 | var point2 = point with { Y = 10 }; 7 | point2.DistanceFromOrigin.Dump(); // Works 8 | } 9 | 10 | record Point (double X, double Y) 11 | { 12 | double? _distance; 13 | public double DistanceFromOrigin => _distance ??= Math.Sqrt (X * X + Y * Y); 14 | 15 | protected Point (Point other) => (X, Y) = (other.X, other.Y); 16 | // protected Point (Point other) => (X, Y) = other; 17 | } 18 | -------------------------------------------------------------------------------- /RecordOverrideEquals.cs: -------------------------------------------------------------------------------- 1 | void Main() 2 | { 3 | var biden1 = new Student("Joe","Biden"); 4 | var biden2 = new Student("Joe","biden"); 5 | 6 | biden1.Equals(biden2).Dump(); 7 | } 8 | 9 | record Student (string FirstName, string LastName) 10 | { 11 | // this'll be consumed at runtime 12 | public virtual bool Equals(Student student) 13 | { 14 | if (student is null) 15 | return false; 16 | 17 | // If run-time types are not exactly the same, return false. 18 | if (this.EqualityContract != student.EqualityContract) 19 | return false; 20 | 21 | // Optimization for a common success case. 22 | if (object.ReferenceEquals(this, student)) 23 | return true; 24 | 25 | return (FirstName.ToLower() == student.FirstName.ToLower()) 26 | && (LastName.ToLower() == student.LastName.ToLower()); 27 | } 28 | 29 | public override int GetHashCode() => (FirstName,LastName).GetHashCode(); 30 | } 31 | -------------------------------------------------------------------------------- /SafeHandleExample.cs: -------------------------------------------------------------------------------- 1 | class BaseClassWithSafeHandle : IDisposable 2 | { 3 | // To detect redundant calls 4 | private bool _disposed; 5 | 6 | // Instantiate a SafeHandle instance. 7 | private SafeHandle _safeHandle = new SafeFileHandle(IntPtr.Zero, true); 8 | 9 | // Public implementation of Dispose pattern callable by consumers. 10 | public void Dispose() => Dispose(true); 11 | 12 | // Protected implementation of Dispose pattern. 13 | protected virtual void Dispose(bool disposing) 14 | { 15 | if (!_disposed) 16 | { 17 | if (disposing) 18 | { 19 | _safeHandle.Dispose(); 20 | } 21 | 22 | _disposed = true; 23 | } 24 | } 25 | } 26 | 27 | // When a base class implements SafeHandle 28 | class DerivedClassWithSafeHandle : BaseClassWithSafeHandle 29 | { 30 | // To detect redundant calls 31 | private bool _disposedValue; 32 | 33 | // Instantiate a SafeHandle instance. 34 | private SafeHandle _safeHandle = new SafeFileHandle(IntPtr.Zero, true); 35 | 36 | // Protected implementation of Dispose pattern. 37 | protected override void Dispose(bool disposing) 38 | { 39 | if (!_disposedValue) 40 | { 41 | if (disposing) 42 | { 43 | _safeHandle.Dispose(); 44 | } 45 | 46 | _disposedValue = true; 47 | } 48 | 49 | // Call base class implementation, Idempotent! 50 | base.Dispose(disposing); 51 | } 52 | } 53 | 54 | 55 | // When a base class implements Finalizer pattern 56 | class DerivedClassWithFinalizer : BaseClassWithFinalizer 57 | { 58 | // To detect redundant calls 59 | private bool _disposedValue; 60 | 61 | ~DerivedClassWithFinalizer() => this.Dispose(false); 62 | 63 | // Protected implementation of Dispose pattern. 64 | protected override void Dispose(bool disposing) 65 | { 66 | if (!_disposedValue) 67 | { 68 | if (disposing) 69 | { 70 | // TODO: dispose managed state (managed objects). 71 | } 72 | 73 | // TODO: free unmanaged resources (unmanaged objects) and override a finalizer below. 74 | // TODO: set large fields to null. 75 | _disposedValue = true; 76 | } 77 | 78 | // Call the base class implementation. 79 | base.Dispose(disposing); 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /ShallowAndDeepCopy.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace ShallowDeepCopy 7 | { 8 | class Program 9 | { 10 | static void Main(string[] args) 11 | { 12 | // Random Social Security Number Generator, which returns a tuple (int threeDigits, int twoDigits,int fourDigits) 13 | // xxx-xx-xxxx format 14 | SSNGenerator ssnGenerator = new(new Random()); 15 | 16 | Staff hrStaff = new(new QuickInfo("Jessy", "Herolt"), 17 | new DetailedInfo(Guid.NewGuid(), 18 | "0001-89938749928-388293", 19 | "Budgie Str. Cathood Avn. 33242 / 233", 20 | new DateTime(1990, 03, 1), ssnGenerator.Ssn), 21 | "dummyData"); 22 | 23 | 24 | Staff shallowCopy = hrStaff.ShallowCopy(); 25 | Staff deepCopy = hrStaff.DeepCopy(); 26 | 27 | Print(hrStaff,"Original"); 28 | 29 | // alter the values in hrStaff , DummyData is the only primitive type in Staff class 30 | hrStaff.QuickInformation.FirstName = "Dalton"; 31 | hrStaff.QuickInformation.LastName = "Mayer"; 32 | hrStaff.DummyData = "DummyData changed"; 33 | hrStaff.DetailedInformation.Id = Guid.NewGuid(); 34 | hrStaff.DetailedInformation.IBAN = "0001-19958649928-088293"; 35 | hrStaff.DetailedInformation.Address = "Nowhere"; 36 | hrStaff.DetailedInformation.BirthDate = new DateTime(1956, 1, 2); 37 | hrStaff.DetailedInformation.SSN = ssnGenerator.Ssn; 38 | 39 | Print(shallowCopy, "Shallow Copy"); 40 | Print(deepCopy, "Deep Copy"); 41 | 42 | 43 | static void Print(Staff hrStaff,string copyType) 44 | { 45 | Console.WriteLine($"{copyType}\n"); 46 | Console.WriteLine($"FirstName:{hrStaff.QuickInformation.FirstName}\nLastName:{hrStaff.QuickInformation.LastName}\nDummyData:{hrStaff.DummyData}\n" + 47 | $"Detailed Information:\n" + 48 | $" Id:{hrStaff.DetailedInformation.Id}\n IBAN:{hrStaff.DetailedInformation.IBAN}\n" + 49 | $" Address:{hrStaff.DetailedInformation.Address}\n BirthDate:{hrStaff.DetailedInformation.BirthDate}\n" + 50 | $" SSN:{hrStaff.DetailedInformation.SSN.treeDigits}-" + 51 | $"{hrStaff.DetailedInformation.SSN.twoDigits}-" + 52 | $"{hrStaff.DetailedInformation.SSN.fourDigits}\n"); 53 | } 54 | } 55 | } 56 | 57 | 58 | public class SSNGenerator 59 | { 60 | public (int threeDigits, int twoDigits, int fourDigits) Ssn => GenerateSSN(); 61 | private readonly Random _random; 62 | 63 | // struct doesn't accept a parameterless constructor 64 | // this is why I'm passing a random parameter 65 | public SSNGenerator(Random random) 66 | { 67 | _random = random; 68 | } 69 | 70 | private (int threeDigits, int twoDigits, int fourDigits) GenerateSSN() 71 | { 72 | 73 | var threeDigits = _random.Next(100, 1000); 74 | var twoDigits = _random.Next(10, 100); 75 | var fourDigits = _random.Next(1000, 10_000); 76 | 77 | return (threeDigits, twoDigits, fourDigits); 78 | } 79 | 80 | } 81 | 82 | public class QuickInfo 83 | { 84 | public QuickInfo(string firstName, string lastName) 85 | { 86 | FirstName = firstName; 87 | LastName = lastName; 88 | } 89 | public QuickInfo ShallowCopy() 90 | { 91 | return this.MemberwiseClone() as QuickInfo; 92 | } 93 | public string FirstName { get; set; } 94 | public string LastName { get; set; } 95 | 96 | } 97 | 98 | public class DetailedInfo 99 | { 100 | public DetailedInfo(Guid id, string iban, string address, DateTime birthDate, (int treeDigits, int twoDigits, int fourDigits) ssn) 101 | { 102 | Id = id; 103 | IBAN = iban; 104 | Address = address; 105 | BirthDate = birthDate; 106 | SSN = ssn; 107 | } 108 | 109 | public DetailedInfo ShallowCopy() 110 | { 111 | return this.MemberwiseClone() as DetailedInfo; 112 | } 113 | 114 | public Guid Id { get; set; } 115 | public string IBAN { get; set; } 116 | public string Address { get; set; } 117 | public DateTime BirthDate { get; set; } 118 | public (int treeDigits, int twoDigits, int fourDigits) SSN { get; set; } // 123-42-6476 format 119 | } 120 | 121 | public class Staff 122 | { 123 | public Staff(QuickInfo quicInfornamtion, DetailedInfo detailedInformation,string dummyData) 124 | { 125 | QuickInformation = quicInfornamtion; 126 | DetailedInformation = detailedInformation; 127 | DummyData = dummyData; 128 | } 129 | public QuickInfo QuickInformation{ get; set; } 130 | public DetailedInfo DetailedInformation { get; set; } 131 | public string DummyData { get; set; } 132 | 133 | public Staff ShallowCopy() 134 | { 135 | return MemberwiseClone() as Staff; 136 | } 137 | 138 | public Staff DeepCopy() 139 | { 140 | var deepCopy = this.MemberwiseClone() as Staff; 141 | deepCopy.DetailedInformation = this.DetailedInformation.ShallowCopy(); 142 | deepCopy.QuickInformation = this.QuickInformation.ShallowCopy(); 143 | return deepCopy; 144 | } 145 | } 146 | } 147 | -------------------------------------------------------------------------------- /StructBigSizeFlags.cs: -------------------------------------------------------------------------------- 1 | // LinqPad 6 evnironment 2 | // MSDN : https://docs.microsoft.com/en-us/dotnet/csharp/write-safe-efficient-code#use-ref-readonly-return-statements 3 | 4 | // create a global variable for SystemIOFlags, this will cut the need of "recreation of same struct on stack" on each call. 5 | private static readonly SystemIOFlags originValue = SystemIOFlags.RefOriginFlags; 6 | 7 | public void Main() 8 | { 9 | // reusable reference on stack 10 | ref readonly var originReference = ref originValue; 11 | 12 | originValue.Dump(); 13 | originReference.Dump(); 14 | 15 | } 16 | 17 | public struct SystemIOFlags 18 | { 19 | private byte _cancelled; 20 | public byte Cancelled { readonly get => _cancelled; set => _cancelled = value; } 21 | 22 | private byte _aborted; 23 | public byte Aborted { readonly get => _aborted; set => _aborted = value; } 24 | 25 | private byte _reset; 26 | public byte Reset { readonly get => _reset; set => _reset = value; } 27 | 28 | private byte _terminated; 29 | public byte Terminated { readonly get => _terminated; set => _terminated = value; } 30 | 31 | private byte _halted; 32 | public byte Halted { readonly get => _halted; set => _halted = value; } 33 | 34 | private byte _continuing; 35 | public byte Continuing { readonly get => _continuing; set => _continuing = value; } 36 | 37 | // and more .... 38 | 39 | public SystemIOFlags(byte cancelled, byte aborted, byte reset 40 | , byte terminated, byte halted, byte continuing) 41 | { 42 | _cancelled = cancelled; 43 | _aborted = aborted; 44 | _reset = reset; 45 | _terminated = terminated; 46 | _halted = halted; 47 | _continuing = continuing; 48 | 49 | } 50 | 51 | // create a long-term instance of SystemIOFlags 52 | private static SystemIOFlags originFlags = 53 | new SystemIOFlags(cancelled:1, aborted:2, reset:3 54 | ,terminated:4, halted:5,continuing:7); 55 | 56 | // use the same reference on each call, this should reduce some overheads. 57 | public static ref readonly SystemIOFlags RefOriginFlags => ref originFlags; 58 | } 59 | -------------------------------------------------------------------------------- /StructDefensiveCopy.cs: -------------------------------------------------------------------------------- 1 | // LinqPad6 2 | 3 | class Program 4 | { 5 | static void Main(string[] args) 6 | { 7 | var Summary = BenchmarkRunner.Run(); 8 | } 9 | } 10 | 11 | public struct MutableStructReadonlyGet 12 | { 13 | // readonly get : prevent defensive copy on creating struct instances 14 | public double X { readonly get => x; set => x = value; } 15 | public double Y { readonly get => y; set => y = value; } 16 | public double Z { readonly get => z; set => z = value; } 17 | 18 | private double z; 19 | private double y; 20 | private double x; 21 | 22 | // mocking a big struct by adding dummy fields 23 | private double a; 24 | private double b; 25 | private double c; 26 | private double d; 27 | private double e; 28 | private double f; 29 | private double g; 30 | private double h; 31 | 32 | public MutableStructReadonlyGet(double x = 0, double y = 0, double z = 0) 33 | { 34 | this.x = x; 35 | this.y = y; 36 | this.z = z; 37 | 38 | this.a = 1; 39 | this.b = 2; 40 | this.c = 3; 41 | this.d = 4; 42 | this.e = 5; 43 | this.f = 6; 44 | this.g = 7; 45 | this.h = 8; 46 | } 47 | } 48 | 49 | public class Benchmarks 50 | { 51 | MutableStructReadonlyGet mutableStructWithReadonlyGet; 52 | 53 | [GlobalSetup] 54 | public void Setup() 55 | { 56 | mutableStructWithReadonlyGet = new MutableStructReadonlyGet(1.9, 9.3); 57 | } 58 | 59 | [Benchmark] 60 | public double MutableReadOnlyAddByDefensiveCopy() 61 | { 62 | return add_by_type(mutableStructWithReadonlyGet); 63 | } 64 | 65 | [Benchmark] 66 | public double MutableReadonlyAddByNoCopy() 67 | { 68 | return add_by_in(in mutableStructWithReadonlyGet); 69 | } 70 | 71 | public double add_by_type(MutableStructReadonlyGet s) 72 | { 73 | return s.X + s.Y; 74 | } 75 | 76 | // in : prevent defesive copy on method calls 77 | public double add_by_in(in MutableStructReadonlyGet s) 78 | { 79 | return s.X + s.Y; 80 | } 81 | } 82 | 83 | //| Method | Mean | Error | StdDev | Median | 84 | //| ------------------------------------ | ---------:| ---------:| ---------:| ---------:| 85 | //| MutableReadOnlyAddByDefensiveCopy | 7.6793 ns | 0.0799 ns | 0.0747 ns | 7.7027 ns | 86 | //| MutableReadonlyAddByNoCopy | 0.0039 ns | 0.0130 ns | 0.0115 ns | 0.0000 ns | 87 | 88 | 89 | /* 90 | BenchmarkDotNet=v0.13.1, OS=Windows 10.0.19044.1586 (21H2) 91 | Intel Core i5-3210M CPU 2.50GHz (Ivy Bridge), 1 CPU, 4 logical and 2 physical cores .NET SDK=6.0.200 92 | [Host] : .NET 5.0.15 (5.0.1522.11506), X64 RyuJIT 93 | */ 94 | -------------------------------------------------------------------------------- /SubsetSumMax.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace DynamicProgrammingAlgorithms 8 | { 9 | class SubsetSumMax 10 | { 11 | // Method shows the proper values which add up to maxSum 12 | // it returns a list where arrays are stored 13 | // maxSum : desired value for maximum sum 14 | // valueSet: an array of values 15 | public List SubsetListWithMaxSum(long maxSum, params long[] valueSet) 16 | { 17 | List tempListSet=new List();//a list to store arrays 18 | List tempList=new List();//a list to store values 19 | 20 | int count = 0; 21 | bool[,] controlBoolArray = Bool2DArrray(maxSum, valueSet);//2DBoolArray is created 22 | 23 | for (int i = valueSet.Length-1; i >=0; i--) 24 | { 25 | count = i; 26 | tempList.Clear();//in every cycle , clear the tempList 27 | 28 | if (controlBoolArray[i, maxSum])//if value is true , jump in 29 | { 30 | tempList.Add(valueSet[i]);//add the value at row 31 | 32 | for (long j = maxSum - valueSet[count]; j >= 0; j-=valueSet[count]) 33 | { 34 | if (j == 0) 35 | { 36 | //Because of the fact that array is a collection of references, 37 | //when I change,clear,sort it affects its refence copies 38 | //so that I created another list copy with a different reference 39 | long[] tempListCopy = new long[tempList.Count]; 40 | tempList.CopyTo(tempListCopy);//copying values to newly created list 41 | tempListSet.Add(tempListCopy);//add an array to list 42 | break; 43 | } 44 | 45 | while (count>=0)// count starts from current location of i which follows [i,maxSum] 46 | { 47 | //check upper location, if it's true then count-- 48 | if (count!=0 && controlBoolArray[count - 1, j]) 49 | count--; 50 | else if(count - 1 == 0 || controlBoolArray[count - 1 , j]==false) 51 | { 52 | //if process bumps into a false label or count==1 then insert the value 53 | tempList.Add(valueSet[count]); 54 | break; 55 | } 56 | 57 | } 58 | } 59 | }//if statement's false , break the traverse 60 | else 61 | break; 62 | } 63 | 64 | return tempListSet; 65 | } 66 | 67 | //this method creates a bool array, which is the essence of table technique 68 | private bool[,] Bool2DArrray(long maxSum, params long[] valueSet) 69 | { 70 | Array.Sort(valueSet);//system only works with sorted sets 71 | 72 | bool[,] myBoolTable=new bool[valueSet.Length,maxSum+1];//all values are false by default 73 | for (int i = 0; i < valueSet.Length; i++) 74 | myBoolTable[i, 0] = true;//0.column is set to true 75 | 76 | for (int i = 0; i < valueSet.Length; i++)//traverse whole table 77 | { 78 | for (int j = 1; j < maxSum + 1; j++) 79 | { 80 | if (i == 0) 81 | { 82 | if (j == valueSet[0]) 83 | myBoolTable[0, j] = true; 84 | } 85 | else 86 | { 87 | if (j < valueSet[i]) 88 | { 89 | myBoolTable[i, j] = myBoolTable[i - 1, j]; 90 | } 91 | else if(j==valueSet[i]) 92 | { 93 | myBoolTable[i, j] = true; 94 | } 95 | else 96 | { 97 | if (myBoolTable[i-1, j]) 98 | myBoolTable[i, j] = true; 99 | else 100 | { 101 | if (myBoolTable[i - 1, j - valueSet[i]]) 102 | myBoolTable[i, j] = true; 103 | else 104 | myBoolTable[i, j] = false; 105 | } 106 | } 107 | } 108 | 109 | } 110 | } 111 | 112 | return myBoolTable; 113 | } 114 | } 115 | } 116 | -------------------------------------------------------------------------------- /TailRecursion.cs: -------------------------------------------------------------------------------- 1 | 2 | // tail recursion, function calls itself as the last action 3 | // so that it reuses the same stack frame, no-overflow 4 | [MethodImpl(MethodImplOptions.AggressiveOptimization)] 5 | long Fact(long n, long a) 6 | { 7 | if(n==0) 8 | return a; 9 | 10 | // first Fact() call doesn't wait for the second Fact() call. 11 | // once upon termination, the previously pushed recursive call is popped and 12 | // this stack space is replaced by a brand new recursive call being pushed. 13 | // the tail-recursive function can execute in constant stack space 14 | // it’s just efficient as an equivalent iterative process. 15 | return Fact(n-1,a*n); 16 | } 17 | 18 | // recursive call, fills up the stack frame till it overflows 19 | long Factorial(int n) 20 | { 21 | if (n < 2) 22 | return 1; 23 | 24 | // first Factorial() call has to wait for other 25 | // n * Factorial() calls, it'll be stacked up 26 | // till the overflow. 27 | return n * Factorial(n - 1); 28 | } 29 | 30 | // tail recursion for fibonacci series 31 | [MethodImpl(MethodImplOptions.AggressiveOptimization)] 32 | long Fibo(int term, long prev = 0L, long curr = 1L) 33 | { 34 | if(term == 0) 35 | return prev; 36 | 37 | return Fibo(term - 1, curr, curr + prev); 38 | } 39 | 40 | // implementation with Tuple 41 | long Fibonacci(int n) 42 | { 43 | if(n == 0) return 0; 44 | if(n == 1) return 1; 45 | 46 | var (prev, curr) = (0L, 1L); 47 | for (int i = 2; i <= n; i++) 48 | (prev, curr) = (curr, curr + prev); 49 | 50 | return curr; 51 | } 52 | 53 | -------------------------------------------------------------------------------- /TravellingSalesmanAlgorithm.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace GraphTheoryInDetail 8 | { 9 | /* 10 | An implementation of the traveling salesman problem in C# using dynamic programming to improve 11 | the time complexity from O(n!) to O(n^2 * 2^n). 12 | 13 | Time Complexity: O(n^2 * 2^n) Space Complexity: O(n * 2^n) 14 | 15 | The main source code in Java belongs to William Fiset 16 | Repository Origin :https://github.com/williamfiset/Algorithms/blob/master/src/main/java/com/williamfiset/algorithms/graphtheory/TspDynamicProgrammingIterative.java 17 | */ 18 | 19 | /* 20 | * Before starting off, 21 | * be sure that all element of your matrix is of double.PositiveInfinity; 22 | * 23 | * for (int i = 0; i < 6; i++) 24 | { 25 | for (int j = 0; j < 6; j++) 26 | { 27 | distanceMatrix[i, j] = double.PositiveInfinity; 28 | } 29 | } 30 | */ 31 | public class TravelingSalesmanProblem 32 | { 33 | private int N, start; 34 | private double[,] distance; 35 | private List tour; 36 | private double minTourCost; 37 | private bool ranSolver; 38 | 39 | public TravelingSalesmanProblem(int start, double[,] distance) 40 | { 41 | N = distance.GetLength(0); 42 | 43 | if (N <= 2) throw new IndexOutOfRangeException("N <= 2 not yet supported."); 44 | if (N != distance.GetLength(0)) throw new InvalidOperationException("Matrix must be square (n x n)"); 45 | if (start < 0 || start >= N) throw new IndexOutOfRangeException("Invalid start node."); 46 | if (N > 32) 47 | throw new InvalidOperationException( 48 | "Matrix too large! A matrix that size for the DP TSP problem with a time complexity of" 49 | + "O(n^2*2^n) requires way too much computation for any modern home computer to handle"); 50 | 51 | this.start = start; 52 | this.distance = distance; 53 | this.tour = new List(); 54 | this.minTourCost = double.PositiveInfinity; 55 | this.ranSolver = false; 56 | } 57 | 58 | // Returns the optimal tour for the traveling salesman problem. 59 | public List GetTour() 60 | { 61 | if (!ranSolver) 62 | Solve(); 63 | 64 | return tour; 65 | } 66 | 67 | // Returns the minimal tour cost. 68 | public double GetTourCost() 69 | { 70 | if (!ranSolver) 71 | Solve(); 72 | 73 | return minTourCost; 74 | } 75 | 76 | // Solves the traveling salesman problem and caches solution. 77 | private void Solve() 78 | { 79 | 80 | if (ranSolver) return; 81 | 82 | int END_STATE = (1 << N) - 1; 83 | double[,] memo = new double[N, 1 << N]; 84 | 85 | // Add all outgoing edges from the starting node to memo table. 86 | for (int end = 0; end < N; end++) 87 | { 88 | if (end == start) 89 | continue; 90 | 91 | memo[end, (1 << start) | (1 << end)] = distance[start, end]; 92 | } 93 | 94 | for (int r = 3; r <= N; r++) 95 | { 96 | foreach (int subset in Combinations(r, N)) 97 | { 98 | if (NotIn(start, subset)) continue; 99 | for (int next = 0; next < N; next++) 100 | { 101 | if (next == start || NotIn(next, subset)) continue; 102 | int subsetWithoutNext = subset ^ (1 << next); 103 | double minDist = double.PositiveInfinity; 104 | 105 | for (int end = 0; end < N; end++) 106 | { 107 | if (end == start || end == next || NotIn(end, subset)) 108 | continue; 109 | 110 | double newDistance = memo[end, subsetWithoutNext] + distance[end, next]; 111 | if (newDistance < minDist) 112 | { 113 | minDist = newDistance; 114 | } 115 | } 116 | 117 | memo[next, subset] = minDist; 118 | } 119 | } 120 | } 121 | 122 | // Connect tour back to starting node and minimize cost. 123 | for (int i = 0; i < N; i++) 124 | { 125 | if (i == start) 126 | continue; 127 | 128 | double tourCost = memo[i, END_STATE] + distance[i, start]; 129 | if (tourCost < minTourCost) 130 | { 131 | minTourCost = tourCost; 132 | } 133 | } 134 | 135 | int lastIndex = start; 136 | int state = END_STATE; 137 | tour.Add(start); 138 | 139 | // Reconstruct TSP path from memo table. 140 | for (int i = 1; i < N; i++) 141 | { 142 | 143 | int bestIndex = -1; 144 | double bestDist = double.PositiveInfinity; 145 | for (int j = 0; j < N; j++) 146 | { 147 | if (j == start || NotIn(j, state)) 148 | continue; 149 | 150 | double newDist = memo[j, state] + distance[j, lastIndex]; 151 | if (newDist < bestDist) 152 | { 153 | bestIndex = j; 154 | bestDist = newDist; 155 | } 156 | } 157 | 158 | tour.Add(bestIndex); 159 | state = state ^ (1 << bestIndex); 160 | lastIndex = bestIndex; 161 | } 162 | 163 | tour.Add(start); 164 | tour.Reverse(); 165 | 166 | ranSolver = true; 167 | } 168 | 169 | private bool NotIn(int elem, int subset) 170 | { 171 | return ((1 << elem) & subset) == 0; 172 | } 173 | 174 | // This method generates all bit sets of size n where r bits 175 | // are set to one. The result is returned as a list of integer masks. 176 | private List Combinations(int r, int n) 177 | { 178 | List subsets = new List(); 179 | Combinations(0, 0, r, n, subsets); 180 | return subsets; 181 | } 182 | 183 | // To find all the combinations of size r we need to recurse until we have 184 | // selected r elements (aka r = 0), otherwise if r != 0 then we still need to select 185 | // an element which is found after the position of our last selected element 186 | private void Combinations(int set, int at, int r, int n, List subsets) 187 | { 188 | 189 | // Return early if there are more elements left to select than what is available. 190 | int elementsLeftToPick = n - at; 191 | if (elementsLeftToPick < r) return; 192 | 193 | // We selected 'r' elements so we found a valid subset! 194 | if (r == 0) 195 | { 196 | subsets.Add(set); 197 | } 198 | else 199 | { 200 | for (int i = at; i < n; i++) 201 | { 202 | // Try including this element 203 | set ^= (1 << i); 204 | 205 | Combinations(set, i + 1, r - 1, n, subsets); 206 | 207 | // Backtrack and try the instance where we did not include this element 208 | set ^= (1 << i); 209 | } 210 | } 211 | } 212 | } 213 | 214 | } 215 | -------------------------------------------------------------------------------- /ValueEqualityImplementation.cs: -------------------------------------------------------------------------------- 1 | namespace ValueEqualityClass 2 | { 3 | class TwoDPoint : IEquatable 4 | { 5 | public int X { get; private set; } 6 | public int Y { get; private set; } 7 | 8 | public TwoDPoint(int x, int y) 9 | { 10 | if (x is (< 1 or > 640) || y is (< 1 or > 480)) 11 | { 12 | throw new ArgumentException("640x480 2D Model, 1 <= x <= 640 & 1 <= y <= 480"); 13 | } 14 | this.X = x; 15 | this.Y = y; 16 | } 17 | 18 | // TwoDPoint clone ctor 19 | protected TwoDPoint(TwoDPoint pointObject) 20 | { 21 | X = pointObject.X; 22 | Y = pointObject.Y; 23 | } 24 | 25 | protected virtual Type EqualityContract => typeof(TwoDPoint); 26 | 27 | public virtual TwoDPoint Clone() => new TwoDPoint(this); 28 | 29 | public override bool Equals(object obj) => this.Equals(obj as TwoDPoint); 30 | 31 | // it can be overriden by another virtual bool Equals method. 32 | public virtual bool Equals(TwoDPoint point) 33 | { 34 | if (point is null) 35 | return false; 36 | 37 | // If run-time types are not exactly the same, return false. 38 | if (this.EqualityContract != point.EqualityContract) 39 | return false; 40 | 41 | // Optimization for a common success case. 42 | if (object.ReferenceEquals(this, point)) 43 | return true; 44 | 45 | // Return true if the fields match. 46 | // Note that the base class is not invoked because it is 47 | // System.Object, which defines Equals as reference equality. 48 | return (X == point.X) && (Y == point.Y); 49 | } 50 | 51 | public override int GetHashCode() => (X, Y).GetHashCode(); 52 | 53 | public static bool operator ==(TwoDPoint left, TwoDPoint right) 54 | { 55 | if (left is null) 56 | { 57 | if (right is null) 58 | { 59 | return true; 60 | } 61 | // Only the left side is null. 62 | return false; 63 | } 64 | // Equals handles case of null on right side. 65 | return left.Equals(right); 66 | } 67 | 68 | public static bool operator !=(TwoDPoint left, TwoDPoint right) => !(left == right); 69 | } 70 | 71 | // For the sake of simplicity, assume a ThreeDPoint IS a TwoDPoint. 72 | class ThreeDPoint : TwoDPoint, IEquatable 73 | { 74 | public int Z { get; private set; } 75 | 76 | public ThreeDPoint(int x, int y, int z) : base(x, y) 77 | { 78 | if ((z < 1) || (z > 2000)) 79 | { 80 | throw new ArgumentException("Point must be in range 1 - 2000"); 81 | } 82 | this.Z = z; 83 | } 84 | 85 | // ThreeDPoint clone ctor 86 | protected ThreeDPoint(ThreeDPoint pointObj):base(pointObj) 87 | { 88 | Z = pointObj.Z; 89 | } 90 | 91 | public override TwoDPoint Clone() => new ThreeDPoint(this); 92 | 93 | protected override Type EqualityContract => typeof(ThreeDPoint); 94 | 95 | public override bool Equals(object obj) => this.Equals(obj as ThreeDPoint); 96 | 97 | public virtual bool Equals(ThreeDPoint point) 98 | { 99 | if (point is null) 100 | return false; 101 | 102 | // If run-time types are not exactly the same, return false. 103 | if (this.EqualityContract != point.EqualityContract) 104 | return false; 105 | 106 | // Optimization for a common success case. 107 | if (Object.ReferenceEquals(this, point)) 108 | return true; 109 | 110 | // Check properties that this class declares. 111 | if (this.Z == point.Z) 112 | { 113 | // Let base class check its own fields 114 | // and do the run-time type comparison. 115 | return base.Equals(point as TwoDPoint); 116 | } 117 | 118 | return false; 119 | 120 | } 121 | 122 | public override int GetHashCode() => (X, Y, Z).GetHashCode(); 123 | 124 | public static bool operator ==(ThreeDPoint left, ThreeDPoint right) 125 | { 126 | if (left is null) 127 | { 128 | if (right is null) 129 | { 130 | // null == null = true. 131 | return true; 132 | } 133 | 134 | // Only the left side is null. 135 | return false; 136 | } 137 | // Equals handles the case of null on right side. 138 | return left.Equals(right); 139 | } 140 | 141 | public static bool operator !=(ThreeDPoint left, ThreeDPoint right) => !(left == right); 142 | } 143 | 144 | class Program 145 | { 146 | static void Main(string[] args) 147 | { 148 | TwoDPoint pointT = new TwoDPoint(3, 4); 149 | ThreeDPoint pointA = new ThreeDPoint(3, 4, 5); 150 | ThreeDPoint pointB = new ThreeDPoint(3, 4, 5); 151 | ThreeDPoint pointC = null; 152 | 153 | var pointTClone = pointT.Clone(); 154 | var pointBClone = pointB.Clone(); 155 | 156 | string i = "Comparer"; 157 | 158 | Console.WriteLine("pointA.Equals(pointB) = {0}", pointA.Equals(pointB)); // true 159 | Console.WriteLine("pointA == pointB = {0}", pointA == pointB); // true 160 | Console.WriteLine("null comparison = {0}", pointA.Equals(pointC)); // false 161 | Console.WriteLine("Compare to some other type = {0}", pointA.Equals(i)); // false 162 | 163 | TwoDPoint pointD = null; 164 | TwoDPoint pointE = null; 165 | 166 | Console.WriteLine("Two null TwoDPoints are equal: {0}", pointD == pointE); // true 167 | 168 | pointE = new TwoDPoint(3, 4); 169 | Console.WriteLine("(pointE == pointA) = {0}", pointE == pointA); // false 170 | Console.WriteLine("(pointA == pointE) = {0}", pointA == pointE); // false 171 | Console.WriteLine("(pointA != pointE) = {0}", pointA != pointE); // true 172 | 173 | System.Collections.ArrayList list = new System.Collections.ArrayList(); 174 | list.Add(new ThreeDPoint(3, 4, 5)); 175 | 176 | Console.WriteLine("pointE.Equals(list[0]): {0}", pointE.Equals(list[0])); // false 177 | Console.WriteLine("pointA.Equals(list[0]): {0}", pointA.Equals(list[0])); // true 178 | 179 | } 180 | } 181 | 182 | } 183 | -------------------------------------------------------------------------------- /ValueTaskBenchmark.cs: -------------------------------------------------------------------------------- 1 | // LINQPad6 .Net5 2 | void Main() 3 | { 4 | BenchmarkRunner.Run(); 5 | } 6 | 7 | [MemoryDiagnoser] 8 | public class VTaskBench 9 | { 10 | Dictionary _cache; 11 | string[] names; 12 | Random random; 13 | 14 | [GlobalSetup] 15 | public void Setup() 16 | { 17 | random = new(); 18 | _cache = new(); 19 | names = new string[] 20 | { 21 | "sabitkondakci","serhatcan","jimmy","mojombo","defunkt" 22 | ,"pjhyett","wycats","ezmobius","ivey" 23 | }; 24 | } 25 | 26 | public async Task GetUserInfoTaskAsync(string username) 27 | { 28 | string userInfo = _cache.ContainsKey(username) 29 | ? _cache[username] : string.Empty; 30 | 31 | if (userInfo != string.Empty) 32 | return userInfo; 33 | 34 | string url = "https://api.github.com/users/" + username + "/repos"; 35 | using (var client = new HttpClient()) 36 | { 37 | client.DefaultRequestHeaders.Accept.Clear(); 38 | 39 | client.DefaultRequestHeaders.Accept 40 | .Add(new MediaTypeWithQualityHeaderValue("application/vnd.github.v3+json")); 41 | 42 | client.DefaultRequestHeaders.Add("User-Agent", 43 | ".NET Foundation Repository Reporter"); 44 | 45 | var freshUserInfo = await client.GetStringAsync(url); 46 | _cache.TryAdd(username, freshUserInfo); 47 | 48 | return freshUserInfo; 49 | } 50 | } 51 | 52 | public async ValueTask GetUserInfoValueTaskAsync(string username) 53 | { 54 | string userInfo = _cache.ContainsKey(username) 55 | ? _cache[username] : string.Empty; 56 | 57 | if (userInfo != string.Empty) 58 | return userInfo; 59 | 60 | string url = "https://api.github.com/users/" + username + "/repos"; 61 | using (var client = new HttpClient()) 62 | { 63 | client.DefaultRequestHeaders.Accept.Clear(); 64 | 65 | client.DefaultRequestHeaders.Accept 66 | .Add(new MediaTypeWithQualityHeaderValue("application/vnd.github.v3+json")); 67 | 68 | client.DefaultRequestHeaders.Add("User-Agent", 69 | ".NET Foundation Repository Reporter"); 70 | 71 | var freshUserInfo = await client.GetStringAsync(url); 72 | _cache.TryAdd(username, freshUserInfo); 73 | 74 | return freshUserInfo; 75 | } 76 | } 77 | 78 | [Benchmark] 79 | public async Task TaskTest() 80 | { 81 | for (int i = 0; i < 1_000_000; i++) 82 | { 83 | string randomName = names[random.Next(0,9)]; 84 | string info = await GetUserInfoTaskAsync(randomName); 85 | } 86 | } 87 | 88 | [Benchmark] 89 | public async Task ValueTaskTest() 90 | { 91 | 92 | for (int i = 0; i < 1_000_000; i++) 93 | { 94 | string randomName = names[random.Next(0, 9)]; 95 | string info = await GetUserInfoValueTaskAsync(randomName); 96 | } 97 | } 98 | } 99 | --------------------------------------------------------------------------------