mirror of
https://github.com/ossu/computer-science.git
synced 2025-04-18 06:35:58 -04:00
fixed bug where n3 is even and added tests
This commit is contained in:
parent
f33402c916
commit
9013cfb8d3
@ -1,8 +1,17 @@
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>Karatsuba</groupId>
|
||||
<artifactId>KaratsubaImplementation</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<name>Karatsuba implementation</name>
|
||||
<description>Karatsuba implementation</description>
|
||||
<dependencies>
|
||||
<!-- https://mvnrepository.com/artifact/junit/junit -->
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>4.13.2</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
@ -1,77 +1,13 @@
|
||||
package karatsuba;
|
||||
|
||||
public class Karatsuba {
|
||||
public interface Karatsuba {
|
||||
|
||||
//
|
||||
public int multiply(int x, int y);
|
||||
|
||||
public int multiply(int x, int y) {
|
||||
int result;
|
||||
if (x < 10 && y < 10) {
|
||||
result = x*y;
|
||||
return result;
|
||||
}
|
||||
String[] xyStr = intNormalizer(x, y);
|
||||
int n = xyStr[0].length();
|
||||
int[] abcd = intFragmenter(xyStr, n);
|
||||
int a = abcd[0];
|
||||
int b = abcd[1];
|
||||
int c = abcd[2];
|
||||
int d = abcd[3];
|
||||
|
||||
int ac = multiply(a, c);
|
||||
int bd = multiply(b, d);
|
||||
int ADPlusBC = multiply(a+b,c+d) - ac - bd;
|
||||
int tenFactorOne = (int) Math.pow(10, n);
|
||||
int tenFactorTwo = (int) Math.pow(10, n/2);
|
||||
int firstFactor = tenFactorOne*ac;
|
||||
int secondFactor = tenFactorTwo*ADPlusBC;
|
||||
// 10^nAC + 10^(n/2)(AD + BC) + BD
|
||||
result = firstFactor + secondFactor + bd;
|
||||
return result;
|
||||
}
|
||||
// This method exists to add left zeroes to the strings to make their size even and equal. n must be even.
|
||||
String[] intNormalizer(int x, int y);
|
||||
|
||||
// this method returns an array that contains abcd for the karatsuba formula
|
||||
public int[] intFragmenter(String[] xyStr, int n) {
|
||||
int strHalfPoint = n/2;
|
||||
if (strHalfPoint == 1) {
|
||||
int a = Integer.parseInt(String.valueOf(xyStr[0].charAt(0)));
|
||||
int b = Integer.parseInt(String.valueOf(xyStr[0].charAt(1)));
|
||||
int c = Integer.parseInt(String.valueOf(xyStr[1].charAt(0)));
|
||||
int d = Integer.parseInt(String.valueOf(xyStr[1].charAt(1)));
|
||||
return new int[] {a, b, c, d};
|
||||
}
|
||||
int a = Integer.parseInt(xyStr[0].substring(0, strHalfPoint));
|
||||
int b = Integer.parseInt(xyStr[0].substring(strHalfPoint));
|
||||
int c = Integer.parseInt(xyStr[1].substring(0, strHalfPoint));
|
||||
int d = Integer.parseInt(xyStr[1].substring(strHalfPoint));
|
||||
return new int[] {a, b, c, d};
|
||||
}
|
||||
|
||||
// This method exists to add left zeroes to the strings to make their size even and equal
|
||||
public String[] intNormalizer(int x, int y) {
|
||||
String xStr = Integer.toString(x);
|
||||
String yStr = Integer.toString(y);
|
||||
int xSize = xStr.length();
|
||||
int ySize = yStr.length();
|
||||
|
||||
while (!isEven(xSize) || !isEven(ySize) || xSize != ySize) {
|
||||
if (!isEven(xSize) || (xSize < ySize)) {
|
||||
xStr = addLeftZero(xStr);
|
||||
xSize = xStr.length();
|
||||
}
|
||||
if (!isEven(ySize) || (ySize < xSize)) {
|
||||
yStr = addLeftZero(yStr);
|
||||
ySize = yStr.length();
|
||||
}
|
||||
}
|
||||
return new String[] {xStr, yStr};
|
||||
}
|
||||
|
||||
public String addLeftZero(String str) {
|
||||
return "0" + str;
|
||||
}
|
||||
public boolean isEven(int numb) {
|
||||
if (numb/2==0) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
int[] intFragmenter(String[] xyStr, int n);
|
||||
}
|
||||
|
@ -0,0 +1,80 @@
|
||||
package karatsuba;
|
||||
|
||||
public class KaratsubaImplementation implements Karatsuba {
|
||||
|
||||
@Override
|
||||
public int multiply(int x, int y) {
|
||||
int result;
|
||||
if (x < 10 && y < 10) {
|
||||
result = x*y;
|
||||
return result;
|
||||
}
|
||||
String[] xyStr = intNormalizer(x, y);
|
||||
int n = xyStr[0].length();
|
||||
int[] abcd = intFragmenter(xyStr, n);
|
||||
int a = abcd[0];
|
||||
int b = abcd[1];
|
||||
int c = abcd[2];
|
||||
int d = abcd[3];
|
||||
|
||||
int ac = multiply(a, c);
|
||||
int bd = multiply(b, d);
|
||||
int ADPlusBC = multiply(a+b,c+d) - ac - bd;
|
||||
int tenFactorOne = (int) Math.pow(10, n);
|
||||
int tenFactorTwo = (int) Math.pow(10, n/2);
|
||||
int firstFactor = tenFactorOne*ac;
|
||||
int secondFactor = tenFactorTwo*ADPlusBC;
|
||||
// 10^nAC + 10^(n/2)(AD + BC) + BD
|
||||
result = firstFactor + secondFactor + bd;
|
||||
return result;
|
||||
}
|
||||
|
||||
// this method returns an array that contains abcd for the karatsuba formula
|
||||
@Override
|
||||
public int[] intFragmenter(String[] xyStr, int n) {
|
||||
int strHalfPoint = n/2;
|
||||
if (strHalfPoint == 1) {
|
||||
int a = Integer.parseInt(String.valueOf(xyStr[0].charAt(0)));
|
||||
int b = Integer.parseInt(String.valueOf(xyStr[0].charAt(1)));
|
||||
int c = Integer.parseInt(String.valueOf(xyStr[1].charAt(0)));
|
||||
int d = Integer.parseInt(String.valueOf(xyStr[1].charAt(1)));
|
||||
return new int[] {a, b, c, d};
|
||||
}
|
||||
int a = Integer.parseInt(xyStr[0].substring(0, strHalfPoint));
|
||||
int b = Integer.parseInt(xyStr[0].substring(strHalfPoint));
|
||||
int c = Integer.parseInt(xyStr[1].substring(0, strHalfPoint));
|
||||
int d = Integer.parseInt(xyStr[1].substring(strHalfPoint));
|
||||
return new int[] {a, b, c, d};
|
||||
}
|
||||
|
||||
// This method exists to add left zeroes to the strings to make their size even and equal
|
||||
@Override
|
||||
public String[] intNormalizer(int x, int y) {
|
||||
String xStr = Integer.toString(x);
|
||||
String yStr = Integer.toString(y);
|
||||
int xSize = xStr.length();
|
||||
int ySize = yStr.length();
|
||||
|
||||
while (!isEven(xSize) || !isEven(ySize) || xSize != ySize) {
|
||||
if (!isEven(xSize) || (xSize < ySize)) {
|
||||
xStr = addLeftZero(xStr);
|
||||
xSize = xStr.length();
|
||||
}
|
||||
if (!isEven(ySize) || (ySize < xSize)) {
|
||||
yStr = addLeftZero(yStr);
|
||||
ySize = yStr.length();
|
||||
}
|
||||
}
|
||||
return new String[] {xStr, yStr};
|
||||
}
|
||||
|
||||
public String addLeftZero(String str) {
|
||||
return "0" + str;
|
||||
}
|
||||
public boolean isEven(int numb) {
|
||||
if (numb%2 != 0) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
@ -5,7 +5,7 @@ public class Main {
|
||||
// 10^nAC + 10^(n/2)(AD + BC) + BD
|
||||
int x = 1234;
|
||||
int y = 5678;
|
||||
Karatsuba karatsuba = new Karatsuba();
|
||||
Karatsuba karatsuba = new KaratsubaImplementation();
|
||||
int result = karatsuba.multiply(x, y);
|
||||
System.out.println(result);
|
||||
}
|
||||
|
@ -0,0 +1,49 @@
|
||||
package karatsuba;
|
||||
import static org.junit.Assert.*;
|
||||
import org.junit.Test;
|
||||
|
||||
|
||||
public class KaratsubaImplementationTest {
|
||||
|
||||
private Karatsuba karatsuba = new KaratsubaImplementation();
|
||||
|
||||
@Test
|
||||
public void singleDigitMultiplication() {
|
||||
assertEquals(karatsuba.multiply(4, 7), 28);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void doubleDigitMultiplication() {
|
||||
assertEquals(karatsuba.multiply(21, 89), 1869);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void tripleDigitMultiplication() {
|
||||
assertEquals(karatsuba.multiply(313, 862), 269806);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void quadDigitMultiplication() {
|
||||
assertEquals(karatsuba.multiply(1234, 5678), 7006652);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void quadDigitMultiplicationInverse() {
|
||||
assertEquals(karatsuba.multiply(5678, 1234), 7006652);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void fiveDigitMultiplication() {
|
||||
assertEquals(karatsuba.multiply(45689, 752), 34358128);
|
||||
}
|
||||
@Test
|
||||
public void sevenDigitMultiplication() {
|
||||
assertEquals(karatsuba.multiply(34984916, 6521984), 2.28171062393e14);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void unnevenSevenDigitMultiplication() {
|
||||
long result = Long.parseLong("1125628350426");
|
||||
assertEquals(karatsuba.multiply(3519, 319871654), result);
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user