Boolean array and a simple way to try every combination - java

So at the moment i am writing some code for my last comp sci paper, it requires you to red in some input on system.in, process it, first line is always a set of numbers upto 25 numbers. This is followed by a single N or L, and another int which is the aim. Using this input you have to find the the right set of operations (+ and *) that uses the int values to create the aim.
I am using a Boolean array to keep track of what operands i am using in very check however I'm unsure how to "brute force" the solution by trying every different set of operands, i have the code to check each set however Im not sure if there is an simple and easy way to change the array by such as [0,0,0,0] (0 is false) to [0,0,0,1], [0,0,1,0], [0,0,1,1] etc?
Im sure there is a really simple way i have overlooked but for the life of me i am unsure of what it is atm.
static boolean evlN(int[] input, boolean[]ops, int aim){
boolean run = true, found = false;
int[] used = new int[input.length];
int runs = 0 ,ans = 0;
while(!found && runs < (1 << ops.length)){
//finding all multiplys and doing them first
search:
for(int x = 0; x < ops.length; x++){
if(!ops[x]){
used[x] = input[x] * input[x+1];
//need to stop working out and change the ops
if(used[x] > aim){
run = false;
break;
}
}
}
//once multiplys have been done need to do all the adds
if(run){
for(int x = 0; x < ops.length; x++){
if(ops[x]){
if(used[x] != 0) ans += used[x] + input[x+1];
else if(used[x+1] != 0) ans += input[x] + used[x];
}
if(ans > aim) break;
}
}
if(ans == aim) found = true;
used = new int[input.length];
ans= 0;
runs++;
run = !run;
}
if(found) return true;
else return false;
}
this is what im using to work out each set of operands and numbers i just trying to change the boolean array to brute force the answer

Your set of input combinations looks like a binary integer (call it N). You can progress through the different combinations by incrementing N.

There is a fairly generic mechanism that can be used to increment through a set of combination, just as you would do for digits in an integer. I'll demonstrate it using an interface so you can see how it can be applied in general.
public interface UnitValue {
boolean isLast();
UnitValue next();
}
public class <T extends UnitValue> MultiUnitValue {
private final int size;
private final T first;
private final T[] units;
private boolean complete = false;
public MultiUnitValue(int size, T first) {
this.size = size;
this.first = first;
this.units = new T[size];
for (int i = 0; i < size; i++)
units[i] = first;
}
public void next() {
if (!complete) {
int i = 0;
while (units[i].isLast())
units[i++] = first;
units[i].next();
complete = i == size - 1 && units[i].isLast();
}
}
}
I've left out getters for clarity but they should be obvious.
For a non-generic solution for booleans it'd look like:
boolean[] values = new boolean[size];
int i = 0;
while (values[i])
values[i++] = false;
values[i] = true;
A very similar solution works for characters, digits, enums and anything else that fits the same pattern.

Related

Find if a number is in an array, and if so, how many times does it appear

The problem is there is an array of 10000 that is already filled for me. The range of numbers that will fill the array will be between 0 and 2500. The array is unsorted. My goal is to find the existence of 1320 through one linear search, and the second linear search will check how many times the number 1320 appears. The array is a random array.
I have tried setting up a linear search that will check whether the number in the array exists. I have also tried to set up the linear search that will check how many times an array exists. Neither worked, this is my first time working with arrays so I am not sure if I am even doing them correctly
public static void main(String[] args) {
// Finish adding Code
boolean DoesItExist;
int iHowMany;
final int SIZE = 10000, ENTRY = 1320;
int[] NumArray = new int[SIZE];
OwenHeading.getHeader("Assignment 9: Arrays.");
fillTheArray(NumArray, SIZE);
System.out.println("DONE");
}
public static void fillTheArray(int[] iTempArray, int SIZE) {
final int RANGE = 2500;
Random rand = new Random();
for (int index = 0; index <= SIZE - 1; index++)
iTempArray[index] = rand.nextInt(RANGE);
}
public static boolean linearSearchOne(int[] iTempArray, int SIZE, int ENTRY) {
boolean TempDoesItExist;
return TempDoesItExist;
}
public static int linearSearchTwo(int[] iTempArray, int SIZE, int ENTRY) {
int HowManyExist;
return HowManyExist;
}
public static void programOutput(boolean TempDoesItExist, int TempHowMany) {
if (TempDoesItExist)
System.out.println("does");
// Cool, you found the number 1320
else
System.out.println("does not");
// Dang, you didn't find the number 1320
}
}
I am not asking for the exact answer, just some help that will get me going into the right direction. I feel like I would be able to do this project easier if I started from scratch, but my teacher wants us to use his starter project.
Initialize your boolean and counter
Bool doesItExist = false;
Int iHowManyTimes = 0;
You can check for values in arrays in java in a linear fashion like this:
for (int number : NumArray) {
if (anItemInArray == myValue) {
doesItExist = true;
return;
}
}
afterwards do it all over again and increment your counter
for (int number : NumArray) {
if (number == ENTRY) {
iHowMany += 1;
}
}
Edit: Return statement added to first loop, as there is no reason to continue after the value is found
you can modify two methods of linear search you have in this way and that is going to work :
just declare a counter and increment it each time you find your ENTRY number.
public static boolean linearSearchOne(int[] iTempArray, int SIZE, int ENTRY) {
for (int i = 0; i < SIZE; i++) {
if (iTempArray[i] == ENTRY) {
return true;
}
}
return false
}
public static int linearSearchTwo(int[] iTempArray, int SIZE, int ENTRY) {
int HowManyExist;
for (int i = 0; i < SIZE; i++) {
if (iTempArray[i] == ENTRY) {
HowManyExist ++;
}
}
return HowManyExist;
}
It looks like you didn't call the linear search methods. For a linear search you can just do something like the following:
found=false;
howManyCounter=0;
for (int x=0, x<array.length; x++){
if (array[x]==numberYouWant){
found=true;
howManyCounter++;
}
}

Creating a method that returns a certain group of integers from two different integer arrays?

I'm not really sure how to word the question for the title but this post explains what I'm after. I apologize if my question is worded incorrectly.
In Java, how would I go about creating a method that returns the number of 'hippos' found in two different integer arrays:
int[] hippo1 = new int[100];
int[] hippo2 = new int[10000];
given that a 'hippo' is considered an integer that is 75 or above?
Would it be?
public static int calcNumberOfHippos(int[] hippos)
{
for (int i = 0; i < hippos.length; i++)
{
if (hippos[i] >= 75)
{
return hippos[i];
}
}
int numHippos = (int)hippos.length;
return numHippos;
}
I'm not sure if I should return hippos.length at the end. That's the only way I can get it to return something. I would really like to return hippos[i] but every time I try to return that out of the for loop it says that it doesn't recognize the variable i. It says Cannot find symbol variable i.
public static int calcNumberOfHippos(int[] hippos)
{
for (int i = 0; i < hippos.length; i++)
{
if (hippos[i] >= 75)
{
return hippos[i];
}
}
return hippos[i];
}
Can anyone please point me in the right direction?
If you want to calculate the number of hippos (how many members of the array are larger than 75), then this code could help:
public static int calcNumberOfHippos(int[] hippos) {
int numOfHippos = 0;
for (int i = 0; i < hippos.length; i++) {
if (hippos[i] >= 75)
{
numOfHippos++;
}
}
return numOfHippos;
}
The idea is to go over the array and count up every time a hippo is spotted. You don't need to return the first hippo that you see - which is what your original code would've done.
int hippoCount = Arrays.stream(hippos).reduce(0, (acc, n) -> acc + (n >= 75 ? 1 : 0));
should do the trick.

Java Fibonacci Sequence fast method

I need a task about finding Fibonacci Sequence for my independent project in Java. Here are methods for find.
private static long getFibonacci(int n) {
switch (n) {
case 0:
return 0;
case 1:
return 1;
default:
return (getFibonacci(n-1)+getFibonacci(n-2));
}
}
private static long getFibonacciSum(int n) {
long result = 0;
while(n >= 0) {
result += getFibonacci(n);
n--;
}
return result;
}
private static boolean isInFibonacci(long n) {
long a = 0, b = 1, c = 0;
while (c < n) {
c = a + b;
a = b;
b = c;
}
return c == n;
}
Here is main method:
long key = getFibonacciSum(n);
System.out.println("Sum of all Fibonacci Numbers until Fibonacci[n]: "+key);
System.out.println(getFibonacci(n)+" is Fibonacci[n]");
System.out.println("Is n2 in Fibonacci Sequence ?: "+isInFibonacci(n2));
Codes are completely done and working. But if the n or n2 will be more than normal (50th numbers in Fib. Seq.) ? Codes will be runout. Are there any suggestions ?
There is a way to calculate Fibonacci numbers instantaneously by using Binet's Formula
Algorithm:
function fib(n):
root5 = squareroot(5)
gr = (1 + root5) / 2
igr = 1 - gr
value = (power(gr, n) - power(igr, n)) / root5
// round it to the closest integer since floating
// point arithmetic cannot be trusted to give
// perfect integer answers.
return floor(value + 0.5)
Once you do this, you need to be aware of the programming language you're using and how it behaves. This will probably return a floating point decimal type, whereas integers are probably desired.
The complexity of this solution is O(1).
Yes, one improvement you can do is to getFibonacciSum(): instead of calling again and again to isInFibonacci which re-calculates everything from scratch, you can do the exact same thing that isInFibonacci is doing and get the sum in one pass, something like:
private static int getFibonacciSum(int n) {
int a = 0, b = 1, c = 0, sum = 0;
while (c < n) {
c = a + b;
a = b;
sum += b;
b = c;
}
sum += c;
return sum;
}
Well, here goes my solution using a Map and some math formulas. (source:https://www.nayuki.io/page/fast-fibonacci-algorithms)
F(2k) = F(k)[2F(k+1)−F(k)]
F(2k+1) = F(k+1)^2+F(k)^2
It is also possible implement it using lists instead of a map but it is just reinventing the wheel.
When using Iteration solution, we don't worry about running out of memory, but it takes a lot of time to get fib(1000000), for example. In this solution we may be running out of memory for very very very very big inputs (like 10000 billion, idk) but it is much much much faster.
public BigInteger fib(BigInteger n) {
if (n.equals(BigInteger.ZERO))
return BigInteger.ZERO;
if (n.equals(BigInteger.ONE) || n.equals(BigInteger.valueOf(2)))
return BigInteger.ONE;
BigInteger index = n;
//we could have 2 Lists instead of a map
Map<BigInteger,BigInteger> termsToCalculate = new TreeMap<BigInteger,BigInteger>();
//add every index needed to calculate index n
populateMapWhitTerms(termsToCalculate, index);
termsToCalculate.put(n,null); //finally add n to map
Iterator<Map.Entry<BigInteger, BigInteger>> it = termsToCalculate.entrySet().iterator();//it
it.next(); //it = key number 1, contains fib(1);
it.next(); //it = key number 2, contains fib(2);
//map is ordered
while (it.hasNext()) {
Map.Entry<BigInteger, BigInteger> pair = (Entry<BigInteger, BigInteger>)it.next();//first it = key number 3
index = (BigInteger) pair.getKey();
if(index.remainder(BigInteger.valueOf(2)).equals(BigInteger.ZERO)) {
//index is divisible by 2
//F(2k) = F(k)[2F(k+1)−F(k)]
pair.setValue(termsToCalculate.get(index.divide(BigInteger.valueOf(2))).multiply(
(((BigInteger.valueOf(2)).multiply(
termsToCalculate.get(index.divide(BigInteger.valueOf(2)).add(BigInteger.ONE)))).subtract(
termsToCalculate.get(index.divide(BigInteger.valueOf(2)))))));
}
else {
//index is odd
//F(2k+1) = F(k+1)^2+F(k)^2
pair.setValue((termsToCalculate.get(index.divide(BigInteger.valueOf(2)).add(BigInteger.ONE)).multiply(
termsToCalculate.get(index.divide(BigInteger.valueOf(2)).add(BigInteger.ONE)))).add(
(termsToCalculate.get(index.divide(BigInteger.valueOf(2))).multiply(
termsToCalculate.get(index.divide(BigInteger.valueOf(2))))))
);
}
}
// fib(n) was calculated in the while loop
return termsToCalculate.get(n);
}
private void populateMapWhitTerms(Map<BigInteger, BigInteger> termsToCalculate, BigInteger index) {
if (index.equals(BigInteger.ONE)) { //stop
termsToCalculate.put(BigInteger.ONE, BigInteger.ONE);
return;
} else if(index.equals(BigInteger.valueOf(2))){
termsToCalculate.put(BigInteger.valueOf(2), BigInteger.ONE);
return;
} else if(index.remainder(BigInteger.valueOf(2)).equals(BigInteger.ZERO)) {
// index is divisible by 2
// FORMUMA: F(2k) = F(k)[2F(k+1)−F(k)]
// add F(k) key to termsToCalculate (the key is replaced if it is already there, we are working with a map here)
termsToCalculate.put(index.divide(BigInteger.valueOf(2)), null);
populateMapWhitTerms(termsToCalculate, index.divide(BigInteger.valueOf(2)));
// add F(k+1) to termsToCalculate
termsToCalculate.put(index.divide(BigInteger.valueOf(2)).add(BigInteger.ONE), null);
populateMapWhitTerms(termsToCalculate, index.divide(BigInteger.valueOf(2)).add(BigInteger.ONE));
} else {
// index is odd
// FORMULA: F(2k+1) = F(k+1)^2+F(k)^2
// add F(k+1) to termsToCalculate
termsToCalculate.put(((index.subtract(BigInteger.ONE)).divide(BigInteger.valueOf(2)).add(BigInteger.ONE)),null);
populateMapWhitTerms(termsToCalculate,((index.subtract(BigInteger.ONE)).divide(BigInteger.valueOf(2)).add(BigInteger.ONE)));
// add F(k) to termsToCalculate
termsToCalculate.put((index.subtract(BigInteger.ONE)).divide(BigInteger.valueOf(2)), null);
populateMapWhitTerms(termsToCalculate, (index.subtract(BigInteger.ONE)).divide(BigInteger.valueOf(2)));
}
}
This method of solution is called dynamic programming
In this method we are remembering the previous results
so when recursion happens then the cpu doesn't have to do any work to recompute the same value again and again
class fibonacci
{
static int fib(int n)
{
/* Declare an array to store Fibonacci numbers. */
int f[] = new int[n+1];
int i;
/* 0th and 1st number of the series are 0 and 1*/
f[0] = 0;
f[1] = 1;
for (i = 2; i <= n; i++)
{
/* Add the previous 2 numbers in the series
and store it */
f[i] = f[i-1] + f[i-2];
}
return f[n];
}
public static void main (String args[])
{
int n = 9;
System.out.println(fib(n));
}
}
public static long getFib(final int index) {
long a=0,b=0,total=0;
for(int i=0;i<= index;i++) {
if(i==0) {
a=0;
total=a+b;
}else if(i==1) {
b=1;
total=a+b;
}
else if(i%2==0) {
total = a+b;
a=total;
}else {
total = a+b;
b=total;
}
}
return total;
}
I have checked all solutions and for me, the quickest one is to use streams and this code could be easily modified to collect all Fibonacci numbers.
public static Long fibonaciN(long n){
return Stream.iterate(new long[]{0, 1}, a -> new long[]{a[1], a[0] + a[1]})
.limit(n)
.map(a->a[0])
.max(Long::compareTo)
.orElseThrow();
}
50 or just below 50 is as far as you can go with straight recursive implementation. You can switch to iterative or dynamic programming (DP) approaches if you want to go much higher than that. I suggest learning about those from this: https://www.javacodegeeks.com/2014/02/dynamic-programming-introduction.html. And don't forget to look the a solution in the comment by David therein, real efficient. The links shows how even n = 500000 can be computed instantaneously using the DP method. The link also explains the concept of "memoization" to speed up computation by storing intermediate (but later on re-callable) results.

Creating multiple nested loops to generate two numbers that move through the length of a Array

As the title reads, I have been thinking about creating multiple nested loops that aim to achieve one purpose. Move two generated random numbers between 0-9 through each possible possition of an array.
For example, App generates first number (fNum) 1 and second number (sNum) 6. It then moves these numbers in the array which containts ABC. However firstNum and secondNum will need to also try all the possible combinations, so each one will need to be different with each loop.
-1ABC6
-A1BC6
-AB1C6
-ABC16
-ABC61
-AB6C1
-A6BC1
-6ABC1
-A6B1C
-A61BC
-A16BC
-A1B6C
-A1BC6
and so on...
I beleive the best way will be to create a method for generating a counter, which increments the numbers which I can call.
private int getNextNumber(int num) {
if (num == 0) {
return num;
} else {
num++;
}
if (num < 10) {
return num;
} else {
return -1;
}
}
Then I will need multiple nested loops... I have decided to go for several loops which will go infinitly.
while (j < maxlen) {
//J = 0 and maxlen = length of text so in this case 3 as it is ABC
//Add two numbers and check against answer
while (fNum != -1 || sNum != -1) {
//incrememnt numbers
fNum = getNextNumber(fNum);
System.out.println(fNum);
sNum = getNextNumber(sNum);
System.out.println(fNum);
}
String textIni = "ABC";
int lenOfText = textIni.length();
char[] split = textIni.toCharArray();
for (int i = 0; i < lenOfText; i++) {
//here it will look at the length of the Text and
//try the possible positions it could be at....
//maybe wiser to do a longer loop but I am not too sure
}
}
Since you don't need to store all possible combinations, we will save some memory using only O(n) storage with an iterative solution. I propose you a basic implementation but don't expect to use it on large arrays since it has a O(n³) complexity.
public static void generateCombinationsIterative(List<Integer> original, int fnum, int snum) {
int size = original.size();
for (int i=0 ; i<=size ; i++) {
List<Integer> tmp = new ArrayList<>(original);
tmp.add(i,fnum);
for (int j=0 ; j<=size + 1 ; j++) {
tmp.add(j,snum);
System.out.print(tmp + (i == size && j == size + 1 ? "" : ", "));
tmp.remove(j);
}
}
}
For your culture, here is an example of a recursive solution, which takes a lot of memory so don't use it if you don't need to generate the lists of results. Nevertheless, this is a more general solution that can deal with any number of elements to insert.
public static List<List<Integer>> generateCombinations(List<Integer> original, Deque<Integer> toAdd) {
if (toAdd.isEmpty()) {
List<List<Integer>> res = new ArrayList<>();
res.add(original);
return res;
}
int element = toAdd.pop();
List<List<Integer>> res = new LinkedList<>();
for (int i=0 ; i<=original.size() ; i++)
// you must make a copy of toAdd, otherwise each recursive call will perform
// a pop() on it and the result will be wrong
res.addAll(generateCombinations(insertAt(original,element,i),new LinkedList<>(toAdd)));
return res;
}
// a helper function for a clear code
public static List<Integer> insertAt(List<Integer> input, int element, int index) {
List<Integer> result = new ArrayList<>(input);
result.add(index,element);
return result;
}
Note that I did not use any array in order to benefit from dynamic data structures, however you can call the methods like this :
int[] arr = { 1,2,3 };
int fnum = 4, snum = 5;
generateCombinationsIterative(Arrays.asList(arr),fnum,snum);
generateCombinations(Arrays.asList(arr),new LinkedList<>(Arrays.asList(fnum,snum));
Note that both methods generate the combinations in the same order.

How to get the actual integer value from an array list

I am using an ArrayList of ArrayLists for a data structure to play a game of towers of hanoi. The game is constructed and initialized as follows:
private ArrayList<ArrayList> lists = new ArrayList<ArrayList>();
private ArrayList<Integer> peg1 = new ArrayList<Integer>();
private ArrayList<Integer> peg2 = new ArrayList<Integer>();
private ArrayList<Integer> peg3 = new ArrayList<Integer>();
//Constructor
public TowersOfHanoi() {
lists.add(null);
lists.add(peg1);
lists.add(peg2);
lists.add(peg3);
}
public ArrayList initializeGame(int n) {
for (int i = 0; i < n; i++) {
peg1.add(i+1);
}
return peg1;
}
}
I am trying to use a Boolean method to do a check and make sure the user doesn't try to move a larger disc on top of a smaller disc, however, I don't understand how I would grab the the integer value stored in the arrayList. The integer values should serve as a way to gauge the diameter of the discs. I.E. 1 is smaller than two is smaller than 3 etc. This is the code I have come up with... I believe I am just getting the indexes and not the actual values of the integers stored there. How can I get the actual values?
public boolean isMoveLegal(int moveFrom, int moveTo){
ArrayList<Integer> fromPeg = lists.get(moveFrom);
int x = (fromPeg.remove(0)).intValue();
ArrayList<Integer> toPeg = lists.get(moveTo);
int y = (toPeg.get(0)).compareTo(x);
if(x<y){
System.out.println("illegal move");
}
return false;
}
The problem with your code is that isMoveLegal does not have a path where it would return true: the only return statement returns false. You should change the return statement as follows:
return x >= y;
This line is wrong too:
int y = (toPeg.get(0)).compareTo(x);
rather than getting the actual value into y, you are storing the result of comparison of y to x, which is not something you should compare to x again.
Additionally, your check is invasive: it removes the disks at the top of your pegs (it is apparent from your code that the top of the tower corresponds to position zero; this is unorthodox, but you can certainly make it work).
Rather than using remove(0), you should use get(0) after checking that the peg's content is not empty.
If the "from" peg is empty, the move is invalid. If the "to" peg is empty, the move is valid. Otherwise, the regular comparison rules apply (i.e. a bigger disk cannot go on top of a smaller disk).
public boolean isMoveLegal(int moveFrom, int moveTo){
ArrayList<Integer> toPeg = lists.get(moveTo);
if (toPeg.isEmpty()) return true; // You can move anything on an empty peg
int y = toPeg.get(0).intValue();
ArrayList<Integer> fromPeg = lists.get(moveFrom);
if (fromPeg.isEmpty()) return false; // No disks on the "from" peg
int x = fromPeg.get(0).intValue();
if(x>y){
System.out.println("illegal move");
return false;
}
return true;
}
This,
int y = (toPeg.get(0)).compareTo(x);
should be something like
int y = (toPeg.size() > 0) ? toPeg.get(0).intValue() : -1;
Then you can use
if (x > y) { // <-- the reverse of like you were, because the to peg is y.
public boolean isMoveLegal(int moveFrom, int moveTo){
ArrayList<Integer> fromPeg = lists.get(moveFrom);
if(fromPeg != null && fromPeg.size() > 0) {
int x = fromPeg.get(0).intValue();
ArrayList<Integer> toPeg = lists.get(moveTo);
if(toPeg != null) {
if(toPeg.size() == 0) {
return true;
} else {
int y = toPeg.get(0).intValue();
if(x<y){
return true;
}
}
}
}
System.out.println("illegal move");
return false;
}

Categories