Skip to content

Commit 0dde878

Browse files
committed
floating pr tolerance for line intersection
1 parent 86563d1 commit 0dde878

File tree

9 files changed

+76
-107
lines changed

9 files changed

+76
-107
lines changed

Advanced.Algorithms/DistributedSystems/CircularQueue.cs

Lines changed: 7 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using System;
22
using System.Collections.Generic;
3+
using System.Linq;
34

45
namespace Advanced.Algorithms.DataStructures.DistributedSystems
56
{
@@ -12,10 +13,10 @@ public class CircularQueue<T>
1213
private T[] queue;
1314

1415
//points to the index of next element to be deleted
15-
private int start = 0;
16+
private int start;
1617

1718
//points to the index new element should be inserted
18-
private int end = 0;
19+
private int end;
1920

2021
public int Count { get; private set; }
2122

@@ -31,7 +32,7 @@ public CircularQueue(int size)
3132
/// <param name="data"></param>
3233
public T Enqueue(T data)
3334
{
34-
T deleted = default(T);
35+
var deleted = default(T);
3536

3637
//wrap around removing oldest element
3738
if (end > queue.Length - 1)
@@ -67,22 +68,11 @@ public T Enqueue(T data)
6768
/// O(bulk.Length) time complexity
6869
/// </summary>
6970
/// <param name="bulk"></param>
70-
/// <returns></returns>
71+
/// <returns>Deleted items.</returns>
7172
public IEnumerable<T> Enqueue(T[] bulk)
7273
{
73-
var deletedList = new List<T>();
74-
75-
foreach (var item in bulk)
76-
{
77-
var deleted = Enqueue(item);
78-
79-
if (!deleted.Equals(default(T)))
80-
{
81-
deletedList.Add(deleted);
82-
}
83-
}
84-
85-
return deletedList;
74+
return bulk.Select(item => Enqueue(item))
75+
.Where(deleted => !deleted.Equals(default(T))).ToList();
8676
}
8777

8878
/// <summary>

Advanced.Algorithms/DistributedSystems/ConsistentHash.cs

Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -9,22 +9,21 @@ namespace Advanced.Algorithms.DistributedSystems
99

1010
/// <summary>
1111
/// A consistant hash implementation with MurmurHash
12-
/// Adapted from https://github.com/wsq003/consistent-hash/blob/master/ConsistentHash.cs
1312
/// </summary>
1413
/// <typeparam name="T"></typeparam>
1514
public class ConsistentHash<T>
1615
{
17-
SortedDictionary<int, T> circle = new SortedDictionary<int, T>();
18-
int[] circleKeys;
19-
int replicas;
16+
readonly SortedDictionary<int, T> circle = new SortedDictionary<int, T>();
17+
private int[] circleKeys;
18+
readonly int replicas;
2019

2120
public ConsistentHash()
2221
: this(new List<T>(), 100) { }
2322

2423
public ConsistentHash(IEnumerable<T> nodes, int replicas)
2524
{
2625
this.replicas = replicas;
27-
foreach (T node in nodes)
26+
foreach (var node in nodes)
2827
{
2928
AddNode(node);
3029
}
@@ -36,9 +35,9 @@ public ConsistentHash(IEnumerable<T> nodes, int replicas)
3635
/// <param name="node"></param>
3736
public void AddNode(T node)
3837
{
39-
for (int i = 0; i < replicas; i++)
38+
for (var i = 0; i < replicas; i++)
4039
{
41-
int hash = getHashCode(node.GetHashCode().ToString() + i);
40+
var hash = getHashCode(node.GetHashCode().ToString() + i);
4241
circle[hash] = node;
4342
}
4443

@@ -52,8 +51,8 @@ public void AddNode(T node)
5251
/// <returns></returns>
5352
public T GetNode(string key)
5453
{
55-
int hash = getHashCode(key);
56-
int first = Next_ClockWise(circleKeys, hash);
54+
var hash = getHashCode(key);
55+
var first = nextClockWise(circleKeys, hash);
5756
return circle[circleKeys[first]];
5857
}
5958

@@ -63,9 +62,9 @@ public T GetNode(string key)
6362
/// <param name="node"></param>
6463
public void RemoveNode(T node)
6564
{
66-
for (int i = 0; i < replicas; i++)
65+
for (var i = 0; i < replicas; i++)
6766
{
68-
int hash = getHashCode(node.GetHashCode().ToString() + i);
67+
var hash = getHashCode(node.GetHashCode().ToString() + i);
6968
if (!circle.Remove(hash))
7069
{
7170
throw new Exception("Cannot remove a node that was never added.");
@@ -82,21 +81,20 @@ public void RemoveNode(T node)
8281
/// <param name="keys"></param>
8382
/// <param name="hashCode"></param>
8483
/// <returns>Returns the index of bucket</returns>
85-
int Next_ClockWise(int[] keys, int hashCode)
84+
private int nextClockWise(int[] keys, int hashCode)
8685
{
87-
int begin = 0;
88-
int end = keys.Length - 1;
86+
var begin = 0;
87+
var end = keys.Length - 1;
8988

9089
if (keys[end] < hashCode || keys[0] > hashCode)
9190
{
9291
return 0;
9392
}
9493

9594
//do a binary search
96-
int mid = begin;
9795
while (end - begin > 1)
9896
{
99-
mid = (end + begin) / 2;
97+
var mid = (end + begin) / 2;
10098
if (keys[mid] >= hashCode)
10199
{
102100
end = mid;
@@ -118,6 +116,9 @@ private static int getHashCode(string key)
118116

119117
}
120118

119+
/// <summary>
120+
/// Adapted from https://github.com/wsq003/consistent-hash/blob/master/ConsistentHash.cs
121+
/// </summary>
121122
internal class MurmurHash2
122123
{
123124
internal static UInt32 Hash(Byte[] data)

Advanced.Algorithms/DistributedSystems/LRUCache.cs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,18 @@
11
using Advanced.Algorithms.DataStructures;
22
using System;
3-
using System.Collections.Generic;
43
using System.Linq;
54

65

76
namespace Advanced.Algorithms.DistributedSystems
87
{
98
public class LRUCache<K, V>
109
{
11-
private int capacity;
10+
private readonly int capacity;
1211

1312
private System.Collections.Generic.Dictionary<K, DoublyLinkedListNode<Tuple<K, V>>> lookUp
1413
= new System.Collections.Generic.Dictionary<K, DoublyLinkedListNode<Tuple<K, V>>>();
1514

16-
private DoublyLinkedList<Tuple<K, V>> dll = new DoublyLinkedList<Tuple<K, V>>();
15+
private readonly DoublyLinkedList<Tuple<K, V>> dll = new DoublyLinkedList<Tuple<K, V>>();
1716

1817
public LRUCache(int capacity)
1918
{

Advanced.Algorithms/Geometry/ClosestPointPair.cs

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
using System;
22
using System.Collections.Generic;
33
using System.Linq;
4-
using System.Text;
5-
using System.Threading.Tasks;
64

75
namespace Advanced.Algorithms.Geometry
86
{
@@ -35,7 +33,7 @@ public static double Find(List<Point> points, int left, int right)
3533

3634
var strips = new List<Point>();
3735

38-
for (int i = left; i <= right; i++)
36+
for (var i = left; i <= right; i++)
3937
{
4038
if (Math.Abs(points[i].x - midX) < min)
4139
{
@@ -46,9 +44,9 @@ public static double Find(List<Point> points, int left, int right)
4644
//vertical strips within the radius of min
4745
strips = strips.OrderBy(p => p.y).ToList();
4846

49-
for (int i = 0; i < strips.Count; i++)
47+
for (var i = 0; i < strips.Count; i++)
5048
{
51-
for (int j = i + 1; j < strips.Count && Math.Abs(strips[i].y - strips[j].y) < min; j++)
49+
for (var j = i + 1; j < strips.Count && Math.Abs(strips[i].y - strips[j].y) < min; j++)
5250
{
5351
//check for radius
5452
min = Math.Min(min, getDistance(strips[i], strips[j]));
@@ -60,12 +58,12 @@ public static double Find(List<Point> points, int left, int right)
6058

6159
}
6260

63-
private static double bruteForce(List<Point> points, int left, int right)
61+
private static double bruteForce(IList<Point> points, int left, int right)
6462
{
6563
var min = double.MaxValue;
66-
for (int i = left; i < right; i++)
64+
for (var i = left; i < right; i++)
6765
{
68-
for (int j = left + 1; j <= right; j++)
66+
for (var j = left + 1; j <= right; j++)
6967
{
7068
min = Math.Min(min, getDistance(points[i], points[j]));
7169
}

Advanced.Algorithms/Geometry/ConvexHull.cs

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,4 @@
1-
using System;
2-
using System.Collections.Generic;
3-
using System.Linq;
4-
using System.Text;
5-
using System.Threading.Tasks;
1+
using System.Collections.Generic;
62

73
namespace Advanced.Algorithms.Geometry
84
{
@@ -32,7 +28,7 @@ public static List<int[]> Find(List<int[]> points)
3228
//pick a random point as next Point
3329
var nextPointIndex = (currentPointIndex + 1) % points.Count;
3430

35-
for (int i = 0; i < points.Count; i++)
31+
for (var i = 0; i < points.Count; i++)
3632
{
3733
if (i == nextPointIndex)
3834
{
@@ -77,20 +73,16 @@ private static Orientation getOrientation(int[] p, int[] q, int[] r)
7773
{
7874
return Orientation.ClockWise;
7975
}
80-
else if (result > 0)
81-
{
82-
return Orientation.AntiClockWise;
83-
}
8476

85-
return Orientation.Colinear;
77+
return result > 0 ? Orientation.AntiClockWise : Orientation.Colinear;
8678
}
8779

8880

8981
private static int findLeftMostPoint(List<int[]> points)
9082
{
9183
var left = 0;
9284

93-
for (int i = 1; i < points.Count; i++)
85+
for (var i = 1; i < points.Count; i++)
9486
{
9587
if (points[i][0] < points[left][0])
9688
{

Advanced.Algorithms/Geometry/LineIntersection.cs

Lines changed: 17 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,4 @@
11
using System;
2-
using System.Collections.Generic;
3-
using System.Linq;
4-
using System.Text;
5-
using System.Threading.Tasks;
62

73
namespace Advanced.Algorithms.Geometry
84
{
@@ -28,8 +24,9 @@ public class LineIntersection
2824
/// </summary>
2925
/// <param name="lineA"></param>
3026
/// <param name="lineB"></param>
31-
/// <returns></returns>
32-
public static Point FindIntersection(Line lineA, Line lineB)
27+
/// <param name="tolerance">precision tolerance.</param>
28+
/// <returns>The point of intersection.</returns>
29+
public static Point FindIntersection(Line lineA, Line lineB, double tolerance = 0.001)
3330
{
3431
double x1 = lineA.x1, y1 = lineA.y1;
3532
double x2 = lineA.x2, y2 = lineA.y2;
@@ -38,25 +35,25 @@ public static Point FindIntersection(Line lineA, Line lineB)
3835
double x4 = lineB.x2, y4 = lineB.y2;
3936

4037
//equations of the form x=c (two vertical lines)
41-
if (x1 == x2 && x3 == x4 && x1 == x3)
38+
if (Math.Abs(x1 - x2) < tolerance && Math.Abs(x3 - x4) < tolerance && Math.Abs(x1 - x3) < tolerance)
4239
{
4340
throw new Exception("Both lines overlap vertically, ambiguous intersection points.");
4441
}
4542

4643
//equations of the form y=c (two horizontal lines)
47-
if (y1 == y2 && y3 == y4 && y1 == y3)
44+
if (Math.Abs(y1 - y2) < tolerance && Math.Abs(y3 - y4) < tolerance && Math.Abs(y1 - y3) < tolerance)
4845
{
4946
throw new Exception("Both lines overlap horizontally, ambiguous intersection points.");
5047
}
5148

5249
//equations of the form x=c (two vertical lines)
53-
if (x1 == x2 && x3 == x4)
50+
if (Math.Abs(x1 - x2) < tolerance && Math.Abs(x3 - x4) < tolerance)
5451
{
5552
return default(Point);
5653
}
5754

5855
//equations of the form y=c (two horizontal lines)
59-
if (y1 == y2 && y3 == y4)
56+
if (Math.Abs(y1 - y2) < tolerance && Math.Abs(y3 - y4) < tolerance)
6057
{
6158
return default(Point);
6259
}
@@ -72,11 +69,11 @@ public static Point FindIntersection(Line lineA, Line lineB)
7269
//-m2x + y = c2 --------(4)
7370

7471
double x, y;
75-
72+
7673
//lineA is vertical x1 = x2
7774
//slope will be infinity
7875
//so lets derive another solution
79-
if (x1 == x2)
76+
if (Math.Abs(x1 - x2) < tolerance)
8077
{
8178
//compute slope of line 2 (m2) and c2
8279
double m2 = (y4 - y3) / (x4 - x3);
@@ -92,7 +89,7 @@ public static Point FindIntersection(Line lineA, Line lineB)
9289
//lineB is vertical x3 = x4
9390
//slope will be infinity
9491
//so lets derive another solution
95-
else if (x3 == x4)
92+
else if (Math.Abs(x3 - x4) < tolerance)
9693
{
9794
//compute slope of line 1 (m1) and c2
9895
double m1 = (y2 - y1) / (x2 - x1);
@@ -125,8 +122,8 @@ public static Point FindIntersection(Line lineA, Line lineB)
125122
//verify by plugging intersection point (x, y)
126123
//in orginal equations (1) & (2) to see if they intersect
127124
//otherwise x,y values will not be finite and will fail this check
128-
if (!(-m1 * x + y == c1
129-
&& -m2 * x + y == c2))
125+
if (!(Math.Abs(-m1 * x + y - c1) < tolerance
126+
&& Math.Abs(-m2 * x + y - c2) < tolerance))
130127
{
131128
return default(Point);
132129
}
@@ -137,7 +134,7 @@ public static Point FindIntersection(Line lineA, Line lineB)
137134
if (IsInsideLine(lineA, x, y) &&
138135
IsInsideLine(lineB, x, y))
139136
{
140-
return new Point() { x = x, y = y };
137+
return new Point { x = x, y = y };
141138
}
142139

143140
//return default null (no intersection)
@@ -154,10 +151,10 @@ public static Point FindIntersection(Line lineA, Line lineB)
154151
/// <returns></returns>
155152
private static bool IsInsideLine(Line line, double x, double y)
156153
{
157-
return ((x >= line.x1 && x <= line.x2)
158-
|| (x >= line.x2 && x <= line.x1))
159-
&& ((y >= line.y1 && y <= line.y2)
160-
|| (y >= line.y2 && y <= line.y1));
154+
return (x >= line.x1 && x <= line.x2
155+
|| x >= line.x2 && x <= line.x1)
156+
&& (y >= line.y1 && y <= line.y2
157+
|| y >= line.y2 && y <= line.y1);
161158
}
162159
}
163160
}

Advanced.Algorithms/Geometry/PointInsidePolygon.cs

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,4 @@
1-
using System;
2-
using System.Collections.Generic;
3-
using System.Linq;
4-
using System.Text;
5-
using System.Threading.Tasks;
1+
using System.Collections.Generic;
62

73
namespace Advanced.Algorithms.Geometry
84
{

Advanced.Algorithms/Geometry/PointRotation.cs

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,4 @@
11
using System;
2-
using System.Collections.Generic;
3-
using System.Linq;
4-
using System.Text;
5-
using System.Threading.Tasks;
62

73
namespace Advanced.Algorithms.Geometry
84
{
@@ -22,7 +18,7 @@ public static Point Rotate(Point center, Point point, int angle)
2218
var y = sinTheta * (point.x - center.x) +
2319
cosTheta * (point.y - center.y) + center.y;
2420

25-
return new Point() { x = x, y = y };
21+
return new Point { x = x, y = y };
2622
}
2723
}
2824
}

0 commit comments

Comments
 (0)