Mathematical riddle - how to solve numerically in Java? - java

So the riddle is:
John has written down k sequential odd numbers: n{1}, n{2}, ..., n{k-1}, n{k} (where n{2} = n{1} + 2 and so on). We know that:
The sum of the first four numbers is a fourth power of some prime number (so n{1} + n{2} + n{3} + n{4} = p{1} where p{1}^4 is a prime number.
The sum of the last five numbers is a fourth power of some prime number (so n{k} + n{k-1} + n{k-2} + n{k-3} + n{k-4}= p{2}^4 where p{1} is a prime number.
The question is - how many numbers have been written down (k=?).
Below is my attempt to solve it in Java:
import java.math.BigInteger;
import java.util.Set;
//precalculate prime numbers
public class PrimeSieve {
public static boolean[] calculateIntegers(int N) {
// initially assume all integers are prime
boolean[] isPrime = new boolean[N + 1];
for (int i = 2; i <= N; i++) {
isPrime[i] = true;
}
// mark non-primes <= N using Sieve of Eratosthenes
for (int i = 2; i*i <= N; i++) {
// if i is prime, then mark multiples of i as nonprime
// suffices to consider mutiples i, i+1, ..., N/i
if (isPrime[i]) {
for (int j = i; i*j <= N; j++) {
isPrime[i*j] = false;
}
}
}
return isPrime;
}
}
The solving class:
public class Solver {
static boolean[] isPrime = PrimeSieve.calculateIntegers(100000);
public static void main(String[] args) {
int minNumberCount = 5;
int maxNumberCount = 2000;
int startInt = 2;
int endInt = 1000000;
for (int numberCount = minNumberCount; numberCount < maxNumberCount+1; numberCount++) {
System.out.println("Analyzing for " + numberCount + " numbers");
int[] numbers = new int[numberCount];
//loop through number sets
for (int firstNum = startInt; firstNum < endInt; firstNum+=2) {
//populate numbers array
for(int j=0; j<numberCount; j++){
numbers[j] = firstNum + j*2;
}
long bottomSum=0;
long topSum=0;
//calculate bottom sum
for(int iter=0; iter<4; iter++){
bottomSum+=numbers[iter];
}
//calculate top sum
for(int iter=numberCount-1; iter>numberCount-6; iter--){
topSum+=numbers[iter];
}
//check if the sums match the sulution criteria
if(checkPrime(quadRoot(bottomSum)) && checkPrime(quadRoot(topSum))){
System.out.println("SOLUTION!");
for (int i = 0; i < numbers.length; i++) {
System.out.print(numbers[i] + " ");
}
System.exit(0);
}
}
}
}
private static boolean checkPrime(int i){
return isPrime[i];
}
private static boolean checkPrime(double i){
return ((i % 1) == 0) && checkPrime((int) i);
}
private static double quadRoot(long n){
return Math.sqrt(Math.sqrt(n));
}
}
Using this algorithm with the assumed parameters (max k=2000, max n{1}=100000) - I've found no solution. My question is: are the parameter assumptions wrong (no solution in this range), or do I have some algorithmic/numeric error and that is the reason I've found no solution?
EDIT: sorry - my mistake - it should be ODD instead of EVEN.

It is still easier to solve this directly than to write a program.
The first sum is even so it must be 16 (since 2 is the only even prime). The first four numbers are therefore 1,3,5,7.
The sum of five consecutive odd numbers is 5 times the middle number hence must be divisible by 5. Since it is a fourth power of a prime it must be 625 and the last five numbers are therefore 121,123,125,127,129
It is now an easy task to determine k=65

As said in the comments, your riddle has no solution.
Let's suppose there was a solution, then n1 + n2 + n3 + n4 == p1^4 . We know that n1,n2,n3,n4 are even from the definition of the riddle and therefore as a sum of even numbers, n1 + n2 + n3 + n4 is even as well. This leads us to the fact that p1^4 is even. We know that a multiplication of two odd numbers results only an odd number, hence p1^4 = p1 * p1 * p1 * p1 means that p1 must be an even number. However, p1 is prime. The only prime number which is also even is 2. It's easy to see that there are no four consecutive even numbers that sum up to 16 and therefore p1 is not prime. This contradicts the assumption that p1 is a prime, hence, no solution.

If there are only even numbers, the sum of those is an even number. If I understood correctly, your sum has to be the result of the fourth power of a prime number. Considering the sum is an even number, the only number to satisfy your condition is 16 (2*2*2*2), where 2 is a prime number, so your sum of 4 even number has to be 16. Now, if you're certain there's a sequence, then the sum is computed by adding the first and the last number in the sequence, then multiplying the result with the number of elements in the sequence, and dividing the result of the multiplication by 2. For example, 2+4+6+8=(2+8)*4/2=10*4/2=20. Similarly, for your example, n{1}+n{2}+...+n{k}=(n{1}+n{k})*k/2
On a side note, your smallest sum of 4 even numbers (20), the example I used, is already above your only 4th power of the prime number (16), so yes, there is no valid example in your sequence.
I hope this made some sense

Related

I got some problems in adding the prime numbers to an array list

In this problem, I have a variable N.User will input the value of N.So, I have to find the prime number between 2 to N and store them in an array
import java.util.ArrayList;
import java.util.Scanner;
public class Main{
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
ArrayList<Integer> array = new ArrayList<>(10);
int num,i,j,count;
num = sc.nextInt();
for(i=2;i<=num;i++){
count = 0;
for(j=2;j<= num/2;j++) {
if (i % j == 0) {
count++;
}
}
if(count==0){
array.add(i);
}
}
for(int val: array){
System.out.print(val + " ");
}
}
}
So, if N=15.The output should be 2 3 5 7 11 13
But I'm getting 11 13
where is the problem?
If you want to optimize your search for primes you should use a sieve or at least add some simple limitations to your algorithm. I have included a version with comments. The main point of this is to only divide by primes that you have already found.
After 2, only check odd numbers since even numbers are guaranteed to be composite (i.e. non-prime).
Only divide by primes already computed.
Only divide by primes <= to the square root of the candidate. If n is divisible by m to yield q. Then n is also divisible by q to yield m. No need to repeat the test with higher numbers. The threshold is the square root of the candidate.
List<Integer> primes = new ArrayList<>();
primes.add(2); // seed list with first prime
int max = 50;
// only check odd numbers after 2.
for (int candidate = 3; candidate < max; candidate += 2) {
// loop thru existing primes
for (int p : primes) {
// if candidate is divisible by any prime, then discontinue
// testing and move on to next candidate via outer loop
if (candidate % p == 0) {
break;
}
// if the limit has been reached, then a prime has been
// found, so add to list of primes and continue with
// next candidate.
if (p * p > candidate) {
// add new found prime to list
primes.add(candidate);
break;
}
}
}
System.out.println(primes);
Your logic is mixed up, think about what defines a prime number. A prime number is a number that is only divisible by itself and one. So when you check that the remainder equals zero and then increase the count a prime number then wouldn't be added to the array as the count != 0. I do realise you set the limit to j for num / 2 but not sure what your thought process there was. I've added an alternative solution (I've tried to stick to yours and just alter it slightly).
My thought process is that by the time a prime number is divided by itself it should only have produced a remainder of zero that one time.
ArrayList<Integer> array = new ArrayList<>();
int limit = 100;
int i, j;
for (i = 1; i <= limit; i++) {
count = 0;
j = 2;
for (j = 2; j <= i; j++) {
if(i%j == 0){
count += 1;
}
if (j == i && count == 1) {
array.add(i);
}
}
}

Output amount of primes in array

I'm kind of a newbie at Java, and not very good at it. It's a trial and error process for me.
I'm working on a Java program to output the amount of primes in an array. I can get it to output the primes, but I want to also output the quantity of primes. I tried to add each prime to an array list titled "primes" then return "primes.size()" at the end of my program. It doesn't work as intended. The count is actually off. When I create an array of 5 numbers, it outputs 3 primes, 2, 3, and 5. But then it says I have 4 primes. I think it might be counting 1 as a prime. Because when I create an array of 20, the prime numbers output 2,3,5,7,11,13,17 and 19. Then it says the total prime numbers = 9. It should be 8 though.
Here's my code
public class Prime {
public static void main(String[] args) {
int index = 0;
Scanner scan = new Scanner(System. in );
System.out.println("How big would you like the array? ");
int num = scan.nextInt();
int[] array = new int[num];
ArrayList < Integer > primes = new ArrayList < Integer > ();
//System.out.println("How Many threads? ");
//int nThreads = scan.nextInt(); // Create variable 'n' to handle whatever integer the user specifies. nextInt() is used for the scanner to expect and Int.
//Thread[] thread = new Thread[nThreads];
for (int n = 1; n <= array.length; n++) {
boolean prime = true;
for (int j = 2; j < n; j++) {
if (n % j == 0) {
prime = false;
break;
}
}
if (prime) {
primes.add(n);
}
if (prime && n != 1) {
System.out.println(n + "");
}
}
System.out.println("Total Prime numbers = " + primes.size());
System.out.println("Prime Numbers within " + array.length);
}
}
Forgive the sloppiness of it. I actually plan on adding multithreading to it, but I wanted to get this down first.
Any help would be greatly appreciated. Thanks.
You have included 1 in your array of primes, because you started the n for loop at 1. You don't print it because of the final if statement, but it's there in the ArrayList.
Start your n for loop with n = 2. As a consequence, you won't need the final if statement, because n won't be 1 ever. You could print the prime at the same time as you add it to the ArrayList.

Some help figuring out what's wrong with my Sieve of Eratosthenes

So... I have a bit of a problem in a lab. I've been at it for a while, but my program just isn't doing what I'm expecting it to do. I'm currently writing a Sieve of Eratosthenes program in Java. Unfortunately, it's not giving the expected output of a list of primes. I can't, for the life of me, figure out what's wrong... Could anyone here give me a pointer as to where I might have messed something up?
Much thanks!
import java.util.*;
import java.math.*;
public class primeSieve {
/**
* #param args
*/
public static void main(String[] args){
// TODO Auto-generated method stub
Scanner kb = new Scanner(System.in);
//Get user input
System.out.println("Please enter the first number of the set of numbers to calculate primes (first number MUST be prime):");
int first = kb.nextInt();
System.out.println("Please enter the last number of the set of numbers to calculate primes (first number MUST be prime):");
int last = kb.nextInt();
List<Integer> primeList = new ArrayList<Integer>();
List<Integer> numList = new ArrayList<Integer>();
//Make array with values from 2 to the last value entered by user
for(int i = 2; i <= last; i++){
numList.add(i);
}
int size = numList.size();
//Calculate primes
for(int i = 0; i < size; i++)
{
if(i != 0 && i % 2 == 0){continue;} //No point in checking even numbers
if(numList.get(i) == 0){continue;} //If a value has been removed, it's been set to 0. No need to check it.
int prime = numList.get(i); //The current number being worked on. Should be prime
primeList.add(prime); //The number is prime, put it into the prime list.
for(int j = prime; j < size; j += prime) //Loop to remove multiples
{
numList.set(j, 0); //Number is a multiple of the prime previously calculated. Set it to 0, not a prime.
}
}
int primeSize = primeList.size();
System.out.println(primeSize);
System.out.println("The prime numbers from " + first + " to " + last + " are:");
for(int i = first; i < primeSize; i++)
{
System.out.println(primeList.get(i));
}
}
}
Edit: The output for the program when I look for primes between 2 and 50 is this:
The prime numbers from 2 to 50 are:
7
13
19
25
31
39
43
49
In the nested for loop, you start j at prime. However, consider the prime 2: it is at index 0, not index 2. Things should work out if you start j at prime-first. Also, as a commenter pointed out, your print loop should start at index 0 rather than first.

Sum of Digits in Java

import java.util.Scanner;
public class CubesSum {
public static void main (String [] args){
int input;
System.out.println("Enter a positive integer:");
Scanner in = new Scanner(System.in);
input = in.nextInt();
int number = input; //number is a temp variable
int sum = 0;
while(number>0){
int t= number%10;
sum += t*t*t;
number = number/10;
}
System.out.println("The sum of the cubes of the digits is:" +sum);
}
}
Okay so I'm using a while loop. For part B which is to modify to determine what integers of two, three, and four digits are equal to the sum of the cubes of their digits. So for example, 371 = 3³+7³+1³. Can someone tell me how to do it? I need to wrap a for loop around my while loop...
Take the part of your code that computes the sum of the cubes of the digits of a number, and make that a function:
int sumOfCubedDigits(int number) {
int sum = 0;
// compute sum from number
return sum;
}
Then, loop through all the 2-to-4 digit numbers and check whether they equal the sum of the cubes of their digits:
for (int n = 10; n < 10000; n++) {
if (n == sumOfCubedDigits(n)) {
// do whatever with n
}
}
You could keep the sum-of-cubed-digits computation inside the for loop if you want, but it'd be a bit less readable.
Okay, so it looks like you haven't learned about function definitions yet. I shouldn't have assumed. Let's do it with a nested loop, then.
As you said, you need to wrap a for loop around your while. We need to consider all 2-to-4 digit numbers, so our loop will start at the first 2-digit number and end when it reaches the first 5-digit number:
for (int n = 10; n < 10000; n++) {
// More code will go here.
}
Inside the loop, we need to compute the sum of the cubed digits of n. The code you wrote earlier to compute that modifies the number it's operating on, but we can't modify n, or we'll screw up the for loop. We make a copy:
for (int n = 10; n < 10000; n++) {
int temp = n;
int sum = 0;
// Compute the sum of the digits of temp, much like you did before.
}
Finally, if the sum is equal to n, we do something to indicate it. Let's say your assignment said to print all such numbers:
for (int n = 10; n < 10000; n++) {
int temp = n;
int sum = 0;
// Compute the sum of the digits of temp, much like you did before.
if (sum == n) {
System.out.println(n);
}
}
For an arbitrary integer i, it's nth digit dn is, (being n=1 the rightmost digit)
dn = (i % (10^n)) / (10^(n-1)) // all integer operations
as you can see, you'll need to know beforehand the number of digits of your i, otherwise, yes, you'll need a loop
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.print("Please enter number : ");
int num = input.nextInt();
int temp = num, remainder;
int sum = 0;
while(temp %10 != 0){
remainder = temp %10;
sum = sum+ remainder ;
temp = temp/10;
}
System.out.println("Sum of digit : " + sum);
=====OUTPUT====
Please enter number : 123
Sum of digit : 6

abundant sums, logic

I have been working on the problem below but I get the wrong answer. What is wrong with my logic?
A perfect number is a number for which the sum of its proper divisors is exactly equal to the number. For example, the sum of the proper divisors of 28 would be 1 + 2 + 4 + 7 + 14 = 28, which means that 28 is a perfect number.
A number n is called deficient if the sum of its proper divisors is less than n and it is called abundant if this sum exceeds n.
As 12 is the smallest abundant number, 1 + 2 + 3 + 4 + 6 = 16, the smallest number that can be written as the sum of two abundant numbers is 24. By mathematical analysis, it can be shown that all integers greater than 28123 can be written as the sum of two abundant numbers. However, this upper limit cannot be reduced any further by analysis even though it is known that the greatest number that cannot be expressed as the sum of two abundant numbers is less than this limit.
Find the sum of all the positive integers which cannot be written as the sum of two abundant numbers.
Here is my code:
public class EulerProblem23 {
public static void main(String[] args) {
//First, I create an array containing all the numbers ranging from 1 to 28123.
int[] tall = new int[28123];
int x = 0;
for (int j = 1;j<=28123;j++){
tall[x] = j;
x++;
}
//Then, give all the numbers that can be written as the sum of two abundant numbers
//the value 0.
int forrige = 0;
for (int i = 1;i<=28123;i++){
if (isAbundant(i)){
if (2 * i <= 28123){
tall[i - 1] = 0;
}
if (forrige + i <= 28123){
tall[i - 1] = 0;
}
}
}
//All that's left should be summing all the numbers in the array.
long sum = 0;
for (int y = 0;y<28123;y++){
sum += tall[y];
}
System.out.println(sum);
}
public static boolean isAbundant(int n){
int sumAvDivisorer = 0;
for (int i = 1;i<n;i++){
if (n % i == 0){
sumAvDivisorer += i;
}
}
if (sumAvDivisorer > n){
return true;
}
else {
return false;
}
}
}
Is there something wrong with my logic here? Wouldn't all of the integers that can be defined as the sum of two abundant numbers become 0?
I would do it like this:
Make an array of all abundant numbers.
Add all pairs together. You can do this with nested for loops.
For every pair that adds to a number less than or equal to 28123, add the sum of that pair to the total sum.
This code makes no sense:
//Then, give all the numbers that can be written as the sum of two abundant numbers
//the value 0.
int forrige = 0;
for (int i = 1;i<=28123;i++){
if (isAbundant(i)){
if (2 * i <= 28123){
tall[i - 1] = 0;
}
if (forrige + i <= 28123){
tall[i - 1] = 0;
}
}
}
Supposedly, what you want to know if, for each i in the loop, if there are two numbers j and k which are both abundant and such that j + k = i.
Your code has no relation with it. Also, the second if has little meaning, as forrige is always 0.
What I would do.
1) An array of booleans [0, 28123]. True if the number is abundant (previous step). (*)
2) Another array [0, 28123]. True if the number in the position is the add of two abundant numbers. Loop i from 1 to 28123, for each i, loop z from 1 to i/2 (either j <= i/2 or k <= i / 2). For each z, check in the previous array for z and i-z, if both are true set the value to true.
3) Loop the previous array and add all the indexes that are true in the array.
Alternatively, is the condition of "abundant" is sparse enough, you could replace 1) with a list of the numbers which are abundant, and a hashset of them. So, instead of running j from 1 to i/2, you loop this list until you get to i/2 (use the hashset to find quickly if i-j is abundant or not).
Anyway, the idea in this problem is precalculating the values that you will be using again and again, instead of repeating the isAbundant calls to the same values time after time.

Categories

Resources