Java lottery game : finding a sequence in an array - java

How do I see if the first 2, 3, 4 or all numbers are part of another array?Here "lottery" generates 10 numbers 1-100 and "numbers" is getting user's input 5 times.The program compares user's 5 numbers to numbers 1-5 of lottery , 2-6 and so on.Im trying to see if the user guessed a sequence in the lottery array but I cant get it to print out "You guessed 2 nrs" if the user guessed 2 ,3 ,4 or all numbers one after another.I incremented a counter and also tried switch statements but doesn't work.
// to check if user guessed a sequence
int counter=0;
for (int i = 0; i < lottery.length - 5; i++) { // 1-5
for (int j = 0; j < numbers.length; j++) {
if (lottery[i] == numbers[j]) {
counter++;
}
}
}
for (int i = 1; i < lottery.length - 4 ; i++) { // 2-6
for (int j = 0; j < numbers.length; j++) {
if (lottery[i] == numbers[j]) {
counter++;
}
}
}
for (int i = 2; i < lottery.length - 3 ; i++) { // 3 -7 numbers of lottery array
for (int j = 0; j < numbers.length; j++) {
if (lottery[i] == numbers[j]) {
counter++;
}
}
}
for (int i = 3; i < lottery.length - 2; i++) { // 4 - 8 numbers of lottery array
for (int j = 0; j < numbers.length; j++) {
if (lottery[i] == numbers[j]) {
counter++;
}
}
}
for (int i = 4; i < lottery.length - 1; i++) { // 5 -9 numbers of lottery array
for (int j = 0; j < numbers.length; j++) {
if (lottery[i] == numbers[j]) {
counter++;
}
}
}
for (int i = 5; i < lottery.length ; i++) { // 6 -10 numbers of lottery array
for (int j = 0; j < numbers.length; j++) {
if (lottery[i] == numbers[j]) {
counter++;
}
}
}
for (int i = 0; i < numbers.length && i < 2; i++) { // 2 sequence
counter = numbers[i];
}
for (int i = 0; i < numbers.length && i < 3; i++) { // 3 sequence
counter= numbers[i];
}
for (int i =0; i < numbers.length && i < 4; i++) { // 4 sequence
counter = numbers[i];
}
for (int i = 0; i < numbers.length; i++) { // 5 sequence
counter = numbers[i];
}
switch (counter) {
case 1:
System.out.println("You guessed one sequence");
break;
case 2:
System.out.println("You guessed two sequences");
break;
case 3:
System.out.println("You guessed three sequences");
break;
case 4:
System.out.println("You guessed four sequences");
break;
}

Your code is a little bit confusing, most likely because you are not using functions, for what you want to achieve there is a nice code here, lets take a look at it:
static boolean isSubArray(int A[], int B[], int n, int m)
{
// Two pointers to traverse the arrays
int i = 0, j = 0;
// Traverse both arrays simultaneously
while (i < n && j < m)
{
// If element matches
// increment both pointers
if (A[i] == B[j])
{
i++;
j++;
// If array B is completely
// traversed
if (j == m)
return true;
}
// If not,
// increment i and reset j
else
{
i = i - j + 1;
j = 0;
}
}
return false;
}
Now you have a function that will return true if whole sequence A is in sequence B, but that is not the whole code you seem to want. You need to split guessed sequence, what if there is subsequence that fits?
Example (how many are guessed in following?):
int lottery[] = {1,2,3,4,5,6,7,8,9,10};
int A[] = {1,2,3,4,5}; //here we got full match
int B[] = {1,2,4,5,6}; //last three make it 3
int C[] = {1,2,3,7,9}; //first three make it 3
int D[] = {1,3,4,5,9}; //and here is it in the middle!
So what now? You need to check for each lengths, higher lengths first of course, a simple solution can be as follows (check how to create a subarray):
import java.util.Arrays;
public static<T> T[] subArray(T[] array, int beg, int end) {
return Arrays.copyOfRange(array, beg, end + 1);
}
public static boolean checkAll(int A[], int B[], int n, int m, int subset){
for(int i=0;i+subset<n;i++){ //i+subset must be within range
//checking the current subset, iterate them all
if(isSubArray(subArray(A,i,i+subset), B, n, m)){
return true; //if it is there return true!
}
}
return false; //no luck!
}
int lottery[] = {1,2,3,4,5,6,7,8,9,10};
int D[] = {1,3,4,5,9};
counter = 0;
for(counter=D.length; counter>0; counter--){
if(checkAll(D, lottery, D.length, lottery.length, counter)){
break; //we found match, can end
}
}
System.out.println("You guessed sequence of length: %d ", counter);
I guess I have a little bit misunderstood what you are trying to achieve, so same approach for sequences of the lottery:
//subset is probably 5 for lottery
public static int checkAll(int A[], int B[], int n, int m, int subset_A , int subset_B){
int total = 0;//we return this
for(int i=0;i+subset_B<m;i++){ //each subset in lottery
for(int j=0;j+subset_A<n;j++){ //each subset in guesses
if(isSubArray(subArray(A,j,j+subset),subArray(B,i,i+subset), n, m)){
total++;
}
}
return total;
}
int occurences = 0;
for(int counter=lottery.length; counter>0; counter--){
occurences+=checkAll(D, lottery, D.length, lottery.length, counter, 5);
}
System.out.println("Your guessed sequence (and its parts) was present %d times", occurences );
I am still not sure what exactly you want to do, so this code might be a little bit overkill. The code was not tested, some syntax errors might come in the way.

Related

Can someone explain why codes get different outputs if you don't use scopes in some cases?

I'm practicing coding on HackerRank, and I have the following code, which gets a different outputs.
The task is the following:
Given an array of integers, find the longest subarray where the absolute difference between any two elements is less than or equal to.
Example:
a = [1,1,2,2,4,4,5,5,5];
There are two subarrays meeting the criterion: [1,1,2,2] and [4,4,5,5,5]. The maximum length subarray has 5 elements.
The following code gets the desired output:
public static int pickingNumbers(List<Integer> a) {
// Write your code here
int max = 0;
int counter = 0;
Collections.sort(a);
for(int i = 0; i < a.size(); i++){
for(int j = i+1; j< a.size(); j++){
if(Math.abs(a.get(i)-a.get(j)) <= 1){
counter++;
}
}
if(counter > max)
max = counter;
counter = 0;
}
return max+1;
}
While this one, gets a different output -
public static int pickingNumbers(List<Integer> a) {
// Write your code here
int max = 0;
int counter = 0;
Collections.sort(a);
for(int i = 0; i < a.size(); i++){
for(int j = i+1; j< a.size(); j++){
if(Math.abs(a.get(i)-a.get(j)) <= 1){
counter++;
}
}
if(counter > max){
max = counter;
counter = 0;
}
}
return max+1;
}
As you can see, the difference between the 2 codes are just the brackets after the if(counter > max) part. In the latter case, the counter is always 1 unit more than it should be.
Can anyone please explain it to me, why the code behaves different in this case?
It's because in the first snippet counter = 0; is not in the if block.
When if is not enclosed in brackets, it only evaluates the first instruction after it, so the counter = 0; is always executed.
Here's an example with better indentation:
public static int pickingNumbers(List<Integer> a)
{
int max = 0;
int counter = 0;
Collections.sort(a);
for(int i = 0; i < a.size(); i++)
{
for(int j = i+1; j< a.size(); j++)
{
if(Math.abs(a.get(i)-a.get(j)) <= 1)
{
counter++;
}
}
if(counter > max)
max = counter;
counter = 0; // Not in the if statement, so the counter is always reset!
}
return max+1;
}
const genObj = (ar) => {
let obj = {}
for(let i of ar) {
!(obj[i])? obj[i] = 1 : obj[i]++
}
return obj
}
function pickingNumbers(a) {
// Write your code here
let obj = genObj(a)
let k = Object.keys(genObj(a))
let i = 0
let max = 0
while (i <= k.length - 1) {
for(let j = i; j <= k.length - 1; j++){
if(i === j) continue
if(Math.abs(k[i] - k[j]) <= 1) {
if(obj[k[i]] + obj[k[j]] > max)
max = obj[k[i]] + obj[k[j]]
}
}
i++
}
return max > Math.max(...Object.values(obj)) ? max : Math.max(...Object.values(obj))
}

Runtime for Sieve of Eratosthenes

I am currently working on making a sieve for school. Here is my code so far:
public static List<Integer> sieve(int input) {
int[] numbers = new int[input - 2 + 1];
int prime = 2;
// start of with 2 since first prime w/ specific multiples
int counter = 0;
for (int i = prime; i <= input; i++) {
numbers[counter] = i;
counter++;
}
// Main sieve logic: remove all multiples of that number (except itself), move onto next number in ArrayList (which must be prime)
for (int x = 0; x < numbers.length; x++) {
for (int j = findIndex(numbers, prime) + 1; j < numbers.length; j++) {
if (numbers[j] % prime == 0) {
numbers[j] = 0;
}
}
for (int k = findIndex(numbers, prime) + 1; k < numbers.length; k++) {
if (numbers[k] != 0) {
prime = numbers[k];
break;
}
}
}
pushZerosToEnd(numbers, numbers.length);
List<Integer> cleanerResult = new ArrayList<>();
for (int y = 0; y < numbers.length; y++) {
if (numbers[y] != 0) {
cleanerResult.add(numbers[y]);
}
}
return cleanerResult;
}
// Assume that pushZerosToEnd() and findIndex() do their specified action
Because this involves many loops, I know that this method will not be efficient or have high runtimes for bigger inputs. However, how would I find the average runtime (in Big O) of my current code so far?

Counter and accumulator in a java loop

I'm doing this program: Given an integer, n, if the sum of its divisors (not counting itself) equals n, that number is said to be perfect. If the sum is lower, it is said to be decient, and if it is higher it is said to be abundant. For example:
6 has divisors 1,2,3: they add 6, therefore 6 is perfect. 8 has divisors 1,2,4: they add 7, therefore 8 is deciente. 24 has divisors 1,2,3,4,6,8,12: they add 36, therefore 24 is abundant.
Write a program that reads two positive integers and displays, on the screen, how many numbers there are of each type in that interval (including the extremes).
I have the following code and I know where it fails, for example if I enter a single number, I do it well, example of entries 6 and 7. If I then enter 6 and 9 the output is Perfect 1 Deficient 0 Abundant 2, when I should to be Perfect 1 Deficient 2 Abundant 0. Variable j stores the divisors of all in the variable j and then that's why it's abundant but I have not been able to correct it for more than I've tried.
import java.util.Scanner;
public class PerfectNumbers {
public static void main(String[] args) {
System.out.println("Enter two numbers for the interval:");
Scanner teclado = new Scanner(System.in);
int x = teclado.nextInt();
int y = teclado.nextInt();
int cont1 = 0;
int perfect = 0;
int deficient = 0;
int abundant = 0;
for (int i = x; i < y; i++) {
for (int j = 1; j < i; j++) {
if (i % j == 0) {
cont1 += j;
} else {
cont1 += 0;
}
}
if (cont1 == x) {
perfect += 1;
} else if (cont1 < x) {
deficient += 1;
} else if (cont1 > x) {
abundant += 1;
}
}
System.out.println("Perfect"+ perfect);
System.out.println("Deficient"+ deficient);
System.out.println("Abundant"+ abundant);
}
}
One problem is that you didn't reset cont1.
Another problem is that instead of comparing to x to decide perfect/deficient/abundant, you need to compare to i.
for (int i = x; i < y; i++) {
cont1 = 0;
for (int j = 1; j < i; j++) {
if (i % j == 0) {
cont1 += j;
}
}
if (cont1 == i) {
perfect += 1;
} else if (cont1 < i) {
deficient += 1;
} else {
abundant += 1;
}
}
I think the second problem was easy to overlook because of the poor naming of variables. I suggest to improve that, and it will be easier to read and harder to make such mistakes:
for (int n = start; n < end; n++) {
sum = 0;
for (int j = 1; j < n; j++) {
if (n % j == 0) {
sum += j;
}
}
if (sum == n) {
perfect++;
} else if (sum < n) {
deficient++;
} else {
abundant++;
}
}

Taking 100000 inputs in java Sorting program and it shows error in the output

i have taken 10 inputs and my program works perfectly but as i start taking large number of inputs like 100,1000 my programs does not work and get an error or generally it stops working.
So how can i solve it please give me solution.
Below is the code i have written:
package PROGARMS;
import java.util.Random;
import java.util.Scanner;
public class Radix1 {
public static void main(String[] args){
int i,j,k=0,x=10,m=0,n;
Scanner k1=new Scanner(System.in);
Random r=new Random();
System.out.println("enter number of elements u want to sort");
n=k1.nextInt();
int[] a=new int[n];
for(i=0;i<n;i++)
{
a[i]=r.nextInt(10000);
}
n=a.length;
System.out.println("Array before sorting");
for(i=0;i<n;i++)
System.out.println(a[i]+" ");
System.out.println();
int[] b=new int[n];
int[] z=new int[n];
int max=a[0];
for(i=1;i<n;i++)
{
if(max<a[i])
max=a[i];
}
int length=0;
while(max!=0)
{
length++;
max=max/10;
}
//length=1;
System.out.println("length="+length);
while(m<length){
System.out.println("x="+x);
for(i=0;i<n;i++)
{
b[i]=a[i]%x;
}
for(i=0;i<n;i++)
{
for(j=0;j<n;j++)
{
if(b[i]<b[j])
{
int key=b[i];
b[i]=b[j];
b[j]=key;
}
}
}
for(int s=0;s<n;s++)
System.out.println("s="+s+",b[s]="+b[s]);
for(i=0;i<n;i++)
{
for(j=0;j<n;j++)
{
if(b[i]==a[j]%x)
{
if(k>=n)
{
System.out.println("k is greater,M="+m);
k=0;
}
//ystem.out.println("k="+k+",j="+j);
z[k]=a[j];
a[j]=0;
k++;
}
}
}
for(int s=0;s<n;s++)
a[s]=z[s];
//for(int s=0;s<n;s++)
//System.out.println("s="+s+",a[s]="+a[s]);
m++;
x=x*10;
k=0;
System.out.println();
}
System.out.println("After sorting Final result");
for(int s=0;s<n;s++)
System.out.println("s="+s+",a[s]="+a[s]);
}
}
I think I've got it: In your main sort loop, when you're moving the values from a across to z, you remove them from a after you're done. That's fine, except you 'remove' them by setting them to 0:
a[j]=0;
Thing is, 0 is a valid value, so if your loop is looking for values with a 0 in this place, this does not remove it from consideration. This shows up as k overrunning the array, which triggers the k is greater,M= message, but this is swallowed and the program continues.
You can fix this by setting a[j] to a value it couldn't possibly be:
a[j]=-1;
This then can't be double-counted, and the bug disappears.
I've written this change and changed the guard condition to throw an exception below. I've also added some comments for readability, and some changes to the logging which made it more readable for me (although your taste may vary).
import java.util.Random;
import java.util.Scanner;
public class RadixSort {
public static void main(String[] args) {
int i, j, k = 0, x = 10, m = 0, n;
Random r = new Random();
Scanner k1 = new Scanner(System.in);
System.out.println("Enter number of elements you want to sort");
n = k1.nextInt();
// Choose random numbers to sort
int[] a = new int[n];
for (i = 0; i < n; i++) {
a[i] = r.nextInt(10000);
}
// Print initial array
System.out.println("Array before sorting");
for (i = 0; i < n; i++)
System.out.print(a[i] + " ");
System.out.println();
// Find the largest value
int max = a[0];
for (i = 1; i < n; i++) {
if (max < a[i])
max = a[i];
}
// Find the (decimal) length of the longest value
int length = 0;
while (max != 0) {
length++;
max = max / 10;
}
System.out.println("length=" + length);
// Main sort loop
int[] b = new int[n];
int[] z = new int[n];
while (m < length) {
// Place being sorted
System.out.println("x=" + x);
// `b` is a copy of `a` including only the digit to be sorted in this pass
for (i = 0; i < n; i++) {
b[i] = a[i] % x;
}
// Bubble sort `b`
for (i = 0; i < n; i++) {
for (j = 0; j < n; j++) {
if (b[i] < b[j]) {
int key = b[i];
b[i] = b[j];
b[j] = key;
}
}
}
// Print out the sorted `b` array
for (int s = 0; s < n; s++)
System.out.print(b[s]+",");
System.out.println();
// Apply the sort from `b` to `a`.
for (i = 0; i < n; i++) {
for (j = 0; j < n; j++) {
// If the ith entry in `a` has the same digit as `b`, move it across
if (b[i] == a[j] % x) {
// XXX: Some kind of loop guard? This indicates an error, and should exit.
if (k >= n) {
throw new IllegalStateException("k is greater than n, when M=" + m);
}
// Move the jth value out of `a` into a temporary buffer `z`.
z[k] = a[j];
// XXX: Problem is, '0' is a valid value.
a[j] = -1;
k++;
}
}
}
// Transcribe the sorted array back into `a`
for (int s = 0; s < n; s++)
a[s] = z[s];
// Move on to the next digit.
m++;
x = x * 10;
k = 0;
}
// Print the final result
System.out.println("After sorting Final result");
for (int s = 0; s < n; s++)
System.out.print(a[s]+",");
System.out.println();
}
}

Find the prime-->sieve way

I tried it several times but still gives me ArrayOutOfIndex. But i want to save the memory so i use
boolean[]isPrime = new boolean [N/2+1];
instead of
boolean[]isPrime = new boolean [N+1];
This gives me ArrayOutOfIndex for line 23 and 47
line 23:
for (int i = 3; i <= N; i=i+2) {
isPrime[i] = true;
}
line 47:
for (int i = 3; i <= N; i=i+2) {
if (isPrime[i]) primes++;
...
}
Full code:
public class PrimeSieve {
public static void main(String[] args) {
if (args.length < 1) {
System.out.println("Usage: java PrimeSieve N [-s(ilent)]");
System.exit(0);
}
int N = Integer.parseInt(args[0]);
// initially assume all odd integers are prime
boolean[]isPrime = new boolean [N/2+1];
isPrime[2] = true;
for (int i = 3; i <= N; i=i+2) {
isPrime[i] = true;
}
int tripCount = 0;
// mark non-primes <= N using Sieve of Eratosthenes
for (int i = 3; i * i <= N; i=i+2) {
// if i is prime, then mark multiples of i as nonprime
if (isPrime[i]) {
int j = i * i;
while (j <= N){
tripCount++;
isPrime[j] = false;
j = j + 2*i;
}
}
}
System.out.println("Number of times in the inner loop: " + tripCount);
// count and display primes
int primes = 0;
if(N >= 2 ){
primes = 1;
}
for (int i = 3; i <= N; i=i+2) {
if (isPrime[i]) primes++;
if (args.length == 2 && args[1].equals("-s"))
; // do nothing
else
System.out.print(i + " ");
}
System.out.println("The number of primes <= " + N + " is " + primes);
}
}
You should store and access the array using the same indexing function: isPrime[i/2]
When you change the size of your array from [N+1] to [N/2+1], you need to also update the end-conditions of your for-loops. Right now your for-loops run until i=N, so you are trying to do isPrime[i] when i > (N/2+1) ... so you get an ArrayIndexOutOfBoundsException.
Change this:
for (int i = 3; i <= N; i=i+2)
to this:
for (int i = 3; i <= N/2; i=i+2)
Well, for example if N=50 your isPrime only holds 26 elements, and you're trying to access the elements at 3,5..47,49 (which, of course, is out of bounds)
What you probably want is to use i/2 (as the index) inside your loops, that way you are still iterating over the numbers 3,5..47,49, but you use the correct indexes of your vector.

Categories

Resources