Skip to content

Commit 3bf78ae

Browse files
committed
Refactored Chapter 7
1 parent c0e176d commit 3bf78ae

File tree

11 files changed

+274
-164
lines changed

11 files changed

+274
-164
lines changed

src/chapter1/OnePoint1.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ public static boolean uniqueCharacters_1(String string){
2828

2929
/* O(n) runtime, O(1) space: using Array */
3030
public static boolean uniqueCharacters_2(String string){
31-
if (string.length() > 256)
31+
if (string.length() > 256) // here we assume it's an ASCII string. Should ask interviewer if string is ASCII or Unicode
3232
return false;
3333

3434
boolean [] array = new boolean[256];

src/chapter7/Chapter7.java

Lines changed: 71 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,55 @@
11
package chapter7;
22

33
public class Chapter7 {
4-
public static void main (String [] args){
5-
/*** 7.4 ***/
6-
System.out.println("*** Test 7.4");
4+
public static void main(String [] args){
5+
test_Prime();
6+
// 7.1: no code required
7+
// 7.2: no code required
8+
test_SevenPoint3();
9+
test_SevenPoint4();
10+
// 7.5: Skip (no new concepts in this problem. Only trick: line goes through center of 2 squares
11+
test_SevenPoint6();
12+
test_SevenPoint7();
13+
}
14+
15+
public static void test_Prime(){
16+
System.out.println("*** Test Primes");
17+
System.out.println("Is 11 prime? " + Prime.isPrime(11));
18+
System.out.println("Is 12 prime? " + Prime.isPrime(12));
19+
System.out.println("Is 13 prime? " + Prime.isPrime(13));
20+
boolean [] primes = Prime.generatePrimes(50);
21+
System.out.print("Primes from 1-50: ");
22+
for (int i = 0; i < primes.length; i++){
23+
if (primes[i])
24+
System.out.print(i + " ");
25+
}
26+
}
27+
28+
public static void test_SevenPoint3(){
29+
System.out.println("\n\n*** Test 7.3: Intersecting Lines");
30+
Line line1 = new Line(new Point(2,0), new Point(2,3));
31+
Line line2 = new Line(new Point(2,5), new Point(2,7));
32+
Line line3 = new Line(new Point(1,2), new Point(3,3));
33+
Line line4 = new Line(new Point(2,3), new Point(4,4));
34+
35+
System.out.println("Lines intersect? (should be true): " + LineFunctions.intersect(line1, line2));
36+
System.out.println("Lines intersect? (should be true): " + LineFunctions.intersect(line1, line3));
37+
System.out.println("Lines intersect? (should be true): " + LineFunctions.intersect(line1, line4));
38+
System.out.println("Lines intersect? (should be true): " + LineFunctions.intersect(line2, line3));
39+
System.out.println("Lines intersect? (should be true): " + LineFunctions.intersect(line2, line4));
40+
System.out.println("Lines intersect? (should be false): " + LineFunctions.intersect(line3, line4));
41+
42+
// Tests our Line, LineFunctions classes for functions used in 7.6
43+
System.out.println("\nLines intersect? (should be true): " + LineFunctions.sameLine(line1, line2));
44+
System.out.println("Lines intersect? (should be false): " + LineFunctions.sameLine(line1, line3));
45+
System.out.println("Lines intersect? (should be false): " + LineFunctions.sameLine(line1, line4));
46+
System.out.println("Lines intersect? (should be false): " + LineFunctions.sameLine(line2, line3));
47+
System.out.println("Lines intersect? (should be false): " + LineFunctions.sameLine(line2, line4));
48+
System.out.println("Lines intersect? (should be false): " + LineFunctions.sameLine(line3, line4));
49+
}
50+
51+
public static void test_SevenPoint4(){
52+
System.out.println("\n*** Test 7.4: Subtraction, Multiplication, Division");
753
int result = SevenPoint4.subtract(4, 7);
854
System.out.println(" 4 - 7 = " + result + "\n");
955

@@ -15,39 +61,37 @@ public static void main (String [] args){
1561
System.out.println(" 2 * -3 = " + result);
1662
result = SevenPoint4.multiply(-2, -3);
1763
System.out.println("-2 * -3 = " + result + "\n");
18-
19-
result = SevenPoint4.divide(7, 2);
20-
System.out.println(" 7 / 2 = " + result);
21-
result = SevenPoint4.divide(-7, 2);
22-
System.out.println("-7 / 2 = " + result);
23-
result = SevenPoint4.divide(7, -2);
24-
System.out.println(" 7 / -2 = " + result);
25-
result = SevenPoint4.divide(-7, -2);
26-
System.out.println("-7 / -2 = " + result);
27-
28-
//7.6 -- I know how to code it, so I skipped it. Book's code/explanation is weird cuz they do line segments and complicate stuff.
29-
//Things to remember: ( y = mx + b) (The solution line must go through middle of squares)
64+
try{
65+
result = SevenPoint4.divide(7, 2);
66+
System.out.println(" 7 / 2 = " + result);
67+
result = SevenPoint4.divide(-7, 2);
68+
System.out.println("-7 / 2 = " + result);
69+
result = SevenPoint4.divide(7, -2);
70+
System.out.println(" 7 / -2 = " + result);
71+
result = SevenPoint4.divide(-7, -2);
72+
System.out.println("-7 / -2 = " + result);
73+
}
74+
catch(Exception e){
75+
System.out.println(e.getMessage());
76+
}
77+
}
3078

31-
/*** 7.6 ***/
32-
System.out.println("\n*** Test 7.6");
79+
public static void test_SevenPoint6(){
80+
System.out.println("\n*** Test 7.6: Find line passing through most provided points");
3381
Point [] points = new Point[4];
3482
points[0] = new Point(1, 3);
3583
points[1] = new Point(2, 4);
3684
points[2] = new Point(3, 5);
3785
points[3] = new Point(13, 7);
3886

39-
Line bestLine= SevenPoint6.findBestLine(points);
40-
System.out.println("bestLine: Slope = " + bestLine.slope + " Intercept = " + bestLine.intercept);
41-
42-
/*** 7.7 ***/
43-
System.out.println("\n*** Test 7.7");
44-
System.out.println("\n Solution 1");
87+
Line bestLine = SevenPoint6.findBestLine(points);
88+
System.out.println("bestLine = " + bestLine);
89+
}
90+
91+
public static void test_SevenPoint7(){
92+
System.out.println("\n*** Test 7.7: find kth magic number");
4593
for (int i = 1; i <= 6; i++){
4694
System.out.println(i + ": magic number = " + SevenPoint7.getKthMagicNumber(i));
4795
}
48-
System.out.println("\n Solution 2");
49-
for (int i = 1; i <= 6; i++){
50-
System.out.println(i + ": magic number = " + SevenPoint7.getKthMagicNumber2(i));
51-
}
5296
}
5397
}

src/chapter7/Line.java

Lines changed: 61 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,53 +1,84 @@
11
package chapter7;
2-
/* Used in 7.6. I did it slightly differently than book */
3-
public class Line {
4-
public static double epsilon = 0.0001; //notice slightly more efficient to make this static.
52

6-
public double intercept = 0; //usually y-intercept, but if infiniteSlope==true, it will be x-intercept.
7-
public double slope = 0;
8-
public boolean infiniteSlope; //IMPORTANT
3+
/* Useful equations:
4+
* - Line: y = mx + b
5+
* - Slope: (y2 - y1) / (x2 - x1)
6+
*
7+
* Tricks:
8+
* - We represent a Line in 2 different ways
9+
* 1) Vertical Lines: infiniteSlope and x_intercept (We treat vertical lines separately to avoid div-by-0 errors)
10+
* 2) Non-vertical Lines: slope and y_intercept
11+
* - Must use epsilon to see if 2 doubles are equal to each other (within a margin of error)
12+
* - Make Line's variables "final" so they don't change when Lines are hashed, making Line (basically) immutable
13+
*/
14+
public class Line {
15+
private static final double epsilon = 0.0001;
16+
public final Double slope; // I use Double instead of double to be able to set it to null.
17+
public final Double y_intercept;
18+
public final boolean infiniteSlope; // Important
19+
public final double x_intercept; // We want to know x_intercept in case line has infinite slope
920

10-
public Line(Point p, Point q){
11-
/* y = mx + b */
12-
if (Math.abs(p.x - q.x) < epsilon){
21+
/* Constructor */
22+
public Line(double slope, double y_intercept){
23+
this.slope = slope;
24+
this.y_intercept = y_intercept;
25+
infiniteSlope = false;
26+
/* Set x_intercept */
27+
if (y_intercept == 0)
28+
x_intercept = 0;
29+
else
30+
x_intercept = (-1 * slope) / y_intercept; // y = mx + b --> 0 = mx + b --> b = -mx
31+
}
32+
33+
/* Constructor */
34+
public Line(Point p1, Point p2){
35+
if (areEquivalent(p1.x, p2.x)){
36+
slope = null;
37+
y_intercept = null;
1338
infiniteSlope = true;
14-
intercept = floorEpsilon(p.x);
39+
x_intercept = p1.x;
1540
}
1641
else{
1742
infiniteSlope = false;
18-
slope = (p.y - q.y) / (p.x - q.x);
19-
intercept = p.y - slope * p.x; //from y = mx + b ----> b = y - mx
20-
slope = floorEpsilon(slope);
21-
intercept = floorEpsilon(intercept);
43+
slope = (p1.y - p2.y) / (p1.x - p2.x);
44+
y_intercept = p1.y - slope * p1.x; // to find y_intercept, we just plug in 1 of the Points into equation of line
45+
if (y_intercept == 0)
46+
x_intercept = 0;
47+
else
48+
x_intercept = (-1 * slope) / y_intercept;
2249
}
2350
}
24-
25-
/*** Must override both .equals() and .hashCode() for code to work properly. Surprised I got this to work. ***/
51+
52+
/* Can't simply compare doubles using == */
53+
public static boolean areEquivalent(double a, double b){
54+
return Math.abs(a - b) < epsilon;
55+
}
56+
57+
/* Must override both .equals() and .hashCode() for Lines to be hashed properly:
58+
* http://stackoverflow.com/questions/27581/what-issues-should-be-considered-when-overriding-equals-and-hashcode-in-java */
2659
@Override
2760
public boolean equals(Object obj){
2861
if (obj == this)
2962
return true;
30-
if (obj == null || obj.getClass() != this.getClass())
63+
if (obj == null || !(obj instanceof Line))
3164
return false;
65+
3266
Line otherLine = (Line) obj;
33-
if (infiniteSlope && otherLine.infiniteSlope && areEquivalent(intercept, otherLine.intercept))
34-
return true; //same vertical lines
35-
if (!infiniteSlope && !otherLine.infiniteSlope && areEquivalent(slope, otherLine.slope) && areEquivalent(intercept, otherLine.intercept))
36-
return true;
37-
return false;
67+
return LineFunctions.sameLine(this, otherLine);
3868
}
3969

4070
@Override
4171
public int hashCode(){
42-
return (int) (7 * intercept + 31 * slope);
72+
return (int) (2 * x_intercept
73+
+ 3 * (y_intercept == null ? 0 : y_intercept)
74+
+ 5 * (slope == null ? 0 : slope));
4375
}
4476

45-
private double floorEpsilon(double num){ //cool trick from book.
46-
int r = (int) (num / epsilon); //typecast is necessary
47-
return (double) (r * epsilon);
48-
}
49-
50-
private boolean areEquivalent(double a, double b){
51-
return Math.abs(a - b) < epsilon; //do I even need this?...since I round everything to nearest epsilon before saving it.
77+
@Override
78+
public String toString(){
79+
if (infiniteSlope)
80+
return "Line: Vertical line at x = " + x_intercept;
81+
else
82+
return "Line: slope = " + slope + " y-intercept = " + y_intercept;
5283
}
5384
}

src/chapter7/LineFunctions.java

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package chapter7;
2+
3+
public class LineFunctions {
4+
public static boolean intersect(Line line1, Line line2){ // Fact: 2 non-parallel lines intersect
5+
6+
/* Handles vertical lines */
7+
if (line1.infiniteSlope && line2.infiniteSlope && !Line.areEquivalent(line1.x_intercept, line2.x_intercept))
8+
return false; // parallel vertical lines
9+
else if (line1.infiniteSlope || line2.infiniteSlope)
10+
return true;
11+
12+
/* Handles non-vertical lines */
13+
if (Line.areEquivalent(line1.slope, line2.slope) && ! Line.areEquivalent(line1.y_intercept, line2.y_intercept))
14+
return false; // parallel non-vertical lines
15+
return true;
16+
}
17+
18+
public static boolean sameLine(Line line1, Line line2){
19+
/* Handles vertical lines */
20+
if (line1.infiniteSlope && line2.infiniteSlope)
21+
return Line.areEquivalent(line1.x_intercept, line2.x_intercept); // Vertical lines with same x-intercepts are equal
22+
else if (line1.infiniteSlope || line2.infiniteSlope)
23+
return false; // If only 1 line is vertical, it cannot be equal to the other line
24+
25+
/* Handles non-vertical lines: Non-vertical lines with equivalent slopes and y_intercepts are equal */
26+
return Line.areEquivalent(line1.slope, line2.slope) && Line.areEquivalent(line1.y_intercept, line2.y_intercept);
27+
}
28+
}

src/chapter7/Point.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package chapter7;
2-
/* Used in 7.7 */
2+
3+
/* Used in Point and Line class for 7.3, 7.7 */
34
public class Point {
45
double x;
56
double y;

src/chapter7/Prime.java

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
package chapter7;
2+
3+
public class Prime {
4+
public static boolean isPrime(int n){
5+
for (int i = 2; i <= (int) Math.sqrt(n); i++){
6+
if (n % i == 0)
7+
return false;
8+
}
9+
return true;
10+
}
11+
12+
public static boolean[] generatePrimes(int max){
13+
boolean [] flags = new boolean[max + 1];
14+
initialize(flags);
15+
int prime = 2;
16+
while (prime < flags.length && prime <= Math.sqrt(max)){ // see comment in crossOff() to see why we stop at sqrt(max) here
17+
crossOff(flags, prime);
18+
prime = getNextPrime(flags, prime);
19+
}
20+
return flags;
21+
}
22+
23+
private static void initialize(boolean [] flags){
24+
flags[0] = false;
25+
flags[1] = false;
26+
for (int i = 2; i < flags.length; i++){
27+
flags[i] = true;
28+
}
29+
}
30+
31+
/* Cross off multiples of prime from our array */
32+
private static void crossOff(boolean[] flags, int prime) {
33+
/* We can start with (prime*prime), because if we have a k * prime, where , < prime,
34+
this value would have already been crossed off in a prior call to this function */
35+
for (int i = prime*prime; i < flags.length; i += prime){
36+
flags[i] = false;
37+
}
38+
}
39+
40+
private static int getNextPrime(boolean[] flags, int prime) {
41+
for (int i = prime + 1; i < flags.length; i++){
42+
if (flags[i] == true)
43+
return i;
44+
}
45+
return -1; // our boolean[] wasn't big enough so we couldn't find the next prime.
46+
}
47+
}

src/chapter7/SevenPoint3.java

Lines changed: 0 additions & 26 deletions
This file was deleted.

0 commit comments

Comments
 (0)