I need to write a method that takes an array of integers and checks for every element if all its divisors (except the number itself and 1) are present in this array. If yes, the method will return true.
For example, the following array will return true:
4,5,10,2
I can't think of something efficient enough to be implemented. Could you guys help me out here?
I've been thinking to iterate through every element in the array, search for all of its divisors, put them on array, return the array and then compare to the elements in the original array.
This is a possible solution and it could work but I want to know of other possible solutions.
EDIT: Here is a code I've came up with but it is super slow. Could you guys help me optimise it a little bit?:
import java.util.Arrays;
public class Divisors {
public static void main(String[] args) {
int[] numbers = { 4, 5, 10, 2 };
boolean flag = true;
for (int num : numbers) {
if (num % 2 != 0) {
for (int subNum = 1; subNum < num / 2; num += 2) {
if(num%subNum == 0 && subNum != 1) {
if(!Arrays.asList(numbers).contains(subNum)) {
flag = false;
}
}
}
} else {
for (int subNum = 1; subNum < num / 2; num++) {
if(num%subNum == 0 && subNum != 1) {
if(!Arrays.asList(numbers).contains(subNum)) {
flag = false;
}
}
}
}
}
System.out.println("Result is: "+flag);
}
}
I think the following alogorithm solves your need. I have tested it on a few cases and it seems to work.
For example the array:
int[] set = {2, 3, 4, 5, 7, 10, 11, 15, 18, 35};
executes instantly giving the answer "true". Try removing the 7 which will give the answer "false".
You call it thus:
reduce(set, 0, 0)
The principle used is to iterative recursively through the array, reducing the array through factorization of the array by each element. If you find an element which is smaller than the last factor, it means it can't be factored. This only works if the array is sorted. Once you reach the end of the array, you know all elements have been factored.
private static boolean reduce (int[] set, int index, int factor) {
// NOTE: set must be a sorted set of integers
if (index == set.length) {
return true;
} else {
int divisor = set[index];
if (divisor != 1) {
if (divisor < factor) return false;
for (int i = index; i < set.length; i++) {
while ((set[i]%divisor) == 0) {
set[i] = set[i]/divisor;
}
}
return reduce(set, index+1, divisor);
} else {
return reduce(set, index+1, factor);
}
}
}
See if it works, let me know if you run into any problems.
1.Iterate through every element in the array
2. Find in for loop its divisor
3. While doing 2), check for every divisor if it is contained in the array. If false - return false.
Related
I'm working on a project and one of the things I need to do is create a method where it takes in an int array and checks it to see if it has more even than odds. The method needs to be boolean and take in an int[]
I know I need to use a for statement with something like
for (int i = 0; i < hasMoreEvenThanOdd.length; i++)
or
for (int values : hasMoreEvenThanOdd)
But I'm confused on what the for loop would contain something like this?
if (numerator % denomEven == 0) {
boolean res = true;
return res;
} else if (numerator % denomOdd == 0) {
boolean res = true;
return res;
} else {
boolean res = false;
return res;
}
and I'm not sure how to get the math to check out in the end.
You can iterate over this array and filter only even numbers, and then check whether their count is more than half of the array:
public static boolean hasMoreEvenThanOdd(int[] arr) {
return Arrays.stream(arr).filter(i -> i % 2 == 0).count() > arr.length / 2;
}
// test
public static void main(String[] args) {
System.out.println(hasMoreEvenThanOdd(new int[]{2, 3, 4, 5, 6, 7})); // false
System.out.println(hasMoreEvenThanOdd(new int[]{2, 3, 4, 5, 6})); // true
System.out.println(hasMoreEvenThanOdd(new int[]{2, 3, 4, 5})); // false
System.out.println(hasMoreEvenThanOdd(new int[]{2, 3, 4})); // true
System.out.println(hasMoreEvenThanOdd(new int[]{2, 3})); // false
}
You should do something like that:
public boolean checkIfHasMoreEvenThanOdds(int[] hasMoreEvenThanOdds) {
int even = 0;
int odds = 0;
for (int i = 0; i < hasMoreEvenThanOdds.length; i++) {
if (hasMoreEvenThanOdds[i] % 2 == 0) {
even++;
} else {
odds++;
}
}
if (even > odds) {
return true;
}
return false;
}
The method will return true if it has more even than odds, and false if the opposite. This code "parse" the array, and checks element by element if it is or not odd, and increments in a variable (odd or even). By final, it checks which one is greater than, and return in base of that.
First if
Sum all evens
Second if
Sum all odds
Compare if evens is more than odds
Return true is true
I'm not sure if you mean counting the number of even and odd values in your array.
If so, this might help you:
for(..........) {
if (hasMoreEvenThanOdd[i] % 2 == 0)
{
even++;
}
else
{
odd++;
}
}
return even > odd;
What you need to do is iterate over all elements in the array for instance using:
for (int values : hasMoreEvenThanOdd)
or
for (int i = 0; i < hasMoreEvenThanOdd.length; i++)
then keep track of the even numbers for instance:
if (values % 2 == 0)
total_even_numbers++;
Outside the loop:
In the end, to get the total of odd numbers you just need to subtract from the size of the array (i.e., hasMoreEvenThanOdd.length) the total of even numbers that you have found.
Finally, just compare the two values, and return accordingly.
An example:
public boolean hasMoreEvenThanOdd(int[] values){
int even = 0;
for (int value : values)
if (value % 2 == 0)
even++;
return even > (values.length - even);
}
As pointed out in other comments, you would need to maintain two variabled nEven (number of even numbers) and nOdd (number of odd numbers) while iterating the array and increment depending upon whether item at a specified index is even or odd. If you're using Java 8+, you can use streams to filter odd/even numbers and count them:
public static boolean containsMoreEvenThanOdd(int[] array) {
long nEven = Arrays.stream(array).filter(i -> i % 2 == 0).count();
long nOdd = Arrays.stream(array).filter(i -> i % 2 != 0).count();
return nEven > nOdd;
}
separate even and odd values into two groups with Collectors.partitioningBy
public boolean checkIfHasMoreEvenThanOdds(int[] evenAndOdds) {
Map<Boolean, List<Integer>> map = IntStream.of( evenAndOdds )
.boxed().collect( partitioningBy( n -> (n & 1) == 0 ) );
return(map.get( true ).size() > map.get( false ).size());
}
I am trying to write a method that will take in the array int[] numbers and return the sum of all of the odd numbers in the array. I am not sure why it is not returning the correct value. Currently it returns "3" when it should be returning "9".
public static void main(String[] args) {
int[] numbers = { 2, 1, 5, 3, 0 };
System.out.println(oddballsum(numbers));
}
public static int oddballsum(int array[]) {
int sumodds = 0;
for (int i = 0; i < array.length; i++) {
if (array[i] % 2 != 0) { sumodds = +(array[i]);}
}
return sumodds;
}
sumodds =+ (array[i]) means "assign the value of array[i] to sumodds". The + and the () make no difference - it's semantically identical to sumodds = array[i]. Use this if you just want the last odd value in the array.
sumodds += array[i] means "increase the value of sumodds by array[i]. Use this if you're trying to sum the odd values in the array.
The reason of the error is in this piece of code...
if (array[i] % 2 != 0) {
sumodds = +(array[i]);
}
you are not summing or accumulating you are just assigning the value with a positive sign
at the end, your code is just returning the last odd value found in the array...
you have to do instead something like:
if (array[i] % 2 != 0) {
sumodds += array[i];
}
If you write too much code, you have more chance to go wrong, you should use java 8 Streams:
int sumOdd = Arrays.stream(array).filter(t -> t%2==1).sum();
System.out.println(sumOdd);
The problem was with your addition operator =+. It should be += if you want to add and assign the new value to the same variable. Please refer below working code.
public static void main(String[] args) {
int[] numbers = {2, 1, 5, 3, 0};
System.out.println(oddballsum(numbers));
}
public static int oddballsum(int array[]) {
int sumodds = 0;
for(int element : array) {
if(element % 2 != 0) {
sumodds += element;
}
}
return sumodds;
}
This method is supposed to return true if four different numbers in the array are all equal. But whenever I try to run it with 4 equal numbers, I get an error that says:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 5
at Assignment4.containsFourOfaKind(Assignment4.java:93)
at Assignment4.main(Assignment4.java:16)
public static boolean containsFourOfaKind( int hand[] ){
for (int i = 0; i < 5; i++) {
if (hand[i ] == hand[i + 1] &&
hand[i + 1] == hand[i + 2] &&
hand[i + 2] == hand[i + 3]
) {
return true;
}
}
return false;
}
How can I fix this?
Most answers only address the ArrayIndexOutOfBoundsException, but they don't address that your original code wasn't detecting for of a kind. It was trying to detect four-in-a-row. Imagine a hand {3, 0, 3, 3, 3}: even if your code didn't cause the ArrayIndexOutOfBoundsException, it still would say that this wasn't four-of-a-kind, although it clearly is.
You need code that actually counts how many of-a-kind there are and then check if it is four or more out of the total hand. (In a typical playing card deck you couldn't have more than 4 of a kind so you can check with == to 4 as well)
The code below is even agnostic to the number of cards in a hand, although from your code above it looks like your hand size is 5 (which is very typical in poker)
public static boolean containsFourOfaKind(int hand[]) {
for (int i = 0; i < hand.length; i++) {
int countOfKind = 0;
for (int j = 0; j < hand.length; j++) {
if (hand[i] == hand[j]) {
countOfKind++;
}
}
if (countOfKind >= 4) {
return true;
}
}
return false;
}
(Note that this is a native approach. You can optimize this further; for example if you look at this closely you'll see that i doesn't have to go any further than 0 and 1.)
When you run your loop from (i=0; i<5;...) you are checking five values... In your if statement you are looking at hand[i] == hand[i+1] && hand[i+1] == hand[i+2] && hand[i+2] == hand[i+3]. This means that during the iteration when i=4 you are trying to access hand[4] through to hand[7].
I suspect your array, hand, doesn't have that many elements.
public static boolean containsFourOfaKind(int hand[]){
for(int x=0; x < hand.length; x++){
for(int y=0; y < hand.length; y++){
if(y!=x){
if(hand[x]!=hand[y]){
return false;
}
}
}
}
return true;
}
You were going outside the index using the +1 within the loop. The above code checks to see if all of the elements in the array are the same.
While others have addressed the ArrayIndexOutOfBoundsException quite clearly, I'd like to propose another method that uses no indexes:
private boolean isArrayEqual(int[] array) {
Arrays.sort(array); //Sort array to place four of a kind in sequence
int[] setOfFour = Arrays.copyOfRange(array, 0, 4); //Copy first four values
int[] compareArray = new int[4];
Arrays.fill(compareArray, setOfFour[0]); //Make an array containing only first value
if (Arrays.equals(compareArray, setOfFour)) { //Test if first four are equal
return true;
} else { //Test is last four are equal
setOfFour = Arrays.copyOfRange(array, 1, 5); //Copy of last four values
Arrays.fill(compareArray, setOfFour[0]);
return Arrays.equals(compareArray, setOfFour);
}
}
You create a second array which is filled with one of the values from the array in question (any value will do - I picked the first one). Then just see if the arrays are equal. Done.
//brain compiled code
public static boolean containsFourOfaKind(int hand[])
{
for(int i=0; i < hand.length - 1; i++)
{
if(hand[i] != hand[i + 1])
return false;
}
return true;
}
Going with your approach you could have had a simple check that was non-iterative that would just check to see if all the four cards were equal, however if you're going for an iterative approach then this is probably your best bet. Whenever you receive an arrayindexoutofbounds exception you always know that it has something to do with your arrays, and in your case there is only one spot that deals with arrays so it should be easy to visualize once you know what t he exception means.
A noniterative approach is as follows...
//brain compiled code
public static boolean containsFourOfaKind(int hand[])
{
if((hand[0] == hand[1]) && (hand[1] == hand[2]) && (hand[2] == hand[3]))
return true;
return false;
}
This can be used however it is not recommended.
An approach that doesn't specifically target a hand, could be to target a larger group; where the array could be much larger than 4. In this case, you could have a loop add onto a map that counts how many times a certain "object" (literal meaning) is in that list:
public static boolean fourOfaKind(Integer[] hand) {
HashMap<Integer,Integer> counts = new HashMap<Integer,Integer>();
for(Integer i : hand) {
if(counts.containsKey(i))
{
int count = counts.get(i);
counts.put(i, ++count);
if(count >= 4)
return true;
}
else
counts.put(i, 1);
}
return false;
}
simple code can be as follows, this will work for N number of element.
public static boolean containsFourOfaKind(int hand[]){
for(int i=1; i < hand.length; i++){
if(hand[i-1] != hand[i]){
return false;
}
}
return true;
}
In Java8 you can do it very easy:
private static boolean isEqualElements(int[] arr) {
return Arrays.stream(arr).allMatch(value -> arr[0] == value);;
}
The method getPeakCount takes an int array and a range (int) as an input and returns the number of integers that are greater than all the elements to either side for the given range.
For example, consider an array {1,4,2,6,4,5,10,8,7,11} and range 2. The result should be 3, as {..,4,2,6,4,5,..}, {..,4,5,10,8,7,..} and {..,8,7,11} satisfy this condition. These satisfy the condition because 6, 10 and 11 are all greater than the 2 elements to both their left and right.
Note that for the the corner elements like 1 and 11, there's no need to check the left and right side respectively.
My code is below, but it is not correct.
static int getPeakCount(int[] arr, int R) {
int result=0;
for(int i=0;i<arr.length;i++){
if(i==0){
if(arr[i]>arr[i+1]&&arr[i]>arr[i+2]){
result++;
}
} //-----> closing if(i==0) condition
else if(i==arr.length-1){
if(arr[i]>arr[i-1]&&arr[i]>arr[i-2]){
result++;
}
}
else if(i+R>arr.length){
if(arr[i]>arr[i-R] && arr[i]>arr[i-R+1]){
System.out.println(arr[i]);
result++;
}
}
else{
if(arr[i]>arr[i+1] && arr[i]>arr[i+2] && arr[i]>arr[i-R] && arr[i]>arr[i-R+1]){
System.out.println(arr[i]);
result++;
}
}
}
return result;
}
I don't know whether I'm going in the right direction or not, and for last if condition it's throwing an java.lang.ArrayIndexOutOfBoundsException.
P.S. Don't consider this code as solution to remove errors from this. This is just the attempt I tried.
I think the right idea, and devnull is right. You just need to check the center, so change the loop to start at 1 and end 1 before the end. I commented out the end conditions. I think this does what you were asking, though not 100% sure I understood what you were after.
I should add, I use variables like l (left), r (right) and c (center) for clarity. You can make this much faster if you have large arrays. There is also redundancy in that it checks conditions it should know are already false (if I find a peak, I should skip the next value, as it can't also be a peak).
public class PeakChecker {
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
int[] array = new int[]{1, 4, 2, 6, 4, 5, 10, 8, 7, 11};
System.out.println(nPeaks(array, 2));
}
static int nPeaks(int[] array, int range) {
// Check for special cases
if (array == null) {
return 0;
}
int result = 0, l, r;
// Check main body
for (int i = 0; i < array.length; i++) {
boolean isPeak = true;
// Check from left to right
l = Math.max(0, i - range);
r = Math.min(array.length - 1, i + range);
for (int j = l; j <= r; j++) {
// Skip if we are on current
if (i == j) {
continue;
}
if (array[i] < array[j]) {
isPeak = false;
break;
}
}
if (isPeak) {
System.out.println("Peak at " + i + " = " + array[i]);
result++;
i += range;
}
}
return result;
}
}
The last if condition shall throw exception when i == arr.length - 2.
This is because arr[i+2] in that case is out of bounds.
If you read the ArrayIndexOutOfBoundsException stack trace, it will tell you a line of code the error happened on. Look on that line of code and you'll probably see arr[i+1] or arr[i-1] or something. Certainly, at least one access on that line will be out of bounds. That's the problem.
I want to tell if an array of integers is alternating.
in JAVA.
For example:
a[]={1,-1,1,-1,1,-1} --> true
a[]={-1,1,-1,1,-1} --> true
a[]={1,-4,1-6,1} --> true
a[]={1,1,1,14,5,3,2} --> false
I have started to write some code that uses flags. For example if the current_is_positive=0 and else = 1, but I'm not getting anywhere. What is a good way to achieve this effect?
I think you mean alternating in sign, i.e. positive number, negative number, positive number, etc.?
You could use the following strategy:
Skip the first element.
For every other element, compare its sign with the sign of the previous element:
If they're different, the sequence is still alternating upto now - you should continue.
If they're the same sign, the sequence is not alternating. You can stop processing at this point.
As this sounds like a homework assignment, I'll leave it upto you to write the appropriate code in Java.
Here my solution:
This checks that element n+1 is the inverse of the element n.
public static void main(String[] args) {
int[] ints = {1, -1, 2, -1};
System.out.println(new Example().isArrayAlternating(ints));
}
public boolean isArrayAlternating(int[] ints) {
if (ints == null || ints.length % 2 != 0) {
return false;
}
for (int i = 0; i < ints.length - 1; i++) {
if (ints[i] != ints[i + 1]*(-1)) {
return false;
}
}
return true;
}
If you only wanted to check for positive number, negative number...n times, without paying attention to value:
public static void main(String[] args) {
int[] ints = {1, -1, 2, -1};
System.out.println(new Example().isArrayAlternating(ints));
}
public boolean isArrayAlternating(int[] ints) {
if (ints == null || ints.length % 2 != 0) {
return false;
}
for (int i = 0; i < ints.length - 1; i++) {
if (ints[i] >= 0 && ints[i + 1] >= 0 || ints[i] <= 0 && ints[i + 1] <= 0) {
return false;
}
}
return true;
}
You can simply check if all items are equal to the item two steps back. I don't know what language you are using, but for example using C# you could do it like this:
bool alternating = a.Skip(2).Where((n, i) => a[i] == n).Count() == a.Length - 2;
Edit:
So you want to check if the sign of the values are alternating, not the values?
Then just check the sign against the previous item:
bool alternating = a.Skip(1).Where((n,i) => Math.Sign(n) == -Math.Sign(a[i])).Count() == a.Length-1;
boolean prevPositive = arr[0] > 0, error = false;
for (int i = 1; i < arr.length; ++i) {
boolean current = arr[i] > 0;
if (current != prevPositive) {
current = prevPositive;
} else {
error = true;
break;
}
}
if (error)
System.out.println("No");
else
System.out.println("Yes");
private enum SIGN {
POSITIVE, NEGATIVE
};
public static boolean isAlternating(int... ints) {
SIGN last = null;
for (int i : ints) {
if (i >= 0) {
if (last == null) {
last = SIGN.POSITIVE;
} else {
if (last == SIGN.POSITIVE) {
return false;
} else {
last = SIGN.POSITIVE;
}
}
} else {
if (last == null) {
last = SIGN.NEGATIVE;
} else {
if (last == SIGN.NEGATIVE) {
return false;
} else {
last = SIGN.NEGATIVE;
}
}
}
}
return true;
}
Run through the array from index 1 till the end.
At each index, evaluate (a[i] > 0) == (a[i-1] > 0). If this is true, then your array is not alternating.
If you make it till the end without concluding it is not alternating, then it is alternating :)
Run a loop, from first index to maximum possible with a step of 2, to check for same sign.
Then again a loop, from 2nd index to maximum possible with a step of 2, to check for opposite sign, but all same.
So, loop from index - 0, 2, 4, 6, ...
then loop from index - 1, 3, 5, 7, ...
Then check that the multiplication of every number in both loop with the first number in that iteration should be positive.
int a[]={1,-1,1,-1,1,-1};
boolean alternating = true;
for (int i = 0; i < a.length; i = i + 2) {
if (a[i] * a[0] > 0) {
} else {
alternating = false;
}
}
for (int i = 1; i < a.length; i = i + 2) {
if (a[i] * a[1] > 0) {
} else {
alternating = false;
}
}
if (alternating) {
System.out.println("Array is alternating");
} else
System.out.println("Array is not alternating");
}
For i = 2 to n
check whether A[i-1] && A[i] are with diff sign..
in C++; return ((A[i-1] ^ A[i]) < 0).
Same explained here : http://www.youtube.com/watch?v=Z59REm2YKX0
EDIT
If an integer is negative, then the high order bit is 1. Otherwise, it's 0. You can check if two integers have different signs by XORing them together. If the signs are different, then the high order bit of the result will be 1. If they're the same, then the high order bit will be 0. Thus,
A XOR B < 0 is equivalent to "A and B have different signs"
Peter Ruderman