Reputation: 11
I'm trying to write a function that outputs a step by step long division problem given a dividend and a divisor. It's supposed to look like this:
25 r 2
5 | 125
-10
27
-25
2
I can write the bit with the vertical line easily enough, but I can't figure out how to format the top part with the remainder or the subtraction loop. Any help greatly appreciated
Upvotes: 1
Views: 1201
Reputation: 2197
Populate an object and then call to print format.
LongDivision.java
public class LongDivision {
/**
* The Number.
*/
String number;
/**
* The Divider.
*/
String divider;
/**
* The Result.
*/
String result;
/**
* The Lines.
*/
List<String> lines;
/**
* Instantiates a new Long divider.
*
* @param number the number
* @param divider the divider
* @param result the result
* @param lines the lines
*/
public LongDivision(String number, String divider, String result, List<String> lines) {
this.number = number;
this.divider = divider;
this.result = result;
this.lines = lines;
}
/**
* Gets number.
*
* @return the number
*/
public String getNumber() {
return number;
}
/**
* Sets number.
*
* @param number the number
*/
public void setNumber(String number) {
this.number = number;
}
/**
* Gets divider.
*
* @return the divider
*/
public String getDivider() {
return divider;
}
/**
* Sets divider.
*
* @param divider the divider
*/
public void setDivider(String divider) {
this.divider = divider;
}
/**
* Gets result.
*
* @return the result
*/
public String getResult() {
return result;
}
/**
* Sets result.
*
* @param result the result
*/
public void setResult(String result) {
this.result = result;
}
/**
* Gets lines.
*
* @return the lines
*/
public List<String> getLines() {
return lines;
}
/**
* Sets lines.
*
* @param lines the lines
*/
public void setLines(List<String> lines) {
this.lines = lines;
}
@Override
public String toString() {
return String.format(
"LongDivider (number=%s, divider=%s, result=%s, lines=%s)", this.number, this.divider, this.result, this.lines);
}
/**
* print format.
*
* @return the string
*/
public String printFormat() {
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append(result+"\n");
stringBuilder.append(repeat("__", 2));
stringBuilder.append("\n");
stringBuilder.append(number + "| " + divider);
stringBuilder.append("\n");
lines.stream().forEach(s -> stringBuilder.append(s+"\n"));
return stringBuilder.toString();
}
public static String repeat(String s, int n) {
if(s == null) {
return null;
}
final StringBuilder sb = new StringBuilder(s.length() * n);
for(int i = 0; i < n; i++) {
sb.append(s);
}
return sb.toString();
}
}
Main class
public class LongDividerSolution {
/**
* The entry point of application.
*
* @param args the input arguments
*/
public static void main(String[] args) {
String number = "945";
String divider = "4";
String result = "236 (1)";
String lineSeparator = "_";
int max = Math.max(number.length(), result.length());
// TODO Implement the calculation itself.
List<String> strings = new ArrayList<>();
strings.add("8");
strings.add(LongDivision.repeat(lineSeparator, max));
strings.add("14");
strings.add(" 12");
strings.add(LongDivision.repeat(lineSeparator,max));
strings.add(" 25");
strings.add(" 24");
strings.add(LongDivision.repeat(lineSeparator,max));
strings.add("( 1 )");
LongDivision longDivision = new LongDivision(number, divider, result,strings);
System.out.println(longDivision.printFormat());
}
}
Output:
236 (1)
___
945| 4
8
_____
14
12
_____
25
24
_____
( 1 )
Upvotes: 0
Reputation: 61
Here's my solution to this problem, you might want to implement some error checking to see if the dividend is larger than the divisor. The spacing might not always work, but I tried with a few numbers and it seemed fine:
int divisor = 5;
int dividend = 127;
int answer = dividend / divisor;
// Set a space constant for formatting
int spaces = (int) Math.log10(dividend) + (int) Math.log10(divisor) + 4;
// Print the initial bracket
for(int i = 0; i < spaces - (int) Math.log10(answer); i ++) {
System.out.print(" ");
}
System.out.println(Integer.toString(answer) + " r " + Integer.toString(dividend % divisor));
System.out.println(Integer.toString(divisor) + " | " + Integer.toString(dividend));
// Do a while loop to do the subtraction
int remainder = dividend;
while(remainder != dividend % divisor) {
// Find how much of the start of the remainder can be subtracted by making it into a string
String test = Integer.toString(remainder);
int sub = Integer.valueOf(test.substring(0, 1));
test = test.substring(1);
int exp = (int) Math.log10(remainder);
while(sub < divisor) {
sub = sub * 10 + Integer.valueOf(test.substring(0, 1));
test = test.substring(1);
exp--;
}
int multiple = sub - (sub % divisor);
//Print the subtraction and remainder lines
for(int i = 0; i < spaces - 1 - exp - (int) Math.log10(multiple); i++) {
System.out.print(" ");
}
System.out.println("-" + Integer.valueOf(multiple));
remainder -= multiple * Math.pow(10, exp);
for(int i = 0; i < spaces - (int) Math.log10(remainder); i++) {
System.out.print(" ");
}
System.out.println(Integer.valueOf(remainder));
}
The tricky part was working out how much of the remainder needed to be isolated (for example with 127 and 5, 1 cannot be divided by 5, so I needed to use 12) which I achieved by making the remainder into a String to interpret it one character at a time (this can be done mathematically but it hurt my head when it didn't work on my first try so I gave up).
Sample output for dividend = 12, divisor = 5:
25 r 2
5 | 127
-10
27
-25
2
Upvotes: 1