├── .gitignore
├── 03-GameMap
├── 03-GameMap.csproj
└── Program.cs
├── 03-MonthNames
├── 03-MonthNames.csproj
└── Program.cs
├── 03-MultiplicationTable
├── 03-MultiplicationTable.csproj
└── Program.cs
├── 03-SortingAlgorithms
├── 03-SortingAlgorithms.csproj
├── AbstractSort.cs
├── BubbleSort.cs
├── HeapSort.cs
├── InsertionSort.cs
├── MergeSort.cs
├── Program.cs
├── Quicksort.cs
├── SelectionSort.cs
└── ShellSort.cs
├── 03-YearlyTransportPlan
├── 03-YearlyTransportPlan.csproj
├── MeanEnum.cs
└── Program.cs
├── 04-AddressBook
├── 04-AddressBook.csproj
├── Person.cs
└── Program.cs
├── 04-ArtGallery
├── 04-ArtGallery.csproj
├── CircularEnumerator.cs
├── CircularLinkedList.cs
├── CircularLinkedListExtensions.cs
└── Program.cs
├── 04-AverageValue
├── 04-AverageValue.csproj
└── Program.cs
├── 04-BookReader
├── 04-BookReader.csproj
├── Page.cs
└── Program.cs
├── 04-ListOfPeople
├── 04-ListOfPeople.csproj
├── Person.cs
└── Program.cs
├── 04-SpinTheWheel
├── 04-SpinTheWheel.csproj
├── CircularEnumerator.cs
├── CircularLinkedList.cs
├── CircularLinkedListExtensions.cs
└── Program.cs
├── 05-CallCenterManyConsultants
├── 05-CallCenterManyConsultants.csproj
├── CallCenter.cs
├── IncomingCall.cs
└── Program.cs
├── 05-CallCenterPrioritySupport
├── 05-CallCenterPrioritySupport.csproj
├── CallCenter.cs
├── IncomingCall.cs
└── Program.cs
├── 05-CallCenterSingleConsultant
├── 05-CallCenterSingleConsultant.csproj
├── CallCenter.cs
├── IncomingCall.cs
└── Program.cs
├── 05-GravityRollerCoaster
├── 05-GravityRollerCoaster.csproj
├── CircularQueue.cs
└── Program.cs
├── 05-ReversingWord
├── 05-ReversingWord.csproj
└── Program.cs
├── 05-TowerOfHanoi
├── 05-TowerOfHanoi.csproj
├── Game.cs
├── Program.cs
└── Visualization.cs
├── 06-Coupons
├── 06-Coupons.csproj
└── Program.cs
├── 06-Encyclopedia
├── 06-Encyclopedia.csproj
└── Program.cs
├── 06-PhoneBook
├── 06-PhoneBook.csproj
└── Program.cs
├── 06-ProductLocation
├── 06-ProductLocation.csproj
└── Program.cs
├── 06-RemovingDuplicates
├── 06-RemovingDuplicates.csproj
└── Program.cs
├── 06-SwimmingPools
├── 06-SwimmingPools.csproj
├── PoolTypeEnum.cs
└── Program.cs
├── 06-UserDetails
├── 06-UserDetails.csproj
├── Employee.cs
└── Program.cs
├── 07-AutoComplete
├── 07-AutoComplete.csproj
├── Countries.txt
├── Program.cs
├── Trie.cs
└── TrieNode.cs
├── 07-BSTVisualization
├── 07-BSTVisualization.csproj
└── Program.cs
├── 07-CompanyStructure
├── 07-CompanyStructure.csproj
├── Person.cs
└── Program.cs
├── 07-HierarchyOfIdentifiers
├── 07-HierarchyOfIdentifiers.csproj
└── Program.cs
├── 07-SimpleQuiz
├── 07-SimpleQuiz.csproj
└── Program.cs
├── 07-Tree
├── 07-Tree.csproj
├── BinarySearchTree.cs
├── BinaryTree.cs
├── BinaryTreeNode.cs
├── TraversalEnum.cs
├── Tree.cs
└── TreeNode.cs
├── 08-DirectedWeightedEdges
├── 08-DirectedWeightedEdges.csproj
└── Program.cs
├── 08-Graph
├── 08-Graph.csproj
├── Edge.cs
├── Graph.cs
├── Node.cs
└── Subset.cs
├── 08-PathInGame
├── 08-PathInGame.csproj
└── Program.cs
├── 08-TelecommunicationCable
├── 08-TelecommunicationCable.csproj
└── Program.cs
├── 08-UndirectedUnweightedEdges
├── 08-UndirectedUnweightedEdges.csproj
└── Program.cs
├── 08-VoivodeshipMap
├── 08-VoivodeshipMap.csproj
└── Program.cs
├── 09-ClosestPairOfPoints
├── 09-ClosestPairOfPoints.csproj
├── Point.cs
├── Program.cs
└── Result.cs
├── 09-FibonacciSeries
├── 09-FibonacciSeries.csproj
└── Program.cs
├── 09-FractalGeneration
├── 09-FractalGeneration.csproj
└── Program.cs
├── 09-MinimumCoinChange
├── 09-MinimumCoinChange.csproj
└── Program.cs
├── 09-PasswordGuess
├── 09-PasswordGuess.csproj
└── Program.cs
├── 09-RatInMaze
├── 09-RatInMaze.csproj
└── Program.cs
├── 09-SudokuPuzzle
├── 09-SudokuPuzzle.csproj
└── Program.cs
├── 09-TitleGuess
├── 09-TitleGuess.csproj
├── Individual.cs
└── Program.cs
├── Examples.sln
├── LICENSE
└── README.md
/.gitignore:
--------------------------------------------------------------------------------
1 | *.suo
2 | *.user
3 | [Dd]ebug/
4 | [Rr]elease/
5 | [Rr]eleases/
6 | x64/
7 | x86/
8 | [Bb]in/
9 | [Oo]bj/
10 | .vs/
11 |
--------------------------------------------------------------------------------
/03-GameMap/03-GameMap.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | net8.0
6 | _03_GameMap
7 | enable
8 | enable
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/03-GameMap/Program.cs:
--------------------------------------------------------------------------------
1 | // GAME MAP
2 | // Chapter 3 (Arrays and Sorting)
3 | // C# Data Structures and Algorithms, Second Edition
4 |
5 | using System.Text;
6 |
7 | char[,] map =
8 | {
9 | { 's', 's', 's', 'g', 'g', 'g', 'g', 'g' },
10 | { 's', 's', 's', 'g', 'g', 'g', 'g', 'g' },
11 | { 's', 's', 's', 's', 's', 'b', 'b', 'b' },
12 | { 's', 's', 's', 's', 's', 'b', 's', 's' },
13 | { 'w', 'w', 'w', 'w', 'w', 'b', 'w', 'w' },
14 | { 'w', 'w', 'w', 'w', 'w', 'b', 'w', 'w' }
15 |
16 | };
17 | Console.OutputEncoding = Encoding.UTF8;
18 | for (int r = 0; r < map.GetLength(0); r++)
19 | {
20 | for (int c = 0; c < map.GetLength(1); c++)
21 | {
22 | Console.ForegroundColor = GetColor(map[r, c]);
23 | Console.Write(GetChar(map[r, c]) + " ");
24 | }
25 | Console.WriteLine();
26 | }
27 | Console.ResetColor();
28 |
29 |
30 | ConsoleColor GetColor(char terrain)
31 | {
32 | return terrain switch
33 | {
34 | 'g' => ConsoleColor.Green,
35 | 's' => ConsoleColor.Yellow,
36 | 'w' => ConsoleColor.Blue,
37 | _ => ConsoleColor.DarkGray
38 | };
39 | }
40 |
41 | char GetChar(char terrain)
42 | {
43 | return terrain switch
44 | {
45 | 'g' => '\u201c',
46 | 's' => '\u25cb',
47 | 'w' => '\u2248',
48 | _ => '\u25cf'
49 | };
50 | }
51 |
--------------------------------------------------------------------------------
/03-MonthNames/03-MonthNames.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | net8.0
6 | _03_MonthNames
7 | enable
8 | enable
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/03-MonthNames/Program.cs:
--------------------------------------------------------------------------------
1 | // MONTH NAMES
2 | // Chapter 3 (Arrays and Sorting)
3 | // C# Data Structures and Algorithms, Second Edition
4 |
5 | using System.Globalization;
6 |
7 | CultureInfo culture = new("en");
8 | string[] months = new string[12];
9 | for (int month = 1; month <= 12; month++)
10 | {
11 | DateTime firstDay = new(DateTime.Now.Year, month, 1);
12 | string name = firstDay.ToString("MMMM", culture);
13 | months[month - 1] = name;
14 | }
15 |
16 | foreach (string m in months)
17 | {
18 | Console.WriteLine(m);
19 | }
20 |
--------------------------------------------------------------------------------
/03-MultiplicationTable/03-MultiplicationTable.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | net8.0
6 | _03_MultiplicationTable
7 | enable
8 | enable
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/03-MultiplicationTable/Program.cs:
--------------------------------------------------------------------------------
1 | // MULTIPLICATION TABLE
2 | // Chapter 3 (Arrays and Sorting)
3 | // C# Data Structures and Algorithms, Second Edition
4 |
5 | int[,] results = new int[10, 10];
6 |
7 | for (int i = 0; i < results.GetLength(0); i++)
8 | {
9 | for (int j = 0; j < results.GetLength(1); j++)
10 | {
11 | results[i, j] = (i + 1) * (j + 1);
12 | Console.Write($"{results[i, j],4}");
13 | }
14 | Console.WriteLine();
15 | }
16 |
--------------------------------------------------------------------------------
/03-SortingAlgorithms/03-SortingAlgorithms.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | net8.0
6 | _03_SortingAlgorithms
7 | enable
8 | enable
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/03-SortingAlgorithms/AbstractSort.cs:
--------------------------------------------------------------------------------
1 | // SORTING ALGORITHMS
2 | // Chapter 3 (Arrays and Sorting)
3 | // C# Data Structures and Algorithms, Second Edition
4 |
5 | public abstract class AbstractSort
6 | {
7 | public abstract void Sort(int[] a);
8 | }
9 |
--------------------------------------------------------------------------------
/03-SortingAlgorithms/BubbleSort.cs:
--------------------------------------------------------------------------------
1 | // SORTING ALGORITHMS
2 | // Chapter 3 (Arrays and Sorting)
3 | // C# Data Structures and Algorithms, Second Edition
4 |
5 | public class BubbleSort
6 | : AbstractSort
7 | {
8 | public override void Sort(int[] a)
9 | {
10 | for (int i = 0; i < a.Length; i++)
11 | {
12 | bool isAnyChange = false;
13 | for (int j = 0; j < a.Length - 1; j++)
14 | {
15 | if (a[j] > a[j + 1])
16 | {
17 | isAnyChange = true;
18 | (a[j], a[j + 1]) = (a[j + 1], a[j]);
19 | }
20 | }
21 |
22 | if (!isAnyChange) { break; }
23 | }
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/03-SortingAlgorithms/HeapSort.cs:
--------------------------------------------------------------------------------
1 | // SORTING ALGORITHMS
2 | // Chapter 3 (Arrays and Sorting)
3 | // C# Data Structures and Algorithms, Second Edition
4 |
5 | public class HeapSort
6 | : AbstractSort
7 | {
8 | public override void Sort(int[] a)
9 | {
10 | for (int i = a.Length / 2 - 1; i >= 0; i--)
11 | {
12 | Heapify(a, a.Length, i);
13 | }
14 |
15 | for (int i = a.Length - 1; i > 0; i--)
16 | {
17 | (a[0], a[i]) = (a[i], a[0]);
18 | Heapify(a, i, 0);
19 | }
20 | }
21 |
22 | private void Heapify(int[] a, int n, int i)
23 | {
24 | int max = i;
25 | int l = 2 * i + 1;
26 | int r = 2 * i + 2;
27 |
28 | max = l < n && a[l] > a[max] ? l : max;
29 | max = r < n && a[r] > a[max] ? r : max;
30 |
31 | if (max != i)
32 | {
33 | (a[i], a[max]) = (a[max], a[i]);
34 | Heapify(a, n, max);
35 | }
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/03-SortingAlgorithms/InsertionSort.cs:
--------------------------------------------------------------------------------
1 | // SORTING ALGORITHMS
2 | // Chapter 3 (Arrays and Sorting)
3 | // C# Data Structures and Algorithms, Second Edition
4 |
5 | public class InsertionSort
6 | : AbstractSort
7 | {
8 | public override void Sort(int[] a)
9 | {
10 | for (int i = 1; i < a.Length; i++)
11 | {
12 | int j = i;
13 | while (j > 0 && a[j] < a[j - 1])
14 | {
15 | (a[j], a[j - 1]) = (a[j - 1], a[j]);
16 | j--;
17 | }
18 | }
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/03-SortingAlgorithms/MergeSort.cs:
--------------------------------------------------------------------------------
1 | // SORTING ALGORITHMS
2 | // Chapter 3 (Arrays and Sorting)
3 | // C# Data Structures and Algorithms, Second Edition
4 |
5 | public class MergeSort
6 | : AbstractSort
7 | {
8 | public override void Sort(int[] a)
9 | {
10 | if (a.Length <= 1) { return; }
11 |
12 | int m = a.Length / 2;
13 | int[] left = GetSubarray(a, 0, m - 1);
14 | int[] right = GetSubarray(a, m, a.Length - 1);
15 | Sort(left);
16 | Sort(right);
17 |
18 | int i = 0, j = 0, k = 0;
19 | while (i < left.Length && j < right.Length)
20 | {
21 | if (left[i] <= right[j]) { a[k] = left[i++]; }
22 | else { a[k] = right[j++]; }
23 | k++;
24 | }
25 |
26 | while (i < left.Length) { a[k++] = left[i++]; }
27 | while (j < right.Length) { a[k++] = right[j++]; }
28 | }
29 |
30 | private int[] GetSubarray(int[] a, int si, int ei)
31 | {
32 | int[] result = new int[ei - si + 1];
33 | Array.Copy(a, si, result, 0, ei - si + 1);
34 | return result;
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/03-SortingAlgorithms/Program.cs:
--------------------------------------------------------------------------------
1 | // SORTING ALGORITHMS
2 | // Chapter 3 (Arrays and Sorting)
3 | // C# Data Structures and Algorithms, Second Edition
4 |
5 | using System.Diagnostics;
6 |
7 | List algorithms =
8 | [
9 | new SelectionSort(),
10 | new InsertionSort(),
11 | new BubbleSort(),
12 | new MergeSort(),
13 | new ShellSort(),
14 | new Quicksort(),
15 | new HeapSort()
16 | ];
17 |
18 | for (int n = 0; n <= 100000; n += 10000)
19 | {
20 | Console.WriteLine($"\nRunning tests for n = {n}:");
21 | List<(Type Type, long Ms)> milliseconds = [];
22 | for (int i = 0; i < 5; i++)
23 | {
24 | int[] array = GetRandomArray(n);
25 | int[] input = new int[n];
26 | foreach (AbstractSort algorithm in algorithms)
27 | {
28 | array.CopyTo(input, 0);
29 |
30 | Stopwatch stopwatch = Stopwatch.StartNew();
31 | algorithm.Sort(input);
32 | stopwatch.Stop();
33 |
34 | Type type = algorithm.GetType();
35 | long ms = stopwatch.ElapsedMilliseconds;
36 | milliseconds.Add((type, ms));
37 | }
38 | }
39 |
40 | List<(Type, double)> results = milliseconds
41 | .GroupBy(r => r.Type)
42 | .Select(r =>
43 | (r.Key, r.Average(t => t.Ms))).ToList();
44 | foreach ((Type type, double avg) in results)
45 | {
46 | Console.WriteLine($"{type.Name}: {avg} ms");
47 | }
48 | }
49 |
50 | int[] GetRandomArray(long length)
51 | {
52 | Random random = new();
53 | int[] array = new int[length];
54 | for (int i = 0; i < length; i++)
55 | {
56 | array[i] = random.Next(-100000, 100000);
57 | }
58 |
59 | return array;
60 | }
61 |
--------------------------------------------------------------------------------
/03-SortingAlgorithms/Quicksort.cs:
--------------------------------------------------------------------------------
1 | // SORTING ALGORITHMS
2 | // Chapter 3 (Arrays and Sorting)
3 | // C# Data Structures and Algorithms, Second Edition
4 |
5 | public class Quicksort
6 | : AbstractSort
7 | {
8 | public override void Sort(int[] a)
9 | {
10 | SortPart(a, 0, a.Length - 1);
11 | }
12 |
13 | private void SortPart(int[] a, int l, int u)
14 | {
15 | if (l >= u) { return; }
16 |
17 | int pivot = a[u];
18 | int j = l - 1;
19 | for (int i = l; i < u; i++)
20 | {
21 | if (a[i] < pivot)
22 | {
23 | j++;
24 | (a[j], a[i]) = (a[i], a[j]);
25 | }
26 | }
27 |
28 | int p = j + 1;
29 | (a[p], a[u]) = (a[u], a[p]);
30 |
31 | SortPart(a, l, p - 1);
32 | SortPart(a, p + 1, u);
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/03-SortingAlgorithms/SelectionSort.cs:
--------------------------------------------------------------------------------
1 | // SORTING ALGORITHMS
2 | // Chapter 3 (Arrays and Sorting)
3 | // C# Data Structures and Algorithms, Second Edition
4 |
5 | public class SelectionSort
6 | : AbstractSort
7 | {
8 | public override void Sort(int[] a)
9 | {
10 | for (int i = 0; i < a.Length - 1; i++)
11 | {
12 | int minIndex = i;
13 | int minValue = a[i];
14 | for (int j = i + 1; j < a.Length; j++)
15 | {
16 | if (a[j] < minValue)
17 | {
18 | minIndex = j;
19 | minValue = a[j];
20 | }
21 | }
22 |
23 | (a[i], a[minIndex]) = (a[minIndex], a[i]);
24 | }
25 | }
26 | }
--------------------------------------------------------------------------------
/03-SortingAlgorithms/ShellSort.cs:
--------------------------------------------------------------------------------
1 | // SORTING ALGORITHMS
2 | // Chapter 3 (Arrays and Sorting)
3 | // C# Data Structures and Algorithms, Second Edition
4 |
5 | public class ShellSort
6 | : AbstractSort
7 | {
8 | public override void Sort(int[] a)
9 | {
10 | for (int h = a.Length / 2; h > 0; h /= 2)
11 | {
12 | for (int i = h; i < a.Length; i++)
13 | {
14 | int j = i;
15 | int ai = a[i];
16 |
17 | while (j >= h && a[j - h] > ai)
18 | {
19 | a[j] = a[j - h];
20 | j -= h;
21 | }
22 |
23 | a[j] = ai;
24 | }
25 | }
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/03-YearlyTransportPlan/03-YearlyTransportPlan.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | net8.0
6 | _03_YearlyTransportPlan
7 | enable
8 | enable
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/03-YearlyTransportPlan/MeanEnum.cs:
--------------------------------------------------------------------------------
1 | // YEARLY TRANSPORT PLAN
2 | // Chapter 3 (Arrays and Sorting)
3 | // C# Data Structures and Algorithms, Second Edition
4 |
5 | public enum MeanEnum
6 | {
7 | Car,
8 | Bus,
9 | Subway,
10 | Bike,
11 | Walk
12 | }
13 |
--------------------------------------------------------------------------------
/03-YearlyTransportPlan/Program.cs:
--------------------------------------------------------------------------------
1 | // YEARLY TRANSPORT PLAN
2 | // Chapter 3 (Arrays and Sorting)
3 | // C# Data Structures and Algorithms, Second Edition
4 |
5 | using System.Globalization;
6 |
7 | Random random = new();
8 | int meansCount = Enum.GetNames().Length;
9 | int year = DateTime.Now.Year;
10 | MeanEnum[][] means = new MeanEnum[12][];
11 | for (int m = 1; m <= 12; m++)
12 | {
13 | int daysCount = DateTime.DaysInMonth(year, m);
14 | means[m - 1] = new MeanEnum[daysCount];
15 | for (int d = 1; d <= daysCount; d++)
16 | {
17 | int mean = random.Next(meansCount);
18 | means[m - 1][d - 1] = (MeanEnum)mean;
19 | }
20 | }
21 |
22 | string[] months = GetMonthNames();
23 | int nameLength = months.Max(n => n.Length) + 2;
24 | for (int m = 1; m <= 12; m++)
25 | {
26 | string month = months[m - 1];
27 | Console.Write($"{month}:".PadRight(nameLength));
28 | for (int d = 1; d <= means[m - 1].Length; d++)
29 | {
30 | MeanEnum mean = means[m - 1][d - 1];
31 | (char character, ConsoleColor color) = Get(mean);
32 | Console.ForegroundColor = ConsoleColor.White;
33 | Console.BackgroundColor = color;
34 | Console.Write(character);
35 | Console.ResetColor();
36 | Console.Write(" ");
37 | }
38 | Console.WriteLine();
39 | }
40 |
41 | string[] GetMonthNames()
42 | {
43 | CultureInfo culture = new("en");
44 | string[] names = new string[12];
45 | foreach (int m in Enumerable.Range(1, 12))
46 | {
47 | DateTime firstDay = new(DateTime.Now.Year, m, 1);
48 | string name = firstDay.ToString("MMMM", culture);
49 | names[m - 1] = name;
50 | }
51 | return names;
52 | }
53 |
54 | (char Char, ConsoleColor Color) Get(MeanEnum mean)
55 | {
56 | return mean switch
57 | {
58 | MeanEnum.Bike => ('B', ConsoleColor.Blue),
59 | MeanEnum.Bus => ('U', ConsoleColor.DarkGreen),
60 | MeanEnum.Car => ('C', ConsoleColor.Red),
61 | MeanEnum.Subway => ('S', ConsoleColor.Magenta),
62 | MeanEnum.Walk => ('W', ConsoleColor.DarkYellow),
63 | _ => throw new Exception("Unknown type")
64 | };
65 | }
66 |
--------------------------------------------------------------------------------
/04-AddressBook/04-AddressBook.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | net8.0
6 | _04_AddressBook
7 | enable
8 | enable
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/04-AddressBook/Person.cs:
--------------------------------------------------------------------------------
1 | // ADDRESS BOOK
2 | // Chapter 4 (Variants of Lists)
3 | // C# Data Structures and Algorithms, Second Edition
4 |
5 | public record Person(
6 | string Name,
7 | string Street,
8 | string PostalCode,
9 | string City,
10 | string Country);
11 |
--------------------------------------------------------------------------------
/04-AddressBook/Program.cs:
--------------------------------------------------------------------------------
1 | // ADDRESS BOOK
2 | // Chapter 4 (Variants of Lists)
3 | // C# Data Structures and Algorithms, Second Edition
4 |
5 | SortedList people = new()
6 | {
7 | { "Marcin Jamro", new("Marcin Jamro", "Polish Street 1/23", "35-001", "Rzeszow", "PL") },
8 | { "Martyna Kowalska", new("Martyna Kowalska", "World Street 5", "00-123", "Warsaw", "PL") }
9 | };
10 | people.Add("Mark Smith", new("Mark Smith", "German Street 6", "10000", "Berlin", "DE"));
11 | foreach ((string k, Person p) in people)
12 | {
13 | Console.WriteLine($"{k}: {p.Street}, {p.PostalCode} {p.City}, {p.Country}.");
14 | }
15 |
--------------------------------------------------------------------------------
/04-ArtGallery/04-ArtGallery.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | net8.0
6 | _04_ArtGallery
7 | enable
8 | enable
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/04-ArtGallery/CircularEnumerator.cs:
--------------------------------------------------------------------------------
1 | // ART GALLERY
2 | // Chapter 4 (Variants of Lists)
3 | // C# Data Structures and Algorithms, Second Edition
4 |
5 | using System.Collections;
6 |
7 | public class CircularEnumerator(LinkedList list)
8 | : IEnumerator
9 | {
10 | private LinkedListNode? _current = null;
11 | public T Current => _current != null ? _current.Value : default!;
12 | object IEnumerator.Current => Current!;
13 |
14 | public bool MoveNext()
15 | {
16 | if (_current == null)
17 | {
18 | _current = list?.First;
19 | return _current != null;
20 | }
21 | else
22 | {
23 | _current = _current.Next ?? _current!.List?.First;
24 | return true;
25 | }
26 | }
27 |
28 | public void Reset()
29 | {
30 | _current = null;
31 | }
32 |
33 | public void Dispose()
34 | {
35 | }
36 | }
--------------------------------------------------------------------------------
/04-ArtGallery/CircularLinkedList.cs:
--------------------------------------------------------------------------------
1 | // ART GALLERY
2 | // Chapter 4 (Variants of Lists)
3 | // C# Data Structures and Algorithms, Second Edition
4 |
5 | using System.Collections;
6 |
7 | public class CircularLinkedList
8 | : LinkedList
9 | {
10 | public new IEnumerator GetEnumerator() => new CircularEnumerator(this);
11 | }
12 |
--------------------------------------------------------------------------------
/04-ArtGallery/CircularLinkedListExtensions.cs:
--------------------------------------------------------------------------------
1 | // ART GALLERY
2 | // Chapter 4 (Variants of Lists)
3 | // C# Data Structures and Algorithms, Second Edition
4 |
5 | public static class CircularLinkedListExtensions
6 | {
7 | public static LinkedListNode? Next(this LinkedListNode n)
8 | {
9 | return n != null && n.List != null
10 | ? n.Next ?? n.List.First
11 | : null;
12 | }
13 |
14 | public static LinkedListNode? Prev(this LinkedListNode n)
15 | {
16 | return n != null && n.List != null
17 | ? n.Previous ?? n.List.Last
18 | : null;
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/04-ArtGallery/Program.cs:
--------------------------------------------------------------------------------
1 | // ART GALLERY
2 | // Chapter 4 (Variants of Lists)
3 | // C# Data Structures and Algorithms, Second Edition
4 |
5 | string[][] arts = GetArts();
6 | CircularLinkedList images = new();
7 | foreach (string[] art in arts) { images.AddLast(art); }
8 |
9 | LinkedListNode node = images.First!;
10 | ConsoleKey key = ConsoleKey.Spacebar;
11 | do
12 | {
13 | if (key == ConsoleKey.RightArrow)
14 | {
15 | node = node.Next()!;
16 | }
17 | else if (key == ConsoleKey.LeftArrow)
18 | {
19 | node = node.Prev()!;
20 | }
21 |
22 | Console.Clear();
23 | foreach (string line in node.Value)
24 | {
25 | Console.WriteLine(line);
26 | }
27 | }
28 | while ((key = Console.ReadKey().Key) != ConsoleKey.Escape);
29 |
30 | string[][] GetArts() => [
31 | [
32 | " +-----+ ",
33 | "o-| o o |-o",
34 | " | - | ",
35 | " +-----+ ",
36 | " | | "
37 | ],
38 | [
39 | "o +-----+ ",
40 | " \\| o o |\\ ",
41 | " | - | o",
42 | " +-----+ ",
43 | " / | "
44 | ],
45 | [
46 | " +-----+ o",
47 | " /| o o |/ ",
48 | "o | - | ",
49 | " +-----+ ",
50 | " | \\ "
51 | ]
52 | ];
53 |
--------------------------------------------------------------------------------
/04-AverageValue/04-AverageValue.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | net8.0
6 | _04_AverageValue
7 | enable
8 | enable
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/04-AverageValue/Program.cs:
--------------------------------------------------------------------------------
1 | // AVERAGE VALUE
2 | // Chapter 4 (Variants of Lists)
3 | // C# Data Structures and Algorithms, Second Edition
4 |
5 | List num = [];
6 | do
7 | {
8 | Console.Write("Enter the number: ");
9 | string numStr = Console.ReadLine() ?? string.Empty;
10 | if (!double.TryParse(numStr, out double n)) { break; }
11 | num.Add(n);
12 | Console.WriteLine($"Average value: {num.Average()}");
13 | }
14 | while (true);
15 |
--------------------------------------------------------------------------------
/04-BookReader/04-BookReader.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | net8.0
6 | _04_BookReader
7 | enable
8 | enable
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/04-BookReader/Page.cs:
--------------------------------------------------------------------------------
1 | // BOOK READER
2 | // Chapter 4 (Variants of Lists)
3 | // C# Data Structures and Algorithms, Second Edition
4 |
5 | public record Page(string Content);
6 |
--------------------------------------------------------------------------------
/04-BookReader/Program.cs:
--------------------------------------------------------------------------------
1 | // BOOK READER
2 | // Chapter 4 (Variants of Lists)
3 | // C# Data Structures and Algorithms, Second Edition
4 |
5 | Page p1 = new("Welcome to the first chapter in which you start your amazing adventure with data structures and algorithms, in the context of the C# programming language. At the beginning, a short introduction to this language is shown. You will get to know how broad possibilities it has, in how many scenarios you can apply this language, as well as what are some basic constructions that you use. Of course, it is not the C# course, presenting various its features one-by-one, so only a brief description is shown here.");
6 | Page p2 = new("While reading the first chapter of the book, you learned many interesting information about data types. So, now it is high time to introduce you the topic of algorithms. You will take a look at their definition, some real-world examples, notations, and types. As you should take care of performance of your applications, the computational complexity, including time complexity, is also presented and explained.");
7 | Page p3 = new("As a developer, you have certainly stored various collections within your applications, such as data of users, books, and logs. One of the natural ways of storing such data is by using arrays. However, have you ever thought about their variants? For example, have you heard about jagged arrays? In this chapter, you will see arrays in action, together with examples and detailed descriptions.");
8 | Page p4 = new("In the previous chapter you learned a lot about arrays and their types. Of course, an array is not the only way of storing data. Another popular and even more powerful group of data structures contains various variants of lists. In this chapter you will see such data structures in action, together with illustrations, explanations and descriptions.");
9 | Page p5 = new("So far, you learned a lot about arrays and lists. However, these structures are not the only ones available. Among others, there is also a group of more specialized data structures, which are called limited access data structures.");
10 | Page p6 = new("The current chapter focuses on data structures related to dictionaries and sets. A proper application of these data structures makes it possible to map keys to values and perform fast lookup, as well as to make various operations on sets. To simplify the understanding of dictionaries and sets, this chapter contains illustrations and code snippets, together with detailed descriptions.");
11 |
12 | LinkedList pages = new();
13 | pages.AddLast(p2);
14 | LinkedListNode n4 = pages.AddLast(p4);
15 | pages.AddLast(p6);
16 | pages.AddFirst(p1);
17 | pages.AddBefore(n4, p3);
18 | pages.AddAfter(n4, p5);
19 |
20 | LinkedListNode c = pages.First!;
21 | int number = 1;
22 | while (c != null)
23 | {
24 | Console.Clear();
25 | string page = $"- {number} -";
26 | int spaces = (90 - page.Length) / 2;
27 | Console.WriteLine(page.PadLeft(spaces + page.Length));
28 | Console.WriteLine();
29 |
30 | string content = c.Value.Content;
31 | for (int i = 0; i < content.Length; i += 90)
32 | {
33 | string line = content[i..];
34 | line = line.Length > 90 ? line[..90] : line;
35 | Console.WriteLine(line.Trim());
36 | }
37 |
38 | Console.WriteLine($"\nQuote from \"C# Data Structures and Algorithms\"\nby Marcin Jamro, published by Packt in 2024.\n");
39 | Console.Write(c.Previous != null ? "< PREV [P]" : GetSpaces(14));
40 | Console.Write(c.Next != null ? "[N] NEXT >".PadLeft(76) : string.Empty);
41 | Console.WriteLine();
42 |
43 | ConsoleKey key = Console.ReadKey(true).Key;
44 | if (key == ConsoleKey.N && c.Next != null)
45 | {
46 | c = c.Next;
47 | number++;
48 | }
49 | else if (key == ConsoleKey.P && c.Previous != null)
50 | {
51 | c = c.Previous;
52 | number--;
53 | }
54 | }
55 |
56 | string GetSpaces(int number) => string.Join(null, Enumerable.Range(0, number).Select(n => " "));
57 |
--------------------------------------------------------------------------------
/04-ListOfPeople/04-ListOfPeople.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | net8.0
6 | _04_ListOfPeople
7 | enable
8 | enable
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/04-ListOfPeople/Person.cs:
--------------------------------------------------------------------------------
1 | // LIST OF PEOPLE
2 | // Chapter 4 (Variants of Lists)
3 | // C# Data Structures and Algorithms, Second Edition
4 |
5 | public record Person(string Name, int Age, string Country);
6 |
--------------------------------------------------------------------------------
/04-ListOfPeople/Program.cs:
--------------------------------------------------------------------------------
1 | // LIST OF PEOPLE
2 | // Chapter 4 (Variants of Lists)
3 | // C# Data Structures and Algorithms, Second Edition
4 |
5 | List people =
6 | [
7 | new("Marcin", 35, "PL"),
8 | new("Sabine", 25, "DE"),
9 | new("Mark", 31, "PL")
10 | ];
11 |
12 | List r = [.. people.OrderBy(p => p.Name)];
13 | foreach (Person p in r)
14 | {
15 | string line = $"{p.Name} ({p.Age}) from {p.Country}.";
16 | Console.WriteLine(line);
17 | }
18 |
--------------------------------------------------------------------------------
/04-SpinTheWheel/04-SpinTheWheel.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | net8.0
6 | _04_SpinTheWheel
7 | enable
8 | enable
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/04-SpinTheWheel/CircularEnumerator.cs:
--------------------------------------------------------------------------------
1 | // SPIN THE WHEEL
2 | // Chapter 4 (Variants of Lists)
3 | // C# Data Structures and Algorithms, Second Edition
4 |
5 | using System.Collections;
6 |
7 | public class CircularEnumerator(LinkedList list)
8 | : IEnumerator
9 | {
10 | private LinkedListNode? _current = null;
11 | public T Current => _current != null ? _current.Value : default!;
12 | object IEnumerator.Current => Current!;
13 |
14 | public bool MoveNext()
15 | {
16 | if (_current == null)
17 | {
18 | _current = list?.First;
19 | return _current != null;
20 | }
21 | else
22 | {
23 | _current = _current.Next ?? _current!.List?.First;
24 | return true;
25 | }
26 | }
27 |
28 | public void Reset()
29 | {
30 | _current = null;
31 | }
32 |
33 | public void Dispose()
34 | {
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/04-SpinTheWheel/CircularLinkedList.cs:
--------------------------------------------------------------------------------
1 | // SPIN THE WHEEL
2 | // Chapter 4 (Variants of Lists)
3 | // C# Data Structures and Algorithms, Second Edition
4 |
5 | using System.Collections;
6 |
7 | public class CircularLinkedList
8 | : LinkedList
9 | {
10 | public new IEnumerator GetEnumerator() => new CircularEnumerator(this);
11 | }
12 |
--------------------------------------------------------------------------------
/04-SpinTheWheel/CircularLinkedListExtensions.cs:
--------------------------------------------------------------------------------
1 | // SPIN THE WHEEL
2 | // Chapter 4 (Variants of Lists)
3 | // C# Data Structures and Algorithms, Second Edition
4 |
5 | public static class CircularLinkedListExtensions
6 | {
7 | public static LinkedListNode? Next(this LinkedListNode n)
8 | {
9 | return n != null && n.List != null
10 | ? n.Next ?? n.List.First
11 | : null;
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/04-SpinTheWheel/Program.cs:
--------------------------------------------------------------------------------
1 | // SPIN THE WHEEL
2 | // Chapter 4 (Variants of Lists)
3 | // C# Data Structures and Algorithms, Second Edition
4 |
5 | CircularLinkedList categories = new();
6 | categories.AddLast("Sport");
7 | categories.AddLast("Culture");
8 | categories.AddLast("History");
9 | categories.AddLast("Geography");
10 | categories.AddLast("People");
11 | categories.AddLast("Technology");
12 | categories.AddLast("Nature");
13 | categories.AddLast("Science");
14 |
15 | bool isStopped = true;
16 | Random random = new();
17 | DateTime targetTime = DateTime.Now;
18 | int ms = 0;
19 | foreach (string category in categories)
20 | {
21 | if (isStopped)
22 | {
23 | Console.WriteLine("Press [Enter] to start.");
24 | ConsoleKey key = Console.ReadKey().Key;
25 | if (key == ConsoleKey.Enter)
26 | {
27 | ms = random.Next(1000, 5000);
28 | targetTime = DateTime.Now.AddMilliseconds(ms);
29 | isStopped = false;
30 | Console.WriteLine(category);
31 | }
32 | else { return; }
33 | }
34 | else
35 | {
36 | int remaining = (int)(targetTime - DateTime.Now).TotalMilliseconds;
37 | int waiting = Math.Max(100, (ms - remaining) / 5);
38 | await Task.Delay(waiting);
39 |
40 | if (DateTime.Now >= targetTime)
41 | {
42 | Console.ForegroundColor = ConsoleColor.Red;
43 | isStopped = true;
44 | }
45 |
46 | Console.WriteLine(category);
47 | Console.ResetColor();
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/05-CallCenterManyConsultants/05-CallCenterManyConsultants.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | net8.0
6 | _05_CallCenterManyConsultants
7 | enable
8 | enable
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/05-CallCenterManyConsultants/CallCenter.cs:
--------------------------------------------------------------------------------
1 | // CALL CENTER WITH MANY CONSULTANTS
2 | // Chapter 5 (Stacks and Queues)
3 | // C# Data Structures and Algorithms, Second Edition
4 |
5 | using System.Collections.Concurrent;
6 |
7 | public class CallCenter
8 | {
9 | private int _counter = 0;
10 | public ConcurrentQueue Calls { get; private set; }
11 | public CallCenter() => Calls = new ConcurrentQueue();
12 |
13 | public IncomingCall Call(int clientId)
14 | {
15 | IncomingCall call = new()
16 | {
17 | Id = ++_counter,
18 | ClientId = clientId,
19 | CallTime = DateTime.Now
20 | };
21 | Calls.Enqueue(call);
22 | return call;
23 | }
24 |
25 | public IncomingCall? Answer(string consultant)
26 | {
27 | if (!Calls.IsEmpty && Calls.TryDequeue(out IncomingCall? call))
28 | {
29 | call.Consultant = consultant;
30 | call.AnswerTime = DateTime.Now;
31 | return call;
32 | }
33 | return null;
34 | }
35 |
36 | public void End(IncomingCall call) => call.EndTime = DateTime.Now;
37 |
38 | public bool AreWaitingCalls() => !Calls.IsEmpty;
39 | }
40 |
41 |
--------------------------------------------------------------------------------
/05-CallCenterManyConsultants/IncomingCall.cs:
--------------------------------------------------------------------------------
1 | // CALL CENTER WITH MANY CONSULTANTS
2 | // Chapter 5 (Stacks and Queues)
3 | // C# Data Structures and Algorithms, Second Edition
4 |
5 | public class IncomingCall
6 | {
7 | public int Id { get; set; }
8 | public int ClientId { get; set; }
9 | public DateTime CallTime { get; set; }
10 | public DateTime? AnswerTime { get; set; }
11 | public DateTime? EndTime { get; set; }
12 | public string? Consultant { get; set; }
13 | }
14 |
--------------------------------------------------------------------------------
/05-CallCenterManyConsultants/Program.cs:
--------------------------------------------------------------------------------
1 | // CALL CENTER WITH MANY CONSULTANTS
2 | // Chapter 5 (Stacks and Queues)
3 | // C# Data Structures and Algorithms, Second Edition
4 |
5 | Random random = new();
6 | CallCenter center = new();
7 | Parallel.Invoke(
8 | () => Clients(center),
9 | () => Consultant(center, "Marcin", ConsoleColor.Red),
10 | () => Consultant(center, "James", ConsoleColor.Yellow),
11 | () => Consultant(center, "Olivia", ConsoleColor.Green));
12 |
13 | void Clients(CallCenter center)
14 | {
15 | while (true)
16 | {
17 | int clientId = random.Next(1, 10000);
18 | IncomingCall call = center.Call(clientId);
19 | Log($"Incoming call #{call.Id} from client #{clientId}");
20 | Log($"Waiting calls in the queue: {center.Calls.Count}");
21 | Thread.Sleep(random.Next(500, 2000));
22 | }
23 | }
24 |
25 | void Consultant(CallCenter center, string name, ConsoleColor color)
26 | {
27 | while (true)
28 | {
29 | Thread.Sleep(random.Next(500, 1000));
30 | IncomingCall? call = center.Answer(name);
31 | if (call == null) { continue; }
32 |
33 | Log($"Call #{call.Id} from client #{call.ClientId} answered by {call.Consultant}.", color);
34 | Thread.Sleep(random.Next(1000, 10000));
35 | center.End(call);
36 | Log($"Call #{call.Id} from client #{call.ClientId} ended by {call.Consultant}.", color);
37 | }
38 | }
39 |
40 | void Log(string text, ConsoleColor color = ConsoleColor.Gray)
41 | {
42 | Console.ForegroundColor = color;
43 | Console.WriteLine($"[{DateTime.Now:HH:mm:ss.fff}] {text}");
44 | Console.ResetColor();
45 | }
46 |
--------------------------------------------------------------------------------
/05-CallCenterPrioritySupport/05-CallCenterPrioritySupport.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | net8.0
6 | _05_CallCenterPrioritySupport
7 | enable
8 | enable
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/05-CallCenterPrioritySupport/CallCenter.cs:
--------------------------------------------------------------------------------
1 | // CALL CENTER WITH PRIORITY SUPPORT
2 | // Chapter 5 (Stacks and Queues)
3 | // C# Data Structures and Algorithms, Second Edition
4 |
5 | using Priority_Queue;
6 |
7 | public class CallCenter
8 | {
9 | private int _counter = 0;
10 | public SimplePriorityQueue Calls { get; private set; }
11 | public CallCenter() => Calls = new SimplePriorityQueue();
12 |
13 | public IncomingCall Call(int clientId, bool isPriority)
14 | {
15 | IncomingCall call = new()
16 | {
17 | Id = ++_counter,
18 | ClientId = clientId,
19 | CallTime = DateTime.Now,
20 | IsPriority = isPriority
21 | };
22 | Calls.Enqueue(call, isPriority ? 0 : 1);
23 | return call;
24 | }
25 |
26 |
27 | public IncomingCall? Answer(string consultant)
28 | {
29 | if (!AreWaitingCalls()) { return null; }
30 |
31 | IncomingCall call = Calls.Dequeue();
32 | call.Consultant = consultant;
33 | call.AnswerTime = DateTime.Now;
34 | return call;
35 | }
36 |
37 | public void End(IncomingCall call) => call.EndTime = DateTime.Now;
38 |
39 | public bool AreWaitingCalls() => Calls.Count > 0;
40 | }
41 |
--------------------------------------------------------------------------------
/05-CallCenterPrioritySupport/IncomingCall.cs:
--------------------------------------------------------------------------------
1 | // CALL CENTER WITH PRIORITY SUPPORT
2 | // Chapter 5 (Stacks and Queues)
3 | // C# Data Structures and Algorithms, Second Edition
4 |
5 | public class IncomingCall
6 | {
7 | public int Id { get; set; }
8 | public int ClientId { get; set; }
9 | public DateTime CallTime { get; set; }
10 | public DateTime? AnswerTime { get; set; }
11 | public DateTime? EndTime { get; set; }
12 | public string? Consultant { get; set; }
13 | public bool IsPriority { get; set; }
14 | }
15 |
--------------------------------------------------------------------------------
/05-CallCenterPrioritySupport/Program.cs:
--------------------------------------------------------------------------------
1 | // CALL CENTER WITH PRIORITY SUPPORT
2 | // Chapter 5 (Stacks and Queues)
3 | // C# Data Structures and Algorithms, Second Edition
4 |
5 | Random random = new();
6 |
7 | CallCenter center = new();
8 | center.Call(1234, false);
9 | center.Call(5678, true);
10 | center.Call(1468, false);
11 | center.Call(9641, true);
12 |
13 | while (center.AreWaitingCalls())
14 | {
15 | IncomingCall call = center.Answer("Marcin")!;
16 | Log($"Call #{call.Id} from client #{call.ClientId} is answered by { call.Consultant}.", call.IsPriority);
17 | await Task.Delay(random.Next(1000, 10000));
18 | center.End(call);
19 | Log($"Call #{call.Id} from client #{call.ClientId} is ended by { call.Consultant}.", call.IsPriority);
20 | }
21 |
22 | void Log(string text, bool isPriority)
23 | {
24 | Console.ForegroundColor = isPriority ? ConsoleColor.Red : ConsoleColor.Gray;
25 | Console.WriteLine($"[{DateTime.Now:HH:mm:ss}] {text}");
26 | Console.ResetColor();
27 | }
28 |
--------------------------------------------------------------------------------
/05-CallCenterSingleConsultant/05-CallCenterSingleConsultant.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | net8.0
6 | _05_CallCenterSingleConsultant
7 | enable
8 | enable
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/05-CallCenterSingleConsultant/CallCenter.cs:
--------------------------------------------------------------------------------
1 | // CALL CENTER WITH A SINGLE CONSULTANT
2 | // Chapter 5 (Stacks and Queues)
3 | // C# Data Structures and Algorithms, Second Edition
4 |
5 | public class CallCenter
6 | {
7 | private int _counter = 0;
8 | public Queue Calls { get; private set; }
9 | public CallCenter() => Calls = new Queue();
10 |
11 | public IncomingCall Call(int clientId)
12 | {
13 | IncomingCall call = new()
14 | {
15 | Id = ++_counter,
16 | ClientId = clientId,
17 | CallTime = DateTime.Now
18 | };
19 | Calls.Enqueue(call);
20 | return call;
21 | }
22 |
23 | public IncomingCall? Answer(string consultant)
24 | {
25 | if (!AreWaitingCalls()) { return null; }
26 |
27 | IncomingCall call = Calls.Dequeue();
28 | call.Consultant = consultant;
29 | call.AnswerTime = DateTime.Now;
30 | return call;
31 | }
32 |
33 | public void End(IncomingCall call) => call.EndTime = DateTime.Now;
34 |
35 | public bool AreWaitingCalls() => Calls.Count > 0;
36 | }
37 |
--------------------------------------------------------------------------------
/05-CallCenterSingleConsultant/IncomingCall.cs:
--------------------------------------------------------------------------------
1 | // CALL CENTER WITH A SINGLE CONSULTANT
2 | // Chapter 5 (Stacks and Queues)
3 | // C# Data Structures and Algorithms, Second Edition
4 |
5 | public class IncomingCall
6 | {
7 | public int Id { get; set; }
8 | public int ClientId { get; set; }
9 | public DateTime CallTime { get; set; }
10 | public DateTime? AnswerTime { get; set; }
11 | public DateTime? EndTime { get; set; }
12 | public string? Consultant { get; set; }
13 | }
14 |
--------------------------------------------------------------------------------
/05-CallCenterSingleConsultant/Program.cs:
--------------------------------------------------------------------------------
1 | // CALL CENTER WITH A SINGLE CONSULTANT
2 | // Chapter 5 (Stacks and Queues)
3 | // C# Data Structures and Algorithms, Second Edition
4 |
5 | Random random = new();
6 |
7 | CallCenter center = new();
8 | center.Call(1234);
9 | center.Call(5678);
10 | center.Call(1468);
11 | center.Call(9641);
12 |
13 | while (center.AreWaitingCalls())
14 | {
15 | IncomingCall call = center.Answer("Marcin")!;
16 | Log($"Call #{call.Id} from client #{call.ClientId} answered by { call.Consultant}.");
17 | await Task.Delay(random.Next(1000, 10000));
18 | center.End(call);
19 | Log($"Call #{call.Id} from client #{call.ClientId} ended by { call.Consultant}.");
20 | }
21 |
22 | void Log(string text) => Console.WriteLine($"[{DateTime.Now:HH:mm:ss}] {text}");
23 |
--------------------------------------------------------------------------------
/05-GravityRollerCoaster/05-GravityRollerCoaster.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | net8.0
6 | _05_GravityRollerCoaster
7 | enable
8 | enable
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/05-GravityRollerCoaster/CircularQueue.cs:
--------------------------------------------------------------------------------
1 | // GRAVITY ROLLER COASTER
2 | // Chapter 5 (Stacks and Queues)
3 | // C# Data Structures and Algorithms, Second Edition
4 |
5 | public class CircularQueue(int size)
6 | where T : struct
7 | {
8 | private readonly T[] _items = new T[size];
9 | private int _front = -1;
10 | private int _rear = -1;
11 | private int _count = 0;
12 |
13 | public int Count { get { return _count; } }
14 |
15 | public bool Enqueue(T item)
16 | {
17 | if (_count == _items.Length) { return false; }
18 |
19 | if (_front < 0) { _front = _rear = 0; }
20 | else { _rear = ++_rear % _items.Length; }
21 |
22 | _items[_rear] = item;
23 | _count++;
24 | return true;
25 | }
26 |
27 | public T? Dequeue()
28 | {
29 | if (_count == 0) { return null; }
30 |
31 | T result = _items[_front];
32 | if (_front == _rear) { _front = _rear = -1; }
33 | else { _front = ++_front % _items.Length; }
34 |
35 | _count--;
36 | return result;
37 | }
38 |
39 | public T? Peek()
40 | {
41 | if (_count == 0) { return null; }
42 | return _items[_front];
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/05-GravityRollerCoaster/Program.cs:
--------------------------------------------------------------------------------
1 | // GRAVITY ROLLER COASTER
2 | // Chapter 5 (Stacks and Queues)
3 | // C# Data Structures and Algorithms, Second Edition
4 |
5 | using QueueItem = (System.DateTime StartedAt, System.ConsoleColor Color);
6 |
7 | const int rideSeconds = 10;
8 | Random random = new();
9 | CircularQueue queue = new(12);
10 | ConsoleColor color = ConsoleColor.Black;
11 |
12 | while (true)
13 | {
14 | while (queue.Peek() != null)
15 | {
16 | QueueItem item = queue.Peek()!.Value;
17 | TimeSpan elapsed = DateTime.Now - item.StartedAt;
18 | if (elapsed.TotalSeconds < rideSeconds) { break; }
19 | queue.Dequeue();
20 | Log($"> Exits\tTotal: {queue.Count}", item.Color);
21 | }
22 |
23 | bool isNew = random.Next(3) == 1;
24 | if (isNew)
25 | {
26 | color = color == ConsoleColor.White
27 | ? ConsoleColor.DarkBlue
28 | : (ConsoleColor)(((int)color) + 1);
29 | if (queue.Enqueue((DateTime.Now, color)))
30 | {
31 | Log($"< Enters\tTotal: {queue.Count}", color);
32 | }
33 | else
34 | {
35 | Log($"! Not allowed\tTotal: {queue.Count}", ConsoleColor.DarkGray);
36 | }
37 | }
38 |
39 | await Task.Delay(500);
40 | }
41 |
42 | void Log(string text, ConsoleColor color)
43 | {
44 | Console.ForegroundColor = color;
45 | Console.WriteLine($"{DateTime.Now:HH:mm:ss} {text}");
46 | Console.ResetColor();
47 | }
--------------------------------------------------------------------------------
/05-ReversingWord/05-ReversingWord.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | net8.0
6 | _05_ReversingWord
7 | enable
8 | enable
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/05-ReversingWord/Program.cs:
--------------------------------------------------------------------------------
1 | // REVERSING A WORD
2 | // Chapter 5 (Stacks and Queues)
3 | // C# Data Structures and Algorithms, Second Edition
4 |
5 | string text = "MARCIN";
6 | Stack chars = new();
7 | foreach (char c in text) { chars.Push(c); }
8 | while (chars.Count > 0) { Console.Write(chars.Pop()); }
9 |
--------------------------------------------------------------------------------
/05-TowerOfHanoi/05-TowerOfHanoi.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | net8.0
6 | _05_TowerOfHanoi
7 | enable
8 | enable
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/05-TowerOfHanoi/Game.cs:
--------------------------------------------------------------------------------
1 | // TOWER OF HANOI
2 | // Chapter 5 (Stacks and Queues)
3 | // C# Data Structures and Algorithms, Second Edition
4 |
5 | public class Game
6 | {
7 | public Stack From { get; private set; }
8 | public Stack To { get; private set; }
9 | public Stack Auxiliary { get; private set; }
10 | public int DiscsCount { get; private set; }
11 | public int MovesCount { get; private set; }
12 |
13 | public event EventHandler? MoveCompleted;
14 |
15 | public Game(int discsCount)
16 | {
17 | DiscsCount = discsCount;
18 | From = new Stack();
19 | To = new Stack();
20 | Auxiliary = new Stack();
21 | for (int i = 0; i < discsCount; i++)
22 | {
23 | int size = discsCount - i;
24 | From.Push(size);
25 | }
26 | }
27 |
28 | public async Task MoveAsync(int discs, Stack from, Stack to, Stack auxiliary)
29 | {
30 | if (discs == 0) { return; }
31 | await MoveAsync(discs - 1, from, auxiliary, to);
32 | to.Push(from.Pop());
33 | MovesCount++;
34 | MoveCompleted?.Invoke(this, EventArgs.Empty);
35 | await Task.Delay(250);
36 | await MoveAsync(discs - 1, auxiliary, to, from);
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/05-TowerOfHanoi/Program.cs:
--------------------------------------------------------------------------------
1 | // TOWER OF HANOI
2 | // Chapter 5 (Stacks and Queues)
3 | // C# Data Structures and Algorithms, Second Edition
4 |
5 | Game game = new(10);
6 | Visualization vis = new(game);
7 | game.MoveCompleted += (s, e) => vis.Show((Game)s!);
8 | await game.MoveAsync(game.DiscsCount, game.From, game.To, game.Auxiliary);
9 |
--------------------------------------------------------------------------------
/05-TowerOfHanoi/Visualization.cs:
--------------------------------------------------------------------------------
1 | // TOWER OF HANOI
2 | // Chapter 5 (Stacks and Queues)
3 | // C# Data Structures and Algorithms, Second Edition
4 |
5 | public class Visualization
6 | {
7 | private readonly Game _game;
8 | private readonly int _columnSize;
9 | private readonly char[,] _board;
10 |
11 | public Visualization(Game game)
12 | {
13 | _game = game;
14 | _columnSize = Math.Max(6, GetDiscWidth(_game.DiscsCount) + 2);
15 | _board = new char[_game.DiscsCount, _columnSize * 3];
16 | }
17 |
18 | public void Show(Game game)
19 | {
20 | Console.Clear();
21 | if (game.DiscsCount <= 0) { return; }
22 |
23 | FillEmptyBoard();
24 | FillRodOnBoard(1, game.From);
25 | FillRodOnBoard(2, game.To);
26 | FillRodOnBoard(3, game.Auxiliary);
27 |
28 | Console.WriteLine(Center("FROM") + Center("TO") + Center("AUXILIARY"));
29 | DrawBoard();
30 | Console.WriteLine($"\nMoves: {game.MovesCount}");
31 | Console.WriteLine($"Discs: {game.DiscsCount}");
32 | }
33 |
34 | private int GetDiscWidth(int size) => (2 * size) - 1;
35 |
36 | private void FillEmptyBoard()
37 | {
38 | for (int y = 0; y < _board.GetLength(0); y++)
39 | {
40 | for (int x = 0; x < _board.GetLength(1); x++)
41 | {
42 | _board[y, x] = ' ';
43 | }
44 | }
45 | }
46 |
47 | private void FillRodOnBoard(int column, Stack stack)
48 | {
49 | int discsCount = _game.DiscsCount;
50 | int margin = _columnSize * (column - 1);
51 | for (int y = 0; y < stack.Count; y++)
52 | {
53 | int size = stack.ElementAt(y);
54 | int row = discsCount - (stack.Count - y);
55 | int columnStart = margin + discsCount - size;
56 | int columnEnd = columnStart + GetDiscWidth(size);
57 | for (int x = columnStart; x <= columnEnd; x++)
58 | {
59 | _board[row, x] = '=';
60 | }
61 | }
62 | }
63 |
64 | private string Center(string text)
65 | {
66 | int margin = (_columnSize - text.Length) / 2;
67 | return text.PadLeft(margin + text.Length).PadRight(_columnSize);
68 | }
69 |
70 | private void DrawBoard()
71 | {
72 | for (int y = 0; y < _board.GetLength(0); y++)
73 | {
74 | string line = string.Empty;
75 | for (int x = 0; x < _board.GetLength(1); x++)
76 | {
77 | line += _board[y, x];
78 | }
79 | Console.WriteLine(line);
80 | }
81 | }
82 | }
83 |
--------------------------------------------------------------------------------
/06-Coupons/06-Coupons.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | net8.0
6 | _06_Coupons
7 | enable
8 | enable
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/06-Coupons/Program.cs:
--------------------------------------------------------------------------------
1 | // COUPONS
2 | // Chapter 6 (Dictionaries and Sets)
3 | // C# Data Structures and Algorithms, Second Edition
4 |
5 | HashSet usedCoupons = [];
6 | do
7 | {
8 | Console.Write("Enter the number: ");
9 | string number = Console.ReadLine() ?? string.Empty;
10 | if (!int.TryParse(number, out int coupon)) { break; }
11 |
12 | if (usedCoupons.Contains(coupon))
13 | {
14 | Console.WriteLine("Already used.");
15 | }
16 | else
17 | {
18 | usedCoupons.Add(coupon);
19 | Console.WriteLine("Thank you!");
20 | }
21 | }
22 | while (true);
23 |
24 | Console.WriteLine("\nUsed coupons:");
25 | foreach (int coupon in usedCoupons)
26 | {
27 | Console.WriteLine(coupon);
28 | }
29 |
--------------------------------------------------------------------------------
/06-Encyclopedia/06-Encyclopedia.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | net8.0
6 | _06_Encyclopedia
7 | enable
8 | enable
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/06-Encyclopedia/Program.cs:
--------------------------------------------------------------------------------
1 | // ENCYCLOPEDIA
2 | // Chapter 6 (Dictionaries and Sets)
3 | // C# Data Structures and Algorithms, Second Edition
4 |
5 | SortedDictionary definitions = [];
6 | Console.WriteLine("Welcome to your encyclopedia!\n");
7 | do
8 | {
9 | Console.WriteLine("Choose option ([A]dd, [L]ist): ");
10 | ConsoleKeyInfo keyInfo = Console.ReadKey(true);
11 | if (keyInfo.Key == ConsoleKey.A)
12 | {
13 | Console.Write("Enter the key: ");
14 | string key = Console.ReadLine() ?? string.Empty;
15 | Console.Write("Enter the explanation: ");
16 | string explanation = Console.ReadLine() ?? string.Empty;
17 | definitions[key] = explanation;
18 | }
19 | else if (keyInfo.Key == ConsoleKey.L)
20 | {
21 | foreach ((string k, string e) in definitions)
22 | {
23 | Console.WriteLine($"{k}: {e}");
24 | }
25 | }
26 | else
27 | {
28 | Console.WriteLine("Do you want to exit? Y or N.");
29 | if (Console.ReadKey().Key == ConsoleKey.Y)
30 | {
31 | break;
32 | }
33 | }
34 | }
35 | while (true);
36 |
--------------------------------------------------------------------------------
/06-PhoneBook/06-PhoneBook.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | net8.0
6 | _06_PhoneBook
7 | enable
8 | enable
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/06-PhoneBook/Program.cs:
--------------------------------------------------------------------------------
1 | // PHONE BOOK
2 | // Chapter 6 (Dictionaries and Sets)
3 | // C# Data Structures and Algorithms, Second Edition
4 |
5 | using System.Collections;
6 |
7 | Hashtable phoneBook = new()
8 | {
9 | { "Marcin", "101-202-303" },
10 | { "John", "202-303-404" }
11 | };
12 | phoneBook["Aline"] = "303-404-505";
13 |
14 | Console.WriteLine("Phone numbers:");
15 | if (phoneBook.Count == 0)
16 | {
17 | Console.WriteLine("Empty list.");
18 | }
19 |
20 | foreach (DictionaryEntry entry in phoneBook)
21 | {
22 | Console.WriteLine($"{entry.Key}: {entry.Value}");
23 | }
24 |
25 | Console.Write("\nSearch by name: ");
26 | string name = Console.ReadLine() ?? string.Empty;
27 | if (phoneBook.ContainsKey(name))
28 | {
29 | string number = (string)phoneBook[name]!;
30 | Console.WriteLine($"Phone number: {number}");
31 | }
32 | else
33 | {
34 | Console.WriteLine("Does not exist.");
35 | }
36 |
--------------------------------------------------------------------------------
/06-ProductLocation/06-ProductLocation.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | net8.0
6 | _06_ProductLocation
7 | enable
8 | enable
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/06-ProductLocation/Program.cs:
--------------------------------------------------------------------------------
1 | // PRODUCT LOCATION
2 | // Chapter 6 (Dictionaries and Sets)
3 | // C# Data Structures and Algorithms, Second Edition
4 |
5 | Dictionary products = new()
6 | {
7 | { "5901020304050", "A1" },
8 | { "5910203040506", "B5" },
9 | { "5920304050607", "C9" }
10 | };
11 | products["5930405060708"] = "D7";
12 |
13 | string key = "5940506070809";
14 | if (!products.ContainsKey(key))
15 | {
16 | products.Add(key, "A3");
17 | }
18 |
19 | if (!products.TryAdd(key, "B4"))
20 | {
21 | Console.WriteLine("Cannot add.");
22 | }
23 |
24 | Console.WriteLine("All products:");
25 | if (products.Count == 0) { Console.WriteLine("Empty"); }
26 | foreach ((string k, string v) in products)
27 | {
28 | Console.WriteLine($"{k}: {v}");
29 | }
30 |
31 | Console.Write("\nSearch by barcode: ");
32 | string barcode = Console.ReadLine() ?? string.Empty;
33 | if (products.TryGetValue(barcode, out string? location))
34 | {
35 | Console.WriteLine($"The product is in: {location}.");
36 | }
37 | else
38 | {
39 | Console.WriteLine("The product does not exist.");
40 | }
41 |
--------------------------------------------------------------------------------
/06-RemovingDuplicates/06-RemovingDuplicates.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | net8.0
6 | _06_RemovingDuplicates
7 | enable
8 | enable
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/06-RemovingDuplicates/Program.cs:
--------------------------------------------------------------------------------
1 | // REMOVING DUPLICATES
2 | // Chapter 6 (Dictionaries and Sets)
3 | // C# Data Structures and Algorithms, Second Edition
4 |
5 | List names = [ "Marcin", "Mary", "James", "Albert", "Lily", "Emily", "marcin", "James", "Jane" ];
6 | SortedSet sorted = new(
7 | names,
8 | Comparer.Create((a, b) => a.ToLower().CompareTo(b.ToLower())));
9 | foreach (string name in sorted)
10 | {
11 | Console.WriteLine(name);
12 | }
13 |
--------------------------------------------------------------------------------
/06-SwimmingPools/06-SwimmingPools.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | net8.0
6 | _06_SwimmingPools
7 | enable
8 | enable
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/06-SwimmingPools/PoolTypeEnum.cs:
--------------------------------------------------------------------------------
1 | // SWIMMING POOLS
2 | // Chapter 6 (Dictionaries and Sets)
3 | // C# Data Structures and Algorithms, Second Edition
4 |
5 | public enum PoolTypeEnum
6 | {
7 | Recreation,
8 | Competition,
9 | Thermal,
10 | Kids
11 | };
12 |
--------------------------------------------------------------------------------
/06-SwimmingPools/Program.cs:
--------------------------------------------------------------------------------
1 | // SWIMMING POOLS
2 | // Chapter 6 (Dictionaries and Sets)
3 | // C# Data Structures and Algorithms, Second Edition
4 |
5 | Random random = new();
6 | Dictionary> tickets = new()
7 | {
8 | { PoolTypeEnum.Recreation, new() },
9 | { PoolTypeEnum.Competition, new() },
10 | { PoolTypeEnum.Thermal, new() },
11 | { PoolTypeEnum.Kids, new() }
12 | };
13 |
14 | for (int i = 1; i < 100; i++)
15 | {
16 | foreach ((PoolTypeEnum p, HashSet t) in tickets)
17 | {
18 | if (random.Next(2) == 1) { t.Add(i); }
19 | }
20 | }
21 |
22 | Console.WriteLine("Number of visitors by a pool type:");
23 | foreach ((PoolTypeEnum p, HashSet t) in tickets)
24 | {
25 | Console.WriteLine($"- {p}: {t.Count}");
26 | }
27 |
28 | PoolTypeEnum maxVisitors = tickets
29 | .OrderByDescending(t => t.Value.Count)
30 | .Select(t => t.Key)
31 | .FirstOrDefault();
32 | Console.WriteLine($"{maxVisitors} - the most popular.");
33 |
34 | HashSet any = new(tickets[PoolTypeEnum.Recreation]);
35 | any.UnionWith(tickets[PoolTypeEnum.Competition]);
36 | any.UnionWith(tickets[PoolTypeEnum.Thermal]);
37 | any.UnionWith(tickets[PoolTypeEnum.Kids]);
38 | Console.WriteLine($"{any.Count} people visited at least one pool.");
39 |
40 | HashSet all = new(tickets[PoolTypeEnum.Recreation]);
41 | all.IntersectWith(tickets[PoolTypeEnum.Competition]);
42 | all.IntersectWith(tickets[PoolTypeEnum.Thermal]);
43 | all.IntersectWith(tickets[PoolTypeEnum.Kids]);
44 | Console.WriteLine($"{all.Count} people visited all pools.");
45 |
--------------------------------------------------------------------------------
/06-UserDetails/06-UserDetails.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | net8.0
6 | _06_UserDetails
7 | enable
8 | enable
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/06-UserDetails/Employee.cs:
--------------------------------------------------------------------------------
1 | // USER DETAILS
2 | // Chapter 6 (Dictionaries and Sets)
3 | // C# Data Structures and Algorithms, Second Edition
4 |
5 | public record Employee(string FirstName, string LastName, string PhoneNumber);
6 |
--------------------------------------------------------------------------------
/06-UserDetails/Program.cs:
--------------------------------------------------------------------------------
1 | // USER DETAILS
2 | // Chapter 6 (Dictionaries and Sets)
3 | // C# Data Structures and Algorithms, Second Edition
4 |
5 | Dictionary employees = new()
6 | {
7 | { 100, new Employee("Marcin", "Jamro", "101-202-303") },
8 | { 210, new Employee("John", "Smith", "202-303-404") },
9 | { 303, new Employee("Aline", "Weather", "303-404-505") }
10 | };
11 |
12 | do
13 | {
14 | Console.Write("Enter the identifier: ");
15 | string idString = Console.ReadLine() ?? string.Empty;
16 | if (!int.TryParse(idString, out int id)) { break; }
17 |
18 | if (employees.TryGetValue(id, out Employee? employee))
19 | {
20 | Console.WriteLine(
21 | "Full name: {0} {1}\nPhone number: {2}\n",
22 | employee.FirstName,
23 | employee.LastName,
24 | employee.PhoneNumber);
25 | }
26 | else { Console.WriteLine("Does not exist.\n"); }
27 | }
28 | while (true);
29 |
--------------------------------------------------------------------------------
/07-AutoComplete/07-AutoComplete.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | net8.0
6 | 07_AutoComplete
7 | enable
8 | enable
9 |
10 |
11 |
12 |
13 | Always
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/07-AutoComplete/Countries.txt:
--------------------------------------------------------------------------------
1 | Afghanistan
2 | Albania
3 | Algeria
4 | Pakistan
5 | Palau
6 | Panama
7 | Papua New Guinea
8 | Paraguay
9 | Peru
10 | Philippines
11 | Poland
12 | Portugal
13 | Zambia
14 | Zimbabwe
--------------------------------------------------------------------------------
/07-AutoComplete/Program.cs:
--------------------------------------------------------------------------------
1 | // AUTO-COMPLETE
2 | // Chapter 7 (Variants of Trees)
3 | // C# Data Structures and Algorithms, Second Edition
4 |
5 | using System.Text.RegularExpressions;
6 |
7 | Trie trie = new();
8 | string[] countries = await File.ReadAllLinesAsync("Countries.txt");
9 | foreach (string country in countries)
10 | {
11 | Regex regex = new("[^a-z]");
12 | string name = country.ToLower();
13 | name = regex.Replace(name, string.Empty);
14 | trie.Insert(name);
15 | }
16 |
17 | string text = string.Empty;
18 | while (true)
19 | {
20 | Console.Write("Enter next character: ");
21 | ConsoleKeyInfo key = Console.ReadKey();
22 | if (key.KeyChar < 'a' || key.KeyChar > 'z') { return; }
23 | text = (text + key.KeyChar).ToLower();
24 | List results = trie.SearchByPrefix(text);
25 | if (results.Count == 0) { return; }
26 | Console.WriteLine($"\nSuggestions for {text.ToUpper()}:");
27 | results.ForEach(r => Console.WriteLine(r.ToUpper()));
28 | Console.WriteLine();
29 | }
30 |
--------------------------------------------------------------------------------
/07-AutoComplete/Trie.cs:
--------------------------------------------------------------------------------
1 | // AUTO-COMPLETE
2 | // Chapter 7 (Variants of Trees)
3 | // C# Data Structures and Algorithms, Second Edition
4 |
5 | public class Trie
6 | {
7 | private readonly TrieNode _root = new();
8 |
9 | public bool DoesExist(string word)
10 | {
11 | TrieNode current = _root;
12 | foreach (char c in word)
13 | {
14 | TrieNode child = current.Children[c - 'a'];
15 | if (child == null) { return false; }
16 | current = child;
17 | }
18 | return current.IsWord;
19 | }
20 |
21 | public void Insert(string word)
22 | {
23 | TrieNode current = _root;
24 | foreach (char c in word)
25 | {
26 | int i = c - 'a';
27 | current.Children[i] = current.Children[i] ?? new();
28 | current = current.Children[i];
29 | }
30 | current.IsWord = true;
31 | }
32 |
33 | public List SearchByPrefix(string prefix)
34 | {
35 | TrieNode current = _root;
36 | foreach (char c in prefix)
37 | {
38 | TrieNode child = current.Children[c - 'a'];
39 | if (child == null) { return []; }
40 | current = child;
41 | }
42 |
43 | List results = [];
44 | GetAllWithPrefix(current, prefix, results);
45 | return results;
46 | }
47 |
48 | private void GetAllWithPrefix(TrieNode node, string prefix, List results)
49 | {
50 | if (node == null) { return; }
51 | if (node.IsWord) { results.Add(prefix); }
52 |
53 | for (char c = 'a'; c <= 'z'; c++)
54 | {
55 | GetAllWithPrefix(node.Children[c - 'a'], prefix + c, results);
56 | }
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/07-AutoComplete/TrieNode.cs:
--------------------------------------------------------------------------------
1 | // AUTO-COMPLETE
2 | // Chapter 7 (Variants of Trees)
3 | // C# Data Structures and Algorithms, Second Edition
4 |
5 | public class TrieNode
6 | {
7 | public TrieNode[] Children { get; set; } = new TrieNode[26];
8 | public bool IsWord { get; set; } = false;
9 | }
10 |
--------------------------------------------------------------------------------
/07-BSTVisualization/07-BSTVisualization.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | net8.0
6 | _07_BSTVisualization
7 | enable
8 | enable
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/07-BSTVisualization/Program.cs:
--------------------------------------------------------------------------------
1 | // BST VISUALIZATION
2 | // Chapter 7 (Variants of Trees)
3 | // C# Data Structures and Algorithms, Second Edition
4 |
5 | BinarySearchTree tree = new();
6 | tree.Root = new BinaryTreeNode() { Data = 100 };
7 | tree.Root.Left = new() { Data = 50, Parent = tree.Root };
8 | tree.Root.Right = new() { Data = 150, Parent = tree.Root };
9 | tree.Count = 3;
10 | Visualize(tree, "BST with 3 nodes (50, 100, 150):");
11 |
12 | tree.Add(75);
13 | tree.Add(125);
14 | Visualize(tree, "BST after adding 2 nodes (75, 125):");
15 |
16 | tree.Add(25);
17 | tree.Add(175);
18 | tree.Add(90);
19 | tree.Add(110);
20 | tree.Add(135);
21 | Visualize(tree, "BST after adding 5 nodes (25, 175, 90, 110, 135):");
22 |
23 | tree.Remove(25);
24 | Visualize(tree, "BST after removing the node 25:");
25 |
26 | tree.Remove(50);
27 | Visualize(tree, "BST after removing the node 50:");
28 |
29 | tree.Remove(100);
30 | Visualize(tree, "BST after removing the node 100:");
31 |
32 | foreach (TraversalEnum mode in Enum.GetValues())
33 | {
34 | Console.Write($"\n{mode} traversal:\t");
35 | Console.Write(string.Join(", ", tree.Traverse(mode).Select(n => n.Data)));
36 | }
37 |
38 | void Visualize(BinarySearchTree tree, string caption)
39 | {
40 | char[,] console = Initialize(tree, out int width);
41 | VisualizeNode(tree.Root, 0, width / 2, console, width);
42 | Console.WriteLine(caption);
43 | Draw(console);
44 | }
45 |
46 | void Draw(char[,] console)
47 | {
48 | for (int y = 0; y < console.GetLength(0); y++)
49 | {
50 | for (int x = 0; x < console.GetLength(1); x++)
51 | {
52 | Console.Write(console[y, x]);
53 | }
54 | Console.WriteLine();
55 | }
56 | }
57 |
58 | const int ColumnWidth = 5;
59 |
60 | char[,] Initialize(BinarySearchTree tree,
61 | out int width)
62 | {
63 | int height = tree.GetHeight();
64 | width = (int)Math.Pow(2, height) - 1;
65 | char[,] console = new char[height * 2, ColumnWidth * width];
66 | for (int y = 0; y < console.GetLength(0); y++)
67 | {
68 | for (int x = 0; x < console.GetLength(1); x++)
69 | {
70 | console[y, x] = ' ';
71 | }
72 | }
73 | return console;
74 | }
75 |
76 | void VisualizeNode(BinaryTreeNode? node, int row, int column, char[,] console, int width)
77 | {
78 | if (node == null) { return; }
79 |
80 | char[] chars = node.Data.ToString().ToCharArray();
81 | int margin = (ColumnWidth - chars.Length) / 2;
82 | for (int i = 0; i < chars.Length; i++)
83 | {
84 | int col = ColumnWidth * column + i + margin;
85 | console[row, col] = chars[i];
86 | }
87 |
88 | int columnDelta = (width + 1) / (int)Math.Pow(2, node.GetHeight() + 1);
89 | VisualizeNode(node.Left, row + 2, column - columnDelta, console, width);
90 | VisualizeNode(node.Right, row + 2, column + columnDelta, console, width);
91 | DrawLineLeft(node, row, column, console, columnDelta);
92 | DrawLineRight(node, row, column, console, columnDelta);
93 | }
94 |
95 | void DrawLineLeft(BinaryTreeNode node, int row, int column, char[,] console, int columnDelta)
96 | {
97 | if (node.Left == null) { return; }
98 |
99 | int sci = ColumnWidth * (column - columnDelta) + 2;
100 | int eci = ColumnWidth * column + 2;
101 | for (int x = sci + 1; x < eci; x++)
102 | {
103 | console[row + 1, x] = '-';
104 | }
105 |
106 | console[row + 1, sci] = '+';
107 | console[row + 1, eci] = '+';
108 | }
109 |
110 | void DrawLineRight(BinaryTreeNode node, int row, int column, char[,] console, int columnDelta)
111 | {
112 | if (node.Right == null) { return; }
113 |
114 | int sci = ColumnWidth * column + 2;
115 | int eci = ColumnWidth * (column + columnDelta) + 2;
116 | for (int x = sci + 1; x < eci; x++)
117 | {
118 | console[row + 1, x] = '-';
119 | }
120 |
121 | console[row + 1, sci] = '+';
122 | console[row + 1, eci] = '+';
123 | }
124 |
--------------------------------------------------------------------------------
/07-CompanyStructure/07-CompanyStructure.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | net8.0
6 | _07_CompanyStructure
7 | enable
8 | enable
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/07-CompanyStructure/Person.cs:
--------------------------------------------------------------------------------
1 | // COMPANY STRUCTURE
2 | // Chapter 7 (Variants of Trees)
3 | // C# Data Structures and Algorithms, Second Edition
4 |
5 | public record Person(string Name, string Role);
6 |
--------------------------------------------------------------------------------
/07-CompanyStructure/Program.cs:
--------------------------------------------------------------------------------
1 | // COMPANY STRUCTURE
2 | // Chapter 7 (Variants of Trees)
3 | // C# Data Structures and Algorithms, Second Edition
4 |
5 | Tree company = new()
6 | {
7 | Root = new()
8 | {
9 | Data = new Person("Marcin Jamro", "Chief Executive Officer"),
10 | Parent = null
11 | }
12 | };
13 |
14 | company.Root.Children =
15 | [
16 | new() { Data = new Person("John Smith", "Head of Development"), Parent = company.Root },
17 | new() { Data = new Person("Alice Batman", "Head of Research"), Parent = company.Root },
18 | new() { Data = new Person("Lily Smith", "Head of Sales"), Parent = company.Root }
19 | ];
20 | company.Root.Children[2].Children =
21 | [
22 | new() { Data = new Person("Anthony Black", "Senior Sales Specialist"), Parent = company.Root.Children[2] }
23 | ];
24 |
--------------------------------------------------------------------------------
/07-HierarchyOfIdentifiers/07-HierarchyOfIdentifiers.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | net8.0
6 | _07_HierarchyOfIdentifiers
7 | enable
8 | enable
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/07-HierarchyOfIdentifiers/Program.cs:
--------------------------------------------------------------------------------
1 | // HIERARCHY OF IDENTIFIERS
2 | // Chapter 7 (Variants of Trees)
3 | // C# Data Structures and Algorithms, Second Edition
4 |
5 | Tree tree = new() { Root = new() { Data = 100 } };
6 | tree.Root.Children =
7 | [
8 | new() { Data = 50, Parent = tree.Root },
9 | new() { Data = 1, Parent = tree.Root },
10 | new() { Data = 150, Parent = tree.Root }
11 | ];
12 | tree.Root.Children[2].Children =
13 | [
14 | new() { Data = 30, Parent = tree.Root.Children[2] }
15 | ];
16 |
--------------------------------------------------------------------------------
/07-SimpleQuiz/07-SimpleQuiz.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | net8.0
6 | _07_SimpleQuiz
7 | enable
8 | enable
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/07-SimpleQuiz/Program.cs:
--------------------------------------------------------------------------------
1 | // SIMPLE QUIZ
2 | // Chapter 7 (Variants of Trees)
3 | // C# Data Structures and Algorithms, Second Edition
4 |
5 | BinaryTree tree = GetTree();
6 | BinaryTreeNode? node = tree.Root;
7 | while (node != null)
8 | {
9 | if (node.Left != null && node.Right != null)
10 | {
11 | Console.WriteLine(node.Data);
12 | node = Console.ReadKey(true).Key switch
13 | {
14 | ConsoleKey.Y => node.Left,
15 | ConsoleKey.N => node.Right,
16 | _ => node
17 | };
18 | }
19 | else
20 | {
21 | Console.WriteLine(node.Data);
22 | node = null;
23 | }
24 | }
25 |
26 | BinaryTree GetTree()
27 | {
28 | BinaryTree tree = new();
29 | tree.Root = new BinaryTreeNode()
30 | {
31 | Data = "Do you have an experience in app development?",
32 | Children =
33 | [
34 | new BinaryTreeNode()
35 | {
36 | Data = "Have you worked as a developer for 5+ years?",
37 | Children =
38 | [
39 | new() { Data = "Apply as a senior developer" },
40 | new() { Data = "Apply as a middle developer" }
41 | ]
42 | },
43 | new BinaryTreeNode()
44 | {
45 | Data = "Have you completed a university?",
46 | Children =
47 | [
48 | new() { Data = "Apply as a junior developer" },
49 | new BinaryTreeNode()
50 | {
51 | Data = "Will you find some time during the semester?",
52 | Children =
53 | [
54 | new() { Data = "Apply for long-time internship" },
55 | new() { Data = "Apply for summer internship" }
56 | ]
57 | }
58 | ]
59 | }
60 | ]
61 | };
62 | tree.Count = 9;
63 | return tree;
64 | }
65 |
--------------------------------------------------------------------------------
/07-Tree/07-Tree.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | net8.0
5 | _07_Tree
6 | enable
7 | enable
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/07-Tree/BinarySearchTree.cs:
--------------------------------------------------------------------------------
1 | // BINARY SEARCH TREE
2 | // Chapter 7 (Variants of Trees)
3 | // C# Data Structures and Algorithms, Second Edition
4 |
5 | public class BinarySearchTree
6 | : BinaryTree
7 | where T : IComparable
8 | {
9 | public bool Contains(T data)
10 | {
11 | BinaryTreeNode? node = Root;
12 | while (node != null)
13 | {
14 | int result = data.CompareTo(node.Data);
15 | if (result == 0) { return true; }
16 | else if (result < 0) { node = node.Left; }
17 | else { node = node.Right; }
18 | }
19 | return false;
20 | }
21 |
22 | public void Add(T data)
23 | {
24 | BinaryTreeNode? parent = GetParentForNewNode(data);
25 | BinaryTreeNode node = new()
26 | {
27 | Data = data,
28 | Parent = parent
29 | };
30 |
31 | if (parent == null) { Root = node; }
32 | else if (data.CompareTo(parent.Data) < 0) { parent.Left = node; }
33 | else { parent.Right = node; }
34 |
35 | Count++;
36 | }
37 |
38 | private BinaryTreeNode? GetParentForNewNode(T data)
39 | {
40 | BinaryTreeNode? current = Root;
41 | BinaryTreeNode? parent = null;
42 | while (current != null)
43 | {
44 | parent = current;
45 | int result = data.CompareTo(current.Data);
46 | if (result == 0)
47 | {
48 | throw new ArgumentException($"The node {data} already exists.");
49 | }
50 | else if (result < 0) { current = current.Left; }
51 | else { current = current.Right; }
52 | }
53 | return parent;
54 | }
55 |
56 | public void Remove(T data) => Remove(Root, data);
57 |
58 | private void Remove(BinaryTreeNode? node, T data)
59 | {
60 | if (node == null) { return; }
61 | else if (data.CompareTo(node.Data) < 0) { Remove(node.Left, data); }
62 | else if (data.CompareTo(node.Data) > 0) { Remove(node.Right, data); }
63 | else
64 | {
65 | if (node.Left == null || node.Right == null)
66 | {
67 | BinaryTreeNode? newNode =
68 | node.Left == null && node.Right == null
69 | ? null
70 | : node.Left ?? node.Right;
71 | ReplaceInParent(node, newNode!);
72 | Count--;
73 | }
74 | else
75 | {
76 | BinaryTreeNode successor = FindMinimumInSubtree(node.Right);
77 | node.Data = successor.Data;
78 | Remove(successor, successor.Data!);
79 | }
80 | }
81 | }
82 |
83 | private void ReplaceInParent(BinaryTreeNode node, BinaryTreeNode newNode)
84 | {
85 | if (node.Parent != null)
86 | {
87 | BinaryTreeNode parent = (BinaryTreeNode)node.Parent;
88 | if (parent.Left == node) { parent.Left = newNode; }
89 | else { parent.Right = newNode; }
90 | }
91 | else { Root = newNode; }
92 |
93 | if (newNode != null) { newNode.Parent = node.Parent; }
94 | }
95 |
96 | private BinaryTreeNode FindMinimumInSubtree(BinaryTreeNode node)
97 | {
98 | while (node.Left != null) { node = node.Left; }
99 | return node;
100 | }
101 | }
102 |
--------------------------------------------------------------------------------
/07-Tree/BinaryTree.cs:
--------------------------------------------------------------------------------
1 | // BINARY TREE
2 | // Chapter 7 (Variants of Trees)
3 | // C# Data Structures and Algorithms, Second Edition
4 |
5 | public class BinaryTree
6 | {
7 | public BinaryTreeNode? Root { get; set; }
8 | public int Count { get; set; }
9 |
10 | public List> Traverse(TraversalEnum mode)
11 | {
12 | List> nodes = [];
13 | if (Root == null) { return nodes; }
14 | switch (mode)
15 | {
16 | case TraversalEnum.PreOrder:
17 | TraversePreOrder(Root, nodes);
18 | break;
19 | case TraversalEnum.InOrder:
20 | TraverseInOrder(Root, nodes);
21 | break;
22 | case TraversalEnum.PostOrder:
23 | TraversePostOrder(Root, nodes);
24 | break;
25 | }
26 |
27 | return nodes;
28 | }
29 |
30 | public int GetHeight() => Root != null
31 | ? Traverse(TraversalEnum.PreOrder).Max(n => n.GetHeight())
32 | : 0;
33 |
34 | private void TraversePreOrder(BinaryTreeNode? node, List> result)
35 | {
36 | if (node == null) { return; }
37 | result.Add(node);
38 | TraversePreOrder(node.Left, result);
39 | TraversePreOrder(node.Right, result);
40 | }
41 |
42 | private void TraverseInOrder(BinaryTreeNode? node, List> result)
43 | {
44 | if (node == null) { return; }
45 | TraverseInOrder(node.Left, result);
46 | result.Add(node);
47 | TraverseInOrder(node.Right, result);
48 | }
49 |
50 | private void TraversePostOrder(BinaryTreeNode? node, List> result)
51 | {
52 | if (node == null) { return; }
53 | TraversePostOrder(node.Left, result);
54 | TraversePostOrder(node.Right, result);
55 | result.Add(node);
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/07-Tree/BinaryTreeNode.cs:
--------------------------------------------------------------------------------
1 | // BINARY TREE NODE
2 | // Chapter 7 (Variants of Trees)
3 | // C# Data Structures and Algorithms, Second Edition
4 |
5 | public class BinaryTreeNode
6 | : TreeNode
7 | {
8 | public new BinaryTreeNode?[] Children { get; set; } = [null, null];
9 |
10 | public BinaryTreeNode? Left
11 | {
12 | get { return Children[0]; }
13 | set { Children[0] = value; }
14 | }
15 |
16 | public BinaryTreeNode? Right
17 | {
18 | get { return Children[1]; }
19 | set { Children[1] = value; }
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/07-Tree/TraversalEnum.cs:
--------------------------------------------------------------------------------
1 | // BINARY TREE TRAVERSAL
2 | // Chapter 7 (Variants of Trees)
3 | // C# Data Structures and Algorithms, Second Edition
4 |
5 | public enum TraversalEnum
6 | {
7 | PreOrder,
8 | InOrder,
9 | PostOrder
10 | }
--------------------------------------------------------------------------------
/07-Tree/Tree.cs:
--------------------------------------------------------------------------------
1 | // TREE
2 | // Chapter 7 (Variants of Trees)
3 | // C# Data Structures and Algorithms, Second Edition
4 |
5 | public class Tree
6 | {
7 | public TreeNode? Root { get; set; }
8 | }
9 |
--------------------------------------------------------------------------------
/07-Tree/TreeNode.cs:
--------------------------------------------------------------------------------
1 | // TREE NODE
2 | // Chapter 7 (Variants of Trees)
3 | // C# Data Structures and Algorithms, Second Edition
4 |
5 | public class TreeNode
6 | {
7 | public T? Data { get; set; }
8 | public TreeNode? Parent { get; set; }
9 | public List> Children { get; set; } = [];
10 |
11 | public int GetHeight()
12 | {
13 | int height = 1;
14 | TreeNode current = this;
15 | while (current.Parent != null)
16 | {
17 | height++;
18 | current = current.Parent;
19 | }
20 | return height;
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/08-DirectedWeightedEdges/08-DirectedWeightedEdges.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | net8.0
6 | _08_DirectedWeightedEdges
7 | enable
8 | enable
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/08-DirectedWeightedEdges/Program.cs:
--------------------------------------------------------------------------------
1 | // DIRECTED AND WEIGHTED EDGES
2 | // Chapter 8 (Exploring Graphs)
3 | // C# Data Structures and Algorithms, Second Edition
4 |
5 | Graph graph = new() { IsDirected = true, IsWeighted = true };
6 |
7 | Node n1 = graph.AddNode(1);
8 | Node n2 = graph.AddNode(2);
9 | Node n3 = graph.AddNode(3);
10 | Node n4 = graph.AddNode(4);
11 | Node n5 = graph.AddNode(5);
12 | Node n6 = graph.AddNode(6);
13 | Node n7 = graph.AddNode(7);
14 | Node n8 = graph.AddNode(8);
15 |
16 | graph.AddEdge(n1, n2, 9);
17 | graph.AddEdge(n1, n3, 5);
18 | graph.AddEdge(n2, n1, 3);
19 | graph.AddEdge(n2, n4, 18);
20 | graph.AddEdge(n3, n4, 12);
21 | graph.AddEdge(n4, n2, 2);
22 | graph.AddEdge(n4, n8, 8);
23 | graph.AddEdge(n5, n4, 9);
24 | graph.AddEdge(n5, n6, 2);
25 | graph.AddEdge(n5, n7, 5);
26 | graph.AddEdge(n5, n8, 3);
27 | graph.AddEdge(n6, n7, 1);
28 | graph.AddEdge(n7, n5, 4);
29 | graph.AddEdge(n7, n8, 6);
30 | graph.AddEdge(n8, n5, 3);
31 |
32 | Console.WriteLine("DFS:");
33 | graph.DFS().ForEach(Console.WriteLine);
34 |
35 | Console.WriteLine("\nBFS:");
36 | graph.BFS().ForEach(Console.WriteLine);
37 |
38 | Console.WriteLine("\nShortest path:");
39 | List> path = graph.GetShortestPath(n1, n5);
40 | path.ForEach(Console.WriteLine);
41 |
--------------------------------------------------------------------------------
/08-Graph/08-Graph.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | net8.0
5 | _08_Graph
6 | enable
7 | enable
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/08-Graph/Edge.cs:
--------------------------------------------------------------------------------
1 | // GRAPH EDGE
2 | // Chapter 8 (Exploring Graphs)
3 | // C# Data Structures and Algorithms, Second Edition
4 |
5 | public class Edge
6 | {
7 | public required Node From { get; set; }
8 | public required Node To { get; set; }
9 | public int Weight { get; set; }
10 | public override string ToString() => $"{From.Data} -> {To.Data}. Weight: { Weight}.";
11 | }
12 |
--------------------------------------------------------------------------------
/08-Graph/Graph.cs:
--------------------------------------------------------------------------------
1 | // GRAPH
2 | // Chapter 8 (Exploring Graphs)
3 | // C# Data Structures and Algorithms, Second Edition
4 |
5 | using Priority_Queue;
6 |
7 | public partial class Graph
8 | {
9 | public required bool IsDirected { get; init; }
10 | public required bool IsWeighted { get; init; }
11 | public List> Nodes { get; set; } = [];
12 |
13 | #region Get edge and edges
14 | public Edge? this[int from, int to]
15 | {
16 | get
17 | {
18 | Node nodeFrom = Nodes[from];
19 | Node nodeTo = Nodes[to];
20 | int i = nodeFrom.Neighbors.IndexOf(nodeTo);
21 | if (i < 0) { return null; }
22 | Edge edge = new()
23 | {
24 | From = nodeFrom,
25 | To = nodeTo,
26 | Weight = i < nodeFrom.Weights.Count ? nodeFrom.Weights[i] : 0
27 | };
28 | return edge;
29 | }
30 | }
31 |
32 | public List> GetEdges()
33 | {
34 | List> edges = [];
35 | foreach (Node from in Nodes)
36 | {
37 | for (int i = 0; i < from.Neighbors.Count; i++)
38 | {
39 | int weight = i < from.Weights.Count ? from.Weights[i] : 0;
40 | Edge edge = new()
41 | {
42 | From = from,
43 | To = from.Neighbors[i],
44 | Weight = weight
45 | };
46 | edges.Add(edge);
47 | }
48 | }
49 | return edges;
50 | }
51 | #endregion
52 |
53 | #region Add and remove nodes
54 | public Node AddNode(T value)
55 | {
56 | Node node = new() { Data = value };
57 | Nodes.Add(node);
58 | UpdateIndices();
59 | return node;
60 | }
61 |
62 | public void RemoveNode(Node nodeToRemove)
63 | {
64 | Nodes.Remove(nodeToRemove);
65 | UpdateIndices();
66 | Nodes.ForEach(n => RemoveEdge(n, nodeToRemove));
67 | }
68 |
69 | private void UpdateIndices()
70 | {
71 | int i = 0;
72 | Nodes.ForEach(n => n.Index = i++);
73 | }
74 | #endregion
75 |
76 | #region Add and remove edges
77 | public void AddEdge(Node from, Node to, int w = 0)
78 | {
79 | from.Neighbors.Add(to);
80 | if (IsWeighted) { from.Weights.Add(w); }
81 |
82 | if (!IsDirected)
83 | {
84 | to.Neighbors.Add(from);
85 | if (IsWeighted) { to.Weights.Add(w); }
86 | }
87 | }
88 |
89 | public void RemoveEdge(Node from, Node to)
90 | {
91 | int index = from.Neighbors.FindIndex(n => n == to);
92 | if (index < 0) { return; }
93 | from.Neighbors.RemoveAt(index);
94 | if (IsWeighted) { from.Weights.RemoveAt(index); }
95 |
96 | if (!IsDirected)
97 | {
98 | index = to.Neighbors.FindIndex(n => n == from);
99 | if (index < 0) { return; }
100 | to.Neighbors.RemoveAt(index);
101 | if (IsWeighted) { to.Weights.RemoveAt(index); }
102 | }
103 | }
104 | #endregion
105 |
106 | #region Depth-First Search
107 | public List> DFS()
108 | {
109 | bool[] isVisited = new bool[Nodes.Count];
110 | List> result = [];
111 | DFS(isVisited, Nodes[0], result);
112 | return result;
113 | }
114 |
115 | private void DFS(bool[] isVisited, Node node, List> result)
116 | {
117 | result.Add(node);
118 | isVisited[node.Index] = true;
119 |
120 | foreach (Node neighbor in node.Neighbors)
121 | {
122 | if (!isVisited[neighbor.Index])
123 | {
124 | DFS(isVisited, neighbor, result);
125 | }
126 | }
127 | }
128 | #endregion
129 |
130 | #region Breadth-First Search
131 | public List> BFS() => BFS(Nodes[0]);
132 |
133 | private List> BFS(Node node)
134 | {
135 | bool[] isVisited = new bool[Nodes.Count];
136 | isVisited[node.Index] = true;
137 |
138 | List> result = [];
139 | Queue> queue = [];
140 | queue.Enqueue(node);
141 | while (queue.Count > 0)
142 | {
143 | Node next = queue.Dequeue();
144 | result.Add(next);
145 |
146 | foreach (Node neighbor in next.Neighbors)
147 | {
148 | if (!isVisited[neighbor.Index])
149 | {
150 | isVisited[neighbor.Index] = true;
151 | queue.Enqueue(neighbor);
152 | }
153 | }
154 | }
155 |
156 | return result;
157 | }
158 | #endregion
159 |
160 | #region Minimum Spanning Tree - Kruskal's algorithm
161 | public List> MSTKruskal()
162 | {
163 | List> edges = GetEdges();
164 | edges.Sort((a, b) => a.Weight.CompareTo(b.Weight));
165 | Queue> queue = new(edges);
166 |
167 | Subset[] subsets = new Subset[Nodes.Count];
168 | for (int i = 0; i < Nodes.Count; i++)
169 | {
170 | subsets[i] = new() { Parent = Nodes[i] };
171 | }
172 |
173 | List> result = [];
174 | while (result.Count < Nodes.Count - 1)
175 | {
176 | Edge edge = queue.Dequeue();
177 | Node from = GetRoot(subsets, edge.From);
178 | Node to = GetRoot(subsets, edge.To);
179 | if (from == to) { continue; }
180 | result.Add(edge);
181 | Union(subsets, from, to);
182 | }
183 |
184 | return result;
185 | }
186 |
187 | private Node GetRoot(Subset[] ss, Node node)
188 | {
189 | int i = node.Index;
190 | ss[i].Parent = ss[i].Parent != node
191 | ? GetRoot(ss, ss[i].Parent)
192 | : ss[i].Parent;
193 | return ss[i].Parent;
194 | }
195 |
196 | private void Union(Subset[] ss, Node a, Node b)
197 | {
198 | ss[b.Index].Parent = ss[a.Index].Rank >= ss[b.Index].Rank
199 | ? a : ss[b.Index].Parent;
200 | ss[a.Index].Parent = ss[a.Index].Rank < ss[b.Index].Rank
201 | ? b : ss[a.Index].Parent;
202 | if (ss[a.Index].Rank == ss[b.Index].Rank) { ss[a.Index].Rank++; }
203 | }
204 | #endregion
205 |
206 | #region Minimum Spanning Tree - Prim's algorithm
207 | public List> MSTPrim()
208 | {
209 | int[] previous = new int[Nodes.Count];
210 | previous[0] = -1;
211 |
212 | int[] minWeight = new int[Nodes.Count];
213 | Array.Fill(minWeight, int.MaxValue);
214 | minWeight[0] = 0;
215 |
216 | bool[] isInMST = new bool[Nodes.Count];
217 | Array.Fill(isInMST, false);
218 |
219 | for (int i = 0; i < Nodes.Count - 1; i++)
220 | {
221 | int mwi = GetMinWeightIndex(minWeight, isInMST);
222 | isInMST[mwi] = true;
223 |
224 | for (int j = 0; j < Nodes.Count; j++)
225 | {
226 | Edge? edge = this[mwi, j];
227 | int weight = edge != null ? edge.Weight : -1;
228 | if (edge != null && !isInMST[j] && weight < minWeight[j])
229 | {
230 | previous[j] = mwi;
231 | minWeight[j] = weight;
232 | }
233 | }
234 | }
235 |
236 | List> result = [];
237 | for (int i = 1; i < Nodes.Count; i++)
238 | {
239 | result.Add(this[previous[i], i]!);
240 | }
241 |
242 | return result;
243 | }
244 |
245 | private int GetMinWeightIndex(int[] weights, bool[] isInMST)
246 | {
247 | int minValue = int.MaxValue;
248 | int minIndex = 0;
249 |
250 | for (int i = 0; i < Nodes.Count; i++)
251 | {
252 | if (!isInMST[i] && weights[i] < minValue)
253 | {
254 | minValue = weights[i];
255 | minIndex = i;
256 | }
257 | }
258 |
259 | return minIndex;
260 | }
261 | #endregion
262 |
263 | #region Coloring
264 | public int[] Color()
265 | {
266 | int[] colors = new int[Nodes.Count];
267 | Array.Fill(colors, -1);
268 | colors[0] = 0;
269 |
270 | bool[] available = new bool[Nodes.Count];
271 | for (int i = 1; i < Nodes.Count; i++)
272 | {
273 | Array.Fill(available, true);
274 |
275 | foreach (Node neighbor in Nodes[i].Neighbors)
276 | {
277 | int ci = colors[neighbor.Index];
278 | if (ci >= 0) { available[ci] = false; }
279 | }
280 |
281 | colors[i] = Array.IndexOf(available, true);
282 | }
283 |
284 | return colors;
285 | }
286 | #endregion
287 |
288 | #region Shortest Path
289 | public List> GetShortestPath(
290 | Node source, Node target)
291 | {
292 | int[] previous = new int[Nodes.Count];
293 | Array.Fill(previous, -1);
294 |
295 | int[] distances = new int[Nodes.Count];
296 | Array.Fill(distances, int.MaxValue);
297 | distances[source.Index] = 0;
298 |
299 | SimplePriorityQueue> nodes = new();
300 | for (int i = 0; i < Nodes.Count; i++)
301 | {
302 | nodes.Enqueue(Nodes[i], distances[i]);
303 | }
304 |
305 | while (nodes.Count != 0)
306 | {
307 | Node node = nodes.Dequeue();
308 | for (int i = 0; i < node.Neighbors.Count; i++)
309 | {
310 | Node neighbor = node.Neighbors[i];
311 | int weight = i < node.Weights.Count ? node.Weights[i] : 0;
312 | int wTotal = distances[node.Index] + weight;
313 |
314 | if (distances[neighbor.Index] > wTotal)
315 | {
316 | distances[neighbor.Index] = wTotal;
317 | previous[neighbor.Index] = node.Index;
318 | nodes.UpdatePriority(neighbor, distances[neighbor.Index]);
319 | }
320 | }
321 | }
322 |
323 | List indices = [];
324 | int index = target.Index;
325 | while (index >= 0)
326 | {
327 | indices.Add(index);
328 | index = previous[index];
329 | }
330 |
331 | indices.Reverse();
332 | List> result = [];
333 | for (int i = 0; i < indices.Count - 1; i++)
334 | {
335 | Edge edge = this[indices[i], indices[i + 1]]!;
336 | result.Add(edge);
337 | }
338 |
339 | return result;
340 | }
341 | #endregion
342 | }
343 |
--------------------------------------------------------------------------------
/08-Graph/Node.cs:
--------------------------------------------------------------------------------
1 | // GRAPH NODE
2 | // Chapter 8 (Exploring Graphs)
3 | // C# Data Structures and Algorithms, Second Edition
4 |
5 | public class Node
6 | {
7 | public int Index { get; set; }
8 | public required T Data { get; set; }
9 | public List> Neighbors { get; set; } = [];
10 | public List Weights { get; set; } = [];
11 | public override string ToString() => $"Index: {Index}. Data: {Data}. Neighbors: { Neighbors.Count}.";
12 | }
13 |
--------------------------------------------------------------------------------
/08-Graph/Subset.cs:
--------------------------------------------------------------------------------
1 | // SUBSET
2 | // Chapter 8 (Exploring Graphs)
3 | // C# Data Structures and Algorithms, Second Edition
4 |
5 | public class Subset
6 | {
7 | public required Node Parent { get; set; }
8 | public int Rank { get; set; }
9 | public override string ToString() => $"Rank: {Rank}. Parent: {Parent.Data}. Index: {Parent.Index}.";
10 | }
11 |
--------------------------------------------------------------------------------
/08-PathInGame/08-PathInGame.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | net8.0
6 | _08_PathInGame
7 | enable
8 | enable
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/08-PathInGame/Program.cs:
--------------------------------------------------------------------------------
1 | // PATH IN GAME
2 | // Chapter 8 (Exploring Graphs)
3 | // C# Data Structures and Algorithms, Second Edition
4 |
5 | using System.Text;
6 |
7 | string[] lines =
8 | [
9 | "0011100000111110000011111",
10 | "0011100000111110000011111",
11 | "0011100000111110000011111",
12 | "0000000000011100000011111",
13 | "0000001110000000000011111",
14 | "0001001110011100000011111",
15 | "1111111111111110111111100",
16 | "1111111111111110111111101",
17 | "1111111111111110111111100",
18 | "0000000000000000111111110",
19 | "0000000000000000111111100",
20 | "0001111111001100000001101",
21 | "0001111111001100000001100",
22 | "0001100000000000111111110",
23 | "1111100000000000111111100",
24 | "1111100011001100100010001",
25 | "1111100011001100001000100"
26 | ];
27 | bool[][] map = new bool[lines.Length][];
28 | for (int i = 0; i < lines.Length; i++)
29 | {
30 | map[i] = lines[i]
31 | .Select(c => int.Parse(c.ToString()) == 0)
32 | .ToArray();
33 | }
34 |
35 | Graph graph = new() { IsDirected = false, IsWeighted = true };
36 | for (int i = 0; i < map.Length; i++)
37 | {
38 | for (int j = 0; j < map[i].Length; j++)
39 | {
40 | if (!map[i][j]) { continue; }
41 |
42 | Node from = graph.AddNode($"{i}-{j}");
43 |
44 | if (i > 0 && map[i - 1][j])
45 | {
46 | Node to = graph.Nodes.Find(n => n.Data == $"{i - 1}-{j}")!;
47 | graph.AddEdge(from, to, 1);
48 | }
49 |
50 | if (j > 0 && map[i][j - 1])
51 | {
52 | Node to = graph.Nodes.Find(n => n.Data == $"{i}-{j - 1}")!;
53 | graph.AddEdge(from, to, 1);
54 | }
55 | }
56 | }
57 |
58 | Node s = graph.Nodes.Find(n => n.Data == "0-0")!;
59 | Node t = graph.Nodes.Find(n => n.Data == "16-24")!;
60 | List> path = graph.GetShortestPath(s, t);
61 |
62 | Console.OutputEncoding = Encoding.UTF8;
63 | for (int r = 0; r < map.Length; r++)
64 | {
65 | for (int c = 0; c < map[r].Length; c++)
66 | {
67 | bool isPath = path.Any(e => e.From.Data == $"{r}-{c}" || e.To.Data == $"{r}-{c}");
68 | Console.ForegroundColor = isPath ? ConsoleColor.White
69 | : map[r][c] ? ConsoleColor.Green : ConsoleColor.Red;
70 | Console.Write("\u25cf ");
71 | }
72 | Console.WriteLine();
73 | }
74 | Console.ResetColor();
75 |
--------------------------------------------------------------------------------
/08-TelecommunicationCable/08-TelecommunicationCable.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | net8.0
6 | _08_TelecommunicationCable
7 | enable
8 | enable
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/08-TelecommunicationCable/Program.cs:
--------------------------------------------------------------------------------
1 | // TELECOMMUNICATION CABLE
2 | // Chapter 8 (Exploring Graphs)
3 | // C# Data Structures and Algorithms, Second Edition
4 |
5 | Graph graph = new() { IsDirected = false, IsWeighted = true };
6 |
7 | Node nodeB1 = graph.AddNode("B1");
8 | Node nodeB2 = graph.AddNode("B2");
9 | Node nodeB3 = graph.AddNode("B3");
10 | Node nodeB4 = graph.AddNode("B4");
11 | Node nodeB5 = graph.AddNode("B5");
12 | Node nodeB6 = graph.AddNode("B6");
13 | Node nodeR1 = graph.AddNode("R1");
14 | Node nodeR2 = graph.AddNode("R2");
15 | Node nodeR3 = graph.AddNode("R3");
16 | Node nodeR4 = graph.AddNode("R4");
17 | Node nodeR5 = graph.AddNode("R5");
18 | Node nodeR6 = graph.AddNode("R6");
19 |
20 | graph.AddEdge(nodeB1, nodeB2, 2);
21 | graph.AddEdge(nodeB1, nodeB3, 20);
22 | graph.AddEdge(nodeB1, nodeB4, 30);
23 | graph.AddEdge(nodeB2, nodeB3, 30);
24 | graph.AddEdge(nodeB2, nodeB4, 20);
25 | graph.AddEdge(nodeB2, nodeR2, 25);
26 | graph.AddEdge(nodeB3, nodeB4, 2);
27 | graph.AddEdge(nodeB4, nodeR4, 25);
28 | graph.AddEdge(nodeR1, nodeR2, 1);
29 | graph.AddEdge(nodeR2, nodeR3, 1);
30 | graph.AddEdge(nodeR3, nodeR4, 1);
31 | graph.AddEdge(nodeR1, nodeR5, 75);
32 | graph.AddEdge(nodeR3, nodeR6, 100);
33 | graph.AddEdge(nodeR5, nodeR6, 3);
34 | graph.AddEdge(nodeR6, nodeB5, 3);
35 | graph.AddEdge(nodeR6, nodeB6, 10);
36 | graph.AddEdge(nodeB5, nodeB6, 6);
37 |
38 | Console.WriteLine("Minimum Spanning Tree - Kruskal:");
39 | List> kruskal = graph.MSTKruskal();
40 | kruskal.ForEach(Console.WriteLine);
41 | Console.WriteLine("Cost: " + kruskal.Sum(e => e.Weight));
42 |
43 | Console.WriteLine("\nMinimum Spanning Tree - Prim:");
44 | List> prim = graph.MSTPrim();
45 | prim.ForEach(Console.WriteLine);
46 | Console.WriteLine("Cost: " + prim.Sum(e => e.Weight));
47 |
--------------------------------------------------------------------------------
/08-UndirectedUnweightedEdges/08-UndirectedUnweightedEdges.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | net8.0
6 | _08_UndirectedUnweightedEdges
7 | enable
8 | enable
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/08-UndirectedUnweightedEdges/Program.cs:
--------------------------------------------------------------------------------
1 | // UNDIRECTED AND UNWEIGHTED EDGES
2 | // Chapter 8 (Exploring Graphs)
3 | // C# Data Structures and Algorithms, Second Edition
4 |
5 | Graph graph = new() { IsDirected = false, IsWeighted = false };
6 |
7 | Node n1 = graph.AddNode(1);
8 | Node n2 = graph.AddNode(2);
9 | Node n3 = graph.AddNode(3);
10 | Node n4 = graph.AddNode(4);
11 | Node n5 = graph.AddNode(5);
12 | Node n6 = graph.AddNode(6);
13 | Node n7 = graph.AddNode(7);
14 | Node n8 = graph.AddNode(8);
15 |
16 | graph.AddEdge(n1, n2);
17 | graph.AddEdge(n1, n3);
18 | graph.AddEdge(n2, n4);
19 | graph.AddEdge(n3, n4);
20 | graph.AddEdge(n4, n5);
21 | graph.AddEdge(n5, n6);
22 | graph.AddEdge(n5, n7);
23 | graph.AddEdge(n5, n8);
24 | graph.AddEdge(n6, n7);
25 | graph.AddEdge(n7, n8);
26 |
27 | Console.WriteLine("DFS:");
28 | graph.DFS().ForEach(Console.WriteLine);
29 |
30 | Console.WriteLine("\nBFS:");
31 | graph.BFS().ForEach(Console.WriteLine);
32 |
--------------------------------------------------------------------------------
/08-VoivodeshipMap/08-VoivodeshipMap.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | net8.0
6 | _08_VoivodeshipMap
7 | enable
8 | enable
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/08-VoivodeshipMap/Program.cs:
--------------------------------------------------------------------------------
1 | // VOIVODESHIP MAP
2 | // Chapter 8 (Exploring Graphs)
3 | // C# Data Structures and Algorithms, Second Edition
4 |
5 | Graph graph = new() { IsDirected = false, IsWeighted = false };
6 |
7 | List borders =
8 | [
9 | "PK:LU|SK|MA",
10 | "LU:PK|SK|MZ|PD",
11 | "SK:PK|MA|SL|LD|MZ|LU",
12 | "MA:PK|SK|SL",
13 | "SL:MA|SK|LD|OP",
14 | "LD:SL|SK|MZ|KP|WP|OP",
15 | "WP:LD|KP|PM|ZP|LB|DS|OP",
16 | "OP:SL|LD|WP|DS",
17 | "MZ:LU|SK|LD|KP|WM|PD",
18 | "PD:LU|MZ|WM",
19 | "WM:PD|MZ|KP|PM",
20 | "KP:MZ|LD|WP|PM|WM",
21 | "PM:WM|KP|WP|ZP",
22 | "ZP:PM|WP|LB",
23 | "LB:ZP|WP|DS",
24 | "DS:LB|WP|OP"
25 | ];
26 |
27 | Dictionary> nodes = [];
28 | foreach (string border in borders)
29 | {
30 | string[] parts = border.Split(':');
31 | string name = parts[0];
32 | nodes[name] = graph.AddNode(name);
33 | }
34 |
35 | foreach (string border in borders)
36 | {
37 | string[] parts = border.Split(':');
38 | string name = parts[0];
39 | string[] vicinities = parts[1].Split('|');
40 | foreach (string vicinity in vicinities)
41 | {
42 | Node from = nodes[name];
43 | Node to = nodes[vicinity];
44 | if (!from.Neighbors.Contains(to))
45 | {
46 | graph.AddEdge(from, to);
47 | }
48 | }
49 | }
50 |
51 | int[] colors = graph.Color();
52 | for (int i = 0; i < colors.Length; i++)
53 | {
54 | Console.WriteLine($"{graph.Nodes[i].Data}: {colors[i]}");
55 | }
56 |
--------------------------------------------------------------------------------
/09-ClosestPairOfPoints/09-ClosestPairOfPoints.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | net8.0
6 | _09_ClosestPairOfPoints
7 | enable
8 | enable
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/09-ClosestPairOfPoints/Point.cs:
--------------------------------------------------------------------------------
1 | // CLOSEST PAIR OF POINTS
2 | // Chapter 9 (See in Action)
3 | // C# Data Structures and Algorithms, Second Edition
4 |
5 | public record Point(int X, int Y)
6 | {
7 | public float GetDistanceTo(Point p) =>
8 | (float)Math.Sqrt(Math.Pow(X - p.X, 2) + Math.Pow(Y - p.Y, 2));
9 | };
10 |
--------------------------------------------------------------------------------
/09-ClosestPairOfPoints/Program.cs:
--------------------------------------------------------------------------------
1 | // CLOSEST PAIR OF POINTS
2 | // Chapter 9 (See in Action)
3 | // C# Data Structures and Algorithms, Second Edition
4 |
5 | List points =
6 | [
7 | new Point(6, 45), // A
8 | new Point(12, 8), // B
9 | new Point(14, 31), // C
10 | new Point(24, 18), // D
11 | new Point(32, 26), // E
12 | new Point(40, 41), // F
13 | new Point(44, 6), // G
14 | new Point(57, 20), // H
15 | new Point(60, 35), // I
16 | new Point(72, 9), // J
17 | new Point(73, 41), // K
18 | new Point(85, 25), // L
19 | new Point(92, 8), // M
20 | new Point(93, 43) // N
21 | ];
22 |
23 | points.Sort((a, b) => a.X.CompareTo(b.X));
24 | Result? closestPair = FindClosestPair(points.ToArray());
25 | if (closestPair != null)
26 | {
27 | Console.WriteLine(
28 | "Closest pair: ({0}, {1}) and ({2}, {3}) with distance: {4:F2}",
29 | closestPair.P1.X,
30 | closestPair.P1.Y,
31 | closestPair.P2.X,
32 | closestPair.P2.Y,
33 | closestPair.Distance);
34 | }
35 |
36 | Result? FindClosestPair(Point[] points)
37 | {
38 | if (points.Length <= 1) { return null; }
39 | if (points.Length <= 3) { return Closest(points); }
40 |
41 | int m = points.Length / 2;
42 | Result r = Closer(
43 | FindClosestPair(points.Take(m).ToArray())!,
44 | FindClosestPair(points.Skip(m).ToArray())!);
45 |
46 | Point[] strip = points.Where(p => Math.Abs(p.X - points[m].X) < r.Distance).ToArray();
47 | return Closer(r, Closest(strip));
48 | }
49 |
50 | Result Closest(Point[] points)
51 | {
52 | Result result = new(points[0], points[0], double.MaxValue);
53 | for (int i = 0; i < points.Length; i++)
54 | {
55 | for (int j = i + 1; j < points.Length; j++)
56 | {
57 | double distance = points[i].GetDistanceTo(points[j]);
58 | if (distance < result.Distance)
59 | {
60 | result = new(points[i], points[j], distance);
61 | }
62 | }
63 | }
64 | return result;
65 | }
66 |
67 | Result Closer(Result r1, Result r2) => r1.Distance < r2.Distance ? r1 : r2;
68 |
--------------------------------------------------------------------------------
/09-ClosestPairOfPoints/Result.cs:
--------------------------------------------------------------------------------
1 | // CLOSEST PAIR OF POINTS
2 | // Chapter 9 (See in Action)
3 | // C# Data Structures and Algorithms, Second Edition
4 |
5 | public record Result(Point P1, Point P2, double Distance);
6 |
--------------------------------------------------------------------------------
/09-FibonacciSeries/09-FibonacciSeries.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | net8.0
6 | _09_FibonacciSeries
7 | enable
8 | enable
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/09-FibonacciSeries/Program.cs:
--------------------------------------------------------------------------------
1 | // FIBONACCI SERIES
2 | // Chapter 9 (See in Action)
3 | // C# Data Structures and Algorithms, Second Edition
4 |
5 | // Simple recursive implementation:
6 | // long Fibonacci(int n)
7 | // {
8 | // if (n == 0) { return 0; }
9 | // if (n == 1) { return 1; }
10 | // return Fibonacci(n - 1) + Fibonacci(n - 2);
11 | // }
12 |
13 | // Dynamic programming with top-down approach:
14 | // Dictionary cache = [];
15 | // long Fibonacci(int n)
16 | // {
17 | // if (n == 0) { return 0; }
18 | // if (n == 1) { return 1; }
19 | // if (cache.ContainsKey(n)) { return cache[n]; }
20 | // long result = Fibonacci(n - 1) + Fibonacci(n - 2);
21 | // cache[n] = result;
22 | // return result;
23 | // }
24 |
25 | // Dynamic programming with bottom-up approach:
26 | long Fibonacci(int n)
27 | {
28 | if (n == 0) { return 0; }
29 | if (n == 1) { return 1; }
30 |
31 | long a = 0;
32 | long b = 1;
33 | for (int i = 2; i <= n; i++)
34 | {
35 | long result = a + b;
36 | a = b;
37 | b = result;
38 | }
39 |
40 | return b;
41 | }
42 |
43 | long result = Fibonacci(25);
44 | Console.WriteLine($"F(25) = {result}");
45 |
--------------------------------------------------------------------------------
/09-FractalGeneration/09-FractalGeneration.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | net8.0
6 | _09_FractalGeneration
7 | enable
8 | enable
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/09-FractalGeneration/Program.cs:
--------------------------------------------------------------------------------
1 | // FRACTAL GENERATION
2 | // Chapter 9 (See in Action)
3 | // C# Data Structures and Algorithms, Second Edition
4 |
5 | using System.Drawing;
6 | using System.Drawing.Drawing2D;
7 |
8 | const int maxSize = 1000;
9 | List lines = [];
10 | AddLine(14, 0, 0, 500, (float)Math.PI * 1.5f);
11 |
12 | float xMin = lines.Min(l => Math.Min(l.X1, l.X2));
13 | float xMax = lines.Max(l => Math.Max(l.X1, l.X2));
14 | float yMin = lines.Min(l => Math.Min(l.Y1, l.Y2));
15 | float yMax = lines.Max(l => Math.Max(l.Y1, l.Y2));
16 | float size = Math.Max(xMax - xMin, yMax - yMin);
17 | float factor = maxSize / size;
18 | int width = (int)((xMax - xMin) * factor);
19 | int height = (int)((yMax - yMin) * factor);
20 |
21 | #pragma warning disable CA1416
22 | using Bitmap bitmap = new(width, height);
23 | using Graphics graphics = Graphics.FromImage(bitmap);
24 | graphics.Clear(Color.White);
25 | graphics.SmoothingMode = SmoothingMode.AntiAlias;
26 | using Pen pen = new(Color.Black, 1);
27 | foreach (Line line in lines)
28 | {
29 | pen.Width = line.GetLength() / 20;
30 | float sx = (line.X1 - xMin) * factor;
31 | float sy = (line.Y1 - yMin) * factor;
32 | float ex = (line.X2 - xMin) * factor;
33 | float ey = (line.Y2 - yMin) * factor;
34 | graphics.DrawLine(pen, sx, sy, ex, ey);
35 | }
36 | bitmap.Save($"{DateTime.Now:HH-mm-ss}.png");
37 | #pragma warning restore CA1416
38 |
39 | void AddLine(int level, float x, float y, float length, float angle)
40 | {
41 | if (level < 0) { return; }
42 |
43 | float endX = x + (float)(length * Math.Cos(angle));
44 | float endY = y + (float)(length * Math.Sin(angle));
45 | lines.Add(new(x, y, endX, endY));
46 |
47 | AddLine(level - 1, endX, endY, length * 0.8f, angle + (float)Math.PI * 0.3f);
48 | AddLine(level - 1, endX, endY, length * 0.6f, angle + (float)Math.PI * 1.7f);
49 | }
50 |
51 | record Line(float X1, float Y1, float X2, float Y2)
52 | {
53 | public float GetLength() =>
54 | (float)Math.Sqrt(Math.Pow(X1 - X2, 2) + Math.Pow(Y1 - Y2, 2));
55 | }
56 |
--------------------------------------------------------------------------------
/09-MinimumCoinChange/09-MinimumCoinChange.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | net8.0
6 | _09_MinimumCoinChange
7 | enable
8 | enable
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/09-MinimumCoinChange/Program.cs:
--------------------------------------------------------------------------------
1 | // MINIMUM COIN CHANGE
2 | // Chapter 9 (See in Action)
3 | // C# Data Structures and Algorithms, Second Edition
4 |
5 | int[] den = [1, 2, 5, 10, 20, 50, 100, 200, 500];
6 | List coins = GetCoins(158);
7 | coins.ForEach(Console.WriteLine);
8 |
9 | List GetCoins(int amount)
10 | {
11 | List coins = [];
12 | for (int i = den.Length - 1; i >= 0; i--)
13 | {
14 | while (amount >= den[i])
15 | {
16 | amount -= den[i];
17 | coins.Add(den[i]);
18 | }
19 | }
20 | return coins;
21 | }
22 |
--------------------------------------------------------------------------------
/09-PasswordGuess/09-PasswordGuess.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | net8.0
6 | _09_PasswordGuess
7 | enable
8 | enable
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/09-PasswordGuess/Program.cs:
--------------------------------------------------------------------------------
1 | // PASSWORD GUESS
2 | // Chapter 9 (See in Action)
3 | // C# Data Structures and Algorithms, Second Edition
4 |
5 | using System.Diagnostics;
6 | using System.Text;
7 |
8 | const string secretPassword = "csharp";
9 |
10 | int charsCount = 0;
11 | char[] chars = new char[36];
12 | for (char c = 'a'; c <= 'z'; c++) { chars[charsCount++] = c; }
13 | for (char c = '0'; c <= '9'; c++) { chars[charsCount++] = c; }
14 |
15 | for (int length = 2; length <= 8; length++)
16 | {
17 | Stopwatch sw = Stopwatch.StartNew();
18 | int[] indices = new int[length];
19 | for (int i = 0; i < length; i++) { indices[i] = 0; }
20 |
21 | bool isCompleted = false;
22 | StringBuilder builder = new();
23 | long count = 0;
24 | while (!isCompleted)
25 | {
26 | builder.Clear();
27 | for (int i = 0; i < length; i++)
28 | {
29 | builder.Append(chars[indices[i]]);
30 | }
31 |
32 | string guess = builder.ToString();
33 | if (guess == secretPassword)
34 | {
35 | Console.WriteLine("Found.");
36 | }
37 |
38 | count++;
39 |
40 | if (count % 10000000 == 0)
41 | {
42 | Console.WriteLine($" > Checked: {count}.");
43 | }
44 |
45 | indices[length - 1]++;
46 | if (indices[length - 1] >= charsCount)
47 | {
48 | for (int i = length - 1; i >= 0; i--)
49 | {
50 | indices[i] = 0;
51 | indices[i - 1]++;
52 | if (indices[i - 1] < charsCount) { break; }
53 | if (i - 1 == 0 && indices[0] >= charsCount)
54 | {
55 | isCompleted = true;
56 | break;
57 | }
58 | }
59 | }
60 | }
61 |
62 | sw.Stop();
63 | int seconds = (int)sw.ElapsedMilliseconds / 1000;
64 | Console.ForegroundColor = ConsoleColor.White;
65 | Console.WriteLine($"{length} chars: {seconds}s");
66 | Console.ResetColor();
67 | }
68 |
--------------------------------------------------------------------------------
/09-RatInMaze/09-RatInMaze.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | net8.0
6 | _09_RatInMaze
7 | enable
8 | enable
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/09-RatInMaze/Program.cs:
--------------------------------------------------------------------------------
1 | // RAT IN A MAZE
2 | // Chapter 9 (See in Action)
3 | // C# Data Structures and Algorithms, Second Edition
4 |
5 | int size = 8;
6 | bool t = true;
7 | bool f = false;
8 | bool[,] maze =
9 | {
10 | { t, f, t, f, f, t, t, t },
11 | { t, t, t, t, t, f, t, f },
12 | { t, t, f, t, t, f, t, t },
13 | { f, t, t, f, t, f, f, t },
14 | { f, t, t, t, t, t, t, t },
15 | { t, f, t, f, t, f, f, t },
16 | { t, t, t, t, t, t, t, t },
17 | { f, t, f, f, f, t, f, t }
18 | };
19 | bool[,] solution = new bool[size, size];
20 | if (Go(0, 0)) { Print(); }
21 |
22 | bool Go(int row, int col)
23 | {
24 | if (row == size - 1 && col == size - 1 && maze[row, col])
25 | {
26 | solution[row, col] = true;
27 | return true;
28 | }
29 | if (row >= 0 && row < size
30 | && col >= 0 && col < size
31 | && maze[row, col])
32 | {
33 | if (solution[row, col]) { return false; }
34 | solution[row, col] = true;
35 | if (Go(row + 1, col)) { return true; }
36 | if (Go(row, col + 1)) { return true; }
37 | if (Go(row - 1, col)) { return true; }
38 | if (Go(row, col - 1)) { return true; }
39 | solution[row, col] = false;
40 | return false;
41 | }
42 |
43 | return false;
44 | }
45 |
46 | void Print()
47 | {
48 | for (int row = 0; row < size; row++)
49 | {
50 | for (int col = 0; col < size; col++)
51 | {
52 | Console.Write(solution[row, col] ? "x" : "-");
53 | }
54 | Console.WriteLine();
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/09-SudokuPuzzle/09-SudokuPuzzle.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | net8.0
6 | _09_SudokuPuzzle
7 | enable
8 | enable
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/09-SudokuPuzzle/Program.cs:
--------------------------------------------------------------------------------
1 | // SUDOKU PUZZLE
2 | // Chapter 9 (See in Action)
3 | // C# Data Structures and Algorithms, Second Edition
4 |
5 | int[,] board = new int[,]
6 | {
7 | { 0, 5, 0, 4, 0, 1, 0, 0, 6 },
8 | { 1, 0, 0, 9, 5, 0, 8, 0, 0 },
9 | { 9, 0, 4, 0, 6, 0, 0, 0, 1 },
10 | { 6, 2, 0, 0, 0, 5, 3, 0, 4 },
11 | { 0, 9, 0, 0, 7, 0, 2, 0, 5 },
12 | { 5, 0, 7, 0, 0, 0, 0, 8, 9 },
13 | { 8, 0, 0, 5, 1, 9, 0, 0, 2 },
14 | { 2, 3, 0, 0, 0, 6, 5, 0, 8 },
15 | { 4, 1, 0, 2, 0, 8, 6, 0, 0 }
16 | };
17 | if (Solve()) { Print(); }
18 |
19 | bool Solve()
20 | {
21 | (int row, int col) = GetEmpty();
22 | if (row < 0 && col < 0) { return true; }
23 |
24 | for (int i = 1; i <= 9; i++)
25 | {
26 | if (IsCorrect(row, col, i))
27 | {
28 | board[row, col] = i;
29 | if (Solve()) { return true; }
30 | else { board[row, col] = 0; }
31 | }
32 | }
33 |
34 | return false;
35 | }
36 |
37 | (int, int) GetEmpty()
38 | {
39 | for (int r = 0; r < 9; r++)
40 | {
41 | for (int c = 0; c < 9; c++)
42 | {
43 | if (board[r, c] == 0) { return (r, c); }
44 | }
45 | }
46 | return (-1, -1);
47 | }
48 |
49 | bool IsCorrect(int row, int col, int num)
50 | {
51 | for (int i = 0; i < 9; i++)
52 | {
53 | if (board[row, i] == num) { return false; }
54 | if (board[i, col] == num) { return false; }
55 | }
56 |
57 | int rs = row - row % 3;
58 | int cs = col - col % 3;
59 | for (int r = rs; r < rs + 3; r++)
60 | {
61 | for (int c = cs; c < cs + 3; c++)
62 | {
63 | if (board[r, c] == num) { return false; }
64 | }
65 | }
66 |
67 | return true;
68 | }
69 |
70 | void Print()
71 | {
72 | for (int row = 0; row < 9; row++)
73 | {
74 | for (int col = 0; col < 9; col++)
75 | {
76 | Console.Write($"{board[row, col]} ");
77 | }
78 |
79 | Console.WriteLine();
80 | }
81 | }
82 |
--------------------------------------------------------------------------------
/09-TitleGuess/09-TitleGuess.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | net8.0
6 | _09_GeneticAlgorithm
7 | enable
8 | enable
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/09-TitleGuess/Individual.cs:
--------------------------------------------------------------------------------
1 | // TITLE GUESS
2 | // Chapter 9 (See in Action)
3 | // C# Data Structures and Algorithms, Second Edition
4 |
5 | record Individual(string Chromosome, int Fitness);
6 |
--------------------------------------------------------------------------------
/09-TitleGuess/Program.cs:
--------------------------------------------------------------------------------
1 | // TITLE GUESS
2 | // Chapter 9 (See in Action)
3 | // C# Data Structures and Algorithms, Second Edition
4 |
5 | const string Genes = "abcdefghijklmnopqrstuvwxyz#ABCDEFGHIJKLMNOPQRSTUVWXYZ ";
6 | const string Target = "C# Data Structures and Algorithms";
7 |
8 | Random random = new();
9 | int generationNo = 0;
10 | List population = [];
11 |
12 | for (int i = 0; i < 1000; i++)
13 | {
14 | string chromosome = GetRandomChromosome();
15 | population.Add(new(chromosome, GetFitness(chromosome)));
16 | }
17 |
18 | List generation = [];
19 | while (true)
20 | {
21 | population.Sort((a, b) => b.Fitness.CompareTo(a.Fitness));
22 | if (population[0].Fitness == Target.Length)
23 | {
24 | Print();
25 | break;
26 | }
27 |
28 | generation.Clear();
29 |
30 | for (int i = 0; i < 200; i++)
31 | {
32 | generation.Add(population[i]);
33 | }
34 |
35 | for (int i = 0; i < 800; i++)
36 | {
37 | Individual p1 = population[random.Next(400)];
38 | Individual p2 = population[random.Next(400)];
39 | Individual offspring = Mate(p1, p2);
40 | generation.Add(offspring);
41 | }
42 |
43 | population.Clear();
44 | population.AddRange(generation);
45 | Print();
46 | generationNo++;
47 | }
48 |
49 | Individual Mate(Individual p1, Individual p2)
50 | {
51 | string child = string.Empty;
52 | for (int i = 0; i < Target.Length; i++)
53 | {
54 | float r = random.Next(101) / 100.0f;
55 | if (r < 0.45f) { child += p1.Chromosome[i]; }
56 | else if (r < 0.9f) { child += p2.Chromosome[i]; }
57 | else { child += GetRandomGene(); }
58 | }
59 |
60 | return new Individual(child, GetFitness(child));
61 | }
62 |
63 | char GetRandomGene() => Genes[random.Next(Genes.Length)];
64 |
65 | string GetRandomChromosome()
66 | {
67 | string chromosome = string.Empty;
68 | for (int i = 0; i < Target.Length; i++)
69 | {
70 | chromosome += GetRandomGene();
71 | }
72 |
73 | return chromosome;
74 | }
75 |
76 | int GetFitness(string chromosome)
77 | {
78 | int fitness = 0;
79 | for (int i = 0; i < Target.Length; i++)
80 | {
81 | if (chromosome[i] == Target[i]) { fitness++; }
82 | }
83 |
84 | return fitness;
85 | }
86 |
87 | void Print() => Console.WriteLine(
88 | $"Generation {generationNo:D2}: {population[0].Chromosome} / {population[0].Fitness}");
89 |
--------------------------------------------------------------------------------
/Examples.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio Version 17
4 | VisualStudioVersion = 17.8.34309.116
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{18B9A9DC-0797-441E-844E-C966B1019EFD}"
7 | ProjectSection(SolutionItems) = preProject
8 | readme.md = readme.md
9 | EndProjectSection
10 | EndProject
11 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "03-MonthNames", "03-MonthNames\03-MonthNames.csproj", "{F331E6EF-5A31-40EB-A6AE-4F0BAC87E2F3}"
12 | EndProject
13 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "03-GameMap", "03-GameMap\03-GameMap.csproj", "{0EFD26E6-D35B-4621-BA4D-34404703997D}"
14 | EndProject
15 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "03-YearlyTransportPlan", "03-YearlyTransportPlan\03-YearlyTransportPlan.csproj", "{7E561CA8-A2E7-427F-9BF9-C1E2A701B607}"
16 | EndProject
17 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "03-SortingAlgorithms", "03-SortingAlgorithms\03-SortingAlgorithms.csproj", "{481D4B32-0DDE-49D1-AF26-1358FD60CE56}"
18 | EndProject
19 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "03-MultiplicationTable", "03-MultiplicationTable\03-MultiplicationTable.csproj", "{55708A76-4F8F-4BAF-A648-CA6CA1ECE606}"
20 | EndProject
21 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "04-AverageValue", "04-AverageValue\04-AverageValue.csproj", "{941F12AF-2651-4C21-9E5F-C1A09193C9C3}"
22 | EndProject
23 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "04-ListOfPeople", "04-ListOfPeople\04-ListOfPeople.csproj", "{16506F0A-1C51-4DFF-B45F-47A25EDA1AF3}"
24 | EndProject
25 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "04-AddressBook", "04-AddressBook\04-AddressBook.csproj", "{2FBD3412-C2EA-4A8D-904A-CA6F96ADD2EB}"
26 | EndProject
27 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "04-BookReader", "04-BookReader\04-BookReader.csproj", "{75629CA5-27C2-4473-9209-52E761FAE85C}"
28 | EndProject
29 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "04-SpinTheWheel", "04-SpinTheWheel\04-SpinTheWheel.csproj", "{6862634A-D036-42A9-A49A-9A2F4F1D49AA}"
30 | EndProject
31 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "04-ArtGallery", "04-ArtGallery\04-ArtGallery.csproj", "{4C8B36AE-711E-4A51-97E2-FA0BACF0DAFA}"
32 | EndProject
33 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "05-ReversingWord", "05-ReversingWord\05-ReversingWord.csproj", "{B52BB3E9-3F1E-4AC6-BF4A-A63B0D182625}"
34 | EndProject
35 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "05-TowerOfHanoi", "05-TowerOfHanoi\05-TowerOfHanoi.csproj", "{D4F3A0E7-29EF-48A2-A5B1-A125AB4C0FC1}"
36 | EndProject
37 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "05-CallCenterSingleConsultant", "05-CallCenterSingleConsultant\05-CallCenterSingleConsultant.csproj", "{5EDDECCB-30B2-4265-A240-BAF8830E340E}"
38 | EndProject
39 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "05-CallCenterManyConsultants", "05-CallCenterManyConsultants\05-CallCenterManyConsultants.csproj", "{A08E9A53-43B3-4040-BE2F-DC617C8547ED}"
40 | EndProject
41 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "05-CallCenterPrioritySupport", "05-CallCenterPrioritySupport\05-CallCenterPrioritySupport.csproj", "{B3076BD8-8E43-4593-879F-48E1571CF8EE}"
42 | EndProject
43 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "05-GravityRollerCoaster", "05-GravityRollerCoaster\05-GravityRollerCoaster.csproj", "{81365CDB-C249-4128-8B1A-56FAD47C3605}"
44 | EndProject
45 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "06-PhoneBook", "06-PhoneBook\06-PhoneBook.csproj", "{0366801E-9010-4CFB-AE93-7A53C498945E}"
46 | EndProject
47 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "06-UserDetails", "06-UserDetails\06-UserDetails.csproj", "{42386C08-26DA-46D7-8EFC-D2362B7F42BE}"
48 | EndProject
49 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "06-Encyclopedia", "06-Encyclopedia\06-Encyclopedia.csproj", "{83090CEF-232F-4DC7-B0A1-BFC9F3D95C97}"
50 | EndProject
51 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "06-ProductLocation", "06-ProductLocation\06-ProductLocation.csproj", "{A708EB72-597E-4265-A8FF-6D0A7A14891E}"
52 | EndProject
53 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "06-Coupons", "06-Coupons\06-Coupons.csproj", "{15581515-A9D6-4B54-BEB1-1A3845D35DA6}"
54 | EndProject
55 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "06-SwimmingPools", "06-SwimmingPools\06-SwimmingPools.csproj", "{30C78C1B-77CC-4073-A36F-FC482EE14570}"
56 | EndProject
57 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "06-RemovingDuplicates", "06-RemovingDuplicates\06-RemovingDuplicates.csproj", "{7C6C6768-BE1E-4186-9E0E-8A7832AB42F8}"
58 | EndProject
59 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "07-Tree", "07-Tree\07-Tree.csproj", "{378623C4-AC42-4685-91DD-A38D96109EF3}"
60 | EndProject
61 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "07-HierarchyOfIdentifiers", "07-HierarchyOfIdentifiers\07-HierarchyOfIdentifiers.csproj", "{73C2D7E1-3AA8-47F9-AC62-7EF52E310BD9}"
62 | EndProject
63 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "07-CompanyStructure", "07-CompanyStructure\07-CompanyStructure.csproj", "{DBAC6594-41A4-4BA1-8053-F76633CAF325}"
64 | EndProject
65 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "07-SimpleQuiz", "07-SimpleQuiz\07-SimpleQuiz.csproj", "{75939BA3-7A51-4AD0-9B20-B66610694025}"
66 | EndProject
67 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "07-BSTVisualization", "07-BSTVisualization\07-BSTVisualization.csproj", "{432E7FD3-2DDD-4F6B-9856-F0A157DA9A23}"
68 | EndProject
69 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "07-AutoComplete", "07-AutoComplete\07-AutoComplete.csproj", "{203C82FB-9678-4129-B4E8-8737E19EE4CD}"
70 | EndProject
71 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "08-Graph", "08-Graph\08-Graph.csproj", "{924C584B-4E73-4823-8561-0771CC7201B4}"
72 | EndProject
73 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "08-UndirectedUnweightedEdges", "08-UndirectedUnweightedEdges\08-UndirectedUnweightedEdges.csproj", "{6AABBC33-588C-4DB9-A386-271897D5F68F}"
74 | EndProject
75 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "08-DirectedWeightedEdges", "08-DirectedWeightedEdges\08-DirectedWeightedEdges.csproj", "{A13BF861-66D4-4EF0-AEBF-7C69FD472A9F}"
76 | EndProject
77 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "08-TelecommunicationCable", "08-TelecommunicationCable\08-TelecommunicationCable.csproj", "{881CEC41-C162-4085-ADCE-5174034FA3BF}"
78 | EndProject
79 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "08-VoivodeshipMap", "08-VoivodeshipMap\08-VoivodeshipMap.csproj", "{E7A9D647-8F56-4239-B9B8-D80FDD8377F2}"
80 | EndProject
81 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "08-PathInGame", "08-PathInGame\08-PathInGame.csproj", "{B7B77C6F-A673-4527-924D-D78C9199EF16}"
82 | EndProject
83 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "09-FibonacciSeries", "09-FibonacciSeries\09-FibonacciSeries.csproj", "{C33D3219-49A2-4736-BB8B-3171CD7A8D29}"
84 | EndProject
85 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "09-MinimumCoinChange", "09-MinimumCoinChange\09-MinimumCoinChange.csproj", "{92D21270-1D3B-441A-A365-347220794A48}"
86 | EndProject
87 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "09-ClosestPairOfPoints", "09-ClosestPairOfPoints\09-ClosestPairOfPoints.csproj", "{2D8AFB34-406E-49CD-8FA9-56692D8FD735}"
88 | EndProject
89 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "09-FractalGeneration", "09-FractalGeneration\09-FractalGeneration.csproj", "{AF44B17E-4F5B-4B32-B454-16281E796BDA}"
90 | EndProject
91 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "09-RatInMaze", "09-RatInMaze\09-RatInMaze.csproj", "{886CDDE5-85E0-453C-B857-D0F8DB0F07B9}"
92 | EndProject
93 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "09-SudokuPuzzle", "09-SudokuPuzzle\09-SudokuPuzzle.csproj", "{4B610F83-2840-42DB-86CE-B4379A787AA7}"
94 | EndProject
95 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "09-TitleGuess", "09-TitleGuess\09-TitleGuess.csproj", "{8B295230-D4DE-4AD4-94FC-50691CE717DD}"
96 | EndProject
97 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "09-PasswordGuess", "09-PasswordGuess\09-PasswordGuess.csproj", "{F66F6AE0-5970-444A-BF13-3CEC22AD1A3F}"
98 | EndProject
99 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Chapter-03", "Chapter-03", "{E92C382E-BCAD-4B14-9D7D-5BF64353B6E6}"
100 | EndProject
101 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Chapter-04", "Chapter-04", "{F195B755-FA4D-4A73-B4BF-9C42A400744D}"
102 | EndProject
103 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Chapter-05", "Chapter-05", "{05CFB6CE-3F6D-458D-AB4B-7505CFB7E151}"
104 | EndProject
105 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Chapter-06", "Chapter-06", "{3C036A7C-E6DC-413A-9867-772D601E5F43}"
106 | EndProject
107 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Chapter-07", "Chapter-07", "{653528DA-B8A3-43FB-A805-BC9B9BD0FCB4}"
108 | EndProject
109 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Chapter-08", "Chapter-08", "{05E321BC-F2DE-4B26-9A26-30D75A2F5546}"
110 | EndProject
111 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Chapter-09", "Chapter-09", "{1A270F0C-44AA-4A2A-96F8-6FF3F593D055}"
112 | EndProject
113 | Global
114 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
115 | Debug|Any CPU = Debug|Any CPU
116 | Release|Any CPU = Release|Any CPU
117 | EndGlobalSection
118 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
119 | {F331E6EF-5A31-40EB-A6AE-4F0BAC87E2F3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
120 | {F331E6EF-5A31-40EB-A6AE-4F0BAC87E2F3}.Debug|Any CPU.Build.0 = Debug|Any CPU
121 | {F331E6EF-5A31-40EB-A6AE-4F0BAC87E2F3}.Release|Any CPU.ActiveCfg = Release|Any CPU
122 | {F331E6EF-5A31-40EB-A6AE-4F0BAC87E2F3}.Release|Any CPU.Build.0 = Release|Any CPU
123 | {0EFD26E6-D35B-4621-BA4D-34404703997D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
124 | {0EFD26E6-D35B-4621-BA4D-34404703997D}.Debug|Any CPU.Build.0 = Debug|Any CPU
125 | {0EFD26E6-D35B-4621-BA4D-34404703997D}.Release|Any CPU.ActiveCfg = Release|Any CPU
126 | {0EFD26E6-D35B-4621-BA4D-34404703997D}.Release|Any CPU.Build.0 = Release|Any CPU
127 | {7E561CA8-A2E7-427F-9BF9-C1E2A701B607}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
128 | {7E561CA8-A2E7-427F-9BF9-C1E2A701B607}.Debug|Any CPU.Build.0 = Debug|Any CPU
129 | {7E561CA8-A2E7-427F-9BF9-C1E2A701B607}.Release|Any CPU.ActiveCfg = Release|Any CPU
130 | {7E561CA8-A2E7-427F-9BF9-C1E2A701B607}.Release|Any CPU.Build.0 = Release|Any CPU
131 | {481D4B32-0DDE-49D1-AF26-1358FD60CE56}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
132 | {481D4B32-0DDE-49D1-AF26-1358FD60CE56}.Debug|Any CPU.Build.0 = Debug|Any CPU
133 | {481D4B32-0DDE-49D1-AF26-1358FD60CE56}.Release|Any CPU.ActiveCfg = Release|Any CPU
134 | {481D4B32-0DDE-49D1-AF26-1358FD60CE56}.Release|Any CPU.Build.0 = Release|Any CPU
135 | {55708A76-4F8F-4BAF-A648-CA6CA1ECE606}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
136 | {55708A76-4F8F-4BAF-A648-CA6CA1ECE606}.Debug|Any CPU.Build.0 = Debug|Any CPU
137 | {55708A76-4F8F-4BAF-A648-CA6CA1ECE606}.Release|Any CPU.ActiveCfg = Release|Any CPU
138 | {55708A76-4F8F-4BAF-A648-CA6CA1ECE606}.Release|Any CPU.Build.0 = Release|Any CPU
139 | {941F12AF-2651-4C21-9E5F-C1A09193C9C3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
140 | {941F12AF-2651-4C21-9E5F-C1A09193C9C3}.Debug|Any CPU.Build.0 = Debug|Any CPU
141 | {941F12AF-2651-4C21-9E5F-C1A09193C9C3}.Release|Any CPU.ActiveCfg = Release|Any CPU
142 | {941F12AF-2651-4C21-9E5F-C1A09193C9C3}.Release|Any CPU.Build.0 = Release|Any CPU
143 | {16506F0A-1C51-4DFF-B45F-47A25EDA1AF3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
144 | {16506F0A-1C51-4DFF-B45F-47A25EDA1AF3}.Debug|Any CPU.Build.0 = Debug|Any CPU
145 | {16506F0A-1C51-4DFF-B45F-47A25EDA1AF3}.Release|Any CPU.ActiveCfg = Release|Any CPU
146 | {16506F0A-1C51-4DFF-B45F-47A25EDA1AF3}.Release|Any CPU.Build.0 = Release|Any CPU
147 | {2FBD3412-C2EA-4A8D-904A-CA6F96ADD2EB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
148 | {2FBD3412-C2EA-4A8D-904A-CA6F96ADD2EB}.Debug|Any CPU.Build.0 = Debug|Any CPU
149 | {2FBD3412-C2EA-4A8D-904A-CA6F96ADD2EB}.Release|Any CPU.ActiveCfg = Release|Any CPU
150 | {2FBD3412-C2EA-4A8D-904A-CA6F96ADD2EB}.Release|Any CPU.Build.0 = Release|Any CPU
151 | {75629CA5-27C2-4473-9209-52E761FAE85C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
152 | {75629CA5-27C2-4473-9209-52E761FAE85C}.Debug|Any CPU.Build.0 = Debug|Any CPU
153 | {75629CA5-27C2-4473-9209-52E761FAE85C}.Release|Any CPU.ActiveCfg = Release|Any CPU
154 | {75629CA5-27C2-4473-9209-52E761FAE85C}.Release|Any CPU.Build.0 = Release|Any CPU
155 | {6862634A-D036-42A9-A49A-9A2F4F1D49AA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
156 | {6862634A-D036-42A9-A49A-9A2F4F1D49AA}.Debug|Any CPU.Build.0 = Debug|Any CPU
157 | {6862634A-D036-42A9-A49A-9A2F4F1D49AA}.Release|Any CPU.ActiveCfg = Release|Any CPU
158 | {6862634A-D036-42A9-A49A-9A2F4F1D49AA}.Release|Any CPU.Build.0 = Release|Any CPU
159 | {4C8B36AE-711E-4A51-97E2-FA0BACF0DAFA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
160 | {4C8B36AE-711E-4A51-97E2-FA0BACF0DAFA}.Debug|Any CPU.Build.0 = Debug|Any CPU
161 | {4C8B36AE-711E-4A51-97E2-FA0BACF0DAFA}.Release|Any CPU.ActiveCfg = Release|Any CPU
162 | {4C8B36AE-711E-4A51-97E2-FA0BACF0DAFA}.Release|Any CPU.Build.0 = Release|Any CPU
163 | {B52BB3E9-3F1E-4AC6-BF4A-A63B0D182625}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
164 | {B52BB3E9-3F1E-4AC6-BF4A-A63B0D182625}.Debug|Any CPU.Build.0 = Debug|Any CPU
165 | {B52BB3E9-3F1E-4AC6-BF4A-A63B0D182625}.Release|Any CPU.ActiveCfg = Release|Any CPU
166 | {B52BB3E9-3F1E-4AC6-BF4A-A63B0D182625}.Release|Any CPU.Build.0 = Release|Any CPU
167 | {D4F3A0E7-29EF-48A2-A5B1-A125AB4C0FC1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
168 | {D4F3A0E7-29EF-48A2-A5B1-A125AB4C0FC1}.Debug|Any CPU.Build.0 = Debug|Any CPU
169 | {D4F3A0E7-29EF-48A2-A5B1-A125AB4C0FC1}.Release|Any CPU.ActiveCfg = Release|Any CPU
170 | {D4F3A0E7-29EF-48A2-A5B1-A125AB4C0FC1}.Release|Any CPU.Build.0 = Release|Any CPU
171 | {5EDDECCB-30B2-4265-A240-BAF8830E340E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
172 | {5EDDECCB-30B2-4265-A240-BAF8830E340E}.Debug|Any CPU.Build.0 = Debug|Any CPU
173 | {5EDDECCB-30B2-4265-A240-BAF8830E340E}.Release|Any CPU.ActiveCfg = Release|Any CPU
174 | {5EDDECCB-30B2-4265-A240-BAF8830E340E}.Release|Any CPU.Build.0 = Release|Any CPU
175 | {A08E9A53-43B3-4040-BE2F-DC617C8547ED}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
176 | {A08E9A53-43B3-4040-BE2F-DC617C8547ED}.Debug|Any CPU.Build.0 = Debug|Any CPU
177 | {A08E9A53-43B3-4040-BE2F-DC617C8547ED}.Release|Any CPU.ActiveCfg = Release|Any CPU
178 | {A08E9A53-43B3-4040-BE2F-DC617C8547ED}.Release|Any CPU.Build.0 = Release|Any CPU
179 | {B3076BD8-8E43-4593-879F-48E1571CF8EE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
180 | {B3076BD8-8E43-4593-879F-48E1571CF8EE}.Debug|Any CPU.Build.0 = Debug|Any CPU
181 | {B3076BD8-8E43-4593-879F-48E1571CF8EE}.Release|Any CPU.ActiveCfg = Release|Any CPU
182 | {B3076BD8-8E43-4593-879F-48E1571CF8EE}.Release|Any CPU.Build.0 = Release|Any CPU
183 | {81365CDB-C249-4128-8B1A-56FAD47C3605}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
184 | {81365CDB-C249-4128-8B1A-56FAD47C3605}.Debug|Any CPU.Build.0 = Debug|Any CPU
185 | {81365CDB-C249-4128-8B1A-56FAD47C3605}.Release|Any CPU.ActiveCfg = Release|Any CPU
186 | {81365CDB-C249-4128-8B1A-56FAD47C3605}.Release|Any CPU.Build.0 = Release|Any CPU
187 | {0366801E-9010-4CFB-AE93-7A53C498945E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
188 | {0366801E-9010-4CFB-AE93-7A53C498945E}.Debug|Any CPU.Build.0 = Debug|Any CPU
189 | {0366801E-9010-4CFB-AE93-7A53C498945E}.Release|Any CPU.ActiveCfg = Release|Any CPU
190 | {0366801E-9010-4CFB-AE93-7A53C498945E}.Release|Any CPU.Build.0 = Release|Any CPU
191 | {42386C08-26DA-46D7-8EFC-D2362B7F42BE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
192 | {42386C08-26DA-46D7-8EFC-D2362B7F42BE}.Debug|Any CPU.Build.0 = Debug|Any CPU
193 | {42386C08-26DA-46D7-8EFC-D2362B7F42BE}.Release|Any CPU.ActiveCfg = Release|Any CPU
194 | {42386C08-26DA-46D7-8EFC-D2362B7F42BE}.Release|Any CPU.Build.0 = Release|Any CPU
195 | {83090CEF-232F-4DC7-B0A1-BFC9F3D95C97}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
196 | {83090CEF-232F-4DC7-B0A1-BFC9F3D95C97}.Debug|Any CPU.Build.0 = Debug|Any CPU
197 | {83090CEF-232F-4DC7-B0A1-BFC9F3D95C97}.Release|Any CPU.ActiveCfg = Release|Any CPU
198 | {83090CEF-232F-4DC7-B0A1-BFC9F3D95C97}.Release|Any CPU.Build.0 = Release|Any CPU
199 | {A708EB72-597E-4265-A8FF-6D0A7A14891E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
200 | {A708EB72-597E-4265-A8FF-6D0A7A14891E}.Debug|Any CPU.Build.0 = Debug|Any CPU
201 | {A708EB72-597E-4265-A8FF-6D0A7A14891E}.Release|Any CPU.ActiveCfg = Release|Any CPU
202 | {A708EB72-597E-4265-A8FF-6D0A7A14891E}.Release|Any CPU.Build.0 = Release|Any CPU
203 | {15581515-A9D6-4B54-BEB1-1A3845D35DA6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
204 | {15581515-A9D6-4B54-BEB1-1A3845D35DA6}.Debug|Any CPU.Build.0 = Debug|Any CPU
205 | {15581515-A9D6-4B54-BEB1-1A3845D35DA6}.Release|Any CPU.ActiveCfg = Release|Any CPU
206 | {15581515-A9D6-4B54-BEB1-1A3845D35DA6}.Release|Any CPU.Build.0 = Release|Any CPU
207 | {30C78C1B-77CC-4073-A36F-FC482EE14570}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
208 | {30C78C1B-77CC-4073-A36F-FC482EE14570}.Debug|Any CPU.Build.0 = Debug|Any CPU
209 | {30C78C1B-77CC-4073-A36F-FC482EE14570}.Release|Any CPU.ActiveCfg = Release|Any CPU
210 | {30C78C1B-77CC-4073-A36F-FC482EE14570}.Release|Any CPU.Build.0 = Release|Any CPU
211 | {7C6C6768-BE1E-4186-9E0E-8A7832AB42F8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
212 | {7C6C6768-BE1E-4186-9E0E-8A7832AB42F8}.Debug|Any CPU.Build.0 = Debug|Any CPU
213 | {7C6C6768-BE1E-4186-9E0E-8A7832AB42F8}.Release|Any CPU.ActiveCfg = Release|Any CPU
214 | {7C6C6768-BE1E-4186-9E0E-8A7832AB42F8}.Release|Any CPU.Build.0 = Release|Any CPU
215 | {378623C4-AC42-4685-91DD-A38D96109EF3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
216 | {378623C4-AC42-4685-91DD-A38D96109EF3}.Debug|Any CPU.Build.0 = Debug|Any CPU
217 | {378623C4-AC42-4685-91DD-A38D96109EF3}.Release|Any CPU.ActiveCfg = Release|Any CPU
218 | {378623C4-AC42-4685-91DD-A38D96109EF3}.Release|Any CPU.Build.0 = Release|Any CPU
219 | {73C2D7E1-3AA8-47F9-AC62-7EF52E310BD9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
220 | {73C2D7E1-3AA8-47F9-AC62-7EF52E310BD9}.Debug|Any CPU.Build.0 = Debug|Any CPU
221 | {73C2D7E1-3AA8-47F9-AC62-7EF52E310BD9}.Release|Any CPU.ActiveCfg = Release|Any CPU
222 | {73C2D7E1-3AA8-47F9-AC62-7EF52E310BD9}.Release|Any CPU.Build.0 = Release|Any CPU
223 | {DBAC6594-41A4-4BA1-8053-F76633CAF325}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
224 | {DBAC6594-41A4-4BA1-8053-F76633CAF325}.Debug|Any CPU.Build.0 = Debug|Any CPU
225 | {DBAC6594-41A4-4BA1-8053-F76633CAF325}.Release|Any CPU.ActiveCfg = Release|Any CPU
226 | {DBAC6594-41A4-4BA1-8053-F76633CAF325}.Release|Any CPU.Build.0 = Release|Any CPU
227 | {75939BA3-7A51-4AD0-9B20-B66610694025}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
228 | {75939BA3-7A51-4AD0-9B20-B66610694025}.Debug|Any CPU.Build.0 = Debug|Any CPU
229 | {75939BA3-7A51-4AD0-9B20-B66610694025}.Release|Any CPU.ActiveCfg = Release|Any CPU
230 | {75939BA3-7A51-4AD0-9B20-B66610694025}.Release|Any CPU.Build.0 = Release|Any CPU
231 | {432E7FD3-2DDD-4F6B-9856-F0A157DA9A23}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
232 | {432E7FD3-2DDD-4F6B-9856-F0A157DA9A23}.Debug|Any CPU.Build.0 = Debug|Any CPU
233 | {432E7FD3-2DDD-4F6B-9856-F0A157DA9A23}.Release|Any CPU.ActiveCfg = Release|Any CPU
234 | {432E7FD3-2DDD-4F6B-9856-F0A157DA9A23}.Release|Any CPU.Build.0 = Release|Any CPU
235 | {203C82FB-9678-4129-B4E8-8737E19EE4CD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
236 | {203C82FB-9678-4129-B4E8-8737E19EE4CD}.Debug|Any CPU.Build.0 = Debug|Any CPU
237 | {203C82FB-9678-4129-B4E8-8737E19EE4CD}.Release|Any CPU.ActiveCfg = Release|Any CPU
238 | {203C82FB-9678-4129-B4E8-8737E19EE4CD}.Release|Any CPU.Build.0 = Release|Any CPU
239 | {924C584B-4E73-4823-8561-0771CC7201B4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
240 | {924C584B-4E73-4823-8561-0771CC7201B4}.Debug|Any CPU.Build.0 = Debug|Any CPU
241 | {924C584B-4E73-4823-8561-0771CC7201B4}.Release|Any CPU.ActiveCfg = Release|Any CPU
242 | {924C584B-4E73-4823-8561-0771CC7201B4}.Release|Any CPU.Build.0 = Release|Any CPU
243 | {6AABBC33-588C-4DB9-A386-271897D5F68F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
244 | {6AABBC33-588C-4DB9-A386-271897D5F68F}.Debug|Any CPU.Build.0 = Debug|Any CPU
245 | {6AABBC33-588C-4DB9-A386-271897D5F68F}.Release|Any CPU.ActiveCfg = Release|Any CPU
246 | {6AABBC33-588C-4DB9-A386-271897D5F68F}.Release|Any CPU.Build.0 = Release|Any CPU
247 | {A13BF861-66D4-4EF0-AEBF-7C69FD472A9F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
248 | {A13BF861-66D4-4EF0-AEBF-7C69FD472A9F}.Debug|Any CPU.Build.0 = Debug|Any CPU
249 | {A13BF861-66D4-4EF0-AEBF-7C69FD472A9F}.Release|Any CPU.ActiveCfg = Release|Any CPU
250 | {A13BF861-66D4-4EF0-AEBF-7C69FD472A9F}.Release|Any CPU.Build.0 = Release|Any CPU
251 | {881CEC41-C162-4085-ADCE-5174034FA3BF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
252 | {881CEC41-C162-4085-ADCE-5174034FA3BF}.Debug|Any CPU.Build.0 = Debug|Any CPU
253 | {881CEC41-C162-4085-ADCE-5174034FA3BF}.Release|Any CPU.ActiveCfg = Release|Any CPU
254 | {881CEC41-C162-4085-ADCE-5174034FA3BF}.Release|Any CPU.Build.0 = Release|Any CPU
255 | {E7A9D647-8F56-4239-B9B8-D80FDD8377F2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
256 | {E7A9D647-8F56-4239-B9B8-D80FDD8377F2}.Debug|Any CPU.Build.0 = Debug|Any CPU
257 | {E7A9D647-8F56-4239-B9B8-D80FDD8377F2}.Release|Any CPU.ActiveCfg = Release|Any CPU
258 | {E7A9D647-8F56-4239-B9B8-D80FDD8377F2}.Release|Any CPU.Build.0 = Release|Any CPU
259 | {B7B77C6F-A673-4527-924D-D78C9199EF16}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
260 | {B7B77C6F-A673-4527-924D-D78C9199EF16}.Debug|Any CPU.Build.0 = Debug|Any CPU
261 | {B7B77C6F-A673-4527-924D-D78C9199EF16}.Release|Any CPU.ActiveCfg = Release|Any CPU
262 | {B7B77C6F-A673-4527-924D-D78C9199EF16}.Release|Any CPU.Build.0 = Release|Any CPU
263 | {C33D3219-49A2-4736-BB8B-3171CD7A8D29}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
264 | {C33D3219-49A2-4736-BB8B-3171CD7A8D29}.Debug|Any CPU.Build.0 = Debug|Any CPU
265 | {C33D3219-49A2-4736-BB8B-3171CD7A8D29}.Release|Any CPU.ActiveCfg = Release|Any CPU
266 | {C33D3219-49A2-4736-BB8B-3171CD7A8D29}.Release|Any CPU.Build.0 = Release|Any CPU
267 | {92D21270-1D3B-441A-A365-347220794A48}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
268 | {92D21270-1D3B-441A-A365-347220794A48}.Debug|Any CPU.Build.0 = Debug|Any CPU
269 | {92D21270-1D3B-441A-A365-347220794A48}.Release|Any CPU.ActiveCfg = Release|Any CPU
270 | {92D21270-1D3B-441A-A365-347220794A48}.Release|Any CPU.Build.0 = Release|Any CPU
271 | {2D8AFB34-406E-49CD-8FA9-56692D8FD735}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
272 | {2D8AFB34-406E-49CD-8FA9-56692D8FD735}.Debug|Any CPU.Build.0 = Debug|Any CPU
273 | {2D8AFB34-406E-49CD-8FA9-56692D8FD735}.Release|Any CPU.ActiveCfg = Release|Any CPU
274 | {2D8AFB34-406E-49CD-8FA9-56692D8FD735}.Release|Any CPU.Build.0 = Release|Any CPU
275 | {AF44B17E-4F5B-4B32-B454-16281E796BDA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
276 | {AF44B17E-4F5B-4B32-B454-16281E796BDA}.Debug|Any CPU.Build.0 = Debug|Any CPU
277 | {AF44B17E-4F5B-4B32-B454-16281E796BDA}.Release|Any CPU.ActiveCfg = Release|Any CPU
278 | {AF44B17E-4F5B-4B32-B454-16281E796BDA}.Release|Any CPU.Build.0 = Release|Any CPU
279 | {886CDDE5-85E0-453C-B857-D0F8DB0F07B9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
280 | {886CDDE5-85E0-453C-B857-D0F8DB0F07B9}.Debug|Any CPU.Build.0 = Debug|Any CPU
281 | {886CDDE5-85E0-453C-B857-D0F8DB0F07B9}.Release|Any CPU.ActiveCfg = Release|Any CPU
282 | {886CDDE5-85E0-453C-B857-D0F8DB0F07B9}.Release|Any CPU.Build.0 = Release|Any CPU
283 | {4B610F83-2840-42DB-86CE-B4379A787AA7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
284 | {4B610F83-2840-42DB-86CE-B4379A787AA7}.Debug|Any CPU.Build.0 = Debug|Any CPU
285 | {4B610F83-2840-42DB-86CE-B4379A787AA7}.Release|Any CPU.ActiveCfg = Release|Any CPU
286 | {4B610F83-2840-42DB-86CE-B4379A787AA7}.Release|Any CPU.Build.0 = Release|Any CPU
287 | {8B295230-D4DE-4AD4-94FC-50691CE717DD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
288 | {8B295230-D4DE-4AD4-94FC-50691CE717DD}.Debug|Any CPU.Build.0 = Debug|Any CPU
289 | {8B295230-D4DE-4AD4-94FC-50691CE717DD}.Release|Any CPU.ActiveCfg = Release|Any CPU
290 | {8B295230-D4DE-4AD4-94FC-50691CE717DD}.Release|Any CPU.Build.0 = Release|Any CPU
291 | {F66F6AE0-5970-444A-BF13-3CEC22AD1A3F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
292 | {F66F6AE0-5970-444A-BF13-3CEC22AD1A3F}.Debug|Any CPU.Build.0 = Debug|Any CPU
293 | {F66F6AE0-5970-444A-BF13-3CEC22AD1A3F}.Release|Any CPU.ActiveCfg = Release|Any CPU
294 | {F66F6AE0-5970-444A-BF13-3CEC22AD1A3F}.Release|Any CPU.Build.0 = Release|Any CPU
295 | EndGlobalSection
296 | GlobalSection(SolutionProperties) = preSolution
297 | HideSolutionNode = FALSE
298 | EndGlobalSection
299 | GlobalSection(NestedProjects) = preSolution
300 | {F331E6EF-5A31-40EB-A6AE-4F0BAC87E2F3} = {E92C382E-BCAD-4B14-9D7D-5BF64353B6E6}
301 | {0EFD26E6-D35B-4621-BA4D-34404703997D} = {E92C382E-BCAD-4B14-9D7D-5BF64353B6E6}
302 | {7E561CA8-A2E7-427F-9BF9-C1E2A701B607} = {E92C382E-BCAD-4B14-9D7D-5BF64353B6E6}
303 | {481D4B32-0DDE-49D1-AF26-1358FD60CE56} = {E92C382E-BCAD-4B14-9D7D-5BF64353B6E6}
304 | {55708A76-4F8F-4BAF-A648-CA6CA1ECE606} = {E92C382E-BCAD-4B14-9D7D-5BF64353B6E6}
305 | {941F12AF-2651-4C21-9E5F-C1A09193C9C3} = {F195B755-FA4D-4A73-B4BF-9C42A400744D}
306 | {16506F0A-1C51-4DFF-B45F-47A25EDA1AF3} = {F195B755-FA4D-4A73-B4BF-9C42A400744D}
307 | {2FBD3412-C2EA-4A8D-904A-CA6F96ADD2EB} = {F195B755-FA4D-4A73-B4BF-9C42A400744D}
308 | {75629CA5-27C2-4473-9209-52E761FAE85C} = {F195B755-FA4D-4A73-B4BF-9C42A400744D}
309 | {6862634A-D036-42A9-A49A-9A2F4F1D49AA} = {F195B755-FA4D-4A73-B4BF-9C42A400744D}
310 | {4C8B36AE-711E-4A51-97E2-FA0BACF0DAFA} = {F195B755-FA4D-4A73-B4BF-9C42A400744D}
311 | {B52BB3E9-3F1E-4AC6-BF4A-A63B0D182625} = {05CFB6CE-3F6D-458D-AB4B-7505CFB7E151}
312 | {D4F3A0E7-29EF-48A2-A5B1-A125AB4C0FC1} = {05CFB6CE-3F6D-458D-AB4B-7505CFB7E151}
313 | {5EDDECCB-30B2-4265-A240-BAF8830E340E} = {05CFB6CE-3F6D-458D-AB4B-7505CFB7E151}
314 | {A08E9A53-43B3-4040-BE2F-DC617C8547ED} = {05CFB6CE-3F6D-458D-AB4B-7505CFB7E151}
315 | {B3076BD8-8E43-4593-879F-48E1571CF8EE} = {05CFB6CE-3F6D-458D-AB4B-7505CFB7E151}
316 | {81365CDB-C249-4128-8B1A-56FAD47C3605} = {05CFB6CE-3F6D-458D-AB4B-7505CFB7E151}
317 | {0366801E-9010-4CFB-AE93-7A53C498945E} = {3C036A7C-E6DC-413A-9867-772D601E5F43}
318 | {42386C08-26DA-46D7-8EFC-D2362B7F42BE} = {3C036A7C-E6DC-413A-9867-772D601E5F43}
319 | {83090CEF-232F-4DC7-B0A1-BFC9F3D95C97} = {3C036A7C-E6DC-413A-9867-772D601E5F43}
320 | {A708EB72-597E-4265-A8FF-6D0A7A14891E} = {3C036A7C-E6DC-413A-9867-772D601E5F43}
321 | {15581515-A9D6-4B54-BEB1-1A3845D35DA6} = {3C036A7C-E6DC-413A-9867-772D601E5F43}
322 | {30C78C1B-77CC-4073-A36F-FC482EE14570} = {3C036A7C-E6DC-413A-9867-772D601E5F43}
323 | {7C6C6768-BE1E-4186-9E0E-8A7832AB42F8} = {3C036A7C-E6DC-413A-9867-772D601E5F43}
324 | {378623C4-AC42-4685-91DD-A38D96109EF3} = {653528DA-B8A3-43FB-A805-BC9B9BD0FCB4}
325 | {73C2D7E1-3AA8-47F9-AC62-7EF52E310BD9} = {653528DA-B8A3-43FB-A805-BC9B9BD0FCB4}
326 | {DBAC6594-41A4-4BA1-8053-F76633CAF325} = {653528DA-B8A3-43FB-A805-BC9B9BD0FCB4}
327 | {75939BA3-7A51-4AD0-9B20-B66610694025} = {653528DA-B8A3-43FB-A805-BC9B9BD0FCB4}
328 | {432E7FD3-2DDD-4F6B-9856-F0A157DA9A23} = {653528DA-B8A3-43FB-A805-BC9B9BD0FCB4}
329 | {203C82FB-9678-4129-B4E8-8737E19EE4CD} = {653528DA-B8A3-43FB-A805-BC9B9BD0FCB4}
330 | {924C584B-4E73-4823-8561-0771CC7201B4} = {05E321BC-F2DE-4B26-9A26-30D75A2F5546}
331 | {6AABBC33-588C-4DB9-A386-271897D5F68F} = {05E321BC-F2DE-4B26-9A26-30D75A2F5546}
332 | {A13BF861-66D4-4EF0-AEBF-7C69FD472A9F} = {05E321BC-F2DE-4B26-9A26-30D75A2F5546}
333 | {881CEC41-C162-4085-ADCE-5174034FA3BF} = {05E321BC-F2DE-4B26-9A26-30D75A2F5546}
334 | {E7A9D647-8F56-4239-B9B8-D80FDD8377F2} = {05E321BC-F2DE-4B26-9A26-30D75A2F5546}
335 | {B7B77C6F-A673-4527-924D-D78C9199EF16} = {05E321BC-F2DE-4B26-9A26-30D75A2F5546}
336 | {C33D3219-49A2-4736-BB8B-3171CD7A8D29} = {1A270F0C-44AA-4A2A-96F8-6FF3F593D055}
337 | {92D21270-1D3B-441A-A365-347220794A48} = {1A270F0C-44AA-4A2A-96F8-6FF3F593D055}
338 | {2D8AFB34-406E-49CD-8FA9-56692D8FD735} = {1A270F0C-44AA-4A2A-96F8-6FF3F593D055}
339 | {AF44B17E-4F5B-4B32-B454-16281E796BDA} = {1A270F0C-44AA-4A2A-96F8-6FF3F593D055}
340 | {886CDDE5-85E0-453C-B857-D0F8DB0F07B9} = {1A270F0C-44AA-4A2A-96F8-6FF3F593D055}
341 | {4B610F83-2840-42DB-86CE-B4379A787AA7} = {1A270F0C-44AA-4A2A-96F8-6FF3F593D055}
342 | {8B295230-D4DE-4AD4-94FC-50691CE717DD} = {1A270F0C-44AA-4A2A-96F8-6FF3F593D055}
343 | {F66F6AE0-5970-444A-BF13-3CEC22AD1A3F} = {1A270F0C-44AA-4A2A-96F8-6FF3F593D055}
344 | EndGlobalSection
345 | GlobalSection(ExtensibilityGlobals) = postSolution
346 | SolutionGuid = {DCE01536-C269-40E2-9F20-68FB9B7440E0}
347 | EndGlobalSection
348 | EndGlobal
349 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2023 Packt
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 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # C# Data Structures and Algorithms
2 |
3 |
4 |
5 | This is the code repository for [C# Data Structures and Algorithms](https://www.packtpub.com/product/c-data-structures-and-algorithms-second-edition/9781803248271), published by Packt.
6 |
7 | **Harness the power of C# to build a diverse range of efficient applications**
8 |
9 | ## What is this book about?
10 | Explore efficient data organization in C# with this guide to implementing and utilizing diverse data structures, along with common algorithms, offering reusable solutions for effective development.
11 |
12 | This book covers the following exciting features:
13 | * Understand the fundamentals of algorithms and their classification
14 | * Store data using arrays and lists, and explore various ways to sort arrays
15 | * Build enhanced applications with stacks, queues, hashtables, dictionaries, and sets
16 | * Create efficient applications with tree-related algorithms, such as for searching in a binary search tree
17 | * Boost solution efficiency with graphs, including finding the shortest path in the graph
18 | * Implement algorithms solving Tower of Hanoi and Sudoku games, generating fractals, and even guessing the title of this book
19 |
20 | If you feel this book is for you, get your [copy](https://www.amazon.com/Data-Structures-Algorithms-efficient-applications-ebook/dp/B0CTTCFL1K/ref=sr_1_5?crid=2ZJB95PW6Q12V&keywords=c%23+data+structures+and+algorithms&qid=1707129568&sprefix=c+data+structures+and+algorithms%2Caps%2C287&sr=8-5) today!
21 |
22 |
23 | ## Instructions and Navigations
24 | All of the code is organized into folders. For example, Chapter03.
25 |
26 | The code will look like the following:
27 | ```
28 | int[,] numbers = new int[,]
29 | {
30 | { 9, 5, -9 },
31 | { -11, 4, 0 },
32 | { 6, 115, 3 },
33 | { -12, -9, 71 },
34 | { 1, -6, -1 }
35 | };
36 |
37 | ```
38 |
39 | **Following is what you need for this book:**
40 | This book is for developers looking to learn data structures and algorithms in C#. While basic programming skills and C# knowledge is useful, beginners will find value in the provided code snippets, illustrations, and detailed explanations, enhancing their programming skills. Advanced developers can use this book as a valuable resource for reusable code snippets, instead of writing algorithms from scratch each time.
41 |
42 |
43 |
44 | ### Related products
45 | * Refactoring with C# [[Packt]](https://www.packtpub.com/product/refactoring-with-c/9781835089989) [[Amazon]](https://www.amazon.com/Refactoring-Safely-improve-applications-technical/dp/1835089984/ref=sr_1_1?crid=3I5V1DQTYQTSQ&keywords=refactoring+with+C%23&qid=1707129778&sprefix=refactoring+with+c%2Caps%2C301&sr=8-1)
46 |
47 | * Clean Code with C# [[Packt]](https://www.packtpub.com/product/clean-code-with-c-second-edition/9781837635191) [[Amazon]](https://www.amazon.com/Clean-Code-application-performance-practices/dp/1837635196/ref=sr_1_1?crid=1Y008MZ1O4DRC&keywords=clean+code+with+C%23&qid=1707129895&sprefix=clean+code+with+c%2Caps%2C291&sr=8-1)
48 |
49 | ## Get to Know the Author
50 | **Marcin Jamro**, PhD, DSc is an entrepreneur, expert and experienced developer with significant international experience. He held the role of CEO at a few IT companies, operated as CTO at projects in various countries, as well as worked at Microsoft Corporation in Redmond, USA. He is the author of a few books and numerous publications. The results of his research have been presented and discussed at many scientific conferences. He has MCPD, MCTS, MCP and CAE certificates. Marcin is a multiple laureate, finalist and mentor in various competitions. He has significant experience in project development, especially .NET-based, and shares his knowledge as an expert in domestic and international projects, as well as invests in modern solutions.
51 |
52 | ## Other books by the author
53 | * Windows Application Development Cookbook [[Packt]](https://www.packtpub.com/product/windows-application-development-cookbook/9781786467720) [[Amazon]](https://www.amazon.com/Windows-Application-Development-Cookbook-Marcin/dp/1786467720/ref=tmm_pap_swatch_0?_encoding=UTF8&qid=1707130470&sr=8-1)
54 |
55 |
--------------------------------------------------------------------------------