Ethan Villarosa
Ethan Villarosa

Reputation: 11

Step by step long division in Java?

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

Answers (2)

4EACH
4EACH

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

Owen Waldron
Owen Waldron

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

Related Questions