From 5cfeb01e981dc10531cc028d2a53d660814a5cea Mon Sep 17 00:00:00 2001 From: Xavier Date: Mon, 20 Mar 2017 22:23:42 -0700 Subject: [PATCH 01/33] Use abstract base Question class --- Ch 01. Arrays and Strings/Q1_01_Is_Unique.cs | 4 +- .../Q1_02_Check_Permutation.cs | 4 +- Ch 01. Arrays and Strings/Q1_03_URLify.cs | 4 +- .../Q1_04_Palindrome_Permutation.cs | 4 +- Ch 01. Arrays and Strings/Q1_05_One_Away_A.cs | 4 +- .../Q1_06_String_Compression.cs | 4 +- .../Q1_07_Rotate_Matrix.cs | 4 +- .../Q1_08_Zero_Matrix.cs | 4 +- .../Q1_09_String_Rotation.cs | 4 +- Ch 02. Linked Lists/Q2_01_Remove_Dups.cs | 4 +- .../Q2_02_Return_Kth_To_Last.cs | 4 +- .../Q2_03_Delete_Middle_Node.cs | 4 +- Ch 02. Linked Lists/Q2_04_Partition.cs | 4 +- Ch 02. Linked Lists/Q2_05_Sum_Lists.cs | 4 +- Ch 02. Linked Lists/Q2_06_Palindrome.cs | 4 +- Ch 02. Linked Lists/Q2_07_Intersection.cs | 4 +- Ch 02. Linked Lists/Q2_08_Loop_Detection.cs | 4 +- Ch 05. Bit Manipulation/Q5_01_Insertion.cs | 4 +- .../Q5_02_Binary_to_String.cs | 4 +- Ch 05. Bit Manipulation/Q5_04_Next_Number.cs | 606 +++++++++--------- Ch 05. Bit Manipulation/Q5_06_Conversion.cs | 4 +- .../Q5_07_Pairwise_Swap.cs | 34 +- Ch 05. Bit Manipulation/Q5_08_Draw_Line.cs | 160 ++--- .../Q10_01_Sorted_Merge.cs | 4 +- .../Q10_02_Group_Anagrams.cs | 4 +- .../Q10_03_Search_in_Rotated_Array.cs | 66 +- .../Q10_05_Sparse_Search.cs | 4 +- .../Q10_08_Find_Duplicates.cs | 4 +- .../Q10_09_Sorted_Matrix_Search.cs | 4 +- .../Q10_10_Rank_from_Stream.cs | 4 +- .../Q10_11_Peaks_and_Valleys.cs | 10 +- Introduction/CompareBinaryToHex.cs | 4 +- Introduction/SwapMinMax.cs | 4 +- ctci.Contracts/IQuestion.cs | 6 +- ctci/Program.cs | 58 +- 35 files changed, 543 insertions(+), 509 deletions(-) diff --git a/Ch 01. Arrays and Strings/Q1_01_Is_Unique.cs b/Ch 01. Arrays and Strings/Q1_01_Is_Unique.cs index 42b8169..3531ba0 100644 --- a/Ch 01. Arrays and Strings/Q1_01_Is_Unique.cs +++ b/Ch 01. Arrays and Strings/Q1_01_Is_Unique.cs @@ -3,7 +3,7 @@ namespace Chapter01 { - public class Q1_01_Is_Unique : IQuestion + public class Q1_01_Is_Unique : Question { private bool IsUniqueChars(string str) { @@ -50,7 +50,7 @@ private bool IsUniqueChars2(String str) return true; } - public void Run() + public override void Run() { string[] words = { "abcde", "hello", "apple", "kite", "padle" }; diff --git a/Ch 01. Arrays and Strings/Q1_02_Check_Permutation.cs b/Ch 01. Arrays and Strings/Q1_02_Check_Permutation.cs index 405f50b..120f1d7 100644 --- a/Ch 01. Arrays and Strings/Q1_02_Check_Permutation.cs +++ b/Ch 01. Arrays and Strings/Q1_02_Check_Permutation.cs @@ -3,7 +3,7 @@ namespace Chapter01 { - public class Q1_02_Check_Permutation : IQuestion + public class Q1_02_Check_Permutation : Question { private bool IsPermutation(string original, string valueToTest) { @@ -53,7 +53,7 @@ private bool IsPermutation2(string original, string valueToTest) return true; } - public void Run() + public override void Run() { string[][] pairs = { diff --git a/Ch 01. Arrays and Strings/Q1_03_URLify.cs b/Ch 01. Arrays and Strings/Q1_03_URLify.cs index 59c38b1..2176f6d 100644 --- a/Ch 01. Arrays and Strings/Q1_03_URLify.cs +++ b/Ch 01. Arrays and Strings/Q1_03_URLify.cs @@ -3,7 +3,7 @@ namespace Chapter01 { - public class Q1_03_URLify : IQuestion + public class Q1_03_URLify : Question { private void ReplaceSpaces(char[] input, int length) { @@ -39,7 +39,7 @@ private void ReplaceSpaces(char[] input, int length) } } - public void Run() + public override void Run() { const string input = "abc d e f"; var characterArray = new char[input.Length + 3 * 2 + 1]; diff --git a/Ch 01. Arrays and Strings/Q1_04_Palindrome_Permutation.cs b/Ch 01. Arrays and Strings/Q1_04_Palindrome_Permutation.cs index 23ac36b..e84963f 100644 --- a/Ch 01. Arrays and Strings/Q1_04_Palindrome_Permutation.cs +++ b/Ch 01. Arrays and Strings/Q1_04_Palindrome_Permutation.cs @@ -3,7 +3,7 @@ namespace Chapter01 { - public class Q1_04_Palindrome_Permutation : IQuestion + public class Q1_04_Palindrome_Permutation : Question { public static int GetCharNumber(char c) { @@ -135,7 +135,7 @@ public static bool IsPermutationOfPalindrome3(String phrase) #endregion Solution 3 - public void Run() + public override void Run() { String[] strings = {"Rats live on no evil star", "A man, a plan, a canal, panama", diff --git a/Ch 01. Arrays and Strings/Q1_05_One_Away_A.cs b/Ch 01. Arrays and Strings/Q1_05_One_Away_A.cs index b8a9b23..5a25bf7 100644 --- a/Ch 01. Arrays and Strings/Q1_05_One_Away_A.cs +++ b/Ch 01. Arrays and Strings/Q1_05_One_Away_A.cs @@ -3,7 +3,7 @@ namespace Chapter01 { - public class Q1_05_One_Away_A : IQuestion + public class Q1_05_One_Away_A : Question { public static bool OneEditReplace(String s1, String s2) { @@ -99,7 +99,7 @@ public static bool OneEditAway2(String first, String second) return true; } - public void Run() + public override void Run() { String a = "pse"; String b = "pale"; diff --git a/Ch 01. Arrays and Strings/Q1_06_String_Compression.cs b/Ch 01. Arrays and Strings/Q1_06_String_Compression.cs index 6cac24c..dfe7881 100644 --- a/Ch 01. Arrays and Strings/Q1_06_String_Compression.cs +++ b/Ch 01. Arrays and Strings/Q1_06_String_Compression.cs @@ -4,7 +4,7 @@ namespace Chapter01 { - public class Q1_06_String_Compression : IQuestion + public class Q1_06_String_Compression : Question { private int CountCompression(string str) { @@ -69,7 +69,7 @@ private string CompressBetter(string str) return sb.ToString(); } - public void Run() + public override void Run() { const string original = "abbccccccde"; var compressed = CompressBetter(original); diff --git a/Ch 01. Arrays and Strings/Q1_07_Rotate_Matrix.cs b/Ch 01. Arrays and Strings/Q1_07_Rotate_Matrix.cs index 1c2ff24..d8568c6 100644 --- a/Ch 01. Arrays and Strings/Q1_07_Rotate_Matrix.cs +++ b/Ch 01. Arrays and Strings/Q1_07_Rotate_Matrix.cs @@ -4,7 +4,7 @@ namespace Chapter01 { - public class Q1_07_Rotate_Matrix : IQuestion + public class Q1_07_Rotate_Matrix : Question { private void Rotate(int[][] matrix, int n) { @@ -33,7 +33,7 @@ private void Rotate(int[][] matrix, int n) } } - public void Run() + public override void Run() { const int size = 3; diff --git a/Ch 01. Arrays and Strings/Q1_08_Zero_Matrix.cs b/Ch 01. Arrays and Strings/Q1_08_Zero_Matrix.cs index 6e6c5b0..7869d33 100644 --- a/Ch 01. Arrays and Strings/Q1_08_Zero_Matrix.cs +++ b/Ch 01. Arrays and Strings/Q1_08_Zero_Matrix.cs @@ -4,7 +4,7 @@ namespace Chapter01 { - public class Q1_08_Zero_Matrix : IQuestion + public class Q1_08_Zero_Matrix : Question { private void NullifyRow(int[][] matrix, int row) { @@ -166,7 +166,7 @@ private void SetZeros2(int[][] matrix) } } - public void Run() + public override void Run() { const int numberOfRows = 10; const int numberOfColumns = 15; diff --git a/Ch 01. Arrays and Strings/Q1_09_String_Rotation.cs b/Ch 01. Arrays and Strings/Q1_09_String_Rotation.cs index 028557c..e54c326 100644 --- a/Ch 01. Arrays and Strings/Q1_09_String_Rotation.cs +++ b/Ch 01. Arrays and Strings/Q1_09_String_Rotation.cs @@ -3,7 +3,7 @@ namespace Chapter01 { - public class Q1_09_String_Rotation : IQuestion + public class Q1_09_String_Rotation : Question { public static bool IsSubstring(String big, String small) { @@ -25,7 +25,7 @@ public static bool IsRotation(String s1, String s2) return false; } - public void Run() + public override void Run() { string[][] pairs = { diff --git a/Ch 02. Linked Lists/Q2_01_Remove_Dups.cs b/Ch 02. Linked Lists/Q2_01_Remove_Dups.cs index 9bec648..b68d7f9 100644 --- a/Ch 02. Linked Lists/Q2_01_Remove_Dups.cs +++ b/Ch 02. Linked Lists/Q2_01_Remove_Dups.cs @@ -5,7 +5,7 @@ namespace Chapter02 { - public class Q2_01_Remove_Dups : IQuestion + public class Q2_01_Remove_Dups : Question { private int _tapB = 0; private int _tapC = 0; @@ -117,7 +117,7 @@ private void DeleteDupsC(LinkedListNode head) } } - public void Run() + public override void Run() { var first = new LinkedListNode(0, null, null); var originalList = first; diff --git a/Ch 02. Linked Lists/Q2_02_Return_Kth_To_Last.cs b/Ch 02. Linked Lists/Q2_02_Return_Kth_To_Last.cs index e7b00fd..114a57d 100644 --- a/Ch 02. Linked Lists/Q2_02_Return_Kth_To_Last.cs +++ b/Ch 02. Linked Lists/Q2_02_Return_Kth_To_Last.cs @@ -4,7 +4,7 @@ namespace Chapter02 { - public class Q2_02_Return_Kth_To_Last : IQuestion + public class Q2_02_Return_Kth_To_Last : Question { private int NthToLastR1(LinkedListNode head, int n) { @@ -108,7 +108,7 @@ private LinkedListNode NthToLast(LinkedListNode head, int n) return p1; } - public void Run() + public override void Run() { var head = AssortedMethods.RandomLinkedList(10, 0, 10); Console.WriteLine(head.PrintForward()); diff --git a/Ch 02. Linked Lists/Q2_03_Delete_Middle_Node.cs b/Ch 02. Linked Lists/Q2_03_Delete_Middle_Node.cs index f283336..414ca36 100644 --- a/Ch 02. Linked Lists/Q2_03_Delete_Middle_Node.cs +++ b/Ch 02. Linked Lists/Q2_03_Delete_Middle_Node.cs @@ -4,7 +4,7 @@ namespace Chapter02 { - public class Q2_03_Delete_Middle_Node : IQuestion + public class Q2_03_Delete_Middle_Node : Question { private bool DeleteNode(LinkedListNode node) { @@ -20,7 +20,7 @@ private bool DeleteNode(LinkedListNode node) return true; } - public void Run() + public override void Run() { var head = AssortedMethods.RandomLinkedList(10, 0, 10); Console.WriteLine(head.PrintForward()); diff --git a/Ch 02. Linked Lists/Q2_04_Partition.cs b/Ch 02. Linked Lists/Q2_04_Partition.cs index 02e4f3e..0917178 100644 --- a/Ch 02. Linked Lists/Q2_04_Partition.cs +++ b/Ch 02. Linked Lists/Q2_04_Partition.cs @@ -4,7 +4,7 @@ namespace Chapter02 { - public class Q2_04_Partition : IQuestion + public class Q2_04_Partition : Question { private LinkedListNode Partition(LinkedListNode node, int pivot) { @@ -175,7 +175,7 @@ private LinkedListNode Partition4(LinkedListNode listHead, int pivot) return listHead; } - public void Run() + public override void Run() { /* Create linked list */ int[] vals = { 1, 3, 7, 5, 2, 9, 4 }; diff --git a/Ch 02. Linked Lists/Q2_05_Sum_Lists.cs b/Ch 02. Linked Lists/Q2_05_Sum_Lists.cs index 8404fea..639ad7c 100644 --- a/Ch 02. Linked Lists/Q2_05_Sum_Lists.cs +++ b/Ch 02. Linked Lists/Q2_05_Sum_Lists.cs @@ -4,7 +4,7 @@ namespace Chapter02 { - public class Q2_05_Sum_Lists : IQuestion + public class Q2_05_Sum_Lists : Question { #region First Part @@ -167,7 +167,7 @@ private int linkedListToInt(LinkedListNode node) #endregion Followup - public void Run() + public override void Run() { #region First Part diff --git a/Ch 02. Linked Lists/Q2_06_Palindrome.cs b/Ch 02. Linked Lists/Q2_06_Palindrome.cs index e4800f9..0ff7fa3 100644 --- a/Ch 02. Linked Lists/Q2_06_Palindrome.cs +++ b/Ch 02. Linked Lists/Q2_06_Palindrome.cs @@ -5,7 +5,7 @@ namespace Chapter02 { - public class Q2_06_Palindrome : IQuestion + public class Q2_06_Palindrome : Question { private class Result { @@ -100,7 +100,7 @@ private bool IsPalindrome2(LinkedListNode head) return true; } - public void Run() + public override void Run() { const int length = 10; var nodes = new LinkedListNode[length]; diff --git a/Ch 02. Linked Lists/Q2_07_Intersection.cs b/Ch 02. Linked Lists/Q2_07_Intersection.cs index c0f8467..a5a0f1b 100644 --- a/Ch 02. Linked Lists/Q2_07_Intersection.cs +++ b/Ch 02. Linked Lists/Q2_07_Intersection.cs @@ -4,7 +4,7 @@ namespace Chapter02 { - public class Q2_07_Intersection : IQuestion + public class Q2_07_Intersection : Question { public class Result { @@ -75,7 +75,7 @@ public static LinkedListNode findIntersection(LinkedListNode list1, LinkedListNo return longer; } - public void Run() + public override void Run() { /* Create linked list */ int[] vals = { -1, -2, 0, 1, 2, 3, 4, 5, 6, 7, 8 }; diff --git a/Ch 02. Linked Lists/Q2_08_Loop_Detection.cs b/Ch 02. Linked Lists/Q2_08_Loop_Detection.cs index 583e5bf..f65a829 100644 --- a/Ch 02. Linked Lists/Q2_08_Loop_Detection.cs +++ b/Ch 02. Linked Lists/Q2_08_Loop_Detection.cs @@ -4,7 +4,7 @@ namespace Chapter02 { - public class Q2_08_Loop_Detection : IQuestion + public class Q2_08_Loop_Detection : Question { private LinkedListNode FindBeginning(LinkedListNode head) { @@ -43,7 +43,7 @@ private LinkedListNode FindBeginning(LinkedListNode head) return fast; } - public void Run() + public override void Run() { const int listLength = 10; const int k = 3; diff --git a/Ch 05. Bit Manipulation/Q5_01_Insertion.cs b/Ch 05. Bit Manipulation/Q5_01_Insertion.cs index 0f2becd..13853d8 100644 --- a/Ch 05. Bit Manipulation/Q5_01_Insertion.cs +++ b/Ch 05. Bit Manipulation/Q5_01_Insertion.cs @@ -3,7 +3,7 @@ namespace Chapter05 { - public class Q5_01_Insertion : IQuestion + public class Q5_01_Insertion : Question { private static int UpdateBits(int n, int m, int i, int j) { @@ -30,7 +30,7 @@ private static int UpdateBits(int n, int m, int i, int j) return nCleared | mShifted;// OR them, and we're done } - public void Run() + public override void Run() { Console.WriteLine(UpdateBits(100, 10, 2, 6)); } diff --git a/Ch 05. Bit Manipulation/Q5_02_Binary_to_String.cs b/Ch 05. Bit Manipulation/Q5_02_Binary_to_String.cs index 380500d..519d6d1 100644 --- a/Ch 05. Bit Manipulation/Q5_02_Binary_to_String.cs +++ b/Ch 05. Bit Manipulation/Q5_02_Binary_to_String.cs @@ -4,7 +4,7 @@ namespace Chapter05 { - public class Q5_02_Binary_to_String : IQuestion + public class Q5_02_Binary_to_String : Question { private string PrintBinary(double number) { @@ -74,7 +74,7 @@ private string PrintBinary2(double number) return binary.ToString(); } - public void Run() + public override void Run() { var binaryString = PrintBinary2(.125); Console.WriteLine(binaryString); diff --git a/Ch 05. Bit Manipulation/Q5_04_Next_Number.cs b/Ch 05. Bit Manipulation/Q5_04_Next_Number.cs index 1752dcd..bf42b66 100644 --- a/Ch 05. Bit Manipulation/Q5_04_Next_Number.cs +++ b/Ch 05. Bit Manipulation/Q5_04_Next_Number.cs @@ -1,306 +1,306 @@ -using ctci.Contracts; -using ctci.Library; -using System; - -namespace Chapter05 -{ - public class Q5_04_Next_Number : IQuestion - { - public static int CountOnes(int number) - { - var count = 0; - - while (number > 0) - { - if ((number & 1) == 1) - { - count++; - } - - number = number >> 1; - } - - return count; - } - - public static int CountZeros(int number) - { - return 32 - CountOnes(number); - } - - public static bool HasValidNext(int number) - { - if (number == 0) - { - return false; - } - var count = 0; - - while ((number & 1) == 0) - { - number >>= 1; - count++; - } - - while ((number & 1) == 1) - { - number >>= 1; - count++; - } - - if (count == 31) - { - return false; - } - - return true; - } - - public static bool HasValidPrev(int number) - { - while ((number & 1) == 1) - { - number >>= 1; - } - - if (number == 0) - { - return false; - } - - return true; - } - - public static int GetNextSlow(int number) - { - if (!HasValidNext(number)) - { - return -1; - } - - var numOnes = CountOnes(number); - number++; - - while (CountOnes(number) != numOnes) - { - number++; - } - - return number; - } - - public static int GetPrevSlow(int number) - { - if (!HasValidPrev(number)) - { - return -1; - } - - var numOnes = CountOnes(number); - number--; - - while (CountOnes(number) != numOnes) - { - number--; - } - - return number; - } - - public static int GetNext(int number) - { - var c = number; - var c0 = 0; - var c1 = 0; - - while (((c & 1) == 0) && (c != 0)) - { - c0++; - c >>= 1; - } - - while ((c & 1) == 1) - { - c1++; - c >>= 1; - } - - /* If c is 0, then n is a sequence of 1s followed by a sequence of 0s. This is already the biggest - * number with c1 ones. Return error. - */ - if (c0 + c1 == 31 || c0 + c1 == 0) - { - return -1; - } - - int pos = c0 + c1; // position of right-most non-trailing zero (where the right most bit is bit 0) - - /* Flip the right-most non-trailing zero (which will be at position pos) */ - number |= (1 << pos); // Flip right-most non-trailing zero - - /* Clear all bits to the right of pos. - * Example with pos = 5 - * (1) Shift 1 over by 5 to create 0..0100000 [ mask = 1 << pos ] - * (2) Subtract 1 to get 0..0011111 [ mask = mask - 1 ] - * (3) Flip all the bits by using '~' to get 1..1100000 [ mask = ~mask ] - * (4) AND with n - */ - number &= ~((1 << pos) - 1); // Clear all bits to the right of pos - - /* Put (ones-1) 1s on the right by doing the following: - * (1) Shift 1 over by (ones-1) spots. If ones = 3, this gets you 0..0100 - * (2) Subtract one from that to get 0..0011 - * (3) OR with n - */ - number |= (1 << (c1 - 1)) - 1; - - return number; - } - - public static int GetNextArith(int number) - { - var c = number; - var c0 = 0; - var c1 = 0; - - while (((c & 1) == 0) && (c != 0)) - { - c0++; - c >>= 1; - } - - while ((c & 1) == 1) - { - c1++; - c >>= 1; - } - - /* If c is 0, then n is a sequence of 1s followed by a sequence of 0s. This is already the biggest - * number with c1 ones. Return error. - */ - if (c0 + c1 == 31 || c0 + c1 == 0) - { - return -1; - } - - /* Arithmetically: - * 2^c0 = 1 << c0 - * 2^(c1-1) = 1 << (c0 - 1) - * next = n + 2^c0 + 2^(c1-1) - 1; - */ - - return number + (1 << c0) + (1 << (c1 - 1)) - 1; - } - - public static int GetPrev(int number) - { - var temp = number; - var c0 = 0; - var c1 = 0; - - while ((temp & 1) == 1) - { - c1++; - temp >>= 1; - } - - /* If temp is 0, then the number is a sequence of 0s followed by a sequence of 1s. This is already - * the smallest number with c1 ones. Return -1 for an error. - */ - if (temp == 0) - { - return -1; - } - - while (((temp & 1) == 0) && (temp != 0)) - { - c0++; - temp >>= 1; - } - - var p = c0 + c1; // position of right-most non-trailing one (where the right most bit is bit 0) - - /* Flip right-most non-trailing one. - * Example: n = 00011100011. - * c1 = 2 - * c0 = 3 - * pos = 5 - * - * Build up a mask as follows: - * (1) ~0 will be a sequence of 1s - * (2) shifting left by p + 1 will give you 11.111000000 (six 0s) - * (3) ANDing with n will clear the last 6 bits - * n is now 00011000000 - */ - number &= ((~0) << (p + 1)); // clears from bit p onwards (to the right) - - /* Create a sequence of (c1+1) 1s as follows - * (1) Shift 1 to the left (c1+1) times. If c1 is 2, this will give you 0..001000 - * (2) Subtract one from that. This will give you 0..00111 - */ - var mask = (1 << (c1 + 1)) - 1; // Sequence of (c1+1) ones - - /* Move the ones to be right up next to bit p - * Since this is a sequence of (c1+1) ones, and p = c1 + c0, we just need to - * shift this over by (c0-1) spots. - * If c0 = 3 and c1 = 2, then this will look like 00...0011100 - * - * Then, finally, we OR this with n. - */ - number |= mask << (c0 - 1); - - return number; - } - - public static int GetPrevArith(int number) - { - var temp = number; - var c0 = 0; - var c1 = 0; - - while (((temp & 1) == 1) && (temp != 0)) - { - c1++; - temp >>= 1; - } - - /* If temp is 0, then the number is a sequence of 0s followed by a sequence of 1s. This is already - * the smallest number with c1 ones. Return -1 for an error. - */ - if (temp == 0) - { - return -1; - } - - while ((temp & 1) == 0 && (temp != 0)) - { - c0++; - temp >>= 1; - } - - /* Arithmetic: - * 2^c1 = 1 << c1 - * 2^(c0 - 1) = 1 << (c0 - 1) - */ - return number - (1 << c1) - (1 << (c0 - 1)) + 1; - } - +using ctci.Contracts; +using ctci.Library; +using System; + +namespace Chapter05 +{ + public class Q5_04_Next_Number : Question + { + public static int CountOnes(int number) + { + var count = 0; + + while (number > 0) + { + if ((number & 1) == 1) + { + count++; + } + + number = number >> 1; + } + + return count; + } + + public static int CountZeros(int number) + { + return 32 - CountOnes(number); + } + + public static bool HasValidNext(int number) + { + if (number == 0) + { + return false; + } + var count = 0; + + while ((number & 1) == 0) + { + number >>= 1; + count++; + } + + while ((number & 1) == 1) + { + number >>= 1; + count++; + } + + if (count == 31) + { + return false; + } + + return true; + } + + public static bool HasValidPrev(int number) + { + while ((number & 1) == 1) + { + number >>= 1; + } + + if (number == 0) + { + return false; + } + + return true; + } + + public static int GetNextSlow(int number) + { + if (!HasValidNext(number)) + { + return -1; + } + + var numOnes = CountOnes(number); + number++; + + while (CountOnes(number) != numOnes) + { + number++; + } + + return number; + } + + public static int GetPrevSlow(int number) + { + if (!HasValidPrev(number)) + { + return -1; + } + + var numOnes = CountOnes(number); + number--; + + while (CountOnes(number) != numOnes) + { + number--; + } + + return number; + } + + public static int GetNext(int number) + { + var c = number; + var c0 = 0; + var c1 = 0; + + while (((c & 1) == 0) && (c != 0)) + { + c0++; + c >>= 1; + } + + while ((c & 1) == 1) + { + c1++; + c >>= 1; + } + + /* If c is 0, then n is a sequence of 1s followed by a sequence of 0s. This is already the biggest + * number with c1 ones. Return error. + */ + if (c0 + c1 == 31 || c0 + c1 == 0) + { + return -1; + } + + int pos = c0 + c1; // position of right-most non-trailing zero (where the right most bit is bit 0) + + /* Flip the right-most non-trailing zero (which will be at position pos) */ + number |= (1 << pos); // Flip right-most non-trailing zero + + /* Clear all bits to the right of pos. + * Example with pos = 5 + * (1) Shift 1 over by 5 to create 0..0100000 [ mask = 1 << pos ] + * (2) Subtract 1 to get 0..0011111 [ mask = mask - 1 ] + * (3) Flip all the bits by using '~' to get 1..1100000 [ mask = ~mask ] + * (4) AND with n + */ + number &= ~((1 << pos) - 1); // Clear all bits to the right of pos + + /* Put (ones-1) 1s on the right by doing the following: + * (1) Shift 1 over by (ones-1) spots. If ones = 3, this gets you 0..0100 + * (2) Subtract one from that to get 0..0011 + * (3) OR with n + */ + number |= (1 << (c1 - 1)) - 1; + + return number; + } + + public static int GetNextArith(int number) + { + var c = number; + var c0 = 0; + var c1 = 0; + + while (((c & 1) == 0) && (c != 0)) + { + c0++; + c >>= 1; + } + + while ((c & 1) == 1) + { + c1++; + c >>= 1; + } + + /* If c is 0, then n is a sequence of 1s followed by a sequence of 0s. This is already the biggest + * number with c1 ones. Return error. + */ + if (c0 + c1 == 31 || c0 + c1 == 0) + { + return -1; + } + + /* Arithmetically: + * 2^c0 = 1 << c0 + * 2^(c1-1) = 1 << (c0 - 1) + * next = n + 2^c0 + 2^(c1-1) - 1; + */ + + return number + (1 << c0) + (1 << (c1 - 1)) - 1; + } + + public static int GetPrev(int number) + { + var temp = number; + var c0 = 0; + var c1 = 0; + + while ((temp & 1) == 1) + { + c1++; + temp >>= 1; + } + + /* If temp is 0, then the number is a sequence of 0s followed by a sequence of 1s. This is already + * the smallest number with c1 ones. Return -1 for an error. + */ + if (temp == 0) + { + return -1; + } + + while (((temp & 1) == 0) && (temp != 0)) + { + c0++; + temp >>= 1; + } + + var p = c0 + c1; // position of right-most non-trailing one (where the right most bit is bit 0) + + /* Flip right-most non-trailing one. + * Example: n = 00011100011. + * c1 = 2 + * c0 = 3 + * pos = 5 + * + * Build up a mask as follows: + * (1) ~0 will be a sequence of 1s + * (2) shifting left by p + 1 will give you 11.111000000 (six 0s) + * (3) ANDing with n will clear the last 6 bits + * n is now 00011000000 + */ + number &= ((~0) << (p + 1)); // clears from bit p onwards (to the right) + + /* Create a sequence of (c1+1) 1s as follows + * (1) Shift 1 to the left (c1+1) times. If c1 is 2, this will give you 0..001000 + * (2) Subtract one from that. This will give you 0..00111 + */ + var mask = (1 << (c1 + 1)) - 1; // Sequence of (c1+1) ones + + /* Move the ones to be right up next to bit p + * Since this is a sequence of (c1+1) ones, and p = c1 + c0, we just need to + * shift this over by (c0-1) spots. + * If c0 = 3 and c1 = 2, then this will look like 00...0011100 + * + * Then, finally, we OR this with n. + */ + number |= mask << (c0 - 1); + + return number; + } + + public static int GetPrevArith(int number) + { + var temp = number; + var c0 = 0; + var c1 = 0; + + while (((temp & 1) == 1) && (temp != 0)) + { + c1++; + temp >>= 1; + } + + /* If temp is 0, then the number is a sequence of 0s followed by a sequence of 1s. This is already + * the smallest number with c1 ones. Return -1 for an error. + */ + if (temp == 0) + { + return -1; + } + + while ((temp & 1) == 0 && (temp != 0)) + { + c0++; + temp >>= 1; + } + + /* Arithmetic: + * 2^c1 = 1 << c1 + * 2^(c0 - 1) = 1 << (c0 - 1) + */ + return number - (1 << c1) - (1 << (c0 - 1)) + 1; + } + public static void BinPrint(int number) - { + { Console.WriteLine(number + ": " + AssortedMethods.ToFullBinarystring(number)); - } - - public void Run() + } + + public override void Run() { // TODO: Fix this (ported from Java but does not seem to function properly) for (var i = 0; i < 200; i++) - { - var p1 = GetPrevSlow(i); - var p2 = GetPrev(i); - var p3 = GetPrevArith(i); - - var n1 = GetNextSlow(i); - var n2 = GetNext(i); + { + var p1 = GetPrevSlow(i); + var p2 = GetPrev(i); + var p3 = GetPrevArith(i); + + var n1 = GetNextSlow(i); + var n2 = GetNext(i); var n3 = GetNextArith(i); if (p1 != p2 || p2 != p3 || n1 != n2 || n2 != n3) @@ -314,9 +314,9 @@ public void Run() BinPrint(n3); Console.WriteLine(""); } - } - - Console.WriteLine("Done!"); - } - } + } + + Console.WriteLine("Done!"); + } + } } \ No newline at end of file diff --git a/Ch 05. Bit Manipulation/Q5_06_Conversion.cs b/Ch 05. Bit Manipulation/Q5_06_Conversion.cs index 54bdf7c..59e8c70 100644 --- a/Ch 05. Bit Manipulation/Q5_06_Conversion.cs +++ b/Ch 05. Bit Manipulation/Q5_06_Conversion.cs @@ -4,7 +4,7 @@ namespace Chapter05 { - public class Q5_06_Conversion : IQuestion + public class Q5_06_Conversion : Question { public static int BitSwapRequired(int number1, int number2) { @@ -30,7 +30,7 @@ public static int BitSwapRequired2(int number1, int number2) return count; } - public void Run() + public override void Run() { var a = 23432; var b = 512132; diff --git a/Ch 05. Bit Manipulation/Q5_07_Pairwise_Swap.cs b/Ch 05. Bit Manipulation/Q5_07_Pairwise_Swap.cs index c0fa24d..d82144f 100644 --- a/Ch 05. Bit Manipulation/Q5_07_Pairwise_Swap.cs +++ b/Ch 05. Bit Manipulation/Q5_07_Pairwise_Swap.cs @@ -1,22 +1,22 @@ -using ctci.Contracts; -using ctci.Library; -using System; - -namespace Chapter05 -{ - public class Q5_07_Pairwise_Swap : IQuestion - { - public static int SwapOddEvenBits(int x) - { - return (int)(((x & 0xaaaaaaaa) >> 1) | ((x & 0x55555555) << 1)); +using ctci.Contracts; +using ctci.Library; +using System; + +namespace Chapter05 +{ + public class Q5_07_Pairwise_Swap : Question + { + public static int SwapOddEvenBits(int x) + { + return (int)(((x & 0xaaaaaaaa) >> 1) | ((x & 0x55555555) << 1)); } - public void Run() + public override void Run() { var a = 103217; - Console.WriteLine(a + ": " + AssortedMethods.ToFullBinarystring(a)); - var b = SwapOddEvenBits(a); - Console.WriteLine(b + ": " + AssortedMethods.ToFullBinarystring(b)); - } - } + Console.WriteLine(a + ": " + AssortedMethods.ToFullBinarystring(a)); + var b = SwapOddEvenBits(a); + Console.WriteLine(b + ": " + AssortedMethods.ToFullBinarystring(b)); + } + } } \ No newline at end of file diff --git a/Ch 05. Bit Manipulation/Q5_08_Draw_Line.cs b/Ch 05. Bit Manipulation/Q5_08_Draw_Line.cs index d5a51eb..7afcda3 100644 --- a/Ch 05. Bit Manipulation/Q5_08_Draw_Line.cs +++ b/Ch 05. Bit Manipulation/Q5_08_Draw_Line.cs @@ -1,98 +1,98 @@ -using ctci.Contracts; -using System; - -namespace Chapter05 -{ - public class Q5_08_Draw_Line : IQuestion - { - public static int ComputeByteNum(int width, int x, int y) - { - return (width * y + x) / 8; - } - - public static void DrawLine(byte[] screen, int width, int x1, int x2, int y) - { - var startOffset = x1 % 8; - var firstFullByte = x1 / 8; - - if (startOffset != 0) - { - firstFullByte++; - } - - var endOffset = x2 % 8; - var lastFullByte = x2 / 8; - - if (endOffset != 7) - { - lastFullByte--; - } - - // Set full bytes - for (var b = firstFullByte; b <= lastFullByte; b++) - { - screen[(width / 8) * y + b] = (byte)0xFF; - } - - var startMask = (byte)(0xFF >> startOffset); - var endMask = (byte)~(0xFF >> (endOffset + 1)); - - // Set start and end of line - if ((x1 / 8) == (x2 / 8)) +using ctci.Contracts; +using System; + +namespace Chapter05 +{ + public class Q5_08_Draw_Line : Question + { + public static int ComputeByteNum(int width, int x, int y) + { + return (width * y + x) / 8; + } + + public static void DrawLine(byte[] screen, int width, int x1, int x2, int y) + { + var startOffset = x1 % 8; + var firstFullByte = x1 / 8; + + if (startOffset != 0) + { + firstFullByte++; + } + + var endOffset = x2 % 8; + var lastFullByte = x2 / 8; + + if (endOffset != 7) + { + lastFullByte--; + } + + // Set full bytes + for (var b = firstFullByte; b <= lastFullByte; b++) + { + screen[(width / 8) * y + b] = (byte)0xFF; + } + + var startMask = (byte)(0xFF >> startOffset); + var endMask = (byte)~(0xFF >> (endOffset + 1)); + + // Set start and end of line + if ((x1 / 8) == (x2 / 8)) { // If x1 and x2 are in the same byte - var mask = (byte)(startMask & endMask); - screen[(width / 8) * y + (x1 / 8)] |= mask; - } - else - { - if (startOffset != 0) - { - var byteNumber = (width / 8) * y + firstFullByte - 1; - screen[byteNumber] |= startMask; - } - if (endOffset != 7) - { - var byteNumber = (width / 8) * y + lastFullByte + 1; - screen[byteNumber] |= endMask; - } - } - } - - public static void PrintByte(byte b) + var mask = (byte)(startMask & endMask); + screen[(width / 8) * y + (x1 / 8)] |= mask; + } + else + { + if (startOffset != 0) + { + var byteNumber = (width / 8) * y + firstFullByte - 1; + screen[byteNumber] |= startMask; + } + if (endOffset != 7) + { + var byteNumber = (width / 8) * y + lastFullByte + 1; + screen[byteNumber] |= endMask; + } + } + } + + public static void PrintByte(byte b) { for (var i = 7; i >= 0; i--) { Console.Write((b >> i) & 1); } - } - + } + public static void PrintScreen(byte[] screen, int width) { - var height = screen.Length * 8 / width; - + var height = screen.Length * 8 / width; + for (var r = 0; r < height; r++) - { + { for (var c = 0; c < width; c += 8) - { + { var b = screen[ComputeByteNum(width, c, r)]; PrintByte(b); } Console.WriteLine(""); } - } - - public void Run() - { - const int width = 8 * 4; - const int height = 15; - var screen = new byte[width * height / 8]; - //screen[1] = 13; - - DrawLine(screen, width, 8, 10, 2); - - PrintScreen(screen, width); - } - } + } + + public override void Run() + { + const int width = 8 * 4; + const int height = 15; + var screen = new byte[width * height / 8]; + //screen[1] = 13; + + DrawLine(screen, width, 8, 10, 2); + + PrintScreen(screen, width); + } + } } \ No newline at end of file diff --git a/Ch 10. Sorting and Searching/Q10_01_Sorted_Merge.cs b/Ch 10. Sorting and Searching/Q10_01_Sorted_Merge.cs index 699444c..b69fe45 100644 --- a/Ch 10. Sorting and Searching/Q10_01_Sorted_Merge.cs +++ b/Ch 10. Sorting and Searching/Q10_01_Sorted_Merge.cs @@ -4,7 +4,7 @@ namespace Chapter10 { - public class Q10_01_Sorted_Merge : IQuestion + public class Q10_01_Sorted_Merge : Question { /// /// Merges array @@ -36,7 +36,7 @@ private void Merge(int[] a, int[] b, int lastA, int lastB) } } - public void Run() + public override void Run() { int[] a = new int[] { 2, 3, 4, 5, 6, 8, 10, 100, 0, 0, 0, 0, 0, 0 }; int[] b = new int[] { 1, 4, 7, 6, 7, 7 }; diff --git a/Ch 10. Sorting and Searching/Q10_02_Group_Anagrams.cs b/Ch 10. Sorting and Searching/Q10_02_Group_Anagrams.cs index 0d69836..2927ad9 100644 --- a/Ch 10. Sorting and Searching/Q10_02_Group_Anagrams.cs +++ b/Ch 10. Sorting and Searching/Q10_02_Group_Anagrams.cs @@ -6,7 +6,7 @@ namespace Chapter10 { - public class Q10_02_Group_Anagrams : IQuestion + public class Q10_02_Group_Anagrams : Question { private class AnagramComparator : IComparer { @@ -59,7 +59,7 @@ private void Sort(string[] array) } } - public void Run() + public override void Run() { string[] array = { "apple", "banana", "carrot", "ele", "duck", "papel", "tarroc", "cudk", "eel", "lee" }; Console.WriteLine(AssortedMethods.StringArrayToString(array)); diff --git a/Ch 10. Sorting and Searching/Q10_03_Search_in_Rotated_Array.cs b/Ch 10. Sorting and Searching/Q10_03_Search_in_Rotated_Array.cs index 21952e1..b79a1af 100644 --- a/Ch 10. Sorting and Searching/Q10_03_Search_in_Rotated_Array.cs +++ b/Ch 10. Sorting and Searching/Q10_03_Search_in_Rotated_Array.cs @@ -1,22 +1,22 @@ -using ctci.Contracts; -using System; - -namespace Chapter10 -{ - public class Q10_03_Search_in_Rotated_Array : IQuestion - { - /// - /// As in the book, returns the correct index (tested) - /// It's a real kludge though... good initial answer - /// The code runs in O(logn) time - assuming that all elements are unique. However, with many duplicates, the algorithm is O(n) - /// - /// - /// - /// - /// - /// - public int Search(int[] a, int left, int right, int x) - { +using ctci.Contracts; +using System; + +namespace Chapter10 +{ + public class Q10_03_Search_in_Rotated_Array : Question + { + /// + /// As in the book, returns the correct index (tested) + /// It's a real kludge though... good initial answer + /// The code runs in O(logn) time - assuming that all elements are unique. However, with many duplicates, the algorithm is O(n) + /// + /// + /// + /// + /// + /// + public int Search(int[] a, int left, int right, int x) + { int mid = (left + right) / 2; if (x == a[mid]) { // Found element @@ -27,9 +27,9 @@ public int Search(int[] a, int left, int right, int x) return -1; } - /* While there may be an inflection point due to the rotation, either the left or + /* While there may be an inflection point due to the rotation, either the left or * right half must be normally ordered. We can look at the normally ordered half - * to make a determination as to which half we should search. + * to make a determination as to which half we should search. */ if (a[left] < a[mid]) { // Left is normally ordered. @@ -68,17 +68,17 @@ public int Search(int[] a, int left, int right, int x) } } } - return -1; - } - - /* Another way is to do a pivoted binary search, where you first identify the problematic area, basically start of the originally + return -1; + } + + /* Another way is to do a pivoted binary search, where you first identify the problematic area, basically start of the originally * sorted array. */ - - public void Run() - { - int[] a = new int[] { 5, 6, 7, 8, 9, 1, 2, 3, 4 }; - - Console.WriteLine(Search(a, 0, a.Length, 8)); - } - } + + public override void Run() + { + int[] a = new int[] { 5, 6, 7, 8, 9, 1, 2, 3, 4 }; + + Console.WriteLine(Search(a, 0, a.Length, 8)); + } + } } \ No newline at end of file diff --git a/Ch 10. Sorting and Searching/Q10_05_Sparse_Search.cs b/Ch 10. Sorting and Searching/Q10_05_Sparse_Search.cs index cf06a5f..6576134 100644 --- a/Ch 10. Sorting and Searching/Q10_05_Sparse_Search.cs +++ b/Ch 10. Sorting and Searching/Q10_05_Sparse_Search.cs @@ -3,7 +3,7 @@ namespace Chapter10 { - public class Q10_05_Sparse_Search : IQuestion + public class Q10_05_Sparse_Search : Question { public static int Search(String[] strings, String str, int first, int last) { @@ -172,7 +172,7 @@ public static int Search2(String[] strings, String str) return SearchR(strings, str, 0, strings.Length - 1); } - public void Run() + public override void Run() { String[] stringList = { "apple", "", "", "banana", "", "", "", "carrot", "duck", "", "", "eel", "", "flower" }; diff --git a/Ch 10. Sorting and Searching/Q10_08_Find_Duplicates.cs b/Ch 10. Sorting and Searching/Q10_08_Find_Duplicates.cs index c1a3bcd..e60be72 100644 --- a/Ch 10. Sorting and Searching/Q10_08_Find_Duplicates.cs +++ b/Ch 10. Sorting and Searching/Q10_08_Find_Duplicates.cs @@ -4,7 +4,7 @@ namespace Chapter10 { - public class Q10_08_Find_Duplicates : IQuestion + public class Q10_08_Find_Duplicates : Question { public class BitSet { @@ -47,7 +47,7 @@ public static void checkDuplicates(int[] array) } } - public void Run() + public override void Run() { int[] array = AssortedMethods.RandomArray(30, 1, 30); Console.WriteLine(AssortedMethods.ArrayToString(array)); diff --git a/Ch 10. Sorting and Searching/Q10_09_Sorted_Matrix_Search.cs b/Ch 10. Sorting and Searching/Q10_09_Sorted_Matrix_Search.cs index e05fd5d..01f4e9b 100644 --- a/Ch 10. Sorting and Searching/Q10_09_Sorted_Matrix_Search.cs +++ b/Ch 10. Sorting and Searching/Q10_09_Sorted_Matrix_Search.cs @@ -4,7 +4,7 @@ namespace Chapter10 { - public class Q10_09_Sorted_Matrix_Search : IQuestion + public class Q10_09_Sorted_Matrix_Search : Question { public class Coordinate : ICloneable { @@ -124,7 +124,7 @@ public void Run2() Console.WriteLine("Found " + count + " unique elements."); } - public void Run() + public override void Run() { Run1(); Run2(); diff --git a/Ch 10. Sorting and Searching/Q10_10_Rank_from_Stream.cs b/Ch 10. Sorting and Searching/Q10_10_Rank_from_Stream.cs index 4fc5d6b..0594609 100644 --- a/Ch 10. Sorting and Searching/Q10_10_Rank_from_Stream.cs +++ b/Ch 10. Sorting and Searching/Q10_10_Rank_from_Stream.cs @@ -4,7 +4,7 @@ namespace Chapter10 { - public class Q10_10_Rank_from_Stream : IQuestion + public class Q10_10_Rank_from_Stream : Question { private static RankNode root = null; @@ -24,7 +24,7 @@ public static int GetRankOfNumber(int number) return root.GetRank(number); } - public void Run() + public override void Run() { int size = 100; int[] list = AssortedMethods.RandomArray(size, -100, 100); diff --git a/Ch 10. Sorting and Searching/Q10_11_Peaks_and_Valleys.cs b/Ch 10. Sorting and Searching/Q10_11_Peaks_and_Valleys.cs index b7c57b5..6009612 100644 --- a/Ch 10. Sorting and Searching/Q10_11_Peaks_and_Valleys.cs +++ b/Ch 10. Sorting and Searching/Q10_11_Peaks_and_Valleys.cs @@ -4,7 +4,7 @@ namespace Chapter10 { - public class Q10_11_Peaks_and_Valleys : IQuestion + public class Q10_11_Peaks_and_Valleys : Question { public static void Swap(int[] array, int left, int right) { @@ -13,8 +13,8 @@ public static void Swap(int[] array, int left, int right) array[right] = temp; } - #region Solution A - + #region Solution A + public void SortValleyPeak(int[] array) { Array.Sort(array); @@ -81,7 +81,7 @@ public static void SortValleyPeak3(int[] array) } } - public void Run() + public override void Run() { int[] array = { 48, 40, 31, 62, 28, 21, 64, 40, 23, 17 }; @@ -100,6 +100,6 @@ public void Run() Console.WriteLine(AssortedMethods.ArrayToString(array3)); } - #endregion Solution C + #endregion Solution C } } \ No newline at end of file diff --git a/Introduction/CompareBinaryToHex.cs b/Introduction/CompareBinaryToHex.cs index 9119f9f..c9629ae 100644 --- a/Introduction/CompareBinaryToHex.cs +++ b/Introduction/CompareBinaryToHex.cs @@ -3,7 +3,7 @@ namespace Introduction { - public class CompareBinaryToHex : IQuestion + public class CompareBinaryToHex : Question { private int DigitToValue(char c) { @@ -52,7 +52,7 @@ private bool CompareBinToHex(String binary, String hex) } } - public void Run() + public override void Run() { Console.WriteLine(CompareBinToHex("111001011", "1CB")); } diff --git a/Introduction/SwapMinMax.cs b/Introduction/SwapMinMax.cs index 84c7f40..001e958 100644 --- a/Introduction/SwapMinMax.cs +++ b/Introduction/SwapMinMax.cs @@ -4,7 +4,7 @@ namespace Introduction { - public class SwapMinMax : IQuestion + public class SwapMinMax : Question { private int GetMinIndex(int[] array) { @@ -71,7 +71,7 @@ private void DoSwapMinMax(int[] array) array[maxIndex] = temp; } - public void Run() + public override void Run() { int[] array = AssortedMethods.RandomArray(10, -10, 10); Console.WriteLine(AssortedMethods.ArrayToString(array)); diff --git a/ctci.Contracts/IQuestion.cs b/ctci.Contracts/IQuestion.cs index d9976d1..e4ba0ed 100644 --- a/ctci.Contracts/IQuestion.cs +++ b/ctci.Contracts/IQuestion.cs @@ -1,7 +1,9 @@ namespace ctci.Contracts { - public interface IQuestion + public abstract class Question { - void Run(); + abstract public void Run(); + + public string Name => GetType().ToString(); } } \ No newline at end of file diff --git a/ctci/Program.cs b/ctci/Program.cs index 785a25b..84baebf 100644 --- a/ctci/Program.cs +++ b/ctci/Program.cs @@ -15,34 +15,66 @@ private static void Main(string[] args) var chapters = new[] { // Intro - new IQuestion[] { new CompareBinaryToHex(), new SwapMinMax(), }, + new Question[] { new CompareBinaryToHex(), new SwapMinMax(), }, // Chapters - new IQuestion[] { new Q1_01_Is_Unique(), new Q1_02_Check_Permutation(), new Q1_03_URLify(), new Q1_04_Palindrome_Permutation(), new Q1_05_One_Away_A(), new Q1_06_String_Compression(), new Q1_07_Rotate_Matrix(), new Q1_08_Zero_Matrix(), new Q1_09_String_Rotation(),}, + new Question[] { + new Q1_01_Is_Unique(), + new Q1_02_Check_Permutation(), + new Q1_03_URLify(), + new Q1_04_Palindrome_Permutation(), + new Q1_05_One_Away_A(), + new Q1_06_String_Compression(), + new Q1_07_Rotate_Matrix(), + new Q1_08_Zero_Matrix(), + new Q1_09_String_Rotation(), + }, - new IQuestion[] { new Q2_01_Remove_Dups(), new Q2_02_Return_Kth_To_Last(), new Q2_03_Delete_Middle_Node(), new Q2_04_Partition(), new Q2_05_Sum_Lists(), new Q2_06_Palindrome(), new Q2_07_Intersection(), new Q2_08_Loop_Detection() }, + new Question[] { + new Q2_01_Remove_Dups(), + new Q2_02_Return_Kth_To_Last(), + new Q2_03_Delete_Middle_Node(), + new Q2_04_Partition(), + new Q2_05_Sum_Lists(), + new Q2_06_Palindrome(), + new Q2_07_Intersection(), + new Q2_08_Loop_Detection() + }, - new IQuestion[] { new Q5_01_Insertion(), new Q5_02_Binary_to_String(), new Q5_04_Next_Number(), new Q5_06_Conversion(), new Q5_06_Conversion(), new Q5_07_Pairwise_Swap(), new Q5_08_Draw_Line() }, + new Question[] { + new Q5_01_Insertion(), + new Q5_02_Binary_to_String(), + new Q5_04_Next_Number(), + new Q5_06_Conversion(), + new Q5_06_Conversion(), + new Q5_07_Pairwise_Swap(), + new Q5_08_Draw_Line() + }, + + new Question[] { + new Q10_01_Sorted_Merge(), + new Q10_02_Group_Anagrams(), + new Q10_03_Search_in_Rotated_Array(), + new Q10_05_Sparse_Search(), + new Q10_08_Find_Duplicates(), + new Q10_09_Sorted_Matrix_Search(), + new Q10_10_Rank_from_Stream(), + new Q10_11_Peaks_and_Valleys() + }, - new IQuestion[] { new Q10_01_Sorted_Merge(), new Q10_02_Group_Anagrams(), new Q10_03_Search_in_Rotated_Array(), new Q10_05_Sparse_Search(), new Q10_08_Find_Duplicates(), new Q10_09_Sorted_Matrix_Search(), new Q10_10_Rank_from_Stream(), new Q10_11_Peaks_and_Valleys() }, - }; foreach (var chapter in chapters) { - foreach (IQuestion q in chapter) + foreach (Question q in chapter) { - Console.WriteLine(string.Format("{0}{1}", Environment.NewLine, Environment.NewLine)); - Console.WriteLine(string.Format("// Executing: {0}", q.GetType().ToString())); + Console.WriteLine("\n\n"); + Console.WriteLine($"// Executing: {q.Name}"); Console.WriteLine("// ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ----"); q.Run(); } - - Console.WriteLine(); - Console.WriteLine("Press Enter to continue.."); - //Console.ReadLine(); } Console.WriteLine(string.Format("{0}{1}", Environment.NewLine, Environment.NewLine)); From 9f425467a4cd09a87862e4de2e96da1418ee94e8 Mon Sep 17 00:00:00 2001 From: Xavier Date: Mon, 20 Mar 2017 22:31:33 -0700 Subject: [PATCH 02/33] Use hashset to check if characters in a string are unique --- Ch 01. Arrays and Strings/Q1_01_Is_Unique.cs | 20 +++++--------------- 1 file changed, 5 insertions(+), 15 deletions(-) diff --git a/Ch 01. Arrays and Strings/Q1_01_Is_Unique.cs b/Ch 01. Arrays and Strings/Q1_01_Is_Unique.cs index 3531ba0..42ff716 100644 --- a/Ch 01. Arrays and Strings/Q1_01_Is_Unique.cs +++ b/Ch 01. Arrays and Strings/Q1_01_Is_Unique.cs @@ -1,5 +1,6 @@ using ctci.Contracts; using System; +using System.Collections.Generic; namespace Chapter01 { @@ -29,22 +30,11 @@ private bool IsUniqueChars(string str) private bool IsUniqueChars2(String str) { - if (str.Length > 256) + var hashset = new HashSet(); + foreach(var c in str) { - return false; - } - - var charSet = new bool[256]; - - for (var i = 0; i < str.Length; i++) - { - int val = str[i]; - - if (charSet[val]) - { - return false; - } - charSet[val] = true; + if (hashset.Contains(c)) return false; + hashset.Add(c); } return true; From ee7cee16e4da1413cde153b50481f4b8071e9769 Mon Sep 17 00:00:00 2001 From: Xavier Date: Mon, 20 Mar 2017 22:42:31 -0700 Subject: [PATCH 03/33] Use dictionary to check permutation --- .../Q1_02_Check_Permutation.cs | 26 +++++++++++-------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/Ch 01. Arrays and Strings/Q1_02_Check_Permutation.cs b/Ch 01. Arrays and Strings/Q1_02_Check_Permutation.cs index 120f1d7..c2f18b4 100644 --- a/Ch 01. Arrays and Strings/Q1_02_Check_Permutation.cs +++ b/Ch 01. Arrays and Strings/Q1_02_Check_Permutation.cs @@ -1,5 +1,6 @@ using ctci.Contracts; using System; +using System.Collections.Generic; namespace Chapter01 { @@ -30,24 +31,27 @@ private bool IsPermutation2(string original, string valueToTest) return false; } - var letters = new int[256]; - var originalAsArray = original.ToCharArray(); + var letterCount = new Dictionary(); - foreach (var character in originalAsArray) + foreach (var character in original) { - letters[character]++; + if (letterCount.ContainsKey(character)) + letterCount[character]++; + else + letterCount[character] = 1; } - var valueToTestAsArray = valueToTest.ToCharArray(); - - foreach (var character in valueToTestAsArray) + foreach (var character in valueToTest) { - letters[character]--; - - if (letters[character] < 0) + if (letterCount.ContainsKey(character)) { - return false; + letterCount[character]--; + if (letterCount[character] < 0) + { + return false; + } } + else return false; } return true; From 56e7977017f9e2c5eba0328faffa5c3a89f7813c Mon Sep 17 00:00:00 2001 From: Xavier Date: Mon, 20 Mar 2017 23:10:52 -0700 Subject: [PATCH 04/33] URLify --- Ch 01. Arrays and Strings/Q1_03_URLify.cs | 35 ++++++++++------------- 1 file changed, 15 insertions(+), 20 deletions(-) diff --git a/Ch 01. Arrays and Strings/Q1_03_URLify.cs b/Ch 01. Arrays and Strings/Q1_03_URLify.cs index 2176f6d..4f5ea09 100644 --- a/Ch 01. Arrays and Strings/Q1_03_URLify.cs +++ b/Ch 01. Arrays and Strings/Q1_03_URLify.cs @@ -5,38 +5,33 @@ namespace Chapter01 { public class Q1_03_URLify : Question { - private void ReplaceSpaces(char[] input, int length) + int Count_the_number_of_spaces(char[] input) { var spaceCount = 0; - - // count the number of spaces foreach (var character in input) { if (character == ' ') - { spaceCount++; - } } + return spaceCount; + } + private void ReplaceSpaces(char[] input, int length) + { + var space = new[] { '0', '2', '%' }; + var spaceCount = Count_the_number_of_spaces(input); // calculate new string size var index = length + spaceCount * 2; - - // copying the characters backwards and inserting %20 - for (var i = length - 1; i >= 0; i--) + void SetCharsAndMoveIndex(params char[] chars) { - if (input[i] == ' ') - { - input[index - 1] = '0'; - input[index - 2] = '2'; - input[index - 3] = '%'; - index -= 3; - } - else - { - input[index - 1] = input[i]; - index--; - } + foreach (var c in chars) + input[index--] = c; } + // copying the characters backwards and inserting %20 + for (var indexSource = length - 1; indexSource >= 0; indexSource--) + if (input[indexSource] == ' ') + SetCharsAndMoveIndex(space); + else SetCharsAndMoveIndex(input[indexSource]); } public override void Run() From 214f49a504566a9cdd7ffcac9ae917af6396ded0 Mon Sep 17 00:00:00 2001 From: Xavier Date: Tue, 21 Mar 2017 21:22:09 -0700 Subject: [PATCH 05/33] Bug fix Palindrome Permutation --- .../Q1_04_Palindrome_Permutation.cs | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/Ch 01. Arrays and Strings/Q1_04_Palindrome_Permutation.cs b/Ch 01. Arrays and Strings/Q1_04_Palindrome_Permutation.cs index e84963f..f79466d 100644 --- a/Ch 01. Arrays and Strings/Q1_04_Palindrome_Permutation.cs +++ b/Ch 01. Arrays and Strings/Q1_04_Palindrome_Permutation.cs @@ -7,21 +7,18 @@ public class Q1_04_Palindrome_Permutation : Question { public static int GetCharNumber(char c) { - var a = (int)char.GetNumericValue('a'); - var z = (int)char.GetNumericValue('z'); - - var val = (int)char.GetNumericValue(c); - if (a <= val && val <= z) + var val = char.ToLower(c) - 'a'; + if (0 <= val && val <= 25) { - return val - a; + return val; } return -1; } public static int[] BuildCharFrequencyTable(String phrase) { - int[] table = new int[(int)char.GetNumericValue('z') - (int)char.GetNumericValue('a') + 1]; - foreach (char c in phrase.ToCharArray()) + int[] table = new int[26]; + foreach (char c in phrase) { int x = GetCharNumber(c); if (x != -1) @@ -64,7 +61,7 @@ public static bool IsPermutationOfPalindrome(String phrase) public static bool IsPermutationOfPalindrome2(String phrase) { int countOdd = 0; - int[] table = new int[(int)char.GetNumericValue('z') - (int)char.GetNumericValue('a') + 1]; + int[] table = new int[26]; foreach (char c in phrase.ToCharArray()) { int x = GetCharNumber(c); @@ -108,7 +105,7 @@ public static int Toggle(int bitVector, int index) /* Create bit vector for string. For each letter with value i, * toggle the ith bit. */ - public static int CreateBitVector(String phrase) + public static int MarkBitForOddCharacterCount(String phrase) { int bitVector = 0; foreach (char c in phrase.ToCharArray()) @@ -129,7 +126,7 @@ public static bool CheckExactlyOneBitSet(int bitVector) public static bool IsPermutationOfPalindrome3(String phrase) { - int bitVector = CreateBitVector(phrase); + int bitVector = MarkBitForOddCharacterCount(phrase); return bitVector == 0 || CheckExactlyOneBitSet(bitVector); } From c8a0b7668479c9033680afcdfb06448324b5a2cb Mon Sep 17 00:00:00 2001 From: Xavier Date: Sun, 26 Mar 2017 20:48:29 -0700 Subject: [PATCH 06/33] Converted to .net core --- .../Ch 01. Arrays and Strings.csproj | 70 +---- .../Properties/AssemblyInfo.cs | 35 --- .../Ch 02. Linked Lists.csproj | 70 +---- .../Properties/AssemblyInfo.cs | 35 --- .../Ch 05. Bit Manipulation.csproj | 66 +---- .../Properties/AssemblyInfo.cs | 35 --- .../Ch 10. Sorting and Searching.csproj | 78 +----- .../Properties/AssemblyInfo.cs | 35 --- .../Q10_09_Sorted_Matrix_Search.cs | 2 +- Ch 16. Moderate/Ch 16. Moderate.csproj | 11 + Ch 16. Moderate/Q16_01_Number_Swapper.cs | 24 ++ Introduction/Introduction.csproj | 60 +---- Introduction/Properties/AssemblyInfo.cs | 35 --- ctci.Contracts/Properties/AssemblyInfo.cs | 35 --- ctci.Contracts/ctci.Contracts.csproj | 48 +--- ctci.Library/AssortedMethods.cs | 11 - ctci.Library/Properties/AssemblyInfo.cs | 35 --- ctci.Library/Set.cs | 250 ------------------ ctci.Library/ctci.Library.csproj | 59 +---- ctci.sln | 11 +- ctci/Program.cs | 5 + ctci/Properties/AssemblyInfo.cs | 35 --- ctci/app.config | 6 - ctci/ctci.csproj | 83 +----- 24 files changed, 118 insertions(+), 1016 deletions(-) delete mode 100644 Ch 01. Arrays and Strings/Properties/AssemblyInfo.cs delete mode 100644 Ch 02. Linked Lists/Properties/AssemblyInfo.cs delete mode 100644 Ch 05. Bit Manipulation/Properties/AssemblyInfo.cs delete mode 100644 Ch 10. Sorting and Searching/Properties/AssemblyInfo.cs create mode 100644 Ch 16. Moderate/Ch 16. Moderate.csproj create mode 100644 Ch 16. Moderate/Q16_01_Number_Swapper.cs delete mode 100644 Introduction/Properties/AssemblyInfo.cs delete mode 100644 ctci.Contracts/Properties/AssemblyInfo.cs delete mode 100644 ctci.Library/Properties/AssemblyInfo.cs delete mode 100644 ctci.Library/Set.cs delete mode 100644 ctci/Properties/AssemblyInfo.cs delete mode 100644 ctci/app.config diff --git a/Ch 01. Arrays and Strings/Ch 01. Arrays and Strings.csproj b/Ch 01. Arrays and Strings/Ch 01. Arrays and Strings.csproj index 0846ed1..8ab28a9 100644 --- a/Ch 01. Arrays and Strings/Ch 01. Arrays and Strings.csproj +++ b/Ch 01. Arrays and Strings/Ch 01. Arrays and Strings.csproj @@ -1,69 +1,17 @@ - - - + + - Debug - AnyCPU - {3F2DF0FA-D7A0-479B-B720-3AB7411E9539} - Library - Properties + netcoreapp1.1 Chapter01 - Chapter01 - v4.5.2 - 512 - - - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - false - - - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - false - - - - - - - - - - - - - - {d1b538b9-de81-4fff-93b2-a958ed2ce4da} - ctci.Contracts - - - {8dc982e1-042c-4652-bbc4-cd375223c852} - ctci.Library - - + - + + - + + - - + \ No newline at end of file diff --git a/Ch 01. Arrays and Strings/Properties/AssemblyInfo.cs b/Ch 01. Arrays and Strings/Properties/AssemblyInfo.cs deleted file mode 100644 index a9cb65e..0000000 --- a/Ch 01. Arrays and Strings/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,35 +0,0 @@ -using System.Reflection; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("Chapter01")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("Chapter01")] -[assembly: AssemblyCopyright("Copyright © 2014")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("63b1dab9-60c0-4496-b60a-993d72cd5734")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] \ No newline at end of file diff --git a/Ch 02. Linked Lists/Ch 02. Linked Lists.csproj b/Ch 02. Linked Lists/Ch 02. Linked Lists.csproj index 5b86884..6cb8dba 100644 --- a/Ch 02. Linked Lists/Ch 02. Linked Lists.csproj +++ b/Ch 02. Linked Lists/Ch 02. Linked Lists.csproj @@ -1,69 +1,17 @@ - - - + + - Debug - AnyCPU - {D1ACE913-9486-4CDC-B980-A5F848A67108} - Library - Properties + netcoreapp1.1 Chapter02 - Chapter02 - v4.5.2 - 512 - - - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - false - - - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - false - - - - - - - - - - - - - - {d1b538b9-de81-4fff-93b2-a958ed2ce4da} - ctci.Contracts - - - {8dc982e1-042c-4652-bbc4-cd375223c852} - ctci.Library - - + - + + - + + - - + \ No newline at end of file diff --git a/Ch 02. Linked Lists/Properties/AssemblyInfo.cs b/Ch 02. Linked Lists/Properties/AssemblyInfo.cs deleted file mode 100644 index 5c99774..0000000 --- a/Ch 02. Linked Lists/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,35 +0,0 @@ -using System.Reflection; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("Chapter02")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("Chapter02")] -[assembly: AssemblyCopyright("Copyright © 2014")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("bf4a11b4-3b9e-4a05-bee6-26293010f0d3")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] \ No newline at end of file diff --git a/Ch 05. Bit Manipulation/Ch 05. Bit Manipulation.csproj b/Ch 05. Bit Manipulation/Ch 05. Bit Manipulation.csproj index 230c828..98877a9 100644 --- a/Ch 05. Bit Manipulation/Ch 05. Bit Manipulation.csproj +++ b/Ch 05. Bit Manipulation/Ch 05. Bit Manipulation.csproj @@ -1,65 +1,17 @@ - - - + + - Debug - AnyCPU - {6515F74F-66C6-414D-B5EC-10260AAD473C} - Library - Properties + netcoreapp1.1 Chapter05 - Chapter05 - v4.5.2 - 512 - - - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - false - - - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - false - - - - + - - - - - - - + + - - {d1b538b9-de81-4fff-93b2-a958ed2ce4da} - ctci.Contracts - - - {8dc982e1-042c-4652-bbc4-cd375223c852} - ctci.Library - + + - - + \ No newline at end of file diff --git a/Ch 05. Bit Manipulation/Properties/AssemblyInfo.cs b/Ch 05. Bit Manipulation/Properties/AssemblyInfo.cs deleted file mode 100644 index ee6bde1..0000000 --- a/Ch 05. Bit Manipulation/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,35 +0,0 @@ -using System.Reflection; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("Chapter05")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("Chapter05")] -[assembly: AssemblyCopyright("Copyright © 2014")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("d14f0c87-55fb-4977-a846-49161a82afcb")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] \ No newline at end of file diff --git a/Ch 10. Sorting and Searching/Ch 10. Sorting and Searching.csproj b/Ch 10. Sorting and Searching/Ch 10. Sorting and Searching.csproj index b69508f..d5758af 100644 --- a/Ch 10. Sorting and Searching/Ch 10. Sorting and Searching.csproj +++ b/Ch 10. Sorting and Searching/Ch 10. Sorting and Searching.csproj @@ -1,76 +1,12 @@ - - - + + - Debug - AnyCPU - {90D56A57-CEAD-42F8-A978-BC2D33530E0E} - Library - Properties - Chapter11 - Chapter11 - v4.5.2 - 512 - + netcoreapp1.1 - - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - false - - - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - false - - - - - - - - - - - - - {d1b538b9-de81-4fff-93b2-a958ed2ce4da} - ctci.Contracts - - - {8dc982e1-042c-4652-bbc4-cd375223c852} - ctci.Library - - - - - - - - - - - - - + - + + - - + \ No newline at end of file diff --git a/Ch 10. Sorting and Searching/Properties/AssemblyInfo.cs b/Ch 10. Sorting and Searching/Properties/AssemblyInfo.cs deleted file mode 100644 index 583de65..0000000 --- a/Ch 10. Sorting and Searching/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,35 +0,0 @@ -using System.Reflection; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("Chapter11")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("Chapter11")] -[assembly: AssemblyCopyright("Copyright © 2014")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("8dbacb41-d67f-4771-afe9-3552812539e2")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] \ No newline at end of file diff --git a/Ch 10. Sorting and Searching/Q10_09_Sorted_Matrix_Search.cs b/Ch 10. Sorting and Searching/Q10_09_Sorted_Matrix_Search.cs index 01f4e9b..91973ec 100644 --- a/Ch 10. Sorting and Searching/Q10_09_Sorted_Matrix_Search.cs +++ b/Ch 10. Sorting and Searching/Q10_09_Sorted_Matrix_Search.cs @@ -6,7 +6,7 @@ namespace Chapter10 { public class Q10_09_Sorted_Matrix_Search : Question { - public class Coordinate : ICloneable + public class Coordinate { public int row; public int column; diff --git a/Ch 16. Moderate/Ch 16. Moderate.csproj b/Ch 16. Moderate/Ch 16. Moderate.csproj new file mode 100644 index 0000000..3b25946 --- /dev/null +++ b/Ch 16. Moderate/Ch 16. Moderate.csproj @@ -0,0 +1,11 @@ + + + + netcoreapp1.1 + + + + + + + \ No newline at end of file diff --git a/Ch 16. Moderate/Q16_01_Number_Swapper.cs b/Ch 16. Moderate/Q16_01_Number_Swapper.cs new file mode 100644 index 0000000..d619f9c --- /dev/null +++ b/Ch 16. Moderate/Q16_01_Number_Swapper.cs @@ -0,0 +1,24 @@ +using ctci.Contracts; +using System; + +namespace Chapter_16 +{ + public class Q16_01_Number_Swapper : Question + { + void SwapNumbers(ref int a, ref int b) + { + a ^= b; + b ^= a; + a ^= b; + } + + public override void Run() + { + var a = 5; + var b = 10; + Console.WriteLine($"Before {a} {b}"); + SwapNumbers(ref a, ref b); + Console.WriteLine($"After {a} {b}"); + } + } +} diff --git a/Introduction/Introduction.csproj b/Introduction/Introduction.csproj index 8a6079f..294d446 100644 --- a/Introduction/Introduction.csproj +++ b/Introduction/Introduction.csproj @@ -1,58 +1,16 @@ - - - + + - Debug - AnyCPU - {AF745A68-20A9-4FF4-801C-86A3B0383C49} - Library - Properties - Introduction - Introduction - v4.5.2 - 512 - - - - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - false - - - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - false + netcoreapp1.1 + - - - + + - - {d1b538b9-de81-4fff-93b2-a958ed2ce4da} - ctci.Contracts - - - {8dc982e1-042c-4652-bbc4-cd375223c852} - ctci.Library - + + - - + \ No newline at end of file diff --git a/Introduction/Properties/AssemblyInfo.cs b/Introduction/Properties/AssemblyInfo.cs deleted file mode 100644 index 633e874..0000000 --- a/Introduction/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,35 +0,0 @@ -using System.Reflection; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("Introduction")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("Introduction")] -[assembly: AssemblyCopyright("Copyright © 2014")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("438022e5-7a66-406a-8c79-3d4ecf6938c1")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] \ No newline at end of file diff --git a/ctci.Contracts/Properties/AssemblyInfo.cs b/ctci.Contracts/Properties/AssemblyInfo.cs deleted file mode 100644 index 9aecad2..0000000 --- a/ctci.Contracts/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,35 +0,0 @@ -using System.Reflection; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("ctci.Contracts")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("ctci.Contracts")] -[assembly: AssemblyCopyright("Copyright © 2014")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("5b51cf2f-db66-4f60-8d35-87bfd33528cb")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] \ No newline at end of file diff --git a/ctci.Contracts/ctci.Contracts.csproj b/ctci.Contracts/ctci.Contracts.csproj index b1abece..b57c3c8 100644 --- a/ctci.Contracts/ctci.Contracts.csproj +++ b/ctci.Contracts/ctci.Contracts.csproj @@ -1,47 +1,11 @@ - - - + + - Debug - AnyCPU - {D1B538B9-DE81-4FFF-93B2-A958ED2CE4DA} - Library - Properties - ctci.Contracts - ctci.Contracts - v4.5.2 - 512 - - - - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - false - - - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - false + netcoreapp1.1 + - - + - - + \ No newline at end of file diff --git a/ctci.Library/AssortedMethods.cs b/ctci.Library/AssortedMethods.cs index f96df6c..cce1c35 100644 --- a/ctci.Library/AssortedMethods.cs +++ b/ctci.Library/AssortedMethods.cs @@ -1,6 +1,5 @@ using System; using System.Collections.Generic; -using System.Drawing; using System.Text; namespace ctci.Library @@ -193,16 +192,6 @@ public static string CharArrayToString(char[] array) return buffer.ToString(); } - public static string ListOfPointsToString(List list) - { - StringBuilder buffer = new StringBuilder(); - foreach (Point p in list) - { - buffer.Append("(" + p.X + "," + p.Y + ")"); - } - return buffer.ToString(); - } - public static TreeNode RandomBst(int N, int min, int max) { int d = RandomIntInRange(min, max); diff --git a/ctci.Library/Properties/AssemblyInfo.cs b/ctci.Library/Properties/AssemblyInfo.cs deleted file mode 100644 index d497f7a..0000000 --- a/ctci.Library/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,35 +0,0 @@ -using System.Reflection; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("ctci.Library")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("ctci.Library")] -[assembly: AssemblyCopyright("Copyright © 2014")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("00955b3a-9889-4bf1-8f71-82fa9668fb44")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] \ No newline at end of file diff --git a/ctci.Library/Set.cs b/ctci.Library/Set.cs deleted file mode 100644 index 1e8fddb..0000000 --- a/ctci.Library/Set.cs +++ /dev/null @@ -1,250 +0,0 @@ -using System; -using System.Collections; -using System.Collections.Generic; -using System.Runtime.Serialization; - -namespace ctci.Library -{ - public class Set : ICollection, ISerializable, IDeserializationCallback - { - private readonly Dictionary _dictionary; - - public Set() - { - _dictionary = new Dictionary(); - } - - public Set(IEnumerable items) : - this() - { - if (items == null) - { - return; - } - - foreach (T item in items) - { - Add(item); - } - } - - public Set NullSet { get { return new Set(); } } - - public Set Union(Set set) - { - Set unionSet = new Set(this); - - if (null == set) - { - return unionSet; - } - - foreach (T item in set) - { - if (unionSet.Contains(item)) - { - continue; - } - - unionSet.Add(item); - } - - return unionSet; - } - - public Set Subtract(Set set) - { - Set subtractSet = new Set(this); - - if (null == set) - { - return subtractSet; - } - - foreach (T item in set) - { - if (!subtractSet.Contains(item)) - { - continue; - } - - subtractSet._dictionary.Remove(item); - } - - return subtractSet; - } - - public bool IsSubsetOf(Set set) - { - Set setToCompare = set ?? NullSet; - - foreach (T item in this) - { - if (!setToCompare.Contains(item)) - { - return false; - } - } - - return true; - } - - public Set Intersection(Set set) - { - Set intersectionSet = NullSet; - - if (null == set) - { - return intersectionSet; - } - - foreach (T item in this) - { - if (!set.Contains(item)) - { - continue; - } - - intersectionSet.Add(item); - } - - foreach (T item in set) - { - if (!Contains(item) || intersectionSet.Contains(item)) - { - continue; - } - - intersectionSet.Add(item); - } - - return intersectionSet; - } - - public bool IsProperSubsetOf(Set set) - { - Set setToCompare = set ?? NullSet; - - // A is a proper subset of a if the b is a subset of a and a != b - return (IsSubsetOf(setToCompare) && !setToCompare.IsSubsetOf(this)); - } - - public bool IsSupersetOf(Set set) - { - Set setToCompare = set ?? NullSet; - - foreach (T item in setToCompare) - { - if (!Contains(item)) - { - return false; - } - } - - return true; - } - - public bool IsProperSupersetOf(Set set) - { - Set setToCompare = set ?? NullSet; - - // B is a proper superset of a if b is a superset of a and a != b - return (IsSupersetOf(setToCompare) && !setToCompare.IsSupersetOf(this)); - } - - public List ToList() - { - return new List(this); - } - - #region ICollection - - public void Add(T item) - { - if (null == item) - { - throw new ArgumentNullException("item"); - } - - _dictionary[item] = null; - } - - public void Clear() - { - _dictionary.Clear(); - } - - public bool Contains(T item) - { - return _dictionary.ContainsKey(item); - } - - public void CopyTo(T[] array, int arrayIndex) - { - if (array == null) throw new ArgumentNullException("array"); - if (arrayIndex < 0 || arrayIndex >= array.Length || arrayIndex >= Count) - { - throw new ArgumentOutOfRangeException("arrayIndex"); - } - - _dictionary.Keys.CopyTo(array, arrayIndex); - } - - public bool Remove(T item) - { - return _dictionary.Remove(item); - } - - public int Count - { - get { return _dictionary.Count; } - } - - public bool IsReadOnly - { - get - { - return false; - } - } - - #endregion ICollection - - #region ISerializable - - public void GetObjectData(SerializationInfo info, StreamingContext context) - { - if (info == null) - { - throw new ArgumentNullException("info"); - } - - _dictionary.GetObjectData(info, context); - } - - #endregion ISerializable - - #region IDeserializationCallback - - public void OnDeserialization(object sender) - { - _dictionary.OnDeserialization(sender); - } - - #endregion IDeserializationCallback - - #region IEnumerable - - public IEnumerator GetEnumerator() - { - return _dictionary.Keys.GetEnumerator(); - } - - IEnumerator IEnumerable.GetEnumerator() - { - return GetEnumerator(); - } - - #endregion IEnumerable - } -} \ No newline at end of file diff --git a/ctci.Library/ctci.Library.csproj b/ctci.Library/ctci.Library.csproj index ad62727..b57c3c8 100644 --- a/ctci.Library/ctci.Library.csproj +++ b/ctci.Library/ctci.Library.csproj @@ -1,58 +1,11 @@ - - - + + - Debug - AnyCPU - {8DC982E1-042C-4652-BBC4-CD375223C852} - Library - Properties - ctci.Library - ctci.Library - v4.5.2 - 512 - + netcoreapp1.1 - - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - false - - - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - false - - - - - + - - - - - - - - - + - - + \ No newline at end of file diff --git a/ctci.sln b/ctci.sln index df6c323..0425b2d 100644 --- a/ctci.sln +++ b/ctci.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 14 -VisualStudioVersion = 14.0.24720.0 +# Visual Studio 15 +VisualStudioVersion = 15.0.26228.4 MinimumVisualStudioVersion = 10.0.40219.1 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ctci", "ctci\ctci.csproj", "{F7867FE4-E80B-44DD-9666-C82E6D401B8A}" EndProject @@ -23,6 +23,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ch 02. Linked Lists", "Ch 0 EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ch 10. Sorting and Searching", "Ch 10. Sorting and Searching\Ch 10. Sorting and Searching.csproj", "{90D56A57-CEAD-42F8-A978-BC2D33530E0E}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ch 16. Moderate", "Ch 16. Moderate\Ch 16. Moderate.csproj", "{AE0D044B-1AE9-430F-B05D-ADAC72C407B8}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -61,6 +63,10 @@ Global {90D56A57-CEAD-42F8-A978-BC2D33530E0E}.Debug|Any CPU.Build.0 = Debug|Any CPU {90D56A57-CEAD-42F8-A978-BC2D33530E0E}.Release|Any CPU.ActiveCfg = Release|Any CPU {90D56A57-CEAD-42F8-A978-BC2D33530E0E}.Release|Any CPU.Build.0 = Release|Any CPU + {AE0D044B-1AE9-430F-B05D-ADAC72C407B8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {AE0D044B-1AE9-430F-B05D-ADAC72C407B8}.Debug|Any CPU.Build.0 = Debug|Any CPU + {AE0D044B-1AE9-430F-B05D-ADAC72C407B8}.Release|Any CPU.ActiveCfg = Release|Any CPU + {AE0D044B-1AE9-430F-B05D-ADAC72C407B8}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -74,5 +80,6 @@ Global {6515F74F-66C6-414D-B5EC-10260AAD473C} = {8E563D72-A200-4BB7-8AB8-A93BEED3A5B7} {D1ACE913-9486-4CDC-B980-A5F848A67108} = {8E563D72-A200-4BB7-8AB8-A93BEED3A5B7} {90D56A57-CEAD-42F8-A978-BC2D33530E0E} = {8E563D72-A200-4BB7-8AB8-A93BEED3A5B7} + {AE0D044B-1AE9-430F-B05D-ADAC72C407B8} = {8E563D72-A200-4BB7-8AB8-A93BEED3A5B7} EndGlobalSection EndGlobal diff --git a/ctci/Program.cs b/ctci/Program.cs index 84baebf..9cea342 100644 --- a/ctci/Program.cs +++ b/ctci/Program.cs @@ -2,6 +2,7 @@ using Chapter02; using Chapter05; using Chapter10; +using Chapter_16; using ctci.Contracts; using Introduction; using System; @@ -62,6 +63,10 @@ private static void Main(string[] args) new Q10_11_Peaks_and_Valleys() }, + new Question[] + { + new Q16_01_Number_Swapper() + } }; diff --git a/ctci/Properties/AssemblyInfo.cs b/ctci/Properties/AssemblyInfo.cs deleted file mode 100644 index 297c0aa..0000000 --- a/ctci/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,35 +0,0 @@ -using System.Reflection; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("ctci")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("ctci")] -[assembly: AssemblyCopyright("Copyright © 2014")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("9ce652f6-580e-4b47-9e63-441c7038cfdb")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] \ No newline at end of file diff --git a/ctci/app.config b/ctci/app.config deleted file mode 100644 index 4fe5f06..0000000 --- a/ctci/app.config +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/ctci/ctci.csproj b/ctci/ctci.csproj index 38ef380..2a7d047 100644 --- a/ctci/ctci.csproj +++ b/ctci/ctci.csproj @@ -1,78 +1,21 @@ - - - + + - Debug - AnyCPU - {F7867FE4-E80B-44DD-9666-C82E6D401B8A} Exe - Properties - ctci - ctci - v4.5.2 - 512 - + netcoreapp1.1 - - AnyCPU - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - false - - - AnyCPU - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - false - - - - - + - - {3f2df0fa-d7a0-479b-b720-3ab7411e9539} - Ch 01. Arrays and Strings - - - {d1ace913-9486-4cdc-b980-a5f848a67108} - Ch 02. Linked Lists - - - {6515f74f-66c6-414d-b5ec-10260aad473c} - Ch 05. Bit Manipulation - - - {90d56a57-cead-42f8-a978-bc2d33530e0e} - Ch 10. Sorting and Searching - - - {d1b538b9-de81-4fff-93b2-a958ed2ce4da} - ctci.Contracts - - - {af745a68-20a9-4ff4-801c-86a3b0383c49} - Introduction - + + - + + + + + + - - + \ No newline at end of file From f3463f365a4e7720105740bef1d9103450e779e6 Mon Sep 17 00:00:00 2001 From: Xavier Date: Mon, 24 Apr 2017 16:38:23 -0700 Subject: [PATCH 07/33] Check balanced tree --- Ch 04. Trees/Ch 04. Trees.csproj | 12 ++ Ch 04. Trees/Q4_4_CheckBalanced.cs | 40 +++++++ Ch 16. Moderate/Q16_01_Number_Swapper.cs | 2 +- ctci.Library/BTreePrinter.cs | 143 +++++++++++------------ ctci.Library/TreeNode.cs | 2 +- ctci.sln | 7 ++ ctci/Program.cs | 8 +- ctci/ctci.csproj | 1 + 8 files changed, 140 insertions(+), 75 deletions(-) create mode 100644 Ch 04. Trees/Ch 04. Trees.csproj create mode 100644 Ch 04. Trees/Q4_4_CheckBalanced.cs diff --git a/Ch 04. Trees/Ch 04. Trees.csproj b/Ch 04. Trees/Ch 04. Trees.csproj new file mode 100644 index 0000000..b01a999 --- /dev/null +++ b/Ch 04. Trees/Ch 04. Trees.csproj @@ -0,0 +1,12 @@ + + + + netcoreapp1.1 + + + + + + + + \ No newline at end of file diff --git a/Ch 04. Trees/Q4_4_CheckBalanced.cs b/Ch 04. Trees/Q4_4_CheckBalanced.cs new file mode 100644 index 0000000..9554423 --- /dev/null +++ b/Ch 04. Trees/Q4_4_CheckBalanced.cs @@ -0,0 +1,40 @@ +using ctci.Contracts; +using ctci.Library; +using System; + +namespace Chapter04 +{ + public class Q4_4_CheckBalanced: Question + { + public static bool IsBalanced(TreeNode root) + { + if (root == null) return true; + var difference = Math.Abs(Height(root.Left) - Height(root.Right)); + if (difference > 1) return false; + else return IsBalanced(root.Left) && IsBalanced(root.Right); + } + + public static int Height(TreeNode root, int height = 0) + { + if (root == null) return height; + return Math.Max(Height(root.Left, height), Height(root.Right, height)) + 1; + } + + public override void Run() + { + var root = new TreeNode(2); + root.SetLeftChild(new TreeNode(1)); + root.SetRightChild(new TreeNode(3)); + PrintTree(root); + } + + private static void PrintTree(TreeNode root) + { + BTreePrinter.Print(root); + if (IsBalanced(root)) + Console.WriteLine("Tree is balanced"); + else + Console.WriteLine("Tree is not balalnced"); + } + } +} \ No newline at end of file diff --git a/Ch 16. Moderate/Q16_01_Number_Swapper.cs b/Ch 16. Moderate/Q16_01_Number_Swapper.cs index d619f9c..ef685ed 100644 --- a/Ch 16. Moderate/Q16_01_Number_Swapper.cs +++ b/Ch 16. Moderate/Q16_01_Number_Swapper.cs @@ -1,7 +1,7 @@ using ctci.Contracts; using System; -namespace Chapter_16 +namespace Chapter16 { public class Q16_01_Number_Swapper : Question { diff --git a/ctci.Library/BTreePrinter.cs b/ctci.Library/BTreePrinter.cs index a6872ae..06eca86 100644 --- a/ctci.Library/BTreePrinter.cs +++ b/ctci.Library/BTreePrinter.cs @@ -3,104 +3,103 @@ namespace ctci.Library { - public class BTreePrinter + public static class BTreePrinter { - public static void PrintNode(TreeNode root) + class NodeInfo { - int maxLevel = BTreePrinter.MaxLevel(root); - - PrintNodeInternal(new List() { root }, 1, maxLevel); + public TreeNode Node; + public string Text; + public int StartPos; + public int Size { get { return Text.Length; } } + public int EndPos { get { return StartPos + Size; } set { StartPos = value - Size; } } + public NodeInfo Parent, Left, Right; } - private static void PrintNodeInternal(List nodes, int level, int maxLevel) + public static void Print(this TreeNode root, int topMargin = 2, int leftMargin = 2) { - if (nodes.Count == 0 || BTreePrinter.IsAllElementsNull(nodes)) - return; - - int floor = maxLevel - level; - int endgeLines = (int)Math.Pow(2, (Math.Max(floor - 1, 0))); - int firstSpaces = (int)Math.Pow(2, (floor)) - 1; - int betweenSpaces = (int)Math.Pow(2, (floor + 1)) - 1; - - BTreePrinter.PrintWhitespaces(firstSpaces); - - List newNodes = new List(); - foreach (TreeNode node in nodes) + if (root == null) return; + int rootTop = Console.CursorTop + topMargin; + var last = new List(); + var next = root; + for (int level = 0; next != null; level++) { - if (node != null) + var item = new NodeInfo { Node = next, Text = next.Data.ToString(" 0 ") }; + if (level < last.Count) { - Console.Write(node.Data); - newNodes.Add(node.Left); - newNodes.Add(node.Right); + item.StartPos = last[level].EndPos + 1; + last[level] = item; } - else { - newNodes.Add(null); - newNodes.Add(null); - Console.Write(" "); + else + { + item.StartPos = leftMargin; + last.Add(item); } - - BTreePrinter.PrintWhitespaces(betweenSpaces); - } - Console.WriteLine(); - - for (int i = 1; i <= endgeLines; i++) - { - for (int j = 0; j < nodes.Count; j++) + if (level > 0) { - BTreePrinter.PrintWhitespaces(firstSpaces - i); - if (nodes[j] == null) + item.Parent = last[level - 1]; + if (next == item.Parent.Node.Left) { - BTreePrinter.PrintWhitespaces(endgeLines + endgeLines + i + 1); - continue; + item.Parent.Left = item; + item.EndPos = Math.Max(item.EndPos, item.Parent.StartPos); } - - if (nodes[j].Left != null) - Console.Write("/"); else - BTreePrinter.PrintWhitespaces(1); - - BTreePrinter.PrintWhitespaces(i + i - 1); - - if (nodes[j].Right != null) - Console.Write("\\"); + { + item.Parent.Right = item; + item.StartPos = Math.Max(item.StartPos, item.Parent.EndPos); + } + } + next = next.Left ?? next.Right; + for (; next == null; item = item.Parent) + { + Print(item, rootTop + 2 * level); + if (--level < 0) break; + if (item == item.Parent.Left) + { + item.Parent.StartPos = item.EndPos; + next = item.Parent.Node.Right; + } else - BTreePrinter.PrintWhitespaces(1); - - BTreePrinter.PrintWhitespaces(endgeLines + endgeLines - i); + { + if (item.Parent.Left == null) + item.Parent.EndPos = item.StartPos; + else + item.Parent.StartPos += (item.StartPos - item.Parent.EndPos) / 2; + } } - - Console.WriteLine(); } - - PrintNodeInternal(newNodes, level + 1, maxLevel); + Console.SetCursorPosition(0, rootTop + 2 * last.Count - 1); } - private static void PrintWhitespaces(int count) + private static void Print(NodeInfo item, int top) { - string padding = string.Format("{0}", count); - padding = "{0," + padding + "}"; - Console.Write(padding, " "); - //for (int i = 0; i < count; i++) - // Console.Write(" "); + SwapColors(); + Print(item.Text, top, item.StartPos); + SwapColors(); + if (item.Left != null) + PrintLink(top + 1, "┌", "┘", item.Left.StartPos + item.Left.Size / 2, item.StartPos); + if (item.Right != null) + PrintLink(top + 1, "└", "┐", item.EndPos - 1, item.Right.StartPos + item.Right.Size / 2); } - private static int MaxLevel(TreeNode node) + private static void PrintLink(int top, string start, string end, int startPos, int endPos) { - if (node == null) - return 0; - - return Math.Max(BTreePrinter.MaxLevel(node.Left), BTreePrinter.MaxLevel(node.Right)) + 1; + Print(start, top, startPos); + Print("─", top, startPos + 1, endPos); + Print(end, top, endPos); } - private static bool IsAllElementsNull(IEnumerable list) + private static void Print(string s, int top, int left, int right = -1) { - foreach (object o in list) - { - if (o != null) - return false; - } + Console.SetCursorPosition(left, top); + if (right < 0) right = left + s.Length; + while (Console.CursorLeft < right) Console.Write(s); + } - return true; + private static void SwapColors() + { + var color = Console.ForegroundColor; + Console.ForegroundColor = Console.BackgroundColor; + Console.BackgroundColor = color; } } } \ No newline at end of file diff --git a/ctci.Library/TreeNode.cs b/ctci.Library/TreeNode.cs index 4dee8f0..c8f4412 100644 --- a/ctci.Library/TreeNode.cs +++ b/ctci.Library/TreeNode.cs @@ -135,7 +135,7 @@ public static TreeNode CreateMinimalBst(int[] array) public void Print() { - BTreePrinter.PrintNode(this); + BTreePrinter.Print(this); } } } \ No newline at end of file diff --git a/ctci.sln b/ctci.sln index 0425b2d..a5422bd 100644 --- a/ctci.sln +++ b/ctci.sln @@ -25,6 +25,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ch 10. Sorting and Searchin EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ch 16. Moderate", "Ch 16. Moderate\Ch 16. Moderate.csproj", "{AE0D044B-1AE9-430F-B05D-ADAC72C407B8}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ch 04. Trees", "Ch 04. Trees\Ch 04. Trees.csproj", "{AF583937-1A80-407F-B683-3FEED7F3BC16}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -67,6 +69,10 @@ Global {AE0D044B-1AE9-430F-B05D-ADAC72C407B8}.Debug|Any CPU.Build.0 = Debug|Any CPU {AE0D044B-1AE9-430F-B05D-ADAC72C407B8}.Release|Any CPU.ActiveCfg = Release|Any CPU {AE0D044B-1AE9-430F-B05D-ADAC72C407B8}.Release|Any CPU.Build.0 = Release|Any CPU + {AF583937-1A80-407F-B683-3FEED7F3BC16}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {AF583937-1A80-407F-B683-3FEED7F3BC16}.Debug|Any CPU.Build.0 = Debug|Any CPU + {AF583937-1A80-407F-B683-3FEED7F3BC16}.Release|Any CPU.ActiveCfg = Release|Any CPU + {AF583937-1A80-407F-B683-3FEED7F3BC16}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -81,5 +87,6 @@ Global {D1ACE913-9486-4CDC-B980-A5F848A67108} = {8E563D72-A200-4BB7-8AB8-A93BEED3A5B7} {90D56A57-CEAD-42F8-A978-BC2D33530E0E} = {8E563D72-A200-4BB7-8AB8-A93BEED3A5B7} {AE0D044B-1AE9-430F-B05D-ADAC72C407B8} = {8E563D72-A200-4BB7-8AB8-A93BEED3A5B7} + {AF583937-1A80-407F-B683-3FEED7F3BC16} = {8E563D72-A200-4BB7-8AB8-A93BEED3A5B7} EndGlobalSection EndGlobal diff --git a/ctci/Program.cs b/ctci/Program.cs index 9cea342..785b2b7 100644 --- a/ctci/Program.cs +++ b/ctci/Program.cs @@ -1,8 +1,9 @@ using Chapter01; using Chapter02; +using Chapter04; using Chapter05; using Chapter10; -using Chapter_16; +using Chapter16; using ctci.Contracts; using Introduction; using System; @@ -13,6 +14,7 @@ internal class Program { private static void Main(string[] args) { + Console.OutputEncoding = System.Text.Encoding.Unicode; var chapters = new[] { // Intro @@ -42,6 +44,10 @@ private static void Main(string[] args) new Q2_08_Loop_Detection() }, + new Question[] { + new Q4_4_CheckBalanced(), + }, + new Question[] { new Q5_01_Insertion(), new Q5_02_Binary_to_String(), diff --git a/ctci/ctci.csproj b/ctci/ctci.csproj index 2a7d047..20fcae9 100644 --- a/ctci/ctci.csproj +++ b/ctci/ctci.csproj @@ -12,6 +12,7 @@ + From bfaaf76d2f00f961ff5ae51c728bc08788407b0e Mon Sep 17 00:00:00 2001 From: Xavier Date: Mon, 24 Apr 2017 17:33:03 -0700 Subject: [PATCH 08/33] 16.19 Pond size --- Ch 16. Moderate/Q16_19_Pond_Sizes.cs | 84 ++++++++++++++++++++++++++++ ctci/Program.cs | 3 +- 2 files changed, 86 insertions(+), 1 deletion(-) create mode 100644 Ch 16. Moderate/Q16_19_Pond_Sizes.cs diff --git a/Ch 16. Moderate/Q16_19_Pond_Sizes.cs b/Ch 16. Moderate/Q16_19_Pond_Sizes.cs new file mode 100644 index 0000000..3856b8f --- /dev/null +++ b/Ch 16. Moderate/Q16_19_Pond_Sizes.cs @@ -0,0 +1,84 @@ +using ctci.Contracts; +using System; +using System.Collections.Generic; + +namespace Chapter16 +{ + static class MatrixExtentsions + { + static public int Height(this char[,] matrix) + { + return matrix.GetLength(0); + } + static public int Width(this char[,] matrix) + { + return matrix.GetLength(1); + } + + static public bool IsOutOfBounds(this char[,] matrix, int row, int column) + { + if (row < 0 || row >= matrix.Height()) return true; + if (column < 0 || column >= matrix.Width()) return true; + return false; + } + } + public class Q16_19_Pond_Sizes : Question + { + + public override void Run() + { + var matrix = new char[,] + { + {'w','h','l','w'}, + {'w','l','w','1'}, + {'l','l','w','l'}, + {'w','l','w','l'}, + }; + + PrintMatrix(matrix); + + var sizes = GetSizes(matrix, 'w'); + Console.WriteLine("Found w"); + foreach (var size in sizes) + Console.WriteLine(size); + } + + public IList GetSizes(char[,] matrix, char type) + { + var sizes = new List(); + var visited = new bool[matrix.Height(), matrix.Width()]; + for (var r = 0; r < matrix.Height(); r++) + { + for (var c = 0; c < matrix.Width(); c++) + { + if (matrix[r, c] == type && !visited[r,c]) + sizes.Add(GetSize(matrix, visited, r, c, type)); + } + } + return sizes; + } + + private int GetSize(char[,] matrix, bool[,] visited, int r, int c, char type) + { + if (matrix.IsOutOfBounds(r, c)) return 0; + if (visited[r, c]) return 0; + if (matrix[r, c] != type) return 0; + visited[r, c] = true; + int size = 1; + for (var dr = -1; dr < 2; dr++) + for (var dc = -1; dc < 2; dc++) + size += GetSize(matrix, visited, r + dr, c + dc, type); + return size; + } + + private void PrintMatrix(char[,] matrix) + { + for (var r = 0; r < matrix.Height(); r++) + { + for (var c = 0; c < matrix.Width(); c++) + Console.Write(matrix[r, c]); + Console.WriteLine(); + } + } + } +} diff --git a/ctci/Program.cs b/ctci/Program.cs index 785b2b7..527829d 100644 --- a/ctci/Program.cs +++ b/ctci/Program.cs @@ -71,7 +71,8 @@ private static void Main(string[] args) new Question[] { - new Q16_01_Number_Swapper() + new Q16_01_Number_Swapper(), + new Q16_19_Pond_Sizes() } }; From 3a14a9a4eef7d9d565cb50856c300db2b0d26922 Mon Sep 17 00:00:00 2001 From: Xavier Date: Tue, 25 Apr 2017 12:37:54 -0700 Subject: [PATCH 09/33] Create Minimal BST from Sorted Unique Array --- ...2_CreateMinimalBSTfromSortedUniqueArray.cs | 32 +++++++++++++++++++ ctci/Program.cs | 3 +- 2 files changed, 34 insertions(+), 1 deletion(-) create mode 100644 Ch 04. Trees/Q4_2_CreateMinimalBSTfromSortedUniqueArray.cs diff --git a/Ch 04. Trees/Q4_2_CreateMinimalBSTfromSortedUniqueArray.cs b/Ch 04. Trees/Q4_2_CreateMinimalBSTfromSortedUniqueArray.cs new file mode 100644 index 0000000..08e7b3c --- /dev/null +++ b/Ch 04. Trees/Q4_2_CreateMinimalBSTfromSortedUniqueArray.cs @@ -0,0 +1,32 @@ +using ctci.Contracts; +using ctci.Library; +using System; + +namespace Chapter04 +{ + public class Q4_2_CreateMinimalBSTfromSortedUniqueArray: Question + { + public static TreeNode Create(int[] sortedArray) + { + return Create(sortedArray, 0, sortedArray.Length - 1); + } + + private static TreeNode Create(int[] sortedArray, int left, int right) + { + if (left > right) return null; + var mid = left + (right - left) / 2; + var treeNode = new TreeNode(sortedArray[mid]); + treeNode.SetLeftChild(Create(sortedArray, left, mid - 1)); + treeNode.SetRightChild(Create(sortedArray, mid + 1, right)); + return treeNode; + } + + + public override void Run() + { + var sortedArray = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; + var root = Create(sortedArray); + BTreePrinter.Print(root); + } + } +} \ No newline at end of file diff --git a/ctci/Program.cs b/ctci/Program.cs index 527829d..8db4748 100644 --- a/ctci/Program.cs +++ b/ctci/Program.cs @@ -45,7 +45,8 @@ private static void Main(string[] args) }, new Question[] { - new Q4_4_CheckBalanced(), + new Q4_2_CreateMinimalBSTfromSortedUniqueArray(), + new Q4_4_CheckBalanced() }, new Question[] { From 58d964d91c3d3934b74bbd6401f472cf3deec14a Mon Sep 17 00:00:00 2001 From: Xavier Date: Tue, 25 Apr 2017 16:18:47 -0700 Subject: [PATCH 10/33] Replace value In Immutable Tree --- Ch 04. Trees/ReplaceNodeInImmutableTree.cs | 40 ++++++++++++++++++++++ ctci.Library/TreeNode.cs | 9 +++++ ctci/Program.cs | 3 +- 3 files changed, 51 insertions(+), 1 deletion(-) create mode 100644 Ch 04. Trees/ReplaceNodeInImmutableTree.cs diff --git a/Ch 04. Trees/ReplaceNodeInImmutableTree.cs b/Ch 04. Trees/ReplaceNodeInImmutableTree.cs new file mode 100644 index 0000000..7419dcf --- /dev/null +++ b/Ch 04. Trees/ReplaceNodeInImmutableTree.cs @@ -0,0 +1,40 @@ +using ctci.Contracts; +using ctci.Library; +using System; + +namespace Chapter04 +{ + static class TreeNodeExtension + { + static public TreeNode Replace(this TreeNode node, int value) + { + if (node == null) return null; + var newNode = new TreeNode(node); + newNode.Data = value; + TreeNode newParent = newNode; + while (node.Parent != null) + { + newParent = new TreeNode(node.Parent); + newNode.Parent = newParent; + if (newParent.Left == node) + newParent.Left = newNode; + if (newParent.Right == node) + newParent.Right = newNode; + node = node.Parent; + newNode = newParent; + } + return newParent; + } + } + public class ReplaceNodeInImmutableTree : Question + { + public override void Run() + { + var tree = Q4_2_CreateMinimalBSTfromSortedUniqueArray.Create(new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }); + var nodeToReplace = tree.Find(6); + TreeNode newTree = nodeToReplace.Replace(11); + BTreePrinter.Print(tree); + BTreePrinter.Print(newTree); + } + } +} \ No newline at end of file diff --git a/ctci.Library/TreeNode.cs b/ctci.Library/TreeNode.cs index c8f4412..92d6a1f 100644 --- a/ctci.Library/TreeNode.cs +++ b/ctci.Library/TreeNode.cs @@ -18,6 +18,15 @@ public TreeNode(int data) Size = 1; } + public TreeNode(TreeNode node) + { + Data = node.Data; + Size = node.Size; + Left = node.Left; + Right = node.Right; + Parent = node.Parent; + } + public void SetLeftChild(TreeNode left) { Left = left; diff --git a/ctci/Program.cs b/ctci/Program.cs index 8db4748..87ec6f3 100644 --- a/ctci/Program.cs +++ b/ctci/Program.cs @@ -46,7 +46,8 @@ private static void Main(string[] args) new Question[] { new Q4_2_CreateMinimalBSTfromSortedUniqueArray(), - new Q4_4_CheckBalanced() + new Q4_4_CheckBalanced(), + new ReplaceNodeInImmutableTree() }, new Question[] { From 1e72225a8180aef8b07c01fddf58550b96b133ca Mon Sep 17 00:00:00 2001 From: Xavier Date: Wed, 26 Apr 2017 12:33:51 -0700 Subject: [PATCH 11/33] Boggle --- Ch 16. Moderate/Boggle.cs | 65 ++++++++++++++++++++++++++ Ch 16. Moderate/Ch 16. Moderate.csproj | 1 + Ch 16. Moderate/Q16_19_Pond_Sizes.cs | 22 ++++----- ctci.Library/AssortedMethods.cs | 1 + ctci.Library/Trie.cs | 1 + ctci/Program.cs | 3 +- 6 files changed, 81 insertions(+), 12 deletions(-) create mode 100644 Ch 16. Moderate/Boggle.cs diff --git a/Ch 16. Moderate/Boggle.cs b/Ch 16. Moderate/Boggle.cs new file mode 100644 index 0000000..ece5b77 --- /dev/null +++ b/Ch 16. Moderate/Boggle.cs @@ -0,0 +1,65 @@ +using ctci.Contracts; +using ctci.Library; +using System; +using System.Collections.Generic; +using System.Linq; + +namespace Chapter16 +{ + public class Boggle : Question + { + + public override void Run() + { + // become, bee, seem, certain, top + var matrix = new char[,] + { + {'b','c','e','p'}, + {'e','o','r','o'}, + {'e','m','t','n'}, + {'s','e','a','i'}, + }; + + matrix.PrintMatrix(); + var trie = AssortedMethods.GetTrieDictionary(); + var list = Solve(matrix, trie.Root); + Console.WriteLine("Words found"); + foreach (var word in list) + Console.Write($"{word}, "); + Console.WriteLine(); + } + + public IList Solve(char[,] matrix, TrieNode trie) + { + var words = new HashSet(); + var visited = new bool[matrix.Height(), matrix.Width()]; + for (var r = 0; r < matrix.Height(); r++) + for (var c = 0; c < matrix.Width(); c++) + { + Solve("", matrix, visited, r, c, trie, words); + } + return words.ToList(); + } + + private void Solve(string prefix, char[,] matrix, bool[,] visited, int row, int column, TrieNode trie, HashSet words) + { + if (row < 0 || row >= matrix.Height()) return; + if (column < 0 || column >= matrix.Width()) return; + if (visited[row, column]) return; + + if (trie.Terminates) words.Add(prefix); + var trieChild = trie.GetChild(matrix[row, column]); + if (trieChild == null) return; + + visited[row, column] = true; + prefix += matrix[row, column]; + for (var dr = -1; dr <= 1; dr++) + for(var dc = -1; dc <= 1; dc++) + { + Solve(prefix, matrix, visited, row + dr, column + dc, trieChild, words); + } + visited[row, column] = false; + } + } +} + \ No newline at end of file diff --git a/Ch 16. Moderate/Ch 16. Moderate.csproj b/Ch 16. Moderate/Ch 16. Moderate.csproj index 3b25946..b01a999 100644 --- a/Ch 16. Moderate/Ch 16. Moderate.csproj +++ b/Ch 16. Moderate/Ch 16. Moderate.csproj @@ -6,6 +6,7 @@ + \ No newline at end of file diff --git a/Ch 16. Moderate/Q16_19_Pond_Sizes.cs b/Ch 16. Moderate/Q16_19_Pond_Sizes.cs index 3856b8f..35dce09 100644 --- a/Ch 16. Moderate/Q16_19_Pond_Sizes.cs +++ b/Ch 16. Moderate/Q16_19_Pond_Sizes.cs @@ -21,6 +21,16 @@ static public bool IsOutOfBounds(this char[,] matrix, int row, int column) if (column < 0 || column >= matrix.Width()) return true; return false; } + + static public void PrintMatrix(this char[,] matrix) + { + for (var r = 0; r < matrix.Height(); r++) + { + for (var c = 0; c < matrix.Width(); c++) + Console.Write(matrix[r, c]); + Console.WriteLine(); + } + } } public class Q16_19_Pond_Sizes : Question { @@ -35,7 +45,7 @@ public override void Run() {'w','l','w','l'}, }; - PrintMatrix(matrix); + matrix.PrintMatrix(); var sizes = GetSizes(matrix, 'w'); Console.WriteLine("Found w"); @@ -70,15 +80,5 @@ private int GetSize(char[,] matrix, bool[,] visited, int r, int c, char type) size += GetSize(matrix, visited, r + dr, c + dc, type); return size; } - - private void PrintMatrix(char[,] matrix) - { - for (var r = 0; r < matrix.Height(); r++) - { - for (var c = 0; c < matrix.Width(); c++) - Console.Write(matrix[r, c]); - Console.WriteLine(); - } - } } } diff --git a/ctci.Library/AssortedMethods.cs b/ctci.Library/AssortedMethods.cs index cce1c35..2d6ad0a 100644 --- a/ctci.Library/AssortedMethods.cs +++ b/ctci.Library/AssortedMethods.cs @@ -333,6 +333,7 @@ public static string[] GetListOfWords() "who", "him", "been", + "bee", "has", "more", "if", diff --git a/ctci.Library/Trie.cs b/ctci.Library/Trie.cs index 82bc38f..4157080 100644 --- a/ctci.Library/Trie.cs +++ b/ctci.Library/Trie.cs @@ -8,6 +8,7 @@ public class Trie // The root of this trie. private readonly TrieNode _root; + public TrieNode Root { get { return _root; } } /* Takes a list of strings as an argument, and constructs a trie that stores these strings. */ public Trie(List list) diff --git a/ctci/Program.cs b/ctci/Program.cs index 87ec6f3..4688570 100644 --- a/ctci/Program.cs +++ b/ctci/Program.cs @@ -74,7 +74,8 @@ private static void Main(string[] args) new Question[] { new Q16_01_Number_Swapper(), - new Q16_19_Pond_Sizes() + new Q16_19_Pond_Sizes(), + new Boggle() } }; From 0970afc40b4f46df89564d1c769a1a03ca75dee0 Mon Sep 17 00:00:00 2001 From: Xavier Date: Wed, 26 Apr 2017 15:04:59 -0700 Subject: [PATCH 12/33] Q16_02_Word_Frequence --- Ch 16. Moderate/Q16_02_Word_Frequence.cs | 32 ++++++++++++++++++++++++ ctci/Program.cs | 1 + 2 files changed, 33 insertions(+) create mode 100644 Ch 16. Moderate/Q16_02_Word_Frequence.cs diff --git a/Ch 16. Moderate/Q16_02_Word_Frequence.cs b/Ch 16. Moderate/Q16_02_Word_Frequence.cs new file mode 100644 index 0000000..32d8802 --- /dev/null +++ b/Ch 16. Moderate/Q16_02_Word_Frequence.cs @@ -0,0 +1,32 @@ +using ctci.Contracts; +using ctci.Library; +using System; +using System.Collections.Generic; +using System.Text; + +namespace Chapter16 +{ + public class Q16_02_Word_Frequence : Question + { + public override void Run() + { + var book = AssortedMethods.GetLongTextBlob(); + var wordFrequence = GetWordFrequency(book); + Console.WriteLine("Word\t\t Frequence"); + foreach (var word in wordFrequence.Keys) + Console.WriteLine($"Word :{word}\t Count:{wordFrequence[word]}"); + } + + public IDictionary GetWordFrequency(string book) + { + var words = book.ToLower().Split(' '); + var dict = new Dictionary(); + foreach (var word in words) + if (dict.ContainsKey(word)) + dict[word]++; + else + dict[word] = 1; + return dict; + } + } +} diff --git a/ctci/Program.cs b/ctci/Program.cs index 4688570..5c5807a 100644 --- a/ctci/Program.cs +++ b/ctci/Program.cs @@ -74,6 +74,7 @@ private static void Main(string[] args) new Question[] { new Q16_01_Number_Swapper(), + new Q16_02_Word_Frequence(), new Q16_19_Pond_Sizes(), new Boggle() } From 2401d8592e90f59b79f042584040fb4b8271d66b Mon Sep 17 00:00:00 2001 From: Xavier Date: Wed, 26 Apr 2017 15:50:48 -0700 Subject: [PATCH 13/33] Q16_04_Tic_Tac_Toe CQRS style --- Ch 16. Moderate/Q16_04_Tic_Tac_Win.cs | 94 +++++++++++++++++++++++++++ ctci/Program.cs | 1 + 2 files changed, 95 insertions(+) create mode 100644 Ch 16. Moderate/Q16_04_Tic_Tac_Win.cs diff --git a/Ch 16. Moderate/Q16_04_Tic_Tac_Win.cs b/Ch 16. Moderate/Q16_04_Tic_Tac_Win.cs new file mode 100644 index 0000000..2b2c269 --- /dev/null +++ b/Ch 16. Moderate/Q16_04_Tic_Tac_Win.cs @@ -0,0 +1,94 @@ +using ctci.Contracts; +using ctci.Library; +using System; +using System.Collections.Generic; +using System.Text; + +namespace Chapter16 +{ + public class Q16_04_Tic_Tac_Toe_Win : Question + { + public class TicTacToe + { + const int BoardSize = 3; + public enum Piece + { + NA = 0, + X, + O + } + Piece[,] _matrix = new Piece[BoardSize, BoardSize]; + Piece _hasWon = Piece.NA; + Piece _whosMove; + + public TicTacToe(Piece whosMove = TicTacToe.Piece.X) + { + if (whosMove == Piece.NA) throw new ArgumentException("Invalid start piece"); + _whosMove = whosMove; + } + + public void Place(int r, int c, Piece piece) + { + if (r < 0 || r >= BoardSize || c < 0 || c >= BoardSize) throw new ArgumentException("location is out of bounds"); + if (piece != _whosMove) throw new ArgumentException("Wrong player"); + if (_matrix[r, c] != Piece.NA) throw new ArgumentException("Square already occupied"); + if (_hasWon != Piece.NA) throw new ArgumentException("Game has already ended"); + + _matrix[r, c] = piece; + _whosMove = piece == Piece.X ? Piece.O : Piece.X; + SetWinnerIfAny(r, c, piece); + } + + private void SetWinnerIfAny(int r, int c, Piece piece) + { + if (CheckHasWonRow(r) || CheckHasWonColumn(c) || + CheckHasWonDiagonally() || CheckHasWonDiagonallyReverse()) + _hasWon = piece; + } + + private bool CheckHasWonDiagonallyReverse() + { + return _matrix[0, 2] == _matrix[1, 1] && _matrix[1, 1] == _matrix[2, 0]; + } + + private bool CheckHasWonDiagonally() + { + return _matrix[0, 0] == _matrix[1, 1] && _matrix[1, 1] == _matrix[2, 2]; + } + + private bool CheckHasWonColumn(int c) + { + return _matrix[0, c] == _matrix[1, c] && _matrix[1, c] == _matrix[2, c]; + } + + private bool CheckHasWonRow(int r) + { + return _matrix[r, 0] == _matrix[r, 1] && _matrix[r, 1] == _matrix[r, 2]; + } + + public Piece GetWinner() + { + return _hasWon; + } + } + + public override void Run() + { + var ticTacToa = new TicTacToe(); + ticTacToa.Place(1, 1, TicTacToe.Piece.X); + Console.WriteLine($"Has winner :{ticTacToa.GetWinner()}"); + + ticTacToa.Place(1, 2, TicTacToe.Piece.O); + Console.WriteLine($"Has winner :{ticTacToa.GetWinner()}"); + + ticTacToa.Place(0, 2, TicTacToe.Piece.X); + Console.WriteLine($"Has winner :{ticTacToa.GetWinner()}"); + + ticTacToa.Place(0, 1, TicTacToe.Piece.O); + Console.WriteLine($"Has winner :{ticTacToa.GetWinner()}"); + + ticTacToa.Place(2, 0, TicTacToe.Piece.X); + Console.WriteLine($"Has winner :{ticTacToa.GetWinner()}"); + } + } +} diff --git a/ctci/Program.cs b/ctci/Program.cs index 5c5807a..13700fe 100644 --- a/ctci/Program.cs +++ b/ctci/Program.cs @@ -75,6 +75,7 @@ private static void Main(string[] args) { new Q16_01_Number_Swapper(), new Q16_02_Word_Frequence(), + new Q16_04_Tic_Tac_Toe_Win(), new Q16_19_Pond_Sizes(), new Boggle() } From a387a93c43b32a9fec5354f2092d75608644b161 Mon Sep 17 00:00:00 2001 From: Xavier Date: Wed, 26 Apr 2017 16:35:39 -0700 Subject: [PATCH 14/33] Q16_06 Smallest Difference between pair in two array. --- Ch 16. Moderate/Q16_06_Smallest_Difference.cs | 49 +++++++++++++++++++ ctci/Program.cs | 1 + 2 files changed, 50 insertions(+) create mode 100644 Ch 16. Moderate/Q16_06_Smallest_Difference.cs diff --git a/Ch 16. Moderate/Q16_06_Smallest_Difference.cs b/Ch 16. Moderate/Q16_06_Smallest_Difference.cs new file mode 100644 index 0000000..a21800f --- /dev/null +++ b/Ch 16. Moderate/Q16_06_Smallest_Difference.cs @@ -0,0 +1,49 @@ +using ctci.Contracts; +using ctci.Library; +using System; +using System.Collections.Generic; +using System.Text; + +namespace Chapter16 +{ + public class Q16_06_Smallest_Difference : Question + { + public override void Run() + { + var input1 = new int[] {1,3,15,11,2 }; + var input2 = new int[] { 23, 127, 235, 19, 8 }; + var smallestPair = GetSmallestDifferencePair(input1, input2); + var difference = Math.Abs(smallestPair.Item1 - smallestPair.Item2); + Console.WriteLine($"Pair {smallestPair.Item1},{smallestPair.Item2} has the smallest difference of {difference}"); + } + + public Tuple GetSmallestDifferencePair(int[] input1, int[] input2) + { + Array.Sort(input1); + Array.Sort(input2); + var item1 = default(int); + var item2 = default(int); + var minDifference = int.MaxValue; + var index1 = 0; + var index2 = 0; + while (index1 < input1.Length && index2 < input2.Length) + { + var value1 = input1[index1]; + var value2 = input2[index2]; + var difference = Math.Abs(value1 - value2); + if (difference < minDifference) + { + minDifference = difference; + item1 = value1; + item2 = value2; + } + if (value1 < value2) + index1++; + else + index2++; + } + + return Tuple.Create(item1, item2); + } + } +} diff --git a/ctci/Program.cs b/ctci/Program.cs index 13700fe..86eafd2 100644 --- a/ctci/Program.cs +++ b/ctci/Program.cs @@ -76,6 +76,7 @@ private static void Main(string[] args) new Q16_01_Number_Swapper(), new Q16_02_Word_Frequence(), new Q16_04_Tic_Tac_Toe_Win(), + new Q16_06_Smallest_Difference(), new Q16_19_Pond_Sizes(), new Boggle() } From 78c0a4889228df812f22639d51956a28a8648c83 Mon Sep 17 00:00:00 2001 From: Xavier Date: Wed, 26 Apr 2017 17:23:10 -0700 Subject: [PATCH 15/33] Convert Int to English --- Ch 16. Moderate/Q16_08_English_Int.cs | 90 +++++++++++++++++++++++++++ ctci/Program.cs | 1 + 2 files changed, 91 insertions(+) create mode 100644 Ch 16. Moderate/Q16_08_English_Int.cs diff --git a/Ch 16. Moderate/Q16_08_English_Int.cs b/Ch 16. Moderate/Q16_08_English_Int.cs new file mode 100644 index 0000000..4f5134a --- /dev/null +++ b/Ch 16. Moderate/Q16_08_English_Int.cs @@ -0,0 +1,90 @@ +using ctci.Contracts; +using ctci.Library; +using System; +using System.Collections.Generic; +using System.Text; + +namespace Chapter16 +{ + public class Q16_08_English_Int : Question + { + public override void Run() + { + var value = 832787436; + var engInt = ConvertIntToEnglish(value); + Console.WriteLine($"{832787436} in English is \n{engInt}"); + } + + public string ConvertIntToEnglish(int number) + { + var smalls = new string[] {"Zero", "One","Two","Three","Four","Five","Six","Seven","Eight","Nine", "Ten", "Eleven","Twelve", "Thirteen", "Fourteen", "Fifteen", "Sixteen", "Seventeen", "Eighteen", "Nineteen" }; + var tens = new string[] { "", "", "Twenty", "Thirty", "Forty", "Fifty", "Sixty", "Seventy", "Eighty", "Ninety" }; + var bigs = new string[] {"","Thousand","Million","Billion" }; + var hundred = "Hundred"; + var negative = "Negative "; + + if (number == 0) return smalls[0]; + if (number < 0) return negative + ConvertIntToEnglish(number * -1); + + var parts = new List(); + int chunkCount = 0; + while (number > 0) + { + if (number % 1000 != 0) + { + var chunk = ConvertChunk(number % 1000) + " " + bigs[chunkCount]; + parts.Insert(0, chunk); + } + number /= 1000; + chunkCount++; + } + + return ListToString(parts); + + string ConvertChunk(int num) + { + var smallParts = new List(); + if (num >= 100) + { + smallParts.Add(smalls[num / 100]); + smallParts.Add(hundred); + num %= 100; + } + + if (num >= 10 && num <=19) + { + smallParts.Add(smalls[num]); + } + else if (num >= 20) + { + smallParts.Add(tens[num / 10]); + num %= 10; + } + + // Convert one place + if (num >=1 && num <=9) + { + smallParts.Add(smalls[num]); + } + + return ListToString(smallParts); + } + + string ListToString(List smallParts) + { + var sb = new StringBuilder(); + while(smallParts.Count > 1) + { + var item = smallParts[0]; + sb.Append(item); + sb.Append(" "); + smallParts.Remove(item); + } + sb.Append(smallParts[0]); + return sb.ToString(); + } + } + + + } +} diff --git a/ctci/Program.cs b/ctci/Program.cs index 86eafd2..240e4bd 100644 --- a/ctci/Program.cs +++ b/ctci/Program.cs @@ -77,6 +77,7 @@ private static void Main(string[] args) new Q16_02_Word_Frequence(), new Q16_04_Tic_Tac_Toe_Win(), new Q16_06_Smallest_Difference(), + new Q16_08_English_Int(), new Q16_19_Pond_Sizes(), new Boggle() } From f74dcdea37bbedb672247671dbe0f0bf9a3fb465 Mon Sep 17 00:00:00 2001 From: Xavier Date: Thu, 27 Apr 2017 13:14:04 -0700 Subject: [PATCH 16/33] Q4_03_List_of_Depths --- Ch 02. Linked Lists/Q2_07_Intersection.cs | 12 ++--- ..._CreateMinimalBSTfromSortedUniqueArray.cs} | 7 ++- Ch 04. Trees/Q4_03_List_of_Depths.cs | 48 +++++++++++++++++++ ...heckBalanced.cs => Q4_04_CheckBalanced.cs} | 2 +- Ch 04. Trees/ReplaceNodeInImmutableTree.cs | 20 ++++---- ctci/Program.cs | 5 +- 6 files changed, 71 insertions(+), 23 deletions(-) rename Ch 04. Trees/{Q4_2_CreateMinimalBSTfromSortedUniqueArray.cs => Q4_02_CreateMinimalBSTfromSortedUniqueArray.cs} (74%) create mode 100644 Ch 04. Trees/Q4_03_List_of_Depths.cs rename Ch 04. Trees/{Q4_4_CheckBalanced.cs => Q4_04_CheckBalanced.cs} (95%) diff --git a/Ch 02. Linked Lists/Q2_07_Intersection.cs b/Ch 02. Linked Lists/Q2_07_Intersection.cs index a5a0f1b..1b98cd2 100644 --- a/Ch 02. Linked Lists/Q2_07_Intersection.cs +++ b/Ch 02. Linked Lists/Q2_07_Intersection.cs @@ -6,19 +6,19 @@ namespace Chapter02 { public class Q2_07_Intersection : Question { - public class Result + public class TailAndSize { public LinkedListNode tail; public int size; - public Result(LinkedListNode tail, int size) + public TailAndSize(LinkedListNode tail, int size) { this.tail = tail; this.size = size; } } - public static Result getTailAndSize(LinkedListNode list) + public static TailAndSize getTailAndSize(LinkedListNode list) { if (list == null) return null; @@ -29,7 +29,7 @@ public static Result getTailAndSize(LinkedListNode list) size++; current = current.Next; } - return new Result(current, size); + return new TailAndSize(current, size); } public static LinkedListNode getKthNode(LinkedListNode head, int k) @@ -48,8 +48,8 @@ public static LinkedListNode findIntersection(LinkedListNode list1, LinkedListNo if (list1 == null || list2 == null) return null; /* Get tail and sizes. */ - Result result1 = getTailAndSize(list1); - Result result2 = getTailAndSize(list2); + TailAndSize result1 = getTailAndSize(list1); + TailAndSize result2 = getTailAndSize(list2); /* If different tail nodes, then there's no intersection. */ if (result1.tail != result2.tail) diff --git a/Ch 04. Trees/Q4_2_CreateMinimalBSTfromSortedUniqueArray.cs b/Ch 04. Trees/Q4_02_CreateMinimalBSTfromSortedUniqueArray.cs similarity index 74% rename from Ch 04. Trees/Q4_2_CreateMinimalBSTfromSortedUniqueArray.cs rename to Ch 04. Trees/Q4_02_CreateMinimalBSTfromSortedUniqueArray.cs index 08e7b3c..e53aa8f 100644 --- a/Ch 04. Trees/Q4_2_CreateMinimalBSTfromSortedUniqueArray.cs +++ b/Ch 04. Trees/Q4_02_CreateMinimalBSTfromSortedUniqueArray.cs @@ -4,9 +4,9 @@ namespace Chapter04 { - public class Q4_2_CreateMinimalBSTfromSortedUniqueArray: Question + public class Q4_02_CreateMinimalBSTfromSortedUniqueArray: Question { - public static TreeNode Create(int[] sortedArray) + public static TreeNode Create(params int[] sortedArray) { return Create(sortedArray, 0, sortedArray.Length - 1); } @@ -24,8 +24,7 @@ private static TreeNode Create(int[] sortedArray, int left, int right) public override void Run() { - var sortedArray = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; - var root = Create(sortedArray); + var root = Create(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); BTreePrinter.Print(root); } } diff --git a/Ch 04. Trees/Q4_03_List_of_Depths.cs b/Ch 04. Trees/Q4_03_List_of_Depths.cs new file mode 100644 index 0000000..8b14720 --- /dev/null +++ b/Ch 04. Trees/Q4_03_List_of_Depths.cs @@ -0,0 +1,48 @@ +using ctci.Contracts; +using ctci.Library; +using System; +using System.Collections.Generic; + +namespace Chapter04 +{ + public class Q4_03_List_of_Depths: Question + { + + public override void Run() + { + var tree = Q4_02_CreateMinimalBSTfromSortedUniqueArray.Create(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); + var listOfDepths = ListOfDepths(tree); + + BTreePrinter.Print(tree); + foreach(var list in listOfDepths) + { + foreach (var sbList in list) + Console.Write($"{sbList.Data},"); + Console.WriteLine(); + } + } + + public List> ListOfDepths(TreeNode root) + { + if (root == null) return null; + var list = new List>(); + var sbList = new List { root }; + while (sbList.Count > 0) + { + list.Add(sbList); + + var prevList = sbList; + sbList = new List(); + foreach (var node in prevList) + AddChildren(node, sbList); + } + return list; + } + + private static void AddChildren(TreeNode node, List list) + { + if (node.Left != null) list.Add(node.Left); + if (node.Right != null) list.Add(node.Right); + } + } +} \ No newline at end of file diff --git a/Ch 04. Trees/Q4_4_CheckBalanced.cs b/Ch 04. Trees/Q4_04_CheckBalanced.cs similarity index 95% rename from Ch 04. Trees/Q4_4_CheckBalanced.cs rename to Ch 04. Trees/Q4_04_CheckBalanced.cs index 9554423..dfbec77 100644 --- a/Ch 04. Trees/Q4_4_CheckBalanced.cs +++ b/Ch 04. Trees/Q4_04_CheckBalanced.cs @@ -4,7 +4,7 @@ namespace Chapter04 { - public class Q4_4_CheckBalanced: Question + public class Q4_04_CheckBalanced: Question { public static bool IsBalanced(TreeNode root) { diff --git a/Ch 04. Trees/ReplaceNodeInImmutableTree.cs b/Ch 04. Trees/ReplaceNodeInImmutableTree.cs index 7419dcf..b2574cb 100644 --- a/Ch 04. Trees/ReplaceNodeInImmutableTree.cs +++ b/Ch 04. Trees/ReplaceNodeInImmutableTree.cs @@ -11,26 +11,26 @@ static public TreeNode Replace(this TreeNode node, int value) if (node == null) return null; var newNode = new TreeNode(node); newNode.Data = value; - TreeNode newParent = newNode; + var newRoot = newNode; while (node.Parent != null) { - newParent = new TreeNode(node.Parent); - newNode.Parent = newParent; - if (newParent.Left == node) - newParent.Left = newNode; - if (newParent.Right == node) - newParent.Right = newNode; + newRoot = new TreeNode(node.Parent); + newNode.Parent = newRoot; + if (newRoot.Left == node) + newRoot.Left = newNode; + if (newRoot.Right == node) + newRoot.Right = newNode; node = node.Parent; - newNode = newParent; + newNode = newRoot; } - return newParent; + return newRoot; } } public class ReplaceNodeInImmutableTree : Question { public override void Run() { - var tree = Q4_2_CreateMinimalBSTfromSortedUniqueArray.Create(new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }); + var tree = Q4_02_CreateMinimalBSTfromSortedUniqueArray.Create(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); var nodeToReplace = tree.Find(6); TreeNode newTree = nodeToReplace.Replace(11); BTreePrinter.Print(tree); diff --git a/ctci/Program.cs b/ctci/Program.cs index 240e4bd..9bb8cd3 100644 --- a/ctci/Program.cs +++ b/ctci/Program.cs @@ -45,8 +45,9 @@ private static void Main(string[] args) }, new Question[] { - new Q4_2_CreateMinimalBSTfromSortedUniqueArray(), - new Q4_4_CheckBalanced(), + new Q4_02_CreateMinimalBSTfromSortedUniqueArray(), + new Q4_03_List_of_Depths(), + new Q4_04_CheckBalanced(), new ReplaceNodeInImmutableTree() }, From c10bd58070b41418da93ca8c2624b82eb337cff0 Mon Sep 17 00:00:00 2001 From: Xavier Date: Thu, 27 Apr 2017 13:24:06 -0700 Subject: [PATCH 17/33] Is Balanced BST --- Ch 04. Trees/Q4_04_CheckBalanced.cs | 44 +++++++++++++++++++++++++++-- 1 file changed, 41 insertions(+), 3 deletions(-) diff --git a/Ch 04. Trees/Q4_04_CheckBalanced.cs b/Ch 04. Trees/Q4_04_CheckBalanced.cs index dfbec77..27857fd 100644 --- a/Ch 04. Trees/Q4_04_CheckBalanced.cs +++ b/Ch 04. Trees/Q4_04_CheckBalanced.cs @@ -20,21 +20,59 @@ public static int Height(TreeNode root, int height = 0) return Math.Max(Height(root.Left, height), Height(root.Right, height)) + 1; } + public static bool IsBalancedBook(TreeNode root) + { + return CheckHeight(root) != -1; + } + + private static int CheckHeight(TreeNode root) + { + if (root == null) return 0; + var leftHeight = CheckHeight(root.Left); + if (leftHeight == -1) return -1; + + var rightHeight = CheckHeight(root.Right); + if (rightHeight == -1) return -1; + + if (Math.Abs(leftHeight - rightHeight) > 1) return -1; + else return (Math.Max(leftHeight, rightHeight) + 1); + } + public override void Run() { - var root = new TreeNode(2); + var root = Q4_02_CreateMinimalBSTfromSortedUniqueArray.Create(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); + PrintTree(root); + + root = new TreeNode(2); root.SetLeftChild(new TreeNode(1)); - root.SetRightChild(new TreeNode(3)); + root.Left.SetLeftChild(new TreeNode(3)); PrintTree(root); } private static void PrintTree(TreeNode root) { BTreePrinter.Print(root); - if (IsBalanced(root)) + var watch = System.Diagnostics.Stopwatch.StartNew(); + var isBalanced1 = IsBalanced(root); + watch.Stop(); + var elapsedMs = watch.ElapsedMilliseconds; + + if (isBalanced1) + Console.WriteLine("Tree is balanced"); + else + Console.WriteLine("Tree is not balalnced"); + Console.WriteLine($"Elapsed milliconds {elapsedMs}"); + + watch = System.Diagnostics.Stopwatch.StartNew(); + var isBalanced2 = IsBalancedBook(root); + watch.Stop(); + elapsedMs = watch.ElapsedMilliseconds; + + if (IsBalancedBook(root)) Console.WriteLine("Tree is balanced"); else Console.WriteLine("Tree is not balalnced"); + Console.WriteLine($"Elapsed milliconds {elapsedMs}"); } } } \ No newline at end of file From 5fec3a6bef4fa5674c4b997dbd1002c61efbf9d4 Mon Sep 17 00:00:00 2001 From: Xavier Date: Thu, 27 Apr 2017 13:34:45 -0700 Subject: [PATCH 18/33] Is Valid BST --- Ch 04. Trees/Q4_05_Validate_BST.cs | 47 ++++++++++++++++++++++++++++++ ctci/Program.cs | 1 + 2 files changed, 48 insertions(+) create mode 100644 Ch 04. Trees/Q4_05_Validate_BST.cs diff --git a/Ch 04. Trees/Q4_05_Validate_BST.cs b/Ch 04. Trees/Q4_05_Validate_BST.cs new file mode 100644 index 0000000..6946cab --- /dev/null +++ b/Ch 04. Trees/Q4_05_Validate_BST.cs @@ -0,0 +1,47 @@ +using ctci.Contracts; +using ctci.Library; +using System; +using System.Collections.Generic; + +namespace Chapter04 +{ + public class Q4_05_Validate_BST: Question + { + + public override void Run() + { + var root = Q4_02_CreateMinimalBSTfromSortedUniqueArray.Create(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); + PrintTree(root); + + root = new TreeNode(2); + root.SetLeftChild(new TreeNode(1)); + root.Left.SetLeftChild(new TreeNode(3)); + PrintTree(root); + } + public static bool IsValidBST(TreeNode root) + { + return IsValidBST(root, null, null); + } + + private static bool IsValidBST(TreeNode root, int? min, int? max) + { + if (root == null) return true; + if (min.HasValue && min > root.Data) return false; + if (max.HasValue && max < root.Data) return false; + return IsValidBST(root.Left, min, root.Data) && IsValidBST(root.Right, root.Data, max); + } + + private static void PrintTree(TreeNode root) + { + BTreePrinter.Print(root); + var isValidBST = IsValidBST(root); + + if (isValidBST) + Console.WriteLine("Tree is a valid BST"); + else + Console.WriteLine("Tree is not a valid BST"); + } + + + } +} \ No newline at end of file diff --git a/ctci/Program.cs b/ctci/Program.cs index 9bb8cd3..6341ac6 100644 --- a/ctci/Program.cs +++ b/ctci/Program.cs @@ -48,6 +48,7 @@ private static void Main(string[] args) new Q4_02_CreateMinimalBSTfromSortedUniqueArray(), new Q4_03_List_of_Depths(), new Q4_04_CheckBalanced(), + new Q4_05_Validate_BST(), new ReplaceNodeInImmutableTree() }, From 80fa5f64baa1b9eb834c2e118a337acd46762290 Mon Sep 17 00:00:00 2001 From: Xavier Date: Thu, 27 Apr 2017 14:06:02 -0700 Subject: [PATCH 19/33] Successor Node. --- Ch 04. Trees/Q4_06_Successor.cs | 53 ++++++++++++++++++++++ Ch 04. Trees/ReplaceNodeInImmutableTree.cs | 2 +- ctci/Program.cs | 1 + 3 files changed, 55 insertions(+), 1 deletion(-) create mode 100644 Ch 04. Trees/Q4_06_Successor.cs diff --git a/Ch 04. Trees/Q4_06_Successor.cs b/Ch 04. Trees/Q4_06_Successor.cs new file mode 100644 index 0000000..43086c7 --- /dev/null +++ b/Ch 04. Trees/Q4_06_Successor.cs @@ -0,0 +1,53 @@ +using ctci.Contracts; +using ctci.Library; +using System; +using System.Collections.Generic; + +namespace Chapter04 +{ + static partial class TreeNodeExtension + { + static public TreeNode Successor(this TreeNode node) + { + if (node == null) return null; + if (node.Right != null) return LeftMost(node.Right); + + var current = node; + var parent = current.Parent; + // go up until we're on left instead of right + while (parent != null && parent.Right == current) + { + current = parent; + parent = current.Parent; + } + return parent; + } + + private static TreeNode LeftMost(TreeNode node) + { + while (node.Left != null) + node = node.Left; + return node; + } + } + + public class Q4_06_Successor : Question + { + + public override void Run() + { + var root = Q4_02_CreateMinimalBSTfromSortedUniqueArray.Create(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); + var node = root.Find(6); + var successorNode = node.Successor(); + Console.WriteLine($"Successor node of {node.Data} is { successorNode.Data}"); + + node = root.Find(1); + successorNode = node.Successor(); + Console.WriteLine($"Successor node of {node.Data} is { successorNode.Data}"); + + node = root.Find(7); + successorNode = node.Successor(); + Console.WriteLine($"Successor node of {node.Data} is { successorNode.Data}"); + } + } +} \ No newline at end of file diff --git a/Ch 04. Trees/ReplaceNodeInImmutableTree.cs b/Ch 04. Trees/ReplaceNodeInImmutableTree.cs index b2574cb..b991a80 100644 --- a/Ch 04. Trees/ReplaceNodeInImmutableTree.cs +++ b/Ch 04. Trees/ReplaceNodeInImmutableTree.cs @@ -4,7 +4,7 @@ namespace Chapter04 { - static class TreeNodeExtension + static partial class TreeNodeExtension { static public TreeNode Replace(this TreeNode node, int value) { diff --git a/ctci/Program.cs b/ctci/Program.cs index 6341ac6..7fda6c0 100644 --- a/ctci/Program.cs +++ b/ctci/Program.cs @@ -49,6 +49,7 @@ private static void Main(string[] args) new Q4_03_List_of_Depths(), new Q4_04_CheckBalanced(), new Q4_05_Validate_BST(), + new Q4_06_Successor(), new ReplaceNodeInImmutableTree() }, From 794667099744a803eb53c4de6c88c0642558c2e5 Mon Sep 17 00:00:00 2001 From: Xavier Date: Thu, 27 Apr 2017 14:48:01 -0700 Subject: [PATCH 20/33] Lowest Common Ancestor with none BST. --- .../Q4_08_LowestCommonAncestorNotBST.cs | 60 +++++++++++++++++++ ctci/Program.cs | 1 + 2 files changed, 61 insertions(+) create mode 100644 Ch 04. Trees/Q4_08_LowestCommonAncestorNotBST.cs diff --git a/Ch 04. Trees/Q4_08_LowestCommonAncestorNotBST.cs b/Ch 04. Trees/Q4_08_LowestCommonAncestorNotBST.cs new file mode 100644 index 0000000..54034a2 --- /dev/null +++ b/Ch 04. Trees/Q4_08_LowestCommonAncestorNotBST.cs @@ -0,0 +1,60 @@ +using ctci.Contracts; +using ctci.Library; +using System; +using System.Collections.Generic; + +namespace Chapter04 +{ + static partial class TreeNodeExtension + { + static public TreeNode LowestCommonAncestor(this TreeNode root, TreeNode p, TreeNode q) + { + if (!root.Covers(p) || !root.Covers(q)) return null; + + return LowestCommonAncestorHelper(root, p, q); + } + + static private TreeNode LowestCommonAncestorHelper(TreeNode root, TreeNode p, TreeNode q) + { + if (root == null) return null; + if (root == p) return root; + if (root == q) return root; + + var pIsOnLeft = root.Left.Covers(p); + var qIsOnLeft = root.Left.Covers(q); + if (pIsOnLeft != qIsOnLeft) return root; + if (pIsOnLeft && qIsOnLeft) return LowestCommonAncestorHelper(root.Left, p, q); + return LowestCommonAncestorHelper(root.Right, p, q); + } + + static private bool Covers(this TreeNode root, TreeNode node) + { + if (root == null) return false; + if (root == node) return true; + return (root.Left.Covers(node) || root.Right.Covers(node)); + } + } + + public class Q4_08_LowestCommonAncestorNotBST : Question + { + + public override void Run() + { + var root = Q4_02_CreateMinimalBSTfromSortedUniqueArray.Create(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); + var p = root.Find(1); + var q = root.Find(3); + var lca = root.LowestCommonAncestor(p, q); + Console.WriteLine($"LCA for {p.Data},{q.Data} is {lca.Data}"); // 2 + + p = root.Find(4); + q = root.Find(7); + lca = root.LowestCommonAncestor(p, q); + Console.WriteLine($"LCA for {p.Data},{q.Data} is {lca.Data}"); // 5 + + p = root.Find(7); + q = root.Find(9); + lca = root.LowestCommonAncestor(p, q); + Console.WriteLine($"LCA for {p.Data},{q.Data} is {lca.Data}"); // 8 + } + } +} \ No newline at end of file diff --git a/ctci/Program.cs b/ctci/Program.cs index 7fda6c0..c1b9172 100644 --- a/ctci/Program.cs +++ b/ctci/Program.cs @@ -50,6 +50,7 @@ private static void Main(string[] args) new Q4_04_CheckBalanced(), new Q4_05_Validate_BST(), new Q4_06_Successor(), + new Q4_08_LowestCommonAncestorNotBST(), new ReplaceNodeInImmutableTree() }, From d34c32cb2dc8bafe93a2a4b4d381201529d7654b Mon Sep 17 00:00:00 2001 From: Xavier Date: Thu, 27 Apr 2017 15:18:54 -0700 Subject: [PATCH 21/33] Check Sub Tree --- Ch 04. Trees/Q4_10_Check_SubTree.cs | 48 +++++++++++++++++++++++++++++ ctci/Program.cs | 1 + 2 files changed, 49 insertions(+) create mode 100644 Ch 04. Trees/Q4_10_Check_SubTree.cs diff --git a/Ch 04. Trees/Q4_10_Check_SubTree.cs b/Ch 04. Trees/Q4_10_Check_SubTree.cs new file mode 100644 index 0000000..32cecb9 --- /dev/null +++ b/Ch 04. Trees/Q4_10_Check_SubTree.cs @@ -0,0 +1,48 @@ +using ctci.Contracts; +using ctci.Library; +using System; +using System.Collections.Generic; + +namespace Chapter04 +{ + public class Q4_10_Check_SubTree : Question + { + + static public bool ContainsTree(TreeNode root, TreeNode p) + { + if (p == null) return true; + if (root == null) return false; + + if (p.Data == root.Data && MatchTree(root, p)) return true; + return ContainsTree(root.Left, p) || ContainsTree(root.Right, p); + } + + static public bool MatchTree(TreeNode t1, TreeNode t2) + { + if (t1 == null && t2 == null) return true; + if (t1 == null || t2 == null) return false; + return t1.Data == t2.Data && MatchTree(t1.Right, t2.Right) && MatchTree(t1.Left, t2.Left); + } + + + public override void Run() + { + var tree = Q4_02_CreateMinimalBSTfromSortedUniqueArray.Create(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); + var subTree = Q4_02_CreateMinimalBSTfromSortedUniqueArray.Create(6, 7, 8, 9, 10); + + Print(tree, subTree); + subTree = Q4_02_CreateMinimalBSTfromSortedUniqueArray.Create(7, 8, 9, 10); + Print(tree, subTree); + } + + private static void Print(TreeNode tree, TreeNode subTree) + { + BTreePrinter.Print(tree); + BTreePrinter.Print(subTree); + if (ContainsTree(tree, subTree)) + Console.WriteLine("It is a sub tree"); + else + Console.WriteLine("It is not a sub tree"); + } + } +} \ No newline at end of file diff --git a/ctci/Program.cs b/ctci/Program.cs index c1b9172..00d0554 100644 --- a/ctci/Program.cs +++ b/ctci/Program.cs @@ -51,6 +51,7 @@ private static void Main(string[] args) new Q4_05_Validate_BST(), new Q4_06_Successor(), new Q4_08_LowestCommonAncestorNotBST(), + new Q4_10_Check_SubTree(), new ReplaceNodeInImmutableTree() }, From 87302b8e5a53b44ef432ad7526c1eabbc10825ac Mon Sep 17 00:00:00 2001 From: Xavier Date: Fri, 28 Apr 2017 08:23:45 -0700 Subject: [PATCH 22/33] Use dictionary in Trie Node instead of List --- Ch 16. Moderate/Boggle.cs | 4 ++-- ctci.Library/TrieNode.cs | 15 +++++---------- 2 files changed, 7 insertions(+), 12 deletions(-) diff --git a/Ch 16. Moderate/Boggle.cs b/Ch 16. Moderate/Boggle.cs index ece5b77..0e7a13c 100644 --- a/Ch 16. Moderate/Boggle.cs +++ b/Ch 16. Moderate/Boggle.cs @@ -43,11 +43,11 @@ public IList Solve(char[,] matrix, TrieNode trie) private void Solve(string prefix, char[,] matrix, bool[,] visited, int row, int column, TrieNode trie, HashSet words) { - if (row < 0 || row >= matrix.Height()) return; - if (column < 0 || column >= matrix.Width()) return; + if (matrix.IsOutOfBounds(row, column)) return; if (visited[row, column]) return; if (trie.Terminates) words.Add(prefix); + var trieChild = trie.GetChild(matrix[row, column]); if (trieChild == null) return; diff --git a/ctci.Library/TrieNode.cs b/ctci.Library/TrieNode.cs index 9df0cdc..ac3236d 100644 --- a/ctci.Library/TrieNode.cs +++ b/ctci.Library/TrieNode.cs @@ -5,7 +5,7 @@ namespace ctci.Library public class TrieNode { // The children of this node in the trie. - private readonly LinkedList _children; + private readonly Dictionary _children; public bool Terminates { get; set; } @@ -20,7 +20,7 @@ public class TrieNode /// This is faster, but will require more space. public TrieNode() { - _children = new LinkedList(); + _children = new Dictionary(); Terminates = false; } @@ -53,7 +53,7 @@ public void AddWord(string word) if (t == null) { child = new TrieNode(firstChar); - _children.AddLast(child); + _children[child.Character] = child; } else { @@ -74,13 +74,8 @@ public void AddWord(string word) /// data. Return null if no such child node is present in the trie. public TrieNode GetChild(char c) { - foreach (TrieNode t in _children) - { - if (t.Character == c) - { - return t; - } - } + if (_children.ContainsKey(c)) + return _children[c]; return null; } } From 05c6170aa87e74a6cdf93827751f46fab91991b8 Mon Sep 17 00:00:00 2001 From: Xavier Date: Sun, 24 Sep 2017 18:56:34 -0700 Subject: [PATCH 23/33] Given a binary search tree with distinct elements, print all possible arrays that could have lead to this tree. --- Ch 04. Trees/Q4 09 BST Sequence.cs | 97 ++++++++++++++++++++++++++++++ ctci.Library/AssortedMethods.cs | 11 +++- ctci/Program.cs | 1 + 3 files changed, 108 insertions(+), 1 deletion(-) create mode 100644 Ch 04. Trees/Q4 09 BST Sequence.cs diff --git a/Ch 04. Trees/Q4 09 BST Sequence.cs b/Ch 04. Trees/Q4 09 BST Sequence.cs new file mode 100644 index 0000000..defc258 --- /dev/null +++ b/Ch 04. Trees/Q4 09 BST Sequence.cs @@ -0,0 +1,97 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using ctci.Contracts; +using ctci.Library; + +namespace Chapter04 +{ + /// + /// Given a binary search tree with distinct elements, + /// print all possible arrays that could have lead to this tree. + /// + public class Q4_09_BST_Sequence : Question + { + + public override void Run() + { + var root = Q4_02_CreateMinimalBSTfromSortedUniqueArray.Create(1, 2, 3); + BTreePrinter.Print(root); + var results = AllSequences(root); + foreach (var list in results) + AssortedMethods.PrintIntList(list); + } + + public List> AllSequences(TreeNode node) + { + var result = new List>(); + + if (node == null) + { + result.Add(new List()); + return result; + } + + var prefix = new List(); + prefix.Add(node.Data); + + var leftSeq = AllSequences(node.Left); + var rightSeq = AllSequences(node.Right); + + Weave(result, leftSeq, rightSeq, prefix); + + return result; + } + + + private void Weave(List> result, List> leftSeq, List> rightSeq, List prefix) + { + foreach (var left in leftSeq) + foreach (var right in rightSeq) + { + var weaved = new List>(); + WeaveLists(left, right, weaved, prefix); + result.AddRange(weaved); + } + } + + /// + /// Weave lists together in all possible ways. This algorithm works by removing the head from one list, + /// recursing, and then doing the same thing wigth the other list. + /// + /// + /// + /// + /// + private void WeaveLists(List first, List second, List> weaved, List prefix) + { + // One list is empty. Add reminder to [a cloned] prefix and store result. + if (first.Count == 0 || second.Count == 0) + { + var result = prefix.ToList(); + result.AddRange(first); + result.AddRange(second); + weaved.Add(result); + return; + } + + // Recurse with head of first added to the prefix. Removing the head will damage + // first, so we'll need to put it back where we found it afterwards + MoveItemFromFirstListToPrefixAndWeave(first, second, weaved, prefix); + + // Do the same thing with second, damaging and then restoring the list + MoveItemFromFirstListToPrefixAndWeave(second, first, weaved, prefix); + } + + private void MoveItemFromFirstListToPrefixAndWeave(List first, List second, List> weaved, List prefix) + { + var headFirst = first[0]; + first.RemoveAt(0); + prefix.Add(headFirst); + WeaveLists(first, second, weaved, prefix); + prefix.RemoveAt(prefix.Count - 1); + first.Insert(0, headFirst); + } + } +} diff --git a/ctci.Library/AssortedMethods.cs b/ctci.Library/AssortedMethods.cs index 2d6ad0a..f0e661f 100644 --- a/ctci.Library/AssortedMethods.cs +++ b/ctci.Library/AssortedMethods.cs @@ -161,7 +161,8 @@ public static void PrintMatrix(bool[][] matrix) { Console.Write("1"); } - else { + else + { Console.Write("0"); } } @@ -178,6 +179,14 @@ public static void PrintIntArray(int[] array) Console.WriteLine(""); } + public static void PrintIntList(IEnumerable list) + { + Console.Write("{"); + foreach (var v in list) + Console.Write($"{v}, "); + Console.WriteLine("\b\b}"); + } + public static string CharArrayToString(char[] array) { StringBuilder buffer = new StringBuilder(array.Length); diff --git a/ctci/Program.cs b/ctci/Program.cs index 00d0554..eb053fb 100644 --- a/ctci/Program.cs +++ b/ctci/Program.cs @@ -51,6 +51,7 @@ private static void Main(string[] args) new Q4_05_Validate_BST(), new Q4_06_Successor(), new Q4_08_LowestCommonAncestorNotBST(), + new Q4_09_BST_Sequence(), new Q4_10_Check_SubTree(), new ReplaceNodeInImmutableTree() }, From b772439f82c882dbd6e7f05d1b16f4e3e9514815 Mon Sep 17 00:00:00 2001 From: Xavier John Date: Wed, 27 Sep 2017 12:07:11 -0700 Subject: [PATCH 24/33] Q4 07 Build order. --- Ch 04. Trees/Q4 07 Build Order.cs | 158 +++++++++++++++++++++++++++++ Ch 04. Trees/Q4 09 BST Sequence.cs | 2 +- ctci.Library/AssortedMethods.cs | 2 +- ctci/Program.cs | 1 + 4 files changed, 161 insertions(+), 2 deletions(-) create mode 100644 Ch 04. Trees/Q4 07 Build Order.cs diff --git a/Ch 04. Trees/Q4 07 Build Order.cs b/Ch 04. Trees/Q4 07 Build Order.cs new file mode 100644 index 0000000..34f4e82 --- /dev/null +++ b/Ch 04. Trees/Q4 07 Build Order.cs @@ -0,0 +1,158 @@ +using System; +using System.Collections.Generic; +using System.Text; +using ctci.Contracts; +using ctci.Library; + +namespace Chapter04 +{ + public class Q4_07_Build_Order : Question + { + // I wrote the solution based on Topological sort in the Algorithms Book, + // and its code is here. https://github.com/kevin-wayne/algs4. + // In topological sort, you are using a directed graph. + // If a -> b, then it means, b depends on a, + // in other words, 'a' needs to be built before 'b.' + // After a topological sort, you expect all the nodes to be arranged such that it is flowing in one direction. + // Since a cycle is not allowed, the code checks if a cycle exists and returns. + // In real life, jobs cannot have circular dependencies. + public override void Run() + { + var diGraph = new DirectedGraph('f'); + diGraph.AddEdge('a', 'd'); // d depends on a + diGraph.AddEdge('f', 'b'); // b depends on f + diGraph.AddEdge('b', 'd'); + diGraph.AddEdge('f', 'a'); + diGraph.AddEdge('d', 'c'); + + var topological = new Topological(diGraph); + var order = topological.Order(); + AssortedMethods.PrintList(order); + } + + public class DirectedGraph + { + Dictionary> AdjacentVertexes; + List Vertexes; + + public DirectedGraph(char v) + { + Vertexes = new List(); + AdjacentVertexes = new Dictionary>(); + for (var a = 'a'; a <= v; a++) + { + AdjacentVertexes[a] = new List(); + Vertexes.Add(a); + } + } + + public void AddEdge(char v, char w) + { + AdjacentVertexes[v].Add(w); + } + public IEnumerable GetVertexes() + { + return Vertexes; + } + + public IEnumerable GetAdjacentVertexes(char v) + { + return AdjacentVertexes[v]; + } + } + + public class DirectedCycle + { + HashSet marked; + Dictionary edgeTo; + + Stack cycle; + Dictionary onStack; + + public DirectedCycle(DirectedGraph G) + { + onStack = new Dictionary(); + edgeTo = new Dictionary(); + marked = new HashSet(); + foreach (var vertex in G.GetVertexes()) + if (!marked.Contains(vertex)) DepthFirstCycleDetection(G, vertex); + } + + private void DepthFirstCycleDetection(DirectedGraph graph, char vertex) + { + onStack[vertex] = true; + marked.Add(vertex); + foreach (var adjVertexes in graph.GetAdjacentVertexes(vertex)) + { + if (this.HasCycle()) return; + else if (!marked.Contains(adjVertexes)) + { + edgeTo[adjVertexes] = vertex; + DepthFirstCycleDetection(graph, adjVertexes); + } + else if (onStack[adjVertexes]) + { + cycle = new Stack(); + for (char x = vertex; x != adjVertexes; x = edgeTo[x]) + cycle.Push(x); + cycle.Push(adjVertexes); + cycle.Push(vertex); + } + } + onStack[vertex] = false; + } + + public bool HasCycle() + { + return cycle != null; + } + } + + public class DepthFirstOrder + { + HashSet marked; + Stack reversePost; + + public DepthFirstOrder(DirectedGraph graph) + { + reversePost = new Stack(); + marked = new HashSet(); + + foreach (var vertex in graph.GetVertexes()) + if (!marked.Contains(vertex)) + DepthFirstSearch(graph, vertex); + } + + private void DepthFirstSearch(DirectedGraph graph, char vertex) + { + marked.Add(vertex); + foreach (var adjVertex in graph.GetAdjacentVertexes(vertex)) + if (!marked.Contains(adjVertex)) + DepthFirstSearch(graph, adjVertex); + reversePost.Push(vertex); + } + + public IEnumerable ReversePost() + { + return reversePost; + } + } + + public class Topological + { + IEnumerable order; + + public Topological(DirectedGraph graph) + { + var cycleFinder = new DirectedCycle(graph); + if (!cycleFinder.HasCycle()) + { + var depthFirstOrder = new DepthFirstOrder(graph); + order = depthFirstOrder.ReversePost(); + } + } + + public IEnumerable Order() { return order; } + } + } +} diff --git a/Ch 04. Trees/Q4 09 BST Sequence.cs b/Ch 04. Trees/Q4 09 BST Sequence.cs index defc258..c4d0071 100644 --- a/Ch 04. Trees/Q4 09 BST Sequence.cs +++ b/Ch 04. Trees/Q4 09 BST Sequence.cs @@ -20,7 +20,7 @@ public override void Run() BTreePrinter.Print(root); var results = AllSequences(root); foreach (var list in results) - AssortedMethods.PrintIntList(list); + AssortedMethods.PrintList(list); } public List> AllSequences(TreeNode node) diff --git a/ctci.Library/AssortedMethods.cs b/ctci.Library/AssortedMethods.cs index f0e661f..294ed2f 100644 --- a/ctci.Library/AssortedMethods.cs +++ b/ctci.Library/AssortedMethods.cs @@ -179,7 +179,7 @@ public static void PrintIntArray(int[] array) Console.WriteLine(""); } - public static void PrintIntList(IEnumerable list) + public static void PrintList(IEnumerable list) { Console.Write("{"); foreach (var v in list) diff --git a/ctci/Program.cs b/ctci/Program.cs index eb053fb..3c47114 100644 --- a/ctci/Program.cs +++ b/ctci/Program.cs @@ -50,6 +50,7 @@ private static void Main(string[] args) new Q4_04_CheckBalanced(), new Q4_05_Validate_BST(), new Q4_06_Successor(), + new Q4_07_Build_Order(), new Q4_08_LowestCommonAncestorNotBST(), new Q4_09_BST_Sequence(), new Q4_10_Check_SubTree(), From 6d5a7329d7399e1af87165a8e945a161bb235ff1 Mon Sep 17 00:00:00 2001 From: Xavier Date: Wed, 27 Sep 2017 17:47:47 -0700 Subject: [PATCH 25/33] minor update --- ...5_One_Away_A.cs => Q1 05 One Edit Away.cs} | 228 +++++++++--------- Ch 01. Arrays and Strings/Q1_01_Is_Unique.cs | 18 +- .../Q1_02_Check_Permutation.cs | 9 +- Ch 04. Trees/Q4_04_CheckBalanced.cs | 10 +- ctci/Program.cs | 2 +- 5 files changed, 125 insertions(+), 142 deletions(-) rename Ch 01. Arrays and Strings/{Q1_05_One_Away_A.cs => Q1 05 One Edit Away.cs} (87%) diff --git a/Ch 01. Arrays and Strings/Q1_05_One_Away_A.cs b/Ch 01. Arrays and Strings/Q1 05 One Edit Away.cs similarity index 87% rename from Ch 01. Arrays and Strings/Q1_05_One_Away_A.cs rename to Ch 01. Arrays and Strings/Q1 05 One Edit Away.cs index 5a25bf7..6de5bd4 100644 --- a/Ch 01. Arrays and Strings/Q1_05_One_Away_A.cs +++ b/Ch 01. Arrays and Strings/Q1 05 One Edit Away.cs @@ -1,113 +1,117 @@ -using ctci.Contracts; -using System; - -namespace Chapter01 -{ - public class Q1_05_One_Away_A : Question - { - public static bool OneEditReplace(String s1, String s2) - { - bool foundDifference = false; - for (int i = 0; i < s1.Length; i++) - { - if (s1[i] != s2[i]) - { - if (foundDifference) - { - return false; - } - - foundDifference = true; - } - } - return true; - } - - /* Check if you can insert a character into s1 to make s2. */ - - public static bool OneEditInsert(String s1, String s2) - { - int index1 = 0; - int index2 = 0; - while (index2 < s2.Length && index1 < s1.Length) - { - if (s1[index1] != s2[index2]) - { - if (index1 != index2) - { - return false; - } - index2++; - } - else { - index1++; - index2++; - } - } - return true; - } - - public static bool OneEditAway(String first, String second) - { - if (first.Length == second.Length) - { - return OneEditReplace(first, second); - } - else if (first.Length + 1 == second.Length) - { - return OneEditInsert(first, second); - } - else if (first.Length - 1 == second.Length) - { - return OneEditInsert(second, first); - } - return false; - } - - public static bool OneEditAway2(String first, String second) - { - /* Length checks. */ - if (Math.Abs(first.Length - second.Length) > 1) - { - return false; - } - - /* Get shorter and longer string.*/ - String s1 = first.Length < second.Length ? first : second; - String s2 = first.Length < second.Length ? second : first; - - int index1 = 0; - int index2 = 0; - bool foundDifference = false; - while (index2 < s2.Length && index1 < s1.Length) - { - if (s1[index1] != s2[index2]) - { - /* Ensure that this is the first difference found.*/ - if (foundDifference) return false; - foundDifference = true; - if (s1.Length == s2.Length) - { // On replace, move shorter pointer - index1++; - } - } - else { - index1++; // If matching, move shorter pointer - } - index2++; // Always move pointer for longer string - } - return true; - } - - public override void Run() - { - String a = "pse"; - String b = "pale"; - bool isOneEdit = OneEditAway(a, b); - Console.WriteLine("{0}, {1}: {2}", a, b, isOneEdit); - - bool isOneEdit2 = OneEditAway2(a, b); - Console.WriteLine("{0}, {1}: {2}", a, b, isOneEdit2); - } - } +using ctci.Contracts; +using System; + +namespace Chapter01 +{ + public class Q1_05_One_Edit_Away : Question + { + public override void Run() + { + String a = "pse"; + String b = "pale"; + var c = "ple"; + var d = "pele"; + Console.WriteLine($"{a}, {b}: {OneEditAway(a, b)} / {OneEditAway2(a, b)}"); + Console.WriteLine($"{b}, {c}: {OneEditAway(b, c)} / {OneEditAway2(b, c)}"); + Console.WriteLine($"{b}, {d}: {OneEditAway(b, d)} / {OneEditAway2(b, d)}"); + + + } + public static bool OneEditReplace(String s1, String s2) + { + bool foundDifference = false; + for (int i = 0; i < s1.Length; i++) + { + if (s1[i] != s2[i]) + { + if (foundDifference) + { + return false; + } + + foundDifference = true; + } + } + return true; + } + + /* Check if you can insert a character into s1 to make s2. */ + + public static bool OneEditInsert(String s1, String s2) + { + int index1 = 0; + int index2 = 0; + while (index2 < s2.Length && index1 < s1.Length) + { + if (s1[index1] != s2[index2]) + { + if (index1 != index2) + { + return false; + } + index2++; + } + else + { + index1++; + index2++; + } + } + return true; + } + + public static bool OneEditAway(String first, String second) + { + if (first.Length == second.Length) + { + return OneEditReplace(first, second); + } + else if (first.Length + 1 == second.Length) + { + return OneEditInsert(first, second); + } + else if (first.Length - 1 == second.Length) + { + return OneEditInsert(second, first); + } + return false; + } + + public static bool OneEditAway2(String first, String second) + { + /* Length checks. */ + if (Math.Abs(first.Length - second.Length) > 1) + { + return false; + } + + /* Get shorter and longer string.*/ + String s1 = first.Length < second.Length ? first : second; + String s2 = first.Length < second.Length ? second : first; + + int index1 = 0; + int index2 = 0; + bool foundDifference = false; + while (index2 < s2.Length && index1 < s1.Length) + { + if (s1[index1] != s2[index2]) + { + /* Ensure that this is the first difference found.*/ + if (foundDifference) return false; + foundDifference = true; + if (s1.Length == s2.Length) + { // On replace, move shorter pointer + index1++; + } + } + else + { + index1++; // If matching, move shorter pointer + } + index2++; // Always move pointer for longer string + } + return true; + } + + } } \ No newline at end of file diff --git a/Ch 01. Arrays and Strings/Q1_01_Is_Unique.cs b/Ch 01. Arrays and Strings/Q1_01_Is_Unique.cs index 42ff716..6d923c1 100644 --- a/Ch 01. Arrays and Strings/Q1_01_Is_Unique.cs +++ b/Ch 01. Arrays and Strings/Q1_01_Is_Unique.cs @@ -1,6 +1,7 @@ using ctci.Contracts; using System; using System.Collections.Generic; +using System.Linq; namespace Chapter01 { @@ -9,19 +10,13 @@ public class Q1_01_Is_Unique : Question private bool IsUniqueChars(string str) { if (str.Length > 256) - { - return false; - } + throw new ArgumentException("String has to be less than 256 characters"); var checker = 0; for (var i = 0; i < str.Length; i++) { var val = str[i] - 'a'; - - if ((checker & (1 << val)) > 0) - { - return false; - } + if ((checker & (1 << val)) > 0) return false; checker |= (1 << val); } @@ -31,20 +26,17 @@ private bool IsUniqueChars(string str) private bool IsUniqueChars2(String str) { var hashset = new HashSet(); - foreach(var c in str) + foreach (var c in str) { if (hashset.Contains(c)) return false; hashset.Add(c); } - return true; } public override void Run() { - string[] words = { "abcde", "hello", "apple", "kite", "padle" }; - - foreach (var word in words) + foreach (var word in new string[] { "abcde", "hello", "apple", "kite", "padle" }) { Console.WriteLine(word + ": " + IsUniqueChars(word) + " " + IsUniqueChars2(word)); } diff --git a/Ch 01. Arrays and Strings/Q1_02_Check_Permutation.cs b/Ch 01. Arrays and Strings/Q1_02_Check_Permutation.cs index c2f18b4..b066780 100644 --- a/Ch 01. Arrays and Strings/Q1_02_Check_Permutation.cs +++ b/Ch 01. Arrays and Strings/Q1_02_Check_Permutation.cs @@ -1,6 +1,7 @@ using ctci.Contracts; using System; using System.Collections.Generic; +using System.Linq; namespace Chapter01 { @@ -9,27 +10,21 @@ public class Q1_02_Check_Permutation : Question private bool IsPermutation(string original, string valueToTest) { if (original.Length != valueToTest.Length) - { return false; - } var originalAsArray = original.ToCharArray(); Array.Sort(originalAsArray); - original = new string(originalAsArray); var valueToTestAsArray = valueToTest.ToCharArray(); Array.Sort(valueToTestAsArray); - valueToTest = new string(valueToTestAsArray); - return original.Equals(valueToTest); + return originalAsArray.SequenceEqual(valueToTestAsArray); } private bool IsPermutation2(string original, string valueToTest) { if (original.Length != valueToTest.Length) - { return false; - } var letterCount = new Dictionary(); diff --git a/Ch 04. Trees/Q4_04_CheckBalanced.cs b/Ch 04. Trees/Q4_04_CheckBalanced.cs index 27857fd..30879b6 100644 --- a/Ch 04. Trees/Q4_04_CheckBalanced.cs +++ b/Ch 04. Trees/Q4_04_CheckBalanced.cs @@ -4,7 +4,7 @@ namespace Chapter04 { - public class Q4_04_CheckBalanced: Question + public class Q4_04_CheckBalanced : Question { public static bool IsBalanced(TreeNode root) { @@ -52,27 +52,19 @@ public override void Run() private static void PrintTree(TreeNode root) { BTreePrinter.Print(root); - var watch = System.Diagnostics.Stopwatch.StartNew(); var isBalanced1 = IsBalanced(root); - watch.Stop(); - var elapsedMs = watch.ElapsedMilliseconds; if (isBalanced1) Console.WriteLine("Tree is balanced"); else Console.WriteLine("Tree is not balalnced"); - Console.WriteLine($"Elapsed milliconds {elapsedMs}"); - watch = System.Diagnostics.Stopwatch.StartNew(); var isBalanced2 = IsBalancedBook(root); - watch.Stop(); - elapsedMs = watch.ElapsedMilliseconds; if (IsBalancedBook(root)) Console.WriteLine("Tree is balanced"); else Console.WriteLine("Tree is not balalnced"); - Console.WriteLine($"Elapsed milliconds {elapsedMs}"); } } } \ No newline at end of file diff --git a/ctci/Program.cs b/ctci/Program.cs index 3c47114..88be0a9 100644 --- a/ctci/Program.cs +++ b/ctci/Program.cs @@ -26,7 +26,7 @@ private static void Main(string[] args) new Q1_02_Check_Permutation(), new Q1_03_URLify(), new Q1_04_Palindrome_Permutation(), - new Q1_05_One_Away_A(), + new Q1_05_One_Edit_Away(), new Q1_06_String_Compression(), new Q1_07_Rotate_Matrix(), new Q1_08_Zero_Matrix(), From d73e4d6a7c84ce8583868c6e880462a61f432b73 Mon Sep 17 00:00:00 2001 From: Xavier Date: Thu, 28 Sep 2017 11:42:26 -0700 Subject: [PATCH 26/33] Label the rotate matrix more intuitively. --- Ch 01. Arrays and Strings/Q1_07_Rotate_Matrix.cs | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/Ch 01. Arrays and Strings/Q1_07_Rotate_Matrix.cs b/Ch 01. Arrays and Strings/Q1_07_Rotate_Matrix.cs index d8568c6..c655adc 100644 --- a/Ch 01. Arrays and Strings/Q1_07_Rotate_Matrix.cs +++ b/Ch 01. Arrays and Strings/Q1_07_Rotate_Matrix.cs @@ -12,23 +12,22 @@ private void Rotate(int[][] matrix, int n) { var first = layer; var last = n - 1 - layer; - for (var i = first; i < last; ++i) { var offset = i - first; - var top = matrix[first][i]; // save top + var top = matrix[first][i]; // save top, left - // left -> top + // top, left <- bottom, left matrix[first][i] = matrix[last - offset][first]; - // bottom -> left + // bottom, left <- bottom, right matrix[last - offset][first] = matrix[last][last - offset]; - // right -> bottom + // bottom, right <- top, right matrix[last][last - offset] = matrix[i][last]; - // top -> right - matrix[i][last] = top; // right <- saved top + // top, right <- top + matrix[i][last] = top; } } } From 08369eab23fcfeb85b796e13cdeffbafe2026c50 Mon Sep 17 00:00:00 2001 From: Xavier Date: Thu, 28 Sep 2017 13:47:07 -0700 Subject: [PATCH 27/33] Update code to use a multidimensional array for matrix instead of jagged arrays. --- .../Q1_07_Rotate_Matrix.cs | 23 +-- .../Q1_08_Zero_Matrix.cs | 145 +++++------------- .../Q10_09_Sorted_Matrix_Search.cs | 57 +++---- ctci.Library/AssortedMethods.cs | 58 ++----- 4 files changed, 94 insertions(+), 189 deletions(-) diff --git a/Ch 01. Arrays and Strings/Q1_07_Rotate_Matrix.cs b/Ch 01. Arrays and Strings/Q1_07_Rotate_Matrix.cs index c655adc..2f5268b 100644 --- a/Ch 01. Arrays and Strings/Q1_07_Rotate_Matrix.cs +++ b/Ch 01. Arrays and Strings/Q1_07_Rotate_Matrix.cs @@ -6,7 +6,7 @@ namespace Chapter01 { public class Q1_07_Rotate_Matrix : Question { - private void Rotate(int[][] matrix, int n) + private void Rotate(int[,] matrix, int n) { for (var layer = 0; layer < n / 2; ++layer) { @@ -15,32 +15,35 @@ private void Rotate(int[][] matrix, int n) for (var i = first; i < last; ++i) { var offset = i - first; - var top = matrix[first][i]; // save top, left + var top = matrix[first, i]; // save top, left // top, left <- bottom, left - matrix[first][i] = matrix[last - offset][first]; + matrix[first, i] = matrix[last - offset, first]; // bottom, left <- bottom, right - matrix[last - offset][first] = matrix[last][last - offset]; + matrix[last - offset, first] = matrix[last, last - offset]; // bottom, right <- top, right - matrix[last][last - offset] = matrix[i][last]; + matrix[last, last - offset] = matrix[i, last]; // top, right <- top - matrix[i][last] = top; + matrix[i, last] = top; } } } public override void Run() { - const int size = 3; - - var matrix = AssortedMethods.RandomMatrix(size, size, 0, 9); + var matrix = new[,] + { + {1,2,3 }, + {4,5,6 }, + {7,8,9 } + }; AssortedMethods.PrintMatrix(matrix); - Rotate(matrix, size); + Rotate(matrix, matrix.GetLength(0)); Console.WriteLine(); AssortedMethods.PrintMatrix(matrix); } diff --git a/Ch 01. Arrays and Strings/Q1_08_Zero_Matrix.cs b/Ch 01. Arrays and Strings/Q1_08_Zero_Matrix.cs index 7869d33..d4a560b 100644 --- a/Ch 01. Arrays and Strings/Q1_08_Zero_Matrix.cs +++ b/Ch 01. Arrays and Strings/Q1_08_Zero_Matrix.cs @@ -6,51 +6,52 @@ namespace Chapter01 { public class Q1_08_Zero_Matrix : Question { - private void NullifyRow(int[][] matrix, int row) + private void NullifyRow(int[,] matrix, int row) { - for (var j = 0; j < matrix[0].Length; j++) + var width = matrix.GetLength(1); + for (var column = 0; column < width; column++) { - matrix[row][j] = 0; + matrix[row, column] = 0; } } - private void NullifyColumn(int[][] matrix, int col) + private void NullifyColumn(int[,] matrix, int col) { - for (var i = 0; i < matrix.Length; i++) + var height = matrix.GetLength(0); + for (var row = 0; row < height; row++) { - matrix[i][col] = 0; + matrix[row, col] = 0; } } - private int[][] CloneMatrix(int[][] matrix) + private int[,] CloneMatrix(int[,] matrix) { - var clone = new int[matrix.Length][]; + var height = matrix.GetLength(0); + var width = matrix.GetLength(1); - for (var i = 0; i < matrix.Length; i++) + var clone = new int[height, width]; + for (var row = 0; row < height; row++) { - clone[i] = new int[matrix[0].Length]; - - for (var j = 0; j < matrix[0].Length; j++) + for (var column = 0; column < width; column++) { - clone[i][j] = matrix[i][j]; + clone[row, column] = matrix[row, column]; } } - return clone; } - private bool MatricesAreEqual(int[][] matrix1, int[][] matrix2) + private bool MatricesAreEqual(int[,] matrix1, int[,] matrix2) { - if (matrix1.Length != matrix2.Length || matrix1[0].Length != matrix2[0].Length) + if (matrix1.GetLength(0) != matrix2.GetLength(0) || matrix1.GetLength(1) != matrix2.GetLength(1)) { return false; } - for (var k = 0; k < matrix1.Length; k++) + for (var row = 0; row < matrix1.GetLength(0); row++) { - for (var j = 0; j < matrix1[0].Length; j++) + for (var column = 0; column < matrix1.GetLength(1); column++) { - if (matrix1[k][j] != matrix2[k][j]) + if (matrix1[row, column] != matrix2[row, column]) { return false; } @@ -60,131 +61,55 @@ private bool MatricesAreEqual(int[][] matrix1, int[][] matrix2) return true; } - private void SetZeros(int[][] matrix) + private void SetZeros(int[,] matrix) { - var row = new bool[matrix.Length]; - var column = new bool[matrix[0].Length]; + var height = matrix.GetLength(0); + var width = matrix.GetLength(1); + + var rowArray = new bool[height]; + var columnArray = new bool[width]; // Store the row and column index with value 0 - for (var i = 0; i < matrix.Length; i++) + for (var row = 0; row < height; row++) { - for (var j = 0; j < matrix[0].Length; j++) + for (var column = 0; column < width; column++) { - if (matrix[i][j] == 0) + if (matrix[row, column] == 0) { - row[i] = true; - column[j] = true; + rowArray[row] = true; + columnArray[column] = true; } } } // Nullify rows - for (var i = 0; i < row.Length; i++) + for (var i = 0; i < rowArray.Length; i++) { - if (row[i]) + if (rowArray[i]) { NullifyRow(matrix, i); } } // Nullify columns - for (var j = 0; j < column.Length; j++) + for (var j = 0; j < columnArray.Length; j++) { - if (column[j]) + if (columnArray[j]) { NullifyColumn(matrix, j); } } } - private void SetZeros2(int[][] matrix) - { - var rowHasZero = false; - var colHasZero = false; - - // Check if first row has a zero - for (var j = 0; j < matrix[0].Length; j++) - { - if (matrix[0][j] == 0) - { - rowHasZero = true; - break; - } - } - - // Check if first column has a zero - for (var i = 0; i < matrix.Length; i++) - { - if (matrix[i][0] == 0) - { - colHasZero = true; - break; - } - } - - // Check for zeros in the rest of the array - for (var i = 1; i < matrix.Length; i++) - { - for (var j = 1; j < matrix[0].Length; j++) - { - if (matrix[i][j] == 0) - { - matrix[i][0] = 0; - matrix[0][j] = 0; - } - } - } - - // Nullify rows based on values in first column - for (var i = 1; i < matrix.Length; i++) - { - if (matrix[i][0] == 0) - { - NullifyRow(matrix, i); - } - } - - // Nullify columns based on values in first row - for (var j = 1; j < matrix[0].Length; j++) - { - if (matrix[0][j] == 0) - { - NullifyColumn(matrix, j); - } - } - - // Nullify first row - if (rowHasZero) - { - NullifyRow(matrix, 0); - } - - // Nullify first column - if (colHasZero) - { - NullifyColumn(matrix, 0); - } - } - public override void Run() { const int numberOfRows = 10; const int numberOfColumns = 15; var matrix1 = AssortedMethods.RandomMatrix(numberOfRows, numberOfColumns, 0, 100); - var matrix2 = CloneMatrix(matrix1); - AssortedMethods.PrintMatrix(matrix1); - SetZeros(matrix1); - SetZeros2(matrix2); - Console.WriteLine(); - AssortedMethods.PrintMatrix(matrix1); - Console.WriteLine(); - AssortedMethods.PrintMatrix(matrix2); - - Console.WriteLine(MatricesAreEqual(matrix1, matrix2) ? "Equal" : "Not Equal"); } } } \ No newline at end of file diff --git a/Ch 10. Sorting and Searching/Q10_09_Sorted_Matrix_Search.cs b/Ch 10. Sorting and Searching/Q10_09_Sorted_Matrix_Search.cs index 91973ec..506bd29 100644 --- a/Ch 10. Sorting and Searching/Q10_09_Sorted_Matrix_Search.cs +++ b/Ch 10. Sorting and Searching/Q10_09_Sorted_Matrix_Search.cs @@ -17,12 +17,12 @@ public Coordinate(int r, int c) column = c; } - public bool Inbounds(int[][] matrix) + public bool Inbounds(int[,] matrix) { return row >= 0 && column >= 0 && - row < matrix.Length && - column < matrix[0].Length; + row < matrix.GetLength(0) && + column < matrix.GetLength(1); } public bool IsBefore(Coordinate p) @@ -48,21 +48,22 @@ public void SetToAverage(Coordinate min, Coordinate max) } } - public static bool FindElement(int[][] matrix, int elem) + public static bool FindElement(int[,] matrix, int elem) { int row = 0; - int col = matrix[0].Length - 1; - while (row < matrix.Length && col >= 0) + int col = matrix.GetLength(1) - 1; + while (row < matrix.GetLength(0) && col >= 0) { - if (matrix[row][col] == elem) + if (matrix[row, col] == elem) { return true; } - else if (matrix[row][col] > elem) + else if (matrix[row, col] > elem) { col--; } - else { + else + { row++; } } @@ -73,13 +74,12 @@ public void Run1() { int M = 10; int N = 5; - var matrix = new int[M][]; + var matrix = new int[M, N]; for (int i = 0; i < M; i++) { - matrix[i] = new int[N]; for (int j = 0; j < N; j++) { - matrix[i][j] = 10 * i + j; + matrix[i, j] = 10 * i + j; } } @@ -97,21 +97,21 @@ public void Run1() public void Run2() { - int[][] matrix = new[] { - new [] {15, 30, 50, 70, 73}, - new [] {35, 40, 100, 102, 120}, - new [] {36, 42, 105, 110, 125}, - new [] {46, 51, 106, 111, 130}, - new [] {48, 55, 109, 140, 150} + int[,] matrix = new[,] { + {15, 30, 50, 70, 73}, + {35, 40, 100, 102, 120}, + {36, 42, 105, 110, 125}, + {46, 51, 106, 111, 130}, + {48, 55, 109, 140, 150} }; AssortedMethods.PrintMatrix(matrix); - int m = matrix.Length; - int n = matrix[0].Length; + int rows = matrix.GetLength(0); + int columns = matrix.GetLength(1); int count = 0; - int littleOverTheMax = matrix[m - 1][n - 1] + 10; + int littleOverTheMax = matrix[rows - 1, columns - 1] + 10; for (int i = 0; i < littleOverTheMax; i++) { Coordinate c = FindElement2(matrix, i); @@ -132,7 +132,7 @@ public override void Run() #region Solution B - public static Coordinate PartitionAndSearch(int[][] matrix, Coordinate origin, Coordinate dest, Coordinate pivot, int x) + public static Coordinate PartitionAndSearch(int[,] matrix, Coordinate origin, Coordinate dest, Coordinate pivot, int x) { Coordinate lowerLeftOrigin = new Coordinate(pivot.row, origin.column); Coordinate lowerLeftDest = new Coordinate(dest.row, pivot.column - 1); @@ -147,13 +147,13 @@ public static Coordinate PartitionAndSearch(int[][] matrix, Coordinate origin, C return lowerLeft; } - public static Coordinate FindElement2(int[][] matrix, Coordinate origin, Coordinate dest, int x) + public static Coordinate FindElement2(int[,] matrix, Coordinate origin, Coordinate dest, int x) { if (!origin.Inbounds(matrix) || !dest.Inbounds(matrix)) { return null; } - if (matrix[origin.row][origin.column] == x) + if (matrix[origin.row, origin.column] == x) { return origin; } @@ -174,12 +174,13 @@ public static Coordinate FindElement2(int[][] matrix, Coordinate origin, Coordin while (start.IsBefore(end)) { p.SetToAverage(start, end); - if (x > matrix[p.row][p.column]) + if (x > matrix[p.row, p.column]) { start.row = p.row + 1; start.column = p.column + 1; } - else { + else + { end.row = p.row - 1; end.column = p.column - 1; } @@ -189,10 +190,10 @@ public static Coordinate FindElement2(int[][] matrix, Coordinate origin, Coordin return PartitionAndSearch(matrix, origin, dest, start, x); } - public static Coordinate FindElement2(int[][] matrix, int x) + public static Coordinate FindElement2(int[,] matrix, int x) { Coordinate origin = new Coordinate(0, 0); - Coordinate dest = new Coordinate(matrix.Length - 1, matrix[0].Length - 1); + Coordinate dest = new Coordinate(matrix.GetLength(0) - 1, matrix.GetLength(1) - 1); return FindElement2(matrix, origin, dest, x); } diff --git a/ctci.Library/AssortedMethods.cs b/ctci.Library/AssortedMethods.cs index 294ed2f..9acf48a 100644 --- a/ctci.Library/AssortedMethods.cs +++ b/ctci.Library/AssortedMethods.cs @@ -28,15 +28,14 @@ public static bool RandomBoolean(int percentTrue) return RandomIntInRange(1, 100) <= percentTrue; } - public static int[][] RandomMatrix(int m, int n, int min, int max) + public static int[,] RandomMatrix(int rows, int columns, int min, int max) { - int[][] matrix = new int[m][]; - for (int i = 0; i < m; i++) + int[,] matrix = new int[rows, columns]; + for (int i = 0; i < rows; i++) { - matrix[i] = new int[n]; - for (int j = 0; j < n; j++) + for (int j = 0; j < columns; j++) { - matrix[i][j] = RandomIntInRange(min, max); + matrix[i, j] = RandomIntInRange(min, max); } } return matrix; @@ -127,57 +126,34 @@ public static string ToBaseNstring(int a, int baseN) return s; } - public static void PrintMatrix(int[][] matrix) + public static void PrintMatrix(int[,] matrix) { - for (int i = 0; i < matrix.Length; i++) + var height = matrix.GetLength(0); + var width = matrix.GetLength(1); + for (int i = 0; i < height; i++) { - for (int j = 0; j < matrix[i].Length; j++) + for (int j = 0; j < width; j++) { - if (matrix[i][j] < 10 && matrix[i][j] > -10) - { - Console.Write(" "); - } - if (matrix[i][j] < 100 && matrix[i][j] > -100) - { - Console.Write(" "); - } - if (matrix[i][j] >= 0) - { - Console.Write(" "); - } - Console.Write(" " + matrix[i][j]); + Console.Write($" {matrix[i, j],3}"); } Console.WriteLine(); } } - public static void PrintMatrix(bool[][] matrix) + public static void PrintMatrix(bool[,] matrix) { - for (int i = 0; i < matrix.Length; i++) + var height = matrix.GetLength(0); + var width = matrix.GetLength(1); + for (int i = 0; i < height; i++) { - for (int j = 0; j < matrix[i].Length; j++) + for (int j = 0; j < width; j++) { - if (matrix[i][j]) - { - Console.Write("1"); - } - else - { - Console.Write("0"); - } + Console.Write(matrix[i, j] ? "1" : "0"); } Console.WriteLine(); } } - public static void PrintIntArray(int[] array) - { - for (int i = 0; i < array.Length; i++) - { - Console.Write(array[i] + " "); - } - Console.WriteLine(""); - } public static void PrintList(IEnumerable list) { From f5eeb233a2c8b65f36e80d04d3c8d33c02194b5c Mon Sep 17 00:00:00 2001 From: Xavier John Date: Tue, 24 Jul 2018 11:27:55 -0700 Subject: [PATCH 28/33] Switch to .net core 2.0 --- Ch 01. Arrays and Strings/Ch 01. Arrays and Strings.csproj | 2 +- Ch 02. Linked Lists/Ch 02. Linked Lists.csproj | 2 +- Ch 04. Trees/Ch 04. Trees.csproj | 2 +- Ch 05. Bit Manipulation/Ch 05. Bit Manipulation.csproj | 2 +- .../Ch 10. Sorting and Searching.csproj | 2 +- Ch 16. Moderate/Ch 16. Moderate.csproj | 2 +- Introduction/Introduction.csproj | 2 +- ctci.Contracts/ctci.Contracts.csproj | 2 +- ctci.Library/ctci.Library.csproj | 2 +- ctci/ctci.csproj | 2 +- 10 files changed, 10 insertions(+), 10 deletions(-) diff --git a/Ch 01. Arrays and Strings/Ch 01. Arrays and Strings.csproj b/Ch 01. Arrays and Strings/Ch 01. Arrays and Strings.csproj index 8ab28a9..ec74bf5 100644 --- a/Ch 01. Arrays and Strings/Ch 01. Arrays and Strings.csproj +++ b/Ch 01. Arrays and Strings/Ch 01. Arrays and Strings.csproj @@ -1,7 +1,7 @@  - netcoreapp1.1 + netstandard2.0 Chapter01 diff --git a/Ch 02. Linked Lists/Ch 02. Linked Lists.csproj b/Ch 02. Linked Lists/Ch 02. Linked Lists.csproj index 6cb8dba..9d6dd83 100644 --- a/Ch 02. Linked Lists/Ch 02. Linked Lists.csproj +++ b/Ch 02. Linked Lists/Ch 02. Linked Lists.csproj @@ -1,7 +1,7 @@  - netcoreapp1.1 + netstandard2.0 Chapter02 diff --git a/Ch 04. Trees/Ch 04. Trees.csproj b/Ch 04. Trees/Ch 04. Trees.csproj index b01a999..f9301ad 100644 --- a/Ch 04. Trees/Ch 04. Trees.csproj +++ b/Ch 04. Trees/Ch 04. Trees.csproj @@ -1,7 +1,7 @@  - netcoreapp1.1 + netstandard2.0 diff --git a/Ch 05. Bit Manipulation/Ch 05. Bit Manipulation.csproj b/Ch 05. Bit Manipulation/Ch 05. Bit Manipulation.csproj index 98877a9..6f2721f 100644 --- a/Ch 05. Bit Manipulation/Ch 05. Bit Manipulation.csproj +++ b/Ch 05. Bit Manipulation/Ch 05. Bit Manipulation.csproj @@ -1,7 +1,7 @@  - netcoreapp1.1 + netstandard2.0 Chapter05 diff --git a/Ch 10. Sorting and Searching/Ch 10. Sorting and Searching.csproj b/Ch 10. Sorting and Searching/Ch 10. Sorting and Searching.csproj index d5758af..7ac2872 100644 --- a/Ch 10. Sorting and Searching/Ch 10. Sorting and Searching.csproj +++ b/Ch 10. Sorting and Searching/Ch 10. Sorting and Searching.csproj @@ -1,7 +1,7 @@  - netcoreapp1.1 + netstandard2.0 diff --git a/Ch 16. Moderate/Ch 16. Moderate.csproj b/Ch 16. Moderate/Ch 16. Moderate.csproj index b01a999..f9301ad 100644 --- a/Ch 16. Moderate/Ch 16. Moderate.csproj +++ b/Ch 16. Moderate/Ch 16. Moderate.csproj @@ -1,7 +1,7 @@  - netcoreapp1.1 + netstandard2.0 diff --git a/Introduction/Introduction.csproj b/Introduction/Introduction.csproj index 294d446..dbf8049 100644 --- a/Introduction/Introduction.csproj +++ b/Introduction/Introduction.csproj @@ -1,7 +1,7 @@  - netcoreapp1.1 + netstandard2.0 diff --git a/ctci.Contracts/ctci.Contracts.csproj b/ctci.Contracts/ctci.Contracts.csproj index b57c3c8..3cbda2f 100644 --- a/ctci.Contracts/ctci.Contracts.csproj +++ b/ctci.Contracts/ctci.Contracts.csproj @@ -1,7 +1,7 @@  - netcoreapp1.1 + netstandard2.0 diff --git a/ctci.Library/ctci.Library.csproj b/ctci.Library/ctci.Library.csproj index b57c3c8..3cbda2f 100644 --- a/ctci.Library/ctci.Library.csproj +++ b/ctci.Library/ctci.Library.csproj @@ -1,7 +1,7 @@  - netcoreapp1.1 + netstandard2.0 diff --git a/ctci/ctci.csproj b/ctci/ctci.csproj index 20fcae9..c2b97d2 100644 --- a/ctci/ctci.csproj +++ b/ctci/ctci.csproj @@ -2,7 +2,7 @@ Exe - netcoreapp1.1 + netcoreapp2.0 From 80319563260c3aa3e2bb9e6f9450413808aa3593 Mon Sep 17 00:00:00 2001 From: Xavier Date: Sun, 21 Oct 2018 11:41:30 -0700 Subject: [PATCH 29/33] Chapter 17, Question 12 BiNode --- Ch 02. Linked Lists/Q2_04_Partition.cs | 2 +- Ch 16. Moderate/Q16_08_English_Int.cs | 1 - Ch 17. Hard/Ch 17. Hard.csproj | 12 ++++ Ch 17. Hard/Q17_12_BiNode.cs | 90 ++++++++++++++++++++++++++ ctci.sln | 30 ++++++--- ctci/Program.cs | 6 ++ ctci/ctci.csproj | 1 + 7 files changed, 130 insertions(+), 12 deletions(-) create mode 100644 Ch 17. Hard/Ch 17. Hard.csproj create mode 100644 Ch 17. Hard/Q17_12_BiNode.cs diff --git a/Ch 02. Linked Lists/Q2_04_Partition.cs b/Ch 02. Linked Lists/Q2_04_Partition.cs index 0917178..aff58eb 100644 --- a/Ch 02. Linked Lists/Q2_04_Partition.cs +++ b/Ch 02. Linked Lists/Q2_04_Partition.cs @@ -178,7 +178,7 @@ private LinkedListNode Partition4(LinkedListNode listHead, int pivot) public override void Run() { /* Create linked list */ - int[] vals = { 1, 3, 7, 5, 2, 9, 4 }; + int[] vals = { 3, 5, 8, 5, 10, 2, 1 }; var head = new LinkedListNode(vals[0], null, null); var current = head; diff --git a/Ch 16. Moderate/Q16_08_English_Int.cs b/Ch 16. Moderate/Q16_08_English_Int.cs index 4f5134a..c8a9d2d 100644 --- a/Ch 16. Moderate/Q16_08_English_Int.cs +++ b/Ch 16. Moderate/Q16_08_English_Int.cs @@ -1,5 +1,4 @@ using ctci.Contracts; -using ctci.Library; using System; using System.Collections.Generic; using System.Text; diff --git a/Ch 17. Hard/Ch 17. Hard.csproj b/Ch 17. Hard/Ch 17. Hard.csproj new file mode 100644 index 0000000..f9301ad --- /dev/null +++ b/Ch 17. Hard/Ch 17. Hard.csproj @@ -0,0 +1,12 @@ + + + + netstandard2.0 + + + + + + + + \ No newline at end of file diff --git a/Ch 17. Hard/Q17_12_BiNode.cs b/Ch 17. Hard/Q17_12_BiNode.cs new file mode 100644 index 0000000..fdfc714 --- /dev/null +++ b/Ch 17. Hard/Q17_12_BiNode.cs @@ -0,0 +1,90 @@ +using ctci.Contracts; +using ctci.Library; +using System; + +namespace Chapter17 +{ + public class Q17_12_BiNode : Question + { + public override void Run() + { + var root = Create(0, 1, 2, 3, 4, 5, 6); + BTreePrinter.Print(root); + var sol1 = new Solution1(); + var result = sol1.Convert(root); + + var curr = result.Head; + + while (curr.Right != null) + { + Console.Write($"{curr.Data} "); + curr = curr.Right; + } + Console.WriteLine($"{curr.Data} "); + + while (curr.Left != null) + { + Console.Write($"{curr.Data} "); + curr = curr.Left; + } + Console.WriteLine($"{curr.Data} "); + } + + public static TreeNode Create(params int[] sortedArray) + { + return Create(sortedArray, 0, sortedArray.Length - 1); + } + + private static TreeNode Create(int[] sortedArray, int left, int right) + { + if (left > right) return null; + var mid = left + (right - left) / 2; + var treeNode = new TreeNode(sortedArray[mid]); + treeNode.SetLeftChild(Create(sortedArray, left, mid - 1)); + treeNode.SetRightChild(Create(sortedArray, mid + 1, right)); + return treeNode; + } + + public class Solution1 + { + public NodePair Convert(TreeNode root) + { + if (root == null) return null; + + var part1 = Convert(root.Left); + var part2 = Convert(root.Right); + + if (part1 != null) + { + Concat(part1.Tail, root); + } + + if (part2 != null) + { + Concat(root, part2.Head); + } + + return new NodePair(part1 == null ? root : part1.Head, part2 == null ? root : part2.Tail); + } + + private void Concat(TreeNode x, TreeNode y) + { + x.Right = y; + y.Left = x; + } + + public class NodePair + { + public TreeNode Head { get; private set; } + public TreeNode Tail { get; private set; } + + public NodePair(TreeNode head, TreeNode tail) + { + this.Head = head; + this.Tail = tail; + } + + } + } + } +} diff --git a/ctci.sln b/ctci.sln index a5422bd..4c8561b 100644 --- a/ctci.sln +++ b/ctci.sln @@ -3,29 +3,31 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 15 VisualStudioVersion = 15.0.26228.4 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ctci", "ctci\ctci.csproj", "{F7867FE4-E80B-44DD-9666-C82E6D401B8A}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ctci", "ctci\ctci.csproj", "{F7867FE4-E80B-44DD-9666-C82E6D401B8A}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ch 01. Arrays and Strings", "Ch 01. Arrays and Strings\Ch 01. Arrays and Strings.csproj", "{3F2DF0FA-D7A0-479B-B720-3AB7411E9539}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ch 01. Arrays and Strings", "Ch 01. Arrays and Strings\Ch 01. Arrays and Strings.csproj", "{3F2DF0FA-D7A0-479B-B720-3AB7411E9539}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ctci.Contracts", "ctci.Contracts\ctci.Contracts.csproj", "{D1B538B9-DE81-4FFF-93B2-A958ED2CE4DA}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ctci.Contracts", "ctci.Contracts\ctci.Contracts.csproj", "{D1B538B9-DE81-4FFF-93B2-A958ED2CE4DA}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ctci.Library", "ctci.Library\ctci.Library.csproj", "{8DC982E1-042C-4652-BBC4-CD375223C852}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ctci.Library", "ctci.Library\ctci.Library.csproj", "{8DC982E1-042C-4652-BBC4-CD375223C852}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Introduction", "Introduction\Introduction.csproj", "{AF745A68-20A9-4FF4-801C-86A3B0383C49}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Introduction", "Introduction\Introduction.csproj", "{AF745A68-20A9-4FF4-801C-86A3B0383C49}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Helpers", "Helpers", "{F9BD47E4-94CA-4823-B074-22E8ABE9B8C8}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Questions", "Questions", "{8E563D72-A200-4BB7-8AB8-A93BEED3A5B7}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ch 05. Bit Manipulation", "Ch 05. Bit Manipulation\Ch 05. Bit Manipulation.csproj", "{6515F74F-66C6-414D-B5EC-10260AAD473C}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ch 05. Bit Manipulation", "Ch 05. Bit Manipulation\Ch 05. Bit Manipulation.csproj", "{6515F74F-66C6-414D-B5EC-10260AAD473C}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ch 02. Linked Lists", "Ch 02. Linked Lists\Ch 02. Linked Lists.csproj", "{D1ACE913-9486-4CDC-B980-A5F848A67108}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ch 02. Linked Lists", "Ch 02. Linked Lists\Ch 02. Linked Lists.csproj", "{D1ACE913-9486-4CDC-B980-A5F848A67108}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ch 10. Sorting and Searching", "Ch 10. Sorting and Searching\Ch 10. Sorting and Searching.csproj", "{90D56A57-CEAD-42F8-A978-BC2D33530E0E}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ch 10. Sorting and Searching", "Ch 10. Sorting and Searching\Ch 10. Sorting and Searching.csproj", "{90D56A57-CEAD-42F8-A978-BC2D33530E0E}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ch 16. Moderate", "Ch 16. Moderate\Ch 16. Moderate.csproj", "{AE0D044B-1AE9-430F-B05D-ADAC72C407B8}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ch 16. Moderate", "Ch 16. Moderate\Ch 16. Moderate.csproj", "{AE0D044B-1AE9-430F-B05D-ADAC72C407B8}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ch 04. Trees", "Ch 04. Trees\Ch 04. Trees.csproj", "{AF583937-1A80-407F-B683-3FEED7F3BC16}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ch 04. Trees", "Ch 04. Trees\Ch 04. Trees.csproj", "{AF583937-1A80-407F-B683-3FEED7F3BC16}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ch 17. Hard", "Ch 17. Hard\Ch 17. Hard.csproj", "{9C214A20-E419-4731-9E19-302D9957AFF3}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -73,6 +75,10 @@ Global {AF583937-1A80-407F-B683-3FEED7F3BC16}.Debug|Any CPU.Build.0 = Debug|Any CPU {AF583937-1A80-407F-B683-3FEED7F3BC16}.Release|Any CPU.ActiveCfg = Release|Any CPU {AF583937-1A80-407F-B683-3FEED7F3BC16}.Release|Any CPU.Build.0 = Release|Any CPU + {9C214A20-E419-4731-9E19-302D9957AFF3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {9C214A20-E419-4731-9E19-302D9957AFF3}.Debug|Any CPU.Build.0 = Debug|Any CPU + {9C214A20-E419-4731-9E19-302D9957AFF3}.Release|Any CPU.ActiveCfg = Release|Any CPU + {9C214A20-E419-4731-9E19-302D9957AFF3}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -88,5 +94,9 @@ Global {90D56A57-CEAD-42F8-A978-BC2D33530E0E} = {8E563D72-A200-4BB7-8AB8-A93BEED3A5B7} {AE0D044B-1AE9-430F-B05D-ADAC72C407B8} = {8E563D72-A200-4BB7-8AB8-A93BEED3A5B7} {AF583937-1A80-407F-B683-3FEED7F3BC16} = {8E563D72-A200-4BB7-8AB8-A93BEED3A5B7} + {9C214A20-E419-4731-9E19-302D9957AFF3} = {8E563D72-A200-4BB7-8AB8-A93BEED3A5B7} + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {E61B239A-17C9-48B6-9C08-0567ECB16243} EndGlobalSection EndGlobal diff --git a/ctci/Program.cs b/ctci/Program.cs index 88be0a9..875aea0 100644 --- a/ctci/Program.cs +++ b/ctci/Program.cs @@ -4,6 +4,7 @@ using Chapter05; using Chapter10; using Chapter16; +using Chapter17; using ctci.Contracts; using Introduction; using System; @@ -87,6 +88,11 @@ private static void Main(string[] args) new Q16_08_English_Int(), new Q16_19_Pond_Sizes(), new Boggle() + }, + + new Question[] + { + new Q17_12_BiNode(), } }; diff --git a/ctci/ctci.csproj b/ctci/ctci.csproj index c2b97d2..971c1fa 100644 --- a/ctci/ctci.csproj +++ b/ctci/ctci.csproj @@ -16,6 +16,7 @@ + From 216ae6543b1d6434f987d53ceb942e8482355f3b Mon Sep 17 00:00:00 2001 From: Xavier Date: Sun, 21 Oct 2018 17:09:16 -0700 Subject: [PATCH 30/33] BiNode 2nd solution. --- Ch 17. Hard/Q17_12_BiNode.cs | 45 +++++++++++++++++++++++++++++++++++- 1 file changed, 44 insertions(+), 1 deletion(-) diff --git a/Ch 17. Hard/Q17_12_BiNode.cs b/Ch 17. Hard/Q17_12_BiNode.cs index fdfc714..955a9f8 100644 --- a/Ch 17. Hard/Q17_12_BiNode.cs +++ b/Ch 17. Hard/Q17_12_BiNode.cs @@ -12,9 +12,16 @@ public override void Run() BTreePrinter.Print(root); var sol1 = new Solution1(); var result = sol1.Convert(root); + Display(result.Head); - var curr = result.Head; + root = Create(0, 1, 2, 3, 4, 5, 6); + var sol2 = new Solution2(); + var result1 = sol2.Convert(root); + Display(result1); + } + private static void Display(TreeNode curr) + { while (curr.Right != null) { Console.Write($"{curr.Data} "); @@ -86,5 +93,41 @@ public NodePair(TreeNode head, TreeNode tail) } } + + public class Solution2 + { + public TreeNode Convert(TreeNode root) + { + if (root == null) return null; + + var part1 = Convert(root.Left); + var part2 = Convert(root.Right); + + if (part1 != null) + { + Concat(GetTail(part1), root); + } + + if (part2 != null) + { + Concat(root, part2); + } + + return part1 == null ? root : part1; + } + + private TreeNode GetTail(TreeNode part1) + { + if (part1 == null) return null; + while (part1.Right != null) part1 = part1.Right; + return part1; + } + + private void Concat(TreeNode x, TreeNode y) + { + x.Right = y; + y.Left = x; + } + } } } From 1799d61ca4ae8a203017c62ee027109c7a1663c2 Mon Sep 17 00:00:00 2001 From: Xavier Date: Sun, 21 Oct 2018 17:26:25 -0700 Subject: [PATCH 31/33] BiNode Solution 3 --- Ch 17. Hard/Q17_12_BiNode.cs | 73 +++++++++++++++++++++++++++++++++++- 1 file changed, 71 insertions(+), 2 deletions(-) diff --git a/Ch 17. Hard/Q17_12_BiNode.cs b/Ch 17. Hard/Q17_12_BiNode.cs index 955a9f8..d67bbe4 100644 --- a/Ch 17. Hard/Q17_12_BiNode.cs +++ b/Ch 17. Hard/Q17_12_BiNode.cs @@ -10,14 +10,22 @@ public override void Run() { var root = Create(0, 1, 2, 3, 4, 5, 6); BTreePrinter.Print(root); + Console.WriteLine("Solution 1"); var sol1 = new Solution1(); var result = sol1.Convert(root); Display(result.Head); + Console.WriteLine("Solution 2"); root = Create(0, 1, 2, 3, 4, 5, 6); var sol2 = new Solution2(); - var result1 = sol2.Convert(root); - Display(result1); + var result2 = sol2.Convert(root); + Display(result2); + + Console.WriteLine("Solution 3"); + root = Create(0, 1, 2, 3, 4, 5, 6); + var sol3 = new Solution3(); + var result3 = sol3.Convert(root); + Display(result3); } private static void Display(TreeNode curr) @@ -129,5 +137,66 @@ private void Concat(TreeNode x, TreeNode y) y.Left = x; } } + + public class Solution3 + { + public TreeNode Convert(TreeNode root) + { + TreeNode head = ConvertToCircular(root); + head.Left.Right = null; + head.Left = null; + return head; + } + + private TreeNode ConvertToCircular(TreeNode root) + { + if (root == null) return null; + var part1 = ConvertToCircular(root.Left); + var part3 = ConvertToCircular(root.Right); + + if (part1 == null && part3 == null) + { + root.Left = root; + root.Right = root; + return root; + } + + var tail3 = part3 == null ? null : part3.Left; + + // Join left to root. + if (part1 == null) + { + Concat(part3.Left, root); + } + else + { + Concat(part1.Left, root); + } + + // Join right to root. + if (part3 == null) + { + Concat(root, part1); + } + else + { + Concat(root, part3); + } + + // join right to left + if (part1 != null && part3 != null) + { + Concat(tail3, part1); + } + + return part1 == null ? root : part1; + } + + private void Concat(TreeNode x, TreeNode y) + { + x.Right = y; + y.Left = x; + } + } } } From 2faa43d6c60b9321f1227af69f1bd0e917e3c300 Mon Sep 17 00:00:00 2001 From: Xavier John Date: Wed, 9 Jan 2019 15:25:14 -0800 Subject: [PATCH 32/33] Add unit test for IsUnique --- Ch 01. Arrays and Strings/Q1_01_Is_Unique.cs | 4 +-- ctci.sln | 11 ++++++- .../Ch 01. Arrays and Strings Tests.csproj | 14 +++++++++ .../IsUniqueTests.cs | 30 +++++++++++++++++++ tests/directory.build.props | 18 +++++++++++ tests/xunit.runner.json | 4 +++ 6 files changed, 78 insertions(+), 3 deletions(-) create mode 100644 tests/Ch 01. Arrays and Strings Tests/Ch 01. Arrays and Strings Tests.csproj create mode 100644 tests/Ch 01. Arrays and Strings Tests/IsUniqueTests.cs create mode 100644 tests/directory.build.props create mode 100644 tests/xunit.runner.json diff --git a/Ch 01. Arrays and Strings/Q1_01_Is_Unique.cs b/Ch 01. Arrays and Strings/Q1_01_Is_Unique.cs index 6d923c1..567675a 100644 --- a/Ch 01. Arrays and Strings/Q1_01_Is_Unique.cs +++ b/Ch 01. Arrays and Strings/Q1_01_Is_Unique.cs @@ -7,7 +7,7 @@ namespace Chapter01 { public class Q1_01_Is_Unique : Question { - private bool IsUniqueChars(string str) + public bool IsUniqueChars(string str) { if (str.Length > 256) throw new ArgumentException("String has to be less than 256 characters"); @@ -23,7 +23,7 @@ private bool IsUniqueChars(string str) return true; } - private bool IsUniqueChars2(String str) + public bool IsUniqueChars2(String str) { var hashset = new HashSet(); foreach (var c in str) diff --git a/ctci.sln b/ctci.sln index 4c8561b..6ca5d15 100644 --- a/ctci.sln +++ b/ctci.sln @@ -27,7 +27,11 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ch 16. Moderate", "Ch 16. M EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ch 04. Trees", "Ch 04. Trees\Ch 04. Trees.csproj", "{AF583937-1A80-407F-B683-3FEED7F3BC16}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ch 17. Hard", "Ch 17. Hard\Ch 17. Hard.csproj", "{9C214A20-E419-4731-9E19-302D9957AFF3}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ch 17. Hard", "Ch 17. Hard\Ch 17. Hard.csproj", "{9C214A20-E419-4731-9E19-302D9957AFF3}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{0079C857-D80C-4FF5-8F48-206CB6D2F3E6}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ch 01. Arrays and Strings Tests", "tests\Ch 01. Arrays and Strings Tests\Ch 01. Arrays and Strings Tests.csproj", "{072EBD5B-C529-4690-B5A3-9EAA4DB43202}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -79,6 +83,10 @@ Global {9C214A20-E419-4731-9E19-302D9957AFF3}.Debug|Any CPU.Build.0 = Debug|Any CPU {9C214A20-E419-4731-9E19-302D9957AFF3}.Release|Any CPU.ActiveCfg = Release|Any CPU {9C214A20-E419-4731-9E19-302D9957AFF3}.Release|Any CPU.Build.0 = Release|Any CPU + {072EBD5B-C529-4690-B5A3-9EAA4DB43202}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {072EBD5B-C529-4690-B5A3-9EAA4DB43202}.Debug|Any CPU.Build.0 = Debug|Any CPU + {072EBD5B-C529-4690-B5A3-9EAA4DB43202}.Release|Any CPU.ActiveCfg = Release|Any CPU + {072EBD5B-C529-4690-B5A3-9EAA4DB43202}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -95,6 +103,7 @@ Global {AE0D044B-1AE9-430F-B05D-ADAC72C407B8} = {8E563D72-A200-4BB7-8AB8-A93BEED3A5B7} {AF583937-1A80-407F-B683-3FEED7F3BC16} = {8E563D72-A200-4BB7-8AB8-A93BEED3A5B7} {9C214A20-E419-4731-9E19-302D9957AFF3} = {8E563D72-A200-4BB7-8AB8-A93BEED3A5B7} + {072EBD5B-C529-4690-B5A3-9EAA4DB43202} = {0079C857-D80C-4FF5-8F48-206CB6D2F3E6} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {E61B239A-17C9-48B6-9C08-0567ECB16243} diff --git a/tests/Ch 01. Arrays and Strings Tests/Ch 01. Arrays and Strings Tests.csproj b/tests/Ch 01. Arrays and Strings Tests/Ch 01. Arrays and Strings Tests.csproj new file mode 100644 index 0000000..3ac99a6 --- /dev/null +++ b/tests/Ch 01. Arrays and Strings Tests/Ch 01. Arrays and Strings Tests.csproj @@ -0,0 +1,14 @@ + + + + netcoreapp2.2 + Ch_01._Arrays_and_Strings_Tests + + false + + + + + + + diff --git a/tests/Ch 01. Arrays and Strings Tests/IsUniqueTests.cs b/tests/Ch 01. Arrays and Strings Tests/IsUniqueTests.cs new file mode 100644 index 0000000..a1415e3 --- /dev/null +++ b/tests/Ch 01. Arrays and Strings Tests/IsUniqueTests.cs @@ -0,0 +1,30 @@ +using Chapter01; +using FluentAssertions; +using Xunit; + +namespace Ch_01._Arrays_and_Strings_Tests +{ + public class IsUniqueTests + { + [Theory] + [InlineData("abcde")] + [InlineData("kite")] + [InlineData("padle")] + public void IsUnique_should_be_true(string word) + { + var unique = new Q1_01_Is_Unique(); + unique.IsUniqueChars(word).Should().BeTrue(); + unique.IsUniqueChars2(word).Should().BeTrue(); + } + + [Theory] + [InlineData("hello")] + [InlineData("apple")] + public void IsUnique_should_be_false(string word) + { + var unique = new Q1_01_Is_Unique(); + unique.IsUniqueChars(word).Should().BeFalse(); + unique.IsUniqueChars2(word).Should().BeFalse(); + } + } +} diff --git a/tests/directory.build.props b/tests/directory.build.props new file mode 100644 index 0000000..16e4a87 --- /dev/null +++ b/tests/directory.build.props @@ -0,0 +1,18 @@ + + + + + + PreserveNewest + false + + + + + + + + + + + \ No newline at end of file diff --git a/tests/xunit.runner.json b/tests/xunit.runner.json new file mode 100644 index 0000000..0d69ec4 --- /dev/null +++ b/tests/xunit.runner.json @@ -0,0 +1,4 @@ +{ + "methodDisplay": "method", + "methodDisplayOptions": "all" +} \ No newline at end of file From e6ca76533c2eb45652dfc5e1f0b0e8c09a3ac29b Mon Sep 17 00:00:00 2001 From: Xavier Date: Wed, 21 Jul 2021 17:02:21 -0700 Subject: [PATCH 33/33] minor update --- .../Q1 05 One Edit Away.cs | 28 +++++++++---------- Ch 04. Trees/Q4_04_CheckBalanced.cs | 9 ++---- Ch 04. Trees/ReplaceNodeInImmutableTree.cs | 7 +++-- 3 files changed, 21 insertions(+), 23 deletions(-) diff --git a/Ch 01. Arrays and Strings/Q1 05 One Edit Away.cs b/Ch 01. Arrays and Strings/Q1 05 One Edit Away.cs index 6de5bd4..5e06c27 100644 --- a/Ch 01. Arrays and Strings/Q1 05 One Edit Away.cs +++ b/Ch 01. Arrays and Strings/Q1 05 One Edit Away.cs @@ -11,9 +11,9 @@ public override void Run() String b = "pale"; var c = "ple"; var d = "pele"; - Console.WriteLine($"{a}, {b}: {OneEditAway(a, b)} / {OneEditAway2(a, b)}"); - Console.WriteLine($"{b}, {c}: {OneEditAway(b, c)} / {OneEditAway2(b, c)}"); - Console.WriteLine($"{b}, {d}: {OneEditAway(b, d)} / {OneEditAway2(b, d)}"); + Console.WriteLine($"{a}, {b}: {OneEditAway(a, b)} / {OneEditAwayBook(a, b)}"); + Console.WriteLine($"{b}, {c}: {OneEditAway(b, c)} / {OneEditAwayBook(b, c)}"); + Console.WriteLine($"{b}, {d}: {OneEditAway(b, d)} / {OneEditAwayBook(b, d)}"); } @@ -77,7 +77,7 @@ public static bool OneEditAway(String first, String second) return false; } - public static bool OneEditAway2(String first, String second) + public static bool OneEditAwayBook(String first, String second) { /* Length checks. */ if (Math.Abs(first.Length - second.Length) > 1) @@ -86,29 +86,29 @@ public static bool OneEditAway2(String first, String second) } /* Get shorter and longer string.*/ - String s1 = first.Length < second.Length ? first : second; - String s2 = first.Length < second.Length ? second : first; + String shorter = first.Length < second.Length ? first : second; + String longer = first.Length < second.Length ? second : first; - int index1 = 0; - int index2 = 0; + int indexS = 0; + int indexL = 0; bool foundDifference = false; - while (index2 < s2.Length && index1 < s1.Length) + while (indexL < longer.Length && indexS < shorter.Length) { - if (s1[index1] != s2[index2]) + if (shorter[indexS] != longer[indexL]) { /* Ensure that this is the first difference found.*/ if (foundDifference) return false; foundDifference = true; - if (s1.Length == s2.Length) + if (shorter.Length == longer.Length) { // On replace, move shorter pointer - index1++; + indexS++; } } else { - index1++; // If matching, move shorter pointer + indexS++; // If matching, move shorter pointer } - index2++; // Always move pointer for longer string + indexL++; // Always move pointer for longer string } return true; } diff --git a/Ch 04. Trees/Q4_04_CheckBalanced.cs b/Ch 04. Trees/Q4_04_CheckBalanced.cs index 30879b6..0662bad 100644 --- a/Ch 04. Trees/Q4_04_CheckBalanced.cs +++ b/Ch 04. Trees/Q4_04_CheckBalanced.cs @@ -52,19 +52,16 @@ public override void Run() private static void PrintTree(TreeNode root) { BTreePrinter.Print(root); - var isBalanced1 = IsBalanced(root); - if (isBalanced1) + if (IsBalanced(root)) Console.WriteLine("Tree is balanced"); else - Console.WriteLine("Tree is not balalnced"); - - var isBalanced2 = IsBalancedBook(root); + Console.WriteLine("Tree is not balanced"); if (IsBalancedBook(root)) Console.WriteLine("Tree is balanced"); else - Console.WriteLine("Tree is not balalnced"); + Console.WriteLine("Tree is not balanced"); } } } \ No newline at end of file diff --git a/Ch 04. Trees/ReplaceNodeInImmutableTree.cs b/Ch 04. Trees/ReplaceNodeInImmutableTree.cs index b991a80..89e0e7a 100644 --- a/Ch 04. Trees/ReplaceNodeInImmutableTree.cs +++ b/Ch 04. Trees/ReplaceNodeInImmutableTree.cs @@ -1,6 +1,5 @@ using ctci.Contracts; using ctci.Library; -using System; namespace Chapter04 { @@ -9,8 +8,10 @@ static partial class TreeNodeExtension static public TreeNode Replace(this TreeNode node, int value) { if (node == null) return null; - var newNode = new TreeNode(node); - newNode.Data = value; + var newNode = new TreeNode(node) + { + Data = value + }; var newRoot = newNode; while (node.Parent != null) {