Last active
December 17, 2015 00:09
-
-
Save trestletech/5518670 to your computer and use it in GitHub Desktop.
Project to compute the minimum integer > 1 which is not representable by combining an integer using the (parenthesized) +, -, /, and * operations.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.io.FileNotFoundException; | |
import java.io.FileOutputStream; | |
import java.io.PrintStream; | |
public class Main { | |
public static void main(String[] args){ | |
try{ | |
//Write out to file assuming IntelliJ project layout. | |
PrintStream out = new PrintStream(new FileOutputStream("src/timing.txt")); | |
//out = System.out; | |
String header = "N\tY\tmin\tElapsed Time"; | |
out.println("Given Examples:"); | |
out.println(header); | |
out.println(logTest(2,5)); // should be 2 | |
out.println(logTest(3,5)); // should be 3 | |
out.println(); | |
out.println("Benchmarking tests:"); | |
out.println(header); | |
for (int i = 1; i <= 9; i++){ | |
out.println(logTest(i,i)); | |
} | |
} catch(FileNotFoundException e){ | |
System.err.println(e); | |
} | |
} | |
/** | |
* Log the run specified. | |
* @param N The number of values to consider in the expression. | |
* @param Y The integer to use in the expressions. | |
* @return A string describing N, Y, the returned result, and the run-time. | |
*/ | |
private static String logTest(int N, int Y){ | |
long startTime = System.nanoTime(); | |
int min = MinNotRepresentable.minNotRepresentable(N,Y); | |
long duration = System.nanoTime() - startTime; | |
return (String.format("%d\t%d\t%d\t%.3fms", N, Y, min, duration/1000.0/1000.0)); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.util.Arrays; | |
import java.util.HashSet; | |
public class MinNotRepresentable { | |
/** | |
* Given two integers N and Y, where N and Y are integers between 1 and 9 (inclusive), write a program that finds | |
* the smallest integer X > 1 that CANNOT be represented with an expression composed of exactly N many, Ys. | |
* The expression may be parenthesized, and the only operations allowed in the expression are the arithmetic | |
* operations of addition, subtraction, multiplication, and division. | |
* @param N The number of integers to consider in the expressions. | |
* @param Y The integer to use in the expressions. | |
* @return The minimum integer which cannot be expressed through some combination of N many Y's. | |
*/ | |
public static int minNotRepresentable(int N, int Y){ | |
HashSet<Double> vals = buildLevels(N, Y); | |
//find the first integer that's not present in the hash. | |
for (double i = 2; true; i++){ | |
if (!vals.contains(i)){ | |
return (int)i; | |
} | |
} | |
} | |
/** | |
* Progressively compute each level up the the maximum level specified. | |
* @param N the number of values to permit in the formula | |
* @param Y the number to use in the formula | |
* @return an array containing all of the values at each level. | |
*/ | |
private static HashSet<Double> buildLevels(int N, int Y){ | |
HashSet<Double>[] levels = new HashSet[N]; | |
//populate the first level -- all you can have is the value of Y. | |
levels[0] = new HashSet<Double>(Arrays.asList((double)Y)); | |
//iteratively compute the numbers in each level. | |
for (int i = 1; i < N; i++){ | |
levels[i] = populateLevel(i, levels); | |
} | |
return levels[N-1]; | |
} | |
/** | |
* Compute the values for the specified level | |
* @param level the level to compute | |
* @param levels the array of the other levels. It is expected that all of the previous levels before 'level' have | |
* been computed already. | |
* @return The values in the requested level. | |
*/ | |
private static HashSet<Double> populateLevel(int level, HashSet<Double>[] levels){ | |
HashSet<Double> toReturn = new HashSet<Double>(); | |
//loop through all valid combinations of `level` Y's. Set 'a' to the number of Y's in the first group | |
for (int a = 0; a < level; a++){ | |
//set 'b' to the number of Y's in the second group. | |
int b = level - a - 1; | |
//extract the numbers that existed at each level. | |
HashSet<Double> levelA = levels[a]; | |
HashSet<Double> levelB = levels[b]; | |
//only compute commutative operations if a <= b | |
boolean includeCommutative = true; | |
if (a > b){ | |
includeCommutative = false; | |
} | |
combineLevels(levelA, levelB, toReturn, includeCommutative); | |
} | |
return toReturn; | |
} | |
/** | |
* Calculate all combinations of level a with level b | |
* @param levelA the values present in the first level | |
* @param levelB the values present in the second level | |
* @param newLevel the Hash into which we should add the values computed by combining levelA and levelB. | |
*/ | |
private static void combineLevels(HashSet<Double> levelA, | |
HashSet<Double> levelB, | |
HashSet<Double> newLevel, | |
boolean includeCommutative){ | |
//loop through all combinations of all values in A and B | |
for (Double a : levelA){ | |
for (Double b : levelB){ | |
//attempt to add, no-op if it already exists. | |
newLevel.add(a - b); | |
newLevel.add(a / b); | |
if (includeCommutative){ | |
newLevel.add(a + b); | |
newLevel.add(a * b); | |
} | |
} | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Given Examples: | |
N Y min Elapsed Time | |
2 5 2 0.804ms | |
3 5 3 0.061ms | |
Benchmarking tests: | |
N Y min Elapsed Time | |
1 1 2 0.009ms | |
2 2 2 0.019ms | |
3 3 5 0.059ms | |
4 4 10 0.252ms | |
5 5 13 1.183ms | |
6 6 22 6.400ms | |
7 7 38 10.582ms | |
8 8 91 13.143ms | |
9 9 195 33.031ms |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment