-
Notifications
You must be signed in to change notification settings - Fork 0
/
NthRootFinder.java
208 lines (193 loc) · 6.97 KB
/
NthRootFinder.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
import java.util.Scanner;
public class NthRootFinder {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
// Read n (for taking the nth root)
int n = Integer.parseInt(sc.nextLine());
// Read number to take the nth root of
int number = Integer.parseInt(sc.nextLine());
// Read the desired precision
int precision = Integer.parseInt(sc.nextLine());
// Print the answer
System.out.println(findNthRoot(number, n, precision));
}
private static String findNthRoot(int number, int n, int precision) {
/*
* Given a int number, the number being rooted, int n, the power by which it is
* being rooted and int precision the number of decimals the root should be
* precise to Returns a string of the nth root of number to precision decimal
* places
*/
double upperBound = number;
double lowerBound = 0.0;
double midPoint;
int numberIterations = 0;
while (true) {
numberIterations++;
midPoint = (upperBound - lowerBound) / 2 + lowerBound;
int numberOfCharsBeforeDecimalPoint = numberOfCharsBeforeDecimal(midPoint);
double doubleValue = power(midPoint, n);
doubleValue = Math.ceil((doubleValue*100)/100);
System.out.println(Double.parseDouble(
String.format("%." + Integer.toString(precision) + "f",
power(midPoint, n))) + " " + midPoint);
if (Double.parseDouble(
String.format("%." + Integer.toString(precision) + "f",
power(midPoint, n))) == number) { //if the midpoint^n == number, returns midpoint
return Integer.toString(numberIterations);
/*String.format("%." + Integer.toString(precision + numberOfCharsBeforeDecimalPoint) + "g",
midPoint)*/
} else if (power(midPoint, n) > number) {
upperBound = midPoint;
} else {
lowerBound = midPoint;
}
}
}
private static double power(double n, int rootNumber) {
/*
* Given int n, the number to be raised to a power And int rootNumber, the power
* it is to be raised to Returns number to that power
*/
double result = n;
for (int i = 1; i < rootNumber; i++) {
result *= n;
}
return result;
}
private static int numberOfCharsBeforeDecimal(double number) {
/*
* Given a number with a decimal point
* Returns the number of digits in the number before the decimal point
*/
String numberConvertedToString = Double.toString(number);
char[] numberAsCharArray = numberConvertedToString.toCharArray();
int accumulateBeforeDecimal = 0;
for (char digit : numberAsCharArray) {
if (digit == '.') {
return accumulateBeforeDecimal;
}
++accumulateBeforeDecimal;
}
return -1;
}
private static int[][] runTests() {
int[][] attempts = new int[254][2];
for (int i = 2; i < 256; i++) {
attempts[i-2][0] = i;
attempts[i-2][1] = Integer.parseInt(findNthRoot(i, 2, 1));
//System.out.println("Finished one " + i);
}
return attempts;
}
}
// private static String findNthRoot(int number, int n, int precision) {
// /*
// * Given a int number, the number being rooted, int n, the power by which is
// it
// * being rooted and int precision the number of decimals the root should be
// * precise to Returns a string of the nth root of number to precision decimal
// * places
// */
// // Number = number to take nth root, n = nth root, precision = number of
// // decimals accurate
// // Approach is binary search
// double upperBound = number;
// double lowerBound = 0.0;
// double midPoint = (upperBound - lowerBound) / 2;
// while (true) {
// String approximateValue = round(power(midPoint, n), precision);
// double approximateValueDouble = Double.parseDouble(round(power(midPoint, n),
// precision));
// if (approximateValueDouble == number) {
// return round(midPoint, precision);
// }
// if (approximateValueDouble > number) {
// upperBound = midPoint;
// } else {
// lowerBound = midPoint;
// }
// midPoint = (upperBound - lowerBound) / 2.0 + lowerBound;
// System.out.println(midPoint);
// System.out.println("Value: " + approximateValueDouble);
// }
// }
//
//
// private static String round(double number, int numPlaces) {
// /*
// * Given Integer number, the number to be rounded And int numPlaces, the
// number
// * of decimal places to round the integer to Returns the integer rounded to
// that
// * decimal place
// */
// String stringNumber = number + "";
// char[] charNumber = stringNumber.toCharArray();
// int placesCount = 0;
// boolean afterDecimalState = false;
// String stringOfNumber = "";
// String result = "";
// for (char charac : charNumber) {//identifies numbers too large and doesn't
// round
// if (charac == 'E') {
// return stringNumber;
// }
// }
//
// for (int i = 0; i < charNumber.length; i++) {
// char character = charNumber[i];
//
// stringOfNumber += character;
// if (character == '.') {
// afterDecimalState = true;
// continue;
// }
// if (afterDecimalState) {
// placesCount++;
// }
// if (placesCount == numPlaces + 1) { // includes number determining what it's
// rounded to
// break;
// }
// }
// for (int i = placesCount; i < numPlaces + 1; i++) { // only executes if above
// loop terminated too early.
// // Includes determinant
// stringOfNumber += "0";
// }
// char[] finalNumberDeterminant = stringOfNumber.toCharArray();
// int lastCharacterToInt = Integer
// .parseInt(Character.toString(finalNumberDeterminant[finalNumberDeterminant.length
// - 1]));
// int secondToLastCharacterToInt = Integer
// .parseInt(Character.toString(finalNumberDeterminant[finalNumberDeterminant.length
// - 2]));
// if (lastCharacterToInt > 5 && secondToLastCharacterToInt < 9) {
// finalNumberDeterminant[finalNumberDeterminant.length - 2] = (char) ((Integer
// .parseInt(Character.toString(finalNumberDeterminant[finalNumberDeterminant.length
// - 2])) + 49));
// // 49 is added since apparently casting char to an integer actually returns
// // start-of-heading unless you add the ascii value of the first char
// } else if (lastCharacterToInt > 5 && secondToLastCharacterToInt == 9) {
// //need to round the next number up if 9
// int i = 2;
// for (; i <= finalNumberDeterminant.length
// && (finalNumberDeterminant[finalNumberDeterminant.length - i] == '9'
// || finalNumberDeterminant[finalNumberDeterminant.length - i] == '.'); i++) {
// if (finalNumberDeterminant[finalNumberDeterminant.length - i] == '9') {
// finalNumberDeterminant[finalNumberDeterminant.length - i] = '0';
// }
// }
// finalNumberDeterminant[finalNumberDeterminant.length - (i-1)] = (char)
// ((Integer
// .parseInt(Character.toString(finalNumberDeterminant[finalNumberDeterminant.length
// - i])) + 49));
// }
// finalNumberDeterminant[finalNumberDeterminant.length - 1] = ' ';
// for (char c : finalNumberDeterminant) { // converts the final value to a
// returnable string
// result += c;
// }
// return result.trim();
// }