Why runtime error for 2 out of 8 cases? - java

I've completed Hackerrank's "Birthday Cake Candles" challenge and have passed 6 out of 8 test cases using the following code that sorts an array, then increments the frequency that the max int occurs and prints that value:
import java.io.*;
import java.util.*;
import java.text.*;
import java.math.*;
import java.util.regex.*;
public class Solution {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int numCandles = in.nextInt();
int height[] = new int[numCandles];
for(int height_i=0; height_i < numCandles; height_i++){
height[height_i] = in.nextInt();
}
//Option 2: Sort the array, then count the number that are highest.
Arrays.sort(height);
int max = height[height.length - 1];
int index = height.length - 1;
int freq = 0;
while(height[index] == max) {
freq++;
index--;
}
System.out.println(freq);
}
}
It's not passing Test Case #6 (input) or Test Case #7. In short, Test Case #6 is 100,000 occurrences of the int 999999 and Test Case #7 is 100,000 occurrences of the int 1. Expected output for both is supposed to be 100000.
I'm thinking it might be encountering a runtime error because of the sorting method I call on the array and the array trying to sort ints of equal value over and over? Can anyone explain why my code won't work for those two Test Cases?

When all values in the input are the same, as in the sample input you included, the condition in this loop will be true until index is reduced to -1, at which point you'll get an ArrayIndexOutOfBoundsException:
while(height[index] == max) {
freq++;
index--;
}
Add a range check to the loop condition, for example:
while (index >= 0 && height[index] == max) {
With this change, the solution will pass all tests. But it's an inefficient solution. You sorted the input to reduce the number of iterations in the while loop. But sorting is an O(n log(n)) operation, which is slower than a simple filtering with O(n). For example:
int numCandles = in.nextInt();
int heights[] = new int[numCandles];
int m = Integer.MIN_VALUE;
for (int i = 0; i < numCandles; i++) {
heights[i] = in.nextInt();
m = Math.max(m, heights[i]);
}
final int max = m;
long freq = IntStream.of(heights).filter(x -> x == max).count();
System.out.println(freq);

You are getting an outbound of exception because you are reaching a part when you go less than 0
while(height[index] == max) {
freq++;
if(index == 0)
break;
index--;
}
This is my solution for this problem
Scanner in = new Scanner(System.in);
int n = in.nextInt();
int height[] = new int[n];
for(int height_i=0; height_i < n; height_i++){
height[height_i] = in.nextInt();
}
Arrays.sort(height);
int counter = 0;
int different = height[n-1];
for(int height_i=n-1; height_i >=0 ; height_i--){
if(different ==height[height_i] )
{
counter = counter + 1;
}
else
{
break;
}
}
System.out.println(counter);
}
This is my solution for this. I think is better to use a for than a while for this.

Simple Solution
static int birthdayCakeCandles(int[] arr) {
int max = arr[0];
int count = 0;
for(int i =0; i<arr.length;i++) {
if(max < arr[i]) {
max = arr[i];
}
}
for(int i =0; i<arr.length;i++) {
if(max == arr[i]) {
count++;
}
}
return count;
}

Related

Sieve of Eratosthenes will not sieve Prime Numbers

For an assignment I am doing for one of my classes, we have to implement a Sieve of Eratosthenes. I have tried seven times to get a code that works and have tried incorporating numerous solutions I've researched. I finally have one that will output numbers. Unfortunately, it prints both composite and prime numbers, and doesn't print 2.
My code is as follows:
public class EratosthenesSieveAttempt6 {
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
Scanner keyboard = new Scanner(System.in);
int limit;
System.out.print("Please enter the highest number to check "
+ "(number must be greater than 2): ");
limit = keyboard.nextInt();
while (limit <= 2){
System.out.println("Error - number must be greater than 2.");
System.out.println("Please enter the highest number to check: ");
limit = keyboard.nextInt();
}
boolean[] numbers = new boolean[limit + 1];
int newPrime = 2;
for(int i = 0; i < limit + 1; i++){
numbers[i] = true;
}
for(int j = 1; j < limit + 1; j++) {
if (j % 2 == 0) {
numbers[j] = false;
}
for(int k = j + 1; k < limit + 1; k++) {
if(numbers[k] == true){
j = k;
System.out.println(k);
}
}
}
}
}
I'm suspecting that there is a problem with my loops. I fixed the i and j variables for my first two loops so that it would print out from 2 onward, the problem seems to be that it's not marking the composite numbers as false after I've initialized the array to true.
Thank you in advance for your help.
Here's an implementation of the Sieve of Eratosthenes I wrote the other day:
import java.util.BitSet;
public static BitSet composite(int max) {
BitSet composite = new BitSet(max);
max = composite.size();
for (int i = 4; i < max; i += 2) composite.set(i, true);
for (int i = 9; i < max; i += 6) composite.set(i, true);
int p = 5;
while (p*p < max) {
if (!composite.get(p)) {
for (int i = p*p; i < max; i += p*2) composite.set(i, true);
}
p += 2;
if (p*p >= max) break;
if (!composite.get(p)) {
for (int i = p*p; i < max; i += p*2) composite.set(i, true);
}
p += 4;
}
return composite;
}
Notes:
BitSet allocates 64-bit words, so the size may be larger than you requested (for example, if you ask it to go up to 1000, it will go up to 1024; that's the reason for max = composite.size() near the top)
Gets the 2's, 3's out of the way explicitly, and then
Relies on the fact that all primes larger than 3 are congruent to either 1 or 5 mod 6; this is the reason the final loop alternates between adding 2 and 4
It returns a BitSet that tells you which numbers are composite. One way to extract just the primes from it would be:
public static int[] primes(BitSet composite) {
int size = composite.size() - 2 - composite.cardinality();
int[] primes = new int[size];
int index = 0;
for (int i = 2; i < composite.size(); i++) {
if (!composite.get(i)) primes[index++] = i;
}
return primes;
}

calculating consecutive 1's in a Binary number

import java.util.Scanner;
import java.util.Arrays;
class Solve
{
public static void main(String args[])
{
Scanner in = new Scanner(System.in);
int i=0,count=0;
int[] arr = new int[10];
int n =in.nextInt();
while(n!=0)
{
arr[i]=n%2;
i++;
n=n/2;
}
System.out.println(Arrays.toString(arr));
}
}
}
I just want to calculate number of consecutive 1's. ? like 1110011001 will give me answer 5.. How can i do that??
System.out.println(Integer.toBinaryString(n).replaceAll("(0|(?<!1)1(?!1))", "").length());
The regex means: replace all 0's and any 1 not preceded or followed by another 1
You can handle this as a String [Edited to sum all consecutive 1's]:
String binary = in.nextLine();
String[] arrayBin = binary.split("0+"); // an array of strings without 0's
int result=0;
for (int i=0; i < arrayBin.length; i++){
if (arrayBin[i].length()<2){
result+=0;
}
else {
result+=arrayBin[i].length();
}
}
System.out.println("Total consecutive = "+result);
We can identify two consecutive binary ones in the least significant positions like this:
(value & 0b11) == 0b11
We can move the bits in value to the right like so:
value >>>= 1;
It's important to use tripple >>> over double >> because we don't care about the sign bit.
Then all we have to do is keep track of the number of consecutive 1s:
int count(int value) {
int count = 1;
int total = 0;
while (value != 0) {
if ((value & 0b11) == 0b11) {
count++;
} else {
if (count > 1) {
total += count;
}
count = 1;
}
value >>>= 1;
}
return total;
}
Test cases:
assertEquals(0, count(0b0));
assertEquals(0, count(0b1));
assertEquals(0, count(0b10));
assertEquals(2, count(0b11));
assertEquals(5, count(0b1110011));
assertEquals(5, count(0b1100111));
assertEquals(6, count(0b1110111));
assertEquals(7, count(0b1111111));
assertEquals(32, count(-1));
If you only want the length of the maximum, I have a similar answer: https://stackoverflow.com/a/42609478/360211
You can make use of Brian Kernighan’s Algorithm for counting the highest consecutive number of 1's.
A java pseudocode would be something like this
// Initialize result
int count = 0;
// Count the number of iterations to
// reach n = 0.
while (n!=0)
{
// This operation reduces length
// of every sequence of 1s by one.
n = (n & (n << 1));
count++;
}
public class Solution {
public int findMaxConsecutiveOnes(int[] nums) {
if(nums == null || nums.length == 0){
return 0;
}
int counter = 0, max = Integer.MIN_VALUE;
for(int i = 0; i < nums.length; i++){
if(nums[i] == 1){
counter += nums[i];
} else{
counter = nums[i];
}
max = Math.max(counter, max);
}
return max;
}
}
To this problem one trick which we can use here with help of some Java operators.
& operator and left shift (<<) in java.
Code snippet will be like :
public getConsecutiveCount(int inputNumber)
{
int count = 0 ;
while(inputNumber != 0)
{
inputNumber = inputNumber & (inputNumber << 1);
count++;
}
}
Explanation :
This function is taking input (ex : we want to check how many
consecutive 1's integer 6 have in its binary representation)
so out input number will be like :
inputNumber = ((110) & ((110)<<1)) {This left shift will result in 100 so final op :
110 & 100 which 100 , every time '0' is added to
our result and we iterate until whole number will
be zero and value of our count variable will be
our expected outcome }
To find Maximum consecutive 1's in binary(like 101)
int n = Convert.ToInt32(Console.ReadLine());
string[] base2=Convert.ToString(n,2).Split('0');
int count=0;
foreach(string s in base2)
count=s.Length>count?s.Length:count;
Console.WriteLine(count);
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int n = in.nextInt();
String bs = Integer.toBinaryString(n);// bs=Binary String
char[] characters = bs.toCharArray();
int max = 1;
int temp = 1;
for (int i = 0; i < characters.length - 1; i++) {
if (characters[i] == characters[i + 1] & characters[i] == '1' & characters[i + 1] == '1') {
temp++;
if (temp > max) {
max = temp;
}
} else {
temp = 1;
}
}
System.out.println(max);
}
/* Given a decimal number print maximum number of consecutive 1's after binary conversion */
import java.io.*;
import java.util.*;
public class Solution {
public void countBinaryOne(int num){
int var =0, countOne= 0, maxCt=0;
while(num>0){
var= num%2;
if(var==1){
countOne=countOne+1;
}else{
if(maxCt<countOne){
maxCt= countOne;
countOne=0;
}else{
countOne=0;
}
}
num=num/2;
}
System.out.println(Math.max(countOne,maxCt));
}
public static void main(String[] args) {
Scanner in= new Scanner(System.in);
int n= in.nextInt();
Solution sol= new Solution();
sol.countBinaryOne(n);
}
}
public static void digitBinaryCountIfOne(int n){
int reminder=0, sum=0, total = 0;
while(n>0)
{
reminder = n%2;
n/=2;
if(reminder==1){
sum++;
if(sum>=total)
total=sum;
}else{
sum=0;
}
}
System.out.println(total);
}

Generating 10 random numbers without duplicate with fundamental techniques

my intend is to use simplest java (array and loops) to generate random numbers without duplicate...but the output turns out to be 10 repeating numbers, and I cannot figure out why.
Here is my code:
int[] number = new int[10];
int count = 0;
int num;
while (count < number.length) {
num = r.nextInt(21);
boolean repeat = false;
do {
for (int i=0; i<number.length; i++) {
if (num == number[i]) {
repeat = true;
} else if (num != number[i] && i == count) {
number[count] = num;
count++;
repeat = true;
}
}
} while (!repeat);
}
for (int j = 0; j < number.length; j++) {
System.out.print(number[j] + " ");
}
How about you use a Set instead? If you also want to keep track of the order of insertion you can use a LinkedHashSet.
Random r = new Random();
Set<Integer> uniqueNumbers = new HashSet<>();
while (uniqueNumbers.size()<10){
uniqueNumbers.add(r.nextInt(21));
}
for (Integer i : uniqueNumbers){
System.out.print(i+" ");
}
A Set in java is like an Array or an ArrayList except it handles duplicates for you. It will only add the Integer to the set if it doesn't already exist in the set. The class Set has similar methods to the Array that you can utilize. For example Set.size() is equivalent to the Array.length and Set.add(Integer) is semi-equivalent to Array[index] = value. Sets do not keep track of insertion order so they do not have an index. It is a very powerful tool in Java once you learn about it. ;)
Hope this helps!
You need to break out of the for loop if either of the conditions are met.
int[] number = new int[10];
int count=0;
int num;
Random r = new Random();
while(count<number.length){
num = r.nextInt(21);
boolean repeat=false;
do{
for(int i=0; i<number.length; i++){
if(num==number[i]){
repeat=true;
break;
}
else if(i==count){
number[count]=num;
count++;
repeat=true;
break;
}
}
}while(!repeat);
}
for(int j=0;j<number.length;j++){
System.out.print(number[j]+" ");
}
This will make YOUR code work but #gonzo proposed a better solution.
Your code will break the while loop under the condition: num == number[i].
This means that if the pseudo-generated number is equal to that positions value (the default int in java is 0), then the code will end execution.
On the second conditional, the expression num != number[i] is always true (otherwise the code would have entered the previous if), but, on the first run, when i == count (or i=0, and count=0) the repeat=true breaks the loop, and nothing else would happen, rendering the output something such as
0 0 0 0 0 0...
Try this:
int[] number = new int[10];
java.util.Random r = new java.util.Random();
for(int i=0; i<number.length; i++){
boolean repeat=false;
do{
repeat=false;
int num = r.nextInt(21);
for(int j=0; j<number.length; j++){
if(number[j]==num){
repeat=true;
}
}
if(!repeat) number[i]=num;
}while(repeat);
}
for (int k = 0; k < number.length; k++) {
System.out.print(number[k] + " ");
}
System.out.println();
Test it here.
I believe the problem is much easier to solve. You could use a List to check if the number has been generated or not (uniqueness). Here is a working block of code.
int count=0;
int num;
Random r = new Random();
List<Integer> numbers = new ArrayList<Integer>();
while (count<10) {
num = r.nextInt(21);
if(!numbers.contains(num) ) {
numbers.add(num);
count++;
}
}
for(int j=0;j<10;j++){
System.out.print(numbers.get(j)+" ");
}
}
Let's start with the most simple approach, putting 10 random - potentially duplicated - numbers into an array:
public class NonUniqueRandoms
{
public static void main(String[] args)
{
int[] number = new int[10];
int count = 0;
while (count < number.length) {
// Use ThreadLocalRandom so this is a contained compilable unit
number[count++] = ThreadLocalRandom.current().nextInt(21);
}
for (int j = 0; j < number.length; j++) {
System.out.println(number[j]);
}
}
}
So that gets you most of the way there, the only thing you know have to do is pick a number and check your array:
public class UniqueRandoms
{
public static void main(String[] args)
{
int[] number = new int[10];
int count = 0;
while (count < number.length) {
// Use ThreadLocalRandom so this is a contained compilable unit
int candidate = ThreadLocalRandom.current().nextInt(21);
// Is candidate in our array already?
boolean exists = false;
for (int i = 0; i < count; i++) {
if (number[i] == candidate) {
exists = true;
break;
}
}
// We didn't find it, so we're good to add it to the array
if (!exists) {
number[count++] = candidate;
}
}
for (int j = 0; j < number.length; j++) {
System.out.println(number[j]);
}
}
}
The problem is with your inner 'for' loop. Once the program finds a unique integer, it adds the integer to the array and then increments the count. On the next loop iteration, the new integer will be added again because (num != number[i] && i == count), eventually filling up the array with the same integer. The for loop needs to exit after adding the unique integer the first time.
But if we look at the construction more deeply, we see that the inner for loop is entirely unnecessary.
See the code below.
import java.util.*;
public class RandomDemo {
public static void main( String args[] ){
// create random object
Random r = new Random();
int[] number = new int[10];
int count = 0;
int num;
while (count < number.length) {
num = r.nextInt(21);
boolean repeat = false;
int i=0;
do {
if (num == number[i]) {
repeat = true;
} else if (num != number[i] && i == count) {
number[count] = num;
count++;
repeat = true;
}
i++;
} while (!repeat && i < number.length);
}
for (int j = 0; j < number.length; j++) {
System.out.print(number[j] + " ");
}
}
}
This would be my approach.
import java.util.Random;
public class uniquerandom {
public static void main(String[] args) {
Random rnd = new Random();
int qask[]=new int[10];
int it,i,t=0,in,flag;
for(it=0;;it++)
{
i=rnd.nextInt(11);
flag=0;
for(in=0;in<qask.length;in++)
{
if(i==qask[in])
{
flag=1;
break;
}
}
if(flag!=1)
{
qask[t++]=i;
}
if(t==10)
break;
}
for(it=0;it<qask.length;it++)
System.out.println(qask[it]);
}}
public String pickStringElement(ArrayList list, int... howMany) {
int counter = howMany.length > 0 ? howMany[0] : 1;
String returnString = "";
ArrayList previousVal = new ArrayList()
for (int i = 1; i <= counter; i++) {
Random rand = new Random()
for(int j=1; j <=list.size(); j++){
int newRand = rand.nextInt(list.size())
if (!previousVal.contains(newRand)){
previousVal.add(newRand)
returnString = returnString + (i>1 ? ", " + list.get(newRand) :list.get(newRand))
break
}
}
}
return returnString;
}
Create simple method and call it where you require-
private List<Integer> q_list = new ArrayList<>(); //declare list integer type
private void checkList(int size)
{
position = getRandom(list.size()); //generating random value less than size
if(q_list.contains(position)) { // check if list contains position
checkList(size); /// if it contains call checkList method again
}
else
{
q_list.add(position); // else add the position in the list
playAnimation(tv_questions, 0, list.get(position).getQuestion()); // task you want to perform after getting value
}
}
for getting random value this method is being called-
public static int getRandom(int max){
return (int) (Math.random()*max);
}

Paul Erdos Conjecture [Java]

I've been trying to solve this rather easy problem on SPOJ: http://www.spoj.com/problems/HS08PAUL/.
It requires the number of prime numbers (less than n) which can be expressed in the form x^2+y^4 (where x and y are integers) to be found out.
I've whipped up a brute force solution which takes up quite a while for (n ~= 1000000), resulting in a TLE (time limit exceeded) error being thrown by the engine. Here's the source code:
import java.io.*;
import java.util.*;
class HS08PAUL {
public static int[] sieve(int n){
boolean[] prime = new boolean[n+1];
int[] primeNumbers = new int[n];
int index = 0;
Arrays.fill(primeNumbers, 0);
Arrays.fill(prime,true);
prime[0] = false;
prime[1] = false;
int m = (int)Math.sqrt(n);
for(int i = 2; i <= m; i++){
if(prime[i])
for(int k = i*i; k<=n; k+=i)
prime[k] = false;
}
for(int j = 2; j <= n; j++) {
if(prime[j]) {
primeNumbers[index] = j;
index++;
}
}
return primeNumbers;
}
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
try{
double numberOfTestCases = in.nextDouble();
while(numberOfTestCases -- > 0) {
int index = 0, y = 0, count = 0;
int num = in.nextInt();
int[] primes = sieve(num);
while(index < num/3 ) {
for(y = 1; y < 57 ; y ++) {
if(Math.ceil(Math.sqrt(primes[index] - Math.pow(y,4))) == Math.floor(Math.sqrt(primes[index] - Math.pow(y,4)))) {
count++;
break;
}
}
index++;
}
System.out.println(count);
}
}
catch(Exception e) {
}
}
}
Is there a way in which I can make this approach work?
P.S.:Please ignore the unruly exception handling.
How many numbers of the form x^2+y^4 are there below 1000000? How many prime numbers are there below 1000000? What do these two numbers tell you about how you should approach the solution?
#isnot2bad's comment is also relevant.

Wrong Answer for Project Euler 50

I am attempting Problem 50 of project Euler.
The prime 41, can be written as the sum of six consecutive primes:
41 = 2 + 3 + 5 + 7 + 11 + 13 This is the longest sum of consecutive
primes that adds to a prime below one-hundred. The longest sum of
consecutive primes below one-thousand that adds to a prime, contains
21 terms, and is equal to 953. Which prime, below one-million, can be
written as the sum of the most consecutive primes?
Here is my code:
public class consPrime
{
static int checker(int ar[],int num,int index) //returns no.of consecutive
{ //primes for the given num
while(true)
{
int temp=num;
for(int i=index;i>=0;i--)
{
temp=temp-ar[i];
if(temp==0)
{
return (index-i+1);
}
}
index--;
if(index==0)
return 0;
}
}
public static void main(String args[])
{
int n=100000;
int ar[]=new int[n];
int total=0;int flag;
for(int i=2;i<1000000;i++) //Generates an array of primes below 1 million
{
flag=1;
for(int j=2;j<=Math.sqrt(i);j++)
{
if(i%j==0)
{
flag=0;
break;
}
}
if(flag==1)
{
ar[total]=i;
total++;
}
}
int m=0;
int Big=0;
for(int i=total;i>=0;i--) //Prints the current answer with no.of prime
{
m=checker(ar,ar[i],i-1);
if(Big<=m)
{Big=m;
System.out.println(ar[i]+" "+Big);
}
}
}
}
Basically it just creates a vector of all primes up to 1000000 and then loops through them finding the right answer. The answer is 997651 and the count is supposed to be 543 but my program outputs 990707 and 75175 respectively. What might be wrong?
Several big problems:
Some minor problem first: learn to proper indent your code, learn to use proper naming convention. In Java, variable names uses camelCasing while type name uses PascalCasing.
Lots of problems in your logics: you loop thru the prime number array, until you hit zero or until looped thru all numbers in the array. However, please be awared that, there is underflow/overflow for integer. It is possible that the "temp" keeps on deducts and become negative and become positive and so-on-and-so-forth and hit zero. However that's not the correct answer
You only tried to find the consecutive numbers that ends at index - 1. For example, to check for prime number at index 10, you are finding consecutive primes from index 9 backwards. However consecutive prime sum up to your target number rarely (in fact almost never, except for 5) contains the "previous" prime number. The whole logic is simply wrong.
Not to mention the incorrect parameters you passed for checker, which is mentioned by comment of user #pm-77-1
Here is another approach that takes 43 ms.
It is based on the following approach:
1) The primes <= 1000000 are generated using a sieve
2) It iterates in O(n2) through all numbers and it counts the consecutive primes. The first loop changes the first element of the sequence, the second one takes the elements starting from that position and adds them to a sum. If the sum is prime and it consists of the biggest number of primes, than it is kept in a variable.
import java.util.ArrayList;
import java.util.List;
public class P50 {
private final static int N = 1_000_000;
public static void main(String[] args) {
boolean primes[] = generatePrimes(N);
List<Integer> primeIntegers = new ArrayList<Integer>();
for (int i = 0; i < primes.length; i++) {
if (primes[i]) {
primeIntegers.add(i);
}
}
int count = 0;
int sum = 0;
int finalSum = 0;
int finalCount = 0;
int totalPrimes = primeIntegers.size();
for (int start = 0; start < totalPrimes; start++) {
sum = 0;
count = 0;
for (int current = start; current < totalPrimes; current++) {
int actual = primeIntegers.get(current);
sum += actual;
if ( sum >= N ) {
break;
}
if ( primes[sum] ) {
if ( count > finalCount ) {
finalCount = count;
finalSum = sum;
}
}
count++;
}
}
System.out.println(finalSum);
}
private static boolean[] generatePrimes(int n) {
boolean primes[] = new boolean[n];
for (int i = 0; i < n; i++) {
primes[i] = true;
}
primes[0] = false;
primes[1] = false;
// i = step
for (int i = 2; i * i < n; i++) {
if (primes[i]) {
for (int j = i * i; j < n; j += i) {
primes[j] = false;
}
}
}
return primes;
}
}

Categories

Resources