From 4facc1ec84a36f36cce89a5402894ee8ce5269fe Mon Sep 17 00:00:00 2001 From: Ezequiel Actis Grosso Date: Thu, 12 Oct 2017 14:54:48 -0300 Subject: [PATCH 1/2] Ch 09 ported from Java Adding Ch 09 folder and ctci.Library/LinkedListExtensions.cs Porting Ch 09-02 Social Network from Java --- .gitignore | 7 +- ...h 09. System Design and Scalability.csproj | 16 ++++ .../Q9_02_Social_Network.cs | 90 +++++++++++++++++++ .../Q9_02_Social_Network/BFSData.cs | 26 ++++++ .../Q9_02_Social_Network/Machine.cs | 12 +++ .../Q9_02_Social_Network/PathNode.cs | 29 ++++++ .../Q9_02_Social_Network/Person.cs | 31 +++++++ .../Q9_02_Social_Network/QuestionA.cs | 33 +++++++ .../Q9_02_Social_Network/QuestionB.cs | 67 ++++++++++++++ .../Q9_02_Social_Network/Server.cs | 29 ++++++ ctci.Library/LinkedListExtensions.cs | 20 +++++ ctci.sln | 20 ++++- ctci/Program.cs | 5 ++ ctci/ctci.csproj | 43 ++++----- 14 files changed, 405 insertions(+), 23 deletions(-) create mode 100644 Ch 09. System Design and Scalability/Ch 09. System Design and Scalability.csproj create mode 100644 Ch 09. System Design and Scalability/Q9_02_Social_Network.cs create mode 100644 Ch 09. System Design and Scalability/Q9_02_Social_Network/BFSData.cs create mode 100644 Ch 09. System Design and Scalability/Q9_02_Social_Network/Machine.cs create mode 100644 Ch 09. System Design and Scalability/Q9_02_Social_Network/PathNode.cs create mode 100644 Ch 09. System Design and Scalability/Q9_02_Social_Network/Person.cs create mode 100644 Ch 09. System Design and Scalability/Q9_02_Social_Network/QuestionA.cs create mode 100644 Ch 09. System Design and Scalability/Q9_02_Social_Network/QuestionB.cs create mode 100644 Ch 09. System Design and Scalability/Q9_02_Social_Network/Server.cs create mode 100644 ctci.Library/LinkedListExtensions.cs diff --git a/.gitignore b/.gitignore index 94420dc..bde861a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,14 +1,19 @@ ## Ignore Visual Studio temporary files, build results, and ## files generated by popular Visual Studio add-ons. +# OS generated files +.DS_Store +.DS_Store? + # User-specific files *.suo *.user *.userosscache *.sln.docstates -# User-specific files (MonoDevelop/Xamarin Studio) +# User-specific files (MonoDevelop/Xamarin Studio/VS Code) *.userprefs +.vscode # Build results [Dd]ebug/ diff --git a/Ch 09. System Design and Scalability/Ch 09. System Design and Scalability.csproj b/Ch 09. System Design and Scalability/Ch 09. System Design and Scalability.csproj new file mode 100644 index 0000000..9283d76 --- /dev/null +++ b/Ch 09. System Design and Scalability/Ch 09. System Design and Scalability.csproj @@ -0,0 +1,16 @@ + + + + netcoreapp1.1 + Chapter09 + + + + + + + + + + + diff --git a/Ch 09. System Design and Scalability/Q9_02_Social_Network.cs b/Ch 09. System Design and Scalability/Q9_02_Social_Network.cs new file mode 100644 index 0000000..255a3c3 --- /dev/null +++ b/Ch 09. System Design and Scalability/Q9_02_Social_Network.cs @@ -0,0 +1,90 @@ +using System; +using System.Linq; +using System.Collections.Generic; +using ctci.Contracts; + +namespace Chapter09 +{ + public class Q9_02_Social_Network : Question + { + public static void PrintPeople(LinkedList path) { + if (path == null) { + Console.WriteLine("No path"); + } else { + foreach (Person p in path) { + Console.WriteLine(p.Id); + } + } + } + + public static bool IsEqual(LinkedList path1, LinkedList path2, bool reverse) { + if (path1 == null || path2 == null) { + return path1 == null && path2 == null; + } + if (path1.Count != path2.Count) { + return false; + } + + for (int i = 0; i < path1.Count; i++) { + int other = reverse ? path2.Count - i - 1 : i; + if (path1.ElementAt(i) != path2.ElementAt(other)) { + return false; + } + } + return true; + } + + public static bool IsEquivalent(LinkedList path1, LinkedList path2) { + bool f1 = IsEqual(path1, path2, false); + bool f2 = IsEqual(path1, path2, true); + return f1 || f2; + } + + public override void Run() + { + int nPeople = 11; + var people = new Dictionary(); + for (int i = 0; i < nPeople; i++) { + Person p = new Person(i); + people.Add(i, p); + } + + int[][] edges = {new[]{1, 4}, new[]{1, 2}, new[]{1, 3}, new[]{3, 2}, new[]{4, 6}, new[]{3, 7}, new[]{6, 9}, new[]{9, 10}, new[]{5, 10}, new[]{2, 5}, new[]{3, 7}}; + //int[][] edges = {{1, 4}, {1, 2}, {4, 6}, {6, 9}, {9, 10}, {5, 10}, {2, 5}}; + //int[][] edges = {{1, 2}, {1, 4}, {2, 3}, {3, 4}, {4, 6}, {5, 6}, {4, 5}}; + foreach (var edge in edges) { + Person source = people[edge[0]]; + source.AddFriend(edge[1]); + + Person destination = people[edge[1]]; + destination.AddFriend(edge[0]); + } + + /*int i = 1; + int j = 10; + LinkedList path1 = findPathBFS(people, i, j); + LinkedList path2 = findPathBiBFS(people, i, j); + System.out.println("Path 1"); + printPeople(path1); + System.out.println("Path 2"); + printPeople(path2);*/ + + for (int i = 0; i < nPeople; i++) { + for (int j = 0; j < nPeople; j++) { + LinkedList path1 = QuestionA.FindPathBFS(people, i, j); + LinkedList path2 = QuestionB.FindPathBiBFS(people, i, j); + if (!IsEquivalent(path1, path2)) { + Console.WriteLine($"Not equal: {i} to {j}"); + Console.WriteLine("Path 1"); + PrintPeople(path1); + Console.WriteLine("Path 2"); + PrintPeople(path2); + break; + } else { + Console.WriteLine($"Is equal: {i} to {j}"); + } + } + } + } + } +} \ No newline at end of file diff --git a/Ch 09. System Design and Scalability/Q9_02_Social_Network/BFSData.cs b/Ch 09. System Design and Scalability/Q9_02_Social_Network/BFSData.cs new file mode 100644 index 0000000..07028a8 --- /dev/null +++ b/Ch 09. System Design and Scalability/Q9_02_Social_Network/BFSData.cs @@ -0,0 +1,26 @@ +using System.Collections.Generic; + +namespace Chapter09 +{ + public class BFSData + { + public Queue ToVisit {get; set;} + public Dictionary Visited {get; set;} + + public BFSData(Person root) { + ToVisit = new Queue(); + Visited = new Dictionary(); + + PathNode sourcePath = new PathNode(root, null); + ToVisit.Enqueue(sourcePath); + Visited.Add(root.Id, sourcePath); + } + + public bool IsFinished() { + return ToVisit.Count == 0; + } + } + +} + + diff --git a/Ch 09. System Design and Scalability/Q9_02_Social_Network/Machine.cs b/Ch 09. System Design and Scalability/Q9_02_Social_Network/Machine.cs new file mode 100644 index 0000000..44de6ab --- /dev/null +++ b/Ch 09. System Design and Scalability/Q9_02_Social_Network/Machine.cs @@ -0,0 +1,12 @@ +// package Q9_02_Social_Network; + +// import java.util.HashMap; + +// public class Machine { +// public HashMap persons = new HashMap(); +// public int machineID; + +// public Person getPersonWithID(int personID) { +// return persons.get(personID); +// } +// } diff --git a/Ch 09. System Design and Scalability/Q9_02_Social_Network/PathNode.cs b/Ch 09. System Design and Scalability/Q9_02_Social_Network/PathNode.cs new file mode 100644 index 0000000..8e1a5b0 --- /dev/null +++ b/Ch 09. System Design and Scalability/Q9_02_Social_Network/PathNode.cs @@ -0,0 +1,29 @@ +using System.Collections.Generic; + +namespace Chapter09 +{ + public class PathNode { + public Person Person {get; private set;} + private PathNode previousNode = null; + public PathNode(Person p, PathNode previous) { + Person = p; + previousNode = previous; + } + + public LinkedList Collapse(bool startsWithRoot) { + LinkedList path = new LinkedList(); + PathNode node = this; + while (node != null) { + if (startsWithRoot) { + path.AddLast(node.Person); + } else { + path.AddFirst(node.Person); + } + node = node.previousNode; + } + return path; + } + } +} + + diff --git a/Ch 09. System Design and Scalability/Q9_02_Social_Network/Person.cs b/Ch 09. System Design and Scalability/Q9_02_Social_Network/Person.cs new file mode 100644 index 0000000..3553e70 --- /dev/null +++ b/Ch 09. System Design and Scalability/Q9_02_Social_Network/Person.cs @@ -0,0 +1,31 @@ + +using System; +using System.Collections.Generic; + +namespace Chapter09 +{ + public class Person + { + private List _friends = new List(); + + public string Info {get; set;} + public int Id { get; private set; } + + public List GetFriends() + { + return _friends; + } + + public void AddFriend(int id) + { + _friends.Add(id); + } + + public Person(int id) + { + Id = id; + } + } +} + + diff --git a/Ch 09. System Design and Scalability/Q9_02_Social_Network/QuestionA.cs b/Ch 09. System Design and Scalability/Q9_02_Social_Network/QuestionA.cs new file mode 100644 index 0000000..cb8589d --- /dev/null +++ b/Ch 09. System Design and Scalability/Q9_02_Social_Network/QuestionA.cs @@ -0,0 +1,33 @@ +using System.Collections.Generic; + +namespace Chapter09 +{ + public class QuestionA + { + public static LinkedList FindPathBFS(Dictionary people, int source, int destination) { + Queue toVisit = new Queue(); + HashSet visited = new HashSet(); + toVisit.Enqueue(new PathNode(people[source], null)); + visited.Add(source); + while (toVisit.Count > 0) { + PathNode node = toVisit.Dequeue(); + Person person = node.Person; + if (person.Id == destination) { + return node.Collapse(false); + } + + /* Search friends. */ + List friends = person.GetFriends(); + foreach (int friendId in friends) { + if (!visited.Contains(friendId)) { + visited.Add(friendId); + Person friend = people[friendId]; + toVisit.Enqueue(new PathNode(friend, node)); + } + } + } + return null; + } + } +} + diff --git a/Ch 09. System Design and Scalability/Q9_02_Social_Network/QuestionB.cs b/Ch 09. System Design and Scalability/Q9_02_Social_Network/QuestionB.cs new file mode 100644 index 0000000..d47d275 --- /dev/null +++ b/Ch 09. System Design and Scalability/Q9_02_Social_Network/QuestionB.cs @@ -0,0 +1,67 @@ +using System.Collections.Generic; +using ctci.Library; + +namespace Chapter09 +{ + public class QuestionB { + public static LinkedList MergePaths(BFSData bfs1, BFSData bfs2, int connection) { + PathNode end1 = bfs1.Visited[connection]; // end1 -> source + PathNode end2 = bfs2.Visited[connection]; // end2 -> dest + LinkedList pathOne = end1.Collapse(false); // forward: source -> connection + LinkedList pathTwo = end2.Collapse(true); // reverse: connection -> dest + pathTwo.RemoveFirst(); // remove connection + pathOne.AddAll(pathTwo); // add second path + return pathOne; + } + + /* Search one level and return collision, if any. */ + public static Person SearchLevel(Dictionary people, BFSData primary, BFSData secondary) { + /* We only want to search one level at a time. Count how many nodes are currently in the primary's + * level and only do that many nodes. We'll continue to add nodes to the end. */ + int count = primary.ToVisit.Count; + for (int i = 0; i < count; i++) { + /* Pull out first node. */ + PathNode pathNode = primary.ToVisit.Dequeue(); + int personId = pathNode.Person.Id; + + /* Check if it's already been visited. */ + if (secondary.Visited.ContainsKey(personId)) { + return pathNode.Person; + } + + /* Add friends to queue. */ + Person person = pathNode.Person; + List friends = person.GetFriends(); + foreach (int friendId in friends) { + if (!primary.Visited.ContainsKey(friendId)) { + Person friend = people[friendId]; + PathNode next = new PathNode(friend, pathNode); + primary.Visited.Add(friendId, next); + primary.ToVisit.Enqueue(next); + } + } + } + return null; + } + public static LinkedList FindPathBiBFS(Dictionary people, int source, int destination) { + BFSData sourceData = new BFSData(people[source]); + BFSData destData = new BFSData(people[destination]); + + while (!sourceData.IsFinished() && !destData.IsFinished()) { + /* Search out from source. */ + Person collision = SearchLevel(people, sourceData, destData); + if (collision != null) { + return MergePaths(sourceData, destData, collision.Id); + } + + /* Search out from destination. */ + collision = SearchLevel(people, destData, sourceData); + if (collision != null) { + return MergePaths(sourceData, destData, collision.Id); + } + } + return null; + } + } +} + diff --git a/Ch 09. System Design and Scalability/Q9_02_Social_Network/Server.cs b/Ch 09. System Design and Scalability/Q9_02_Social_Network/Server.cs new file mode 100644 index 0000000..7e3b180 --- /dev/null +++ b/Ch 09. System Design and Scalability/Q9_02_Social_Network/Server.cs @@ -0,0 +1,29 @@ +// package Q9_02_Social_Network; + +// import java.util.HashMap; + +// public class Server { +// HashMap machines = new HashMap(); +// HashMap personToMachineMap = new HashMap(); + +// public Machine getMachineWithId(int machineID) { +// return machines.get(machineID); +// } + +// public int getMachineIDForUser(int personID) { +// Integer machineID = personToMachineMap.get(personID); +// return machineID == null ? -1 : machineID; +// } + +// public Person getPersonWithID(int personID) { +// Integer machineID = personToMachineMap.get(personID); +// if (machineID == null) { +// return null; +// } +// Machine machine = getMachineWithId(machineID); +// if (machine == null) { +// return null; +// } +// return machine.getPersonWithID(personID); +// } +// } diff --git a/ctci.Library/LinkedListExtensions.cs b/ctci.Library/LinkedListExtensions.cs new file mode 100644 index 0000000..9f390e0 --- /dev/null +++ b/ctci.Library/LinkedListExtensions.cs @@ -0,0 +1,20 @@ +using System.Collections.Generic; + +namespace ctci.Library +{ + public static class LinkedListExtensions + { + public static void AddAll(this LinkedList source, + IEnumerable items) + { + if (source == null) + throw new System.ArgumentNullException(nameof(source)); + + if (items == null) + throw new System.ArgumentNullException(nameof(items)); + + foreach (T item in items) + source.AddLast(item); + } + } +} \ No newline at end of file diff --git a/ctci.sln b/ctci.sln index a5422bd..3ad82b5 100644 --- a/ctci.sln +++ b/ctci.sln @@ -1,4 +1,4 @@ - + Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 15 VisualStudioVersion = 15.0.26228.4 @@ -27,10 +27,16 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ch 16. Moderate", "Ch 16. M EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ch 04. Trees", "Ch 04. Trees\Ch 04. Trees.csproj", "{AF583937-1A80-407F-B683-3FEED7F3BC16}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ch 09. System Design and Scalability", "Ch 09. System Design and Scalability\Ch 09. System Design and Scalability.csproj", "{CF5BD090-6644-4047-928A-86E0E4ADA0C7}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU Release|Any CPU = Release|Any CPU + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|x64 = Release|x64 + Release|x86 = Release|x86 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {F7867FE4-E80B-44DD-9666-C82E6D401B8A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU @@ -73,6 +79,18 @@ 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 + {CF5BD090-6644-4047-928A-86E0E4ADA0C7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {CF5BD090-6644-4047-928A-86E0E4ADA0C7}.Debug|Any CPU.Build.0 = Debug|Any CPU + {CF5BD090-6644-4047-928A-86E0E4ADA0C7}.Debug|x64.ActiveCfg = Debug|x64 + {CF5BD090-6644-4047-928A-86E0E4ADA0C7}.Debug|x64.Build.0 = Debug|x64 + {CF5BD090-6644-4047-928A-86E0E4ADA0C7}.Debug|x86.ActiveCfg = Debug|x86 + {CF5BD090-6644-4047-928A-86E0E4ADA0C7}.Debug|x86.Build.0 = Debug|x86 + {CF5BD090-6644-4047-928A-86E0E4ADA0C7}.Release|Any CPU.ActiveCfg = Release|Any CPU + {CF5BD090-6644-4047-928A-86E0E4ADA0C7}.Release|Any CPU.Build.0 = Release|Any CPU + {CF5BD090-6644-4047-928A-86E0E4ADA0C7}.Release|x64.ActiveCfg = Release|x64 + {CF5BD090-6644-4047-928A-86E0E4ADA0C7}.Release|x64.Build.0 = Release|x64 + {CF5BD090-6644-4047-928A-86E0E4ADA0C7}.Release|x86.ActiveCfg = Release|x86 + {CF5BD090-6644-4047-928A-86E0E4ADA0C7}.Release|x86.Build.0 = Release|x86 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/ctci/Program.cs b/ctci/Program.cs index eb053fb..027fb60 100644 --- a/ctci/Program.cs +++ b/ctci/Program.cs @@ -2,6 +2,7 @@ using Chapter02; using Chapter04; using Chapter05; +using Chapter09; using Chapter10; using Chapter16; using ctci.Contracts; @@ -66,6 +67,10 @@ private static void Main(string[] args) new Q5_08_Draw_Line() }, + new Question[] { + new Q9_02_Social_Network() + }, + new Question[] { new Q10_01_Sorted_Merge(), new Q10_02_Group_Anagrams(), diff --git a/ctci/ctci.csproj b/ctci/ctci.csproj index 20fcae9..5c3611b 100644 --- a/ctci/ctci.csproj +++ b/ctci/ctci.csproj @@ -1,22 +1,23 @@ - - - - Exe - netcoreapp1.1 - - - - - - - - - - - - - - - - + + + + Exe + netcoreapp1.1 + + + + + + + + + + + + + + + + + \ No newline at end of file From 43e243bf7ca82c2f30ccd993b8af1a9205bc587b Mon Sep 17 00:00:00 2001 From: Ezequiel Actis Grosso Date: Fri, 13 Oct 2017 11:47:07 -0300 Subject: [PATCH 2/2] Ch.07 Q7_12 Hash Table added --- .../Ch 07. Object-Oriented Design.csproj | 15 ++ .../Q7_12_Hash_Table.cs | 56 ++++++++ .../Q7_12_Hash_Table/Dummy.cs | 22 +++ .../Q7_12_Hash_Table/Hasher.cs | 134 ++++++++++++++++++ .../Q9_02_Social_Network.cs | 20 +-- .../Q9_02_Social_Network/Machine.cs | 26 ++-- .../Q9_02_Social_Network/Server.cs | 64 +++++---- ctci.sln | 16 +++ ctci/Program.cs | 13 +- ctci/ctci.csproj | 1 + 10 files changed, 315 insertions(+), 52 deletions(-) create mode 100644 Ch 07. Object-Oriented Design/Ch 07. Object-Oriented Design.csproj create mode 100644 Ch 07. Object-Oriented Design/Q7_12_Hash_Table.cs create mode 100644 Ch 07. Object-Oriented Design/Q7_12_Hash_Table/Dummy.cs create mode 100644 Ch 07. Object-Oriented Design/Q7_12_Hash_Table/Hasher.cs diff --git a/Ch 07. Object-Oriented Design/Ch 07. Object-Oriented Design.csproj b/Ch 07. Object-Oriented Design/Ch 07. Object-Oriented Design.csproj new file mode 100644 index 0000000..7f98063 --- /dev/null +++ b/Ch 07. Object-Oriented Design/Ch 07. Object-Oriented Design.csproj @@ -0,0 +1,15 @@ + + + + netcoreapp1.1 + Chapter07 + + + + + + + + + + diff --git a/Ch 07. Object-Oriented Design/Q7_12_Hash_Table.cs b/Ch 07. Object-Oriented Design/Q7_12_Hash_Table.cs new file mode 100644 index 0000000..0c1db65 --- /dev/null +++ b/Ch 07. Object-Oriented Design/Q7_12_Hash_Table.cs @@ -0,0 +1,56 @@ +using System; +using ctci.Contracts; + +namespace Chapter07 +{ + public class Q7_12_Hash_Table: Question + { + public override void Run() + { + Dummy bob = new Dummy("Bob", 20); + Dummy jim = new Dummy("Jim", 25); + Dummy alex = new Dummy("Alex", 30); + Dummy tim = new Dummy("Tim", 35); + Dummy maxwell = new Dummy("Maxwell", 40); + Dummy john = new Dummy("John", 45); + Dummy julie = new Dummy("Julie", 50); + Dummy christy = new Dummy("Christy", 55); + Dummy tim2 = new Dummy("Tim", 100); // This should replace the first "tim" + + Dummy[] dummies = { bob, jim, alex, tim, maxwell, john, julie, christy, tim2 }; + + /* Test: Insert Elements. */ + Hasher hash = new Hasher(3); + foreach (Dummy d in dummies) + { + Console.WriteLine(hash.Put(d.Name, d)); + } + + hash.PrintTable(); + + /* Test: Recall */ + foreach (Dummy d in dummies) + { + String name = d.Name; + Dummy dummy = hash.Get(name); + if (dummy == null) + { + Console.WriteLine($"Dummy named {name}: null"); + } + else + { + Console.WriteLine($"Dummy named {name}: {dummy}"); + } + Dummy d2 = hash.Remove(name); + if (d2 == null) + { + Console.WriteLine($"Dummy removed named {name}: null"); + } + else + { + Console.WriteLine($"Dummy removed named {name}: {d2}"); + } + } + } + } +} diff --git a/Ch 07. Object-Oriented Design/Q7_12_Hash_Table/Dummy.cs b/Ch 07. Object-Oriented Design/Q7_12_Hash_Table/Dummy.cs new file mode 100644 index 0000000..648f2f2 --- /dev/null +++ b/Ch 07. Object-Oriented Design/Q7_12_Hash_Table/Dummy.cs @@ -0,0 +1,22 @@ + +namespace Chapter07 +{ + public class Dummy + { + public string Name { get; private set; } + public int Age { get; private set; } + + public Dummy(string n, int a) + { + Name = n; + Age = a; + } + + + public override string ToString() + { + return "(" + Name + ", " + Age + ")"; + } + } +} + diff --git a/Ch 07. Object-Oriented Design/Q7_12_Hash_Table/Hasher.cs b/Ch 07. Object-Oriented Design/Q7_12_Hash_Table/Hasher.cs new file mode 100644 index 0000000..b96f14a --- /dev/null +++ b/Ch 07. Object-Oriented Design/Q7_12_Hash_Table/Hasher.cs @@ -0,0 +1,134 @@ +using System; +using System.Collections.Generic; + +namespace Chapter07 +{ + public class Hasher + { + private class LinkedListNode + { + public LinkedListNode Next { get; set; } + public LinkedListNode Prev { get; set; } + public K Key { get; set; } + public V Value { get; set; } + + public LinkedListNode(K k, V v) + { + Key = k; + Value = v; + } + + public string PrintForward() + { + string data = $"({Key},{Value})"; + if (Next != null) + { + return data + "->" + Next.PrintForward(); + } + else + { + return data; + } + } + } + + private List> _arr; + public Hasher(int capacity) + { + /* Create list of linked lists. */ + _arr = new List>(); + for (int i = 0; i < capacity; i++) + { + _arr.Add(null); + } + } + + /* Insert key and value into hash table. */ + public V Put(K key, V value) + { + LinkedListNode node = GetNodeForKey(key); + if (node != null) + { + V oldValue = node.Value; + node.Value = value; // just update the value. + return oldValue; + } + + node = new LinkedListNode(key, value); + int index = GetIndexForKey(key); + if (_arr[index] != null) + { + node.Next = _arr[index]; + node.Next.Prev = node; + } + _arr[index] = node; + return default(V); + } + + /* Remove node for key. */ + public V Remove(K key) + { + LinkedListNode node = GetNodeForKey(key); + if (node == null) + { + return default(V); + } + + if (node.Prev != null) + { + node.Prev.Next = node.Next; + } + else + { + /* Removing head - update. */ + int hashKey = GetIndexForKey(key); + _arr[hashKey] = node.Next; + } + + if (node.Next != null) + { + node.Next.Prev = node.Prev; + } + return node.Value; + } + + /* Get value for key. */ + public V Get(K key) + { + if (key == null) return default(V); + LinkedListNode node = GetNodeForKey(key); + return node == null ? default(V) : node.Value; + } + + /* Get linked list node associated with a given key. */ + private LinkedListNode GetNodeForKey(K key) + { + int index = GetIndexForKey(key); + LinkedListNode current = _arr[index]; + while (current != null) + { + if (current.Key.Equals(key)) + { + return current; + } + current = current.Next; + } + return null; + } + + /* Really stupid function to map a key to an index. */ + public int GetIndexForKey(K key) + { + return Math.Abs(key.GetHashCode() % _arr.Count); + } + + public void PrintTable() + { + for (int i = 0; i < _arr.Count; i++) + { + string s = _arr[i] == null ? string.Empty : _arr[i].PrintForward(); + Console.WriteLine($"{i}: {s}"); + } + } + } +} diff --git a/Ch 09. System Design and Scalability/Q9_02_Social_Network.cs b/Ch 09. System Design and Scalability/Q9_02_Social_Network.cs index 255a3c3..2c771ae 100644 --- a/Ch 09. System Design and Scalability/Q9_02_Social_Network.cs +++ b/Ch 09. System Design and Scalability/Q9_02_Social_Network.cs @@ -50,8 +50,8 @@ public override void Run() } int[][] edges = {new[]{1, 4}, new[]{1, 2}, new[]{1, 3}, new[]{3, 2}, new[]{4, 6}, new[]{3, 7}, new[]{6, 9}, new[]{9, 10}, new[]{5, 10}, new[]{2, 5}, new[]{3, 7}}; - //int[][] edges = {{1, 4}, {1, 2}, {4, 6}, {6, 9}, {9, 10}, {5, 10}, {2, 5}}; - //int[][] edges = {{1, 2}, {1, 4}, {2, 3}, {3, 4}, {4, 6}, {5, 6}, {4, 5}}; + //int[][] edges = {new[]{1, 4}, new[]{1, 2}, new[]{4, 6}, new[]{6, 9}, new[]{9, 10}, new[]{5, 10}, new[]{2, 5}}; + //int[][] edges = {new[]{1, 2}, new[]{1, 4}, new[]{2, 3}, new[]{3, 4}, new[]{4, 6}, new[]{5, 6}, new[]{4, 5}}; foreach (var edge in edges) { Person source = people[edge[0]]; source.AddFriend(edge[1]); @@ -60,14 +60,14 @@ public override void Run() destination.AddFriend(edge[0]); } - /*int i = 1; - int j = 10; - LinkedList path1 = findPathBFS(people, i, j); - LinkedList path2 = findPathBiBFS(people, i, j); - System.out.println("Path 1"); - printPeople(path1); - System.out.println("Path 2"); - printPeople(path2);*/ + //int j = 4; + //int z = 9; + //LinkedList path1 = QuestionA.FindPathBFS(people, j, z); + //LinkedList path2 = QuestionB.FindPathBiBFS(people, j, z); + //Console.WriteLine("Path 1"); + //PrintPeople(path1); + //Console.WriteLine("Path 2"); + //PrintPeople(path2); for (int i = 0; i < nPeople; i++) { for (int j = 0; j < nPeople; j++) { diff --git a/Ch 09. System Design and Scalability/Q9_02_Social_Network/Machine.cs b/Ch 09. System Design and Scalability/Q9_02_Social_Network/Machine.cs index 44de6ab..87af577 100644 --- a/Ch 09. System Design and Scalability/Q9_02_Social_Network/Machine.cs +++ b/Ch 09. System Design and Scalability/Q9_02_Social_Network/Machine.cs @@ -1,12 +1,16 @@ -// package Q9_02_Social_Network; +using System.Collections.Generic; + +namespace Chapter09 +{ + public class Machine + { + public Dictionary People { get; set; } + public int MachineID { get; set; } + + public Machine() + { + People = new Dictionary(); + } + } +} -// import java.util.HashMap; - -// public class Machine { -// public HashMap persons = new HashMap(); -// public int machineID; - -// public Person getPersonWithID(int personID) { -// return persons.get(personID); -// } -// } diff --git a/Ch 09. System Design and Scalability/Q9_02_Social_Network/Server.cs b/Ch 09. System Design and Scalability/Q9_02_Social_Network/Server.cs index 7e3b180..3ac34b8 100644 --- a/Ch 09. System Design and Scalability/Q9_02_Social_Network/Server.cs +++ b/Ch 09. System Design and Scalability/Q9_02_Social_Network/Server.cs @@ -1,29 +1,39 @@ -// package Q9_02_Social_Network; +using System.Collections.Generic; + +namespace Chapter09 +{ + public class Server + { + Dictionary _machines = new Dictionary(); + Dictionary _personToMachineMap = new Dictionary(); -// import java.util.HashMap; + public Machine GetMachineWithId(int machineId) + { + if (_machines.ContainsKey(machineId)) + return _machines[machineId]; + + return null; + } -// public class Server { -// HashMap machines = new HashMap(); -// HashMap personToMachineMap = new HashMap(); - -// public Machine getMachineWithId(int machineID) { -// return machines.get(machineID); -// } - -// public int getMachineIDForUser(int personID) { -// Integer machineID = personToMachineMap.get(personID); -// return machineID == null ? -1 : machineID; -// } - -// public Person getPersonWithID(int personID) { -// Integer machineID = personToMachineMap.get(personID); -// if (machineID == null) { -// return null; -// } -// Machine machine = getMachineWithId(machineID); -// if (machine == null) { -// return null; -// } -// return machine.getPersonWithID(personID); -// } -// } + public int GetMachineIdForUser(int personId) + { + if (_personToMachineMap.ContainsKey(personId)) + return _personToMachineMap[personId]; + + return -1; + } + + public Person GetPersonWithId(int personId) + { + var machineId = GetMachineIdForUser(personId); + if (machineId == -1) + return null; + + Machine machine = GetMachineWithId(machineId); + if (machine == null) + return null; + + return machine.People[personId]; + } + } +} diff --git a/ctci.sln b/ctci.sln index 3ad82b5..4d03e8d 100644 --- a/ctci.sln +++ b/ctci.sln @@ -29,6 +29,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ch 04. Trees", "Ch 04. Tree EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ch 09. System Design and Scalability", "Ch 09. System Design and Scalability\Ch 09. System Design and Scalability.csproj", "{CF5BD090-6644-4047-928A-86E0E4ADA0C7}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ch 07. Object-Oriented Design", "Ch 07. Object-Oriented Design\Ch 07. Object-Oriented Design.csproj", "{54CA6ED0-2C57-4D68-AD90-0655103960FD}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -91,6 +93,18 @@ Global {CF5BD090-6644-4047-928A-86E0E4ADA0C7}.Release|x64.Build.0 = Release|x64 {CF5BD090-6644-4047-928A-86E0E4ADA0C7}.Release|x86.ActiveCfg = Release|x86 {CF5BD090-6644-4047-928A-86E0E4ADA0C7}.Release|x86.Build.0 = Release|x86 + {54CA6ED0-2C57-4D68-AD90-0655103960FD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {54CA6ED0-2C57-4D68-AD90-0655103960FD}.Debug|Any CPU.Build.0 = Debug|Any CPU + {54CA6ED0-2C57-4D68-AD90-0655103960FD}.Release|Any CPU.ActiveCfg = Release|Any CPU + {54CA6ED0-2C57-4D68-AD90-0655103960FD}.Release|Any CPU.Build.0 = Release|Any CPU + {54CA6ED0-2C57-4D68-AD90-0655103960FD}.Debug|x64.ActiveCfg = Debug|Any CPU + {54CA6ED0-2C57-4D68-AD90-0655103960FD}.Debug|x64.Build.0 = Debug|Any CPU + {54CA6ED0-2C57-4D68-AD90-0655103960FD}.Debug|x86.ActiveCfg = Debug|Any CPU + {54CA6ED0-2C57-4D68-AD90-0655103960FD}.Debug|x86.Build.0 = Debug|Any CPU + {54CA6ED0-2C57-4D68-AD90-0655103960FD}.Release|x64.ActiveCfg = Release|Any CPU + {54CA6ED0-2C57-4D68-AD90-0655103960FD}.Release|x64.Build.0 = Release|Any CPU + {54CA6ED0-2C57-4D68-AD90-0655103960FD}.Release|x86.ActiveCfg = Release|Any CPU + {54CA6ED0-2C57-4D68-AD90-0655103960FD}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -106,5 +120,7 @@ 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} + {CF5BD090-6644-4047-928A-86E0E4ADA0C7} = {8E563D72-A200-4BB7-8AB8-A93BEED3A5B7} + {54CA6ED0-2C57-4D68-AD90-0655103960FD} = {8E563D72-A200-4BB7-8AB8-A93BEED3A5B7} EndGlobalSection EndGlobal diff --git a/ctci/Program.cs b/ctci/Program.cs index 027fb60..da1a7ef 100644 --- a/ctci/Program.cs +++ b/ctci/Program.cs @@ -1,14 +1,15 @@ +using System; +using Introduction; +using ctci.Contracts; using Chapter01; using Chapter02; using Chapter04; using Chapter05; +using Chapter07; using Chapter09; using Chapter10; using Chapter16; -using ctci.Contracts; -using Introduction; -using System; - + namespace ctci { internal class Program @@ -67,6 +68,10 @@ private static void Main(string[] args) new Q5_08_Draw_Line() }, + new Question[] { + new Q7_12_Hash_Table() + }, + new Question[] { new Q9_02_Social_Network() }, diff --git a/ctci/ctci.csproj b/ctci/ctci.csproj index 5c3611b..e24f5de 100644 --- a/ctci/ctci.csproj +++ b/ctci/ctci.csproj @@ -18,6 +18,7 @@ + \ No newline at end of file