Recursive method for Amicable numbers between 1 - 10000 Java - java

I have a problem with creating a recursive method for finding Amicable numbers between 1 - 10000. I created a method to find out if two numbers are Amicable, but I don't know how to run it against every possible number combination. Here are both methods which I wrote.
public void amicable(int n, int m) {
int sumM = 0;
int sumN = 0;
for (int i = 1; i < n; i++) {
if (n % i == 0) {
sumN += i;
}
}
for (int j = 1; j < m; j++) {
if (m % j == 0) {
sumM += j;
}
}
if (sumN == m && sumM == n) {
System.out.println(n + " and " + m + " are amicable numbers");
}
}
public static void amicableBetween(int n, int m) {
int sumaM = 0;
int sumaN = 0;
if (m >= 1) {
for (int j = 1; j < m; j++) {
if (m % j == 0) {
sumaM += j;
}
}
for (int i = 1; i < n; i++) {
if (n % i == 0) {
sumaN += i;
}
}
if (sumaN == m && sumaM == n) {
System.out.println(n + " and " + m + " are amicable numbers");
amicableBetween(n + 1, m - 1);
} else {
System.out.println(n + " i " + m + " aren't amicable numbers");
amicableBetween(n + 1, m - 1);
}
}
}
}

Minor disclaimer, this method might take forever and you might run out of stack space so I'm not 100% sure that calculating all the amicable numbers from 1-10000 recursively is the way to go. If this is just for fun or practice then I guess is ok.
One approach will be to sweep n until we reach m - 1 and call amicable(n,m) in each step. Once n has reached m - 1, we can decrease m by 1 and repeat the process until n is equal to m - 1 then we have checked all possible combinations. To do this, you can break your two methods into three methods.
The first method is the amicable method you already have, just changed the return type so that we can reuse it while we are going down the recursion chain:
public static boolean amicable(int n, int m) {
int sumM = 0;
int sumN = 0;
for (int i = 1; i < n; i++) {
if (n % i == 0) {
sumN += i;
}
}
for (int j = 1; j < m; j++) {
if (m % j == 0) {
sumM += j;
}
}
return sumN == m && sumM == n;
}
The second will be the public method amicableBetween(int n, int m)
public static void amicableBetween(int n, int m) {
amicableBetween(n, m, true);
}
Which will call a third private helper method amicableBetween(int n, int m, boolean start) that has a third parameter start that it can use to identify if n has reached m. Then we need to decrease m by 1 and repeat the process:
private static void amicableBetween(int n, int m, boolean start) {
if(n == m) {
return;
}
if (m >= 1) {
if (amicable(n, m)) {
System.out.println(n + " and " + m + " are amicable numbers");
} else {
System.out.println(n + " and " + m + " aren't amicable numbers");
}
amicableBetween(n + 1, m, false);
}
if(start) {
amicableBetween(n, m - 1, true);
}
}

I wonder why do you want a recursive algorithm. Don't you warry about StackOvervlowException?! It is pretty easy to find with simple Map within O(n) time:
public static void amicable(int lo, int hi) {
Map<Integer, Integer> map = new HashMap<>();
for (int i = lo; i <= hi; i++) {
int j = map.computeIfAbsent(i, DIV_SUM);
if (j > i && j <= hi && map.computeIfAbsent(j, DIV_SUM) == i)
System.out.format("[%d : %d]\n", i, j);
}
}
private static final Function<Integer, Integer> DIV_SUM = val -> {
int sum = 0;
for (int i = 1, max = val / 2; i <= max; i++)
if (val % i == 0)
sum += i;
return sum;
};
Demo: time ~150ms
amicable(1, 10000);
[220 : 284]
[1184 : 1210]
[2620 : 2924]
[5020 : 5564]
[6232 : 6368]

So, you wrote a method that can tell if two numbers are amicable. That's the hard part out of the way. All you have to do is call that from inside two loops, one for the upper bound, one for the lower bound.
for(lowerNumber = 1; lowerNumber < 10000; lowerNumber++){
for(upperNumber = lowerNumber + 1; upperNumber <= 10000; upperNumber++){
amicable(lowerNumber, upperNumber);
}
}

I'm not sure why you need two parameters in the amicable function. An amicable number has a repeating aliquot sequence of period 2, which means
s(s(n)) == n
We can find the number's complement by retrieving the sum of its proper divisors and checking the assertion above.
This means to find the amicable numbers for n between 1 and 10,000 we only need n, and would also make trivial the part of the process you seem to want as a recursion.
JavaScript code:
function s(n){
let s = n > 1 ? 1 : 0;
let sqrt_n = Math.sqrt(n);
let d1=Math.floor(n/2);
for (; d1>=sqrt_n; d1--){
let d2 = n / d1;
if (d2 == Math.floor(d2))
s += d1 + d2;
}
if (d1 == sqrt_n)
s += d1;
return s;
}
let n = 220;
let s_n = s(n);
if (s(s_n) == n)
console.log('Amicable!', n, s_n);

Related

Count the minimum number of jumps required for a frog to get to the other side of a river

I work with a Codility problem provided below,
The Fibonacci sequence is defined using the following recursive formula:
F(0) = 0
F(1) = 1
F(M) = F(M - 1) + F(M - 2) if M >= 2
A small frog wants to get to the other side of a river. The frog is initially located at one bank of the river (position −1) and wants to get to the other bank (position N). The frog can jump over any distance F(K), where F(K) is the K-th Fibonacci number. Luckily, there are many leaves on the river, and the frog can jump between the leaves, but only in the direction of the bank at position N.
The leaves on the river are represented in an array A consisting of N integers. Consecutive elements of array A represent consecutive positions from 0 to N − 1 on the river. Array A contains only 0s and/or 1s:
0 represents a position without a leaf;
1 represents a position containing a leaf.
The goal is to count the minimum number of jumps in which the frog can get to the other side of the river (from position −1 to position N). The frog can jump between positions −1 and N (the banks of the river) and every position containing a leaf.
For example, consider array A such that:
A[0] = 0
A[1] = 0
A[2] = 0
A[3] = 1
A[4] = 1
A[5] = 0
A[6] = 1
A[7] = 0
A[8] = 0
A[9] = 0
A[10] = 0
The frog can make three jumps of length F(5) = 5, F(3) = 2 and F(5) = 5.
Write a function:
class Solution { public int solution(int[] A); }
that, given an array A consisting of N integers, returns the minimum number of jumps by which the frog can get to the other side of the river. If the frog cannot reach the other side of the river, the function should return −1.
For example, given:
A[0] = 0
A[1] = 0
A[2] = 0
A[3] = 1
A[4] = 1
A[5] = 0
A[6] = 1
A[7] = 0
A[8] = 0
A[9] = 0
A[10] = 0
the function should return 3, as explained above.
Assume that:
N is an integer within the range [0..100,000];
each element of array A is an integer that can have one of the following values: 0, 1.
Complexity:
expected worst-case time complexity is O(N*log(N));
expected worst-case space complexity is O(N) (not counting the storage required for input arguments).
I wrote the following solution,
class Solution {
private class Jump {
int position;
int number;
public int getPosition() {
return position;
}
public int getNumber() {
return number;
}
public Jump(int pos, int number) {
this.position = pos;
this.number = number;
}
}
public int solution(int[] A) {
int N = A.length;
List<Integer> fibs = getFibonacciNumbers(N + 1);
Stack<Jump> jumps = new Stack<>();
jumps.push(new Jump(-1, 0));
boolean[] visited = new boolean[N];
while (!jumps.isEmpty()) {
Jump jump = jumps.pop();
int position = jump.getPosition();
int number = jump.getNumber();
for (int fib : fibs) {
if (position + fib > N) {
break;
} else if (position + fib == N) {
return number + 1;
} else if (!visited[position + fib] && A[position + fib] == 1) {
visited[position + fib] = true;
jumps.add(new Jump(position + fib, number + 1));
}
}
}
return -1;
}
private List<Integer> getFibonacciNumbers(int N) {
List<Integer> list = new ArrayList<>();
for (int i = 0; i < 2; i++) {
list.add(i);
}
int i = 2;
while (list.get(list.size() - 1) <= N) {
list.add(i, (list.get(i - 1) + list.get(i - 2)));
i++;
}
for (i = 0; i < 2; i++) {
list.remove(i);
}
return list;
}
public static void main(String[] args) {
int[] A = new int[11];
A[0] = 0;
A[1] = 0;
A[2] = 0;
A[3] = 1;
A[4] = 1;
A[5] = 0;
A[6] = 1;
A[7] = 0;
A[8] = 0;
A[9] = 0;
A[10] = 0;
System.out.println(solution(A));
}
}
However, while the correctness seems good, the performance is not high enough. Is there a bug in the code and how do I improve the performance?
Got 100% with simple BFS:
public class Jump {
int pos;
int move;
public Jump(int pos, int move) {
this.pos = pos;
this.move = move;
}
}
public int solution(int[] A) {
int n = A.length;
List < Integer > fibs = fibArray(n + 1);
Queue < Jump > positions = new LinkedList < Jump > ();
boolean[] visited = new boolean[n + 1];
if (A.length <= 2)
return 1;
for (int i = 0; i < fibs.size(); i++) {
int initPos = fibs.get(i) - 1;
if (A[initPos] == 0)
continue;
positions.add(new Jump(initPos, 1));
visited[initPos] = true;
}
while (!positions.isEmpty()) {
Jump jump = positions.remove();
for (int j = fibs.size() - 1; j >= 0; j--) {
int nextPos = jump.pos + fibs.get(j);
if (nextPos == n)
return jump.move + 1;
else if (nextPos < n && A[nextPos] == 1 && !visited[nextPos]) {
positions.add(new Jump(nextPos, jump.move + 1));
visited[nextPos] = true;
}
}
}
return -1;
}
private List < Integer > fibArray(int n) {
List < Integer > fibs = new ArrayList < > ();
fibs.add(1);
fibs.add(2);
while (fibs.get(fibs.size() - 1) + fibs.get(fibs.size() - 2) <= n) {
fibs.add(fibs.get(fibs.size() - 1) + fibs.get(fibs.size() - 2));
}
return fibs;
}
You can apply knapsack algorithms to solve this problem.
In my solution I precomputed fibonacci numbers. And applied knapsack algorithm to solve it. It contains duplicate code, did not have much time to refactor it. Online ide with the same code is in repl
import java.util.*;
class Main {
public static int solution(int[] A) {
int N = A.length;
int inf=1000000;
int[] fibs={1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181, 6765, 10946, 17711, 28657, 46368, 75025};
int[] moves = new int[N+1];
for(int i=0; i<=N; i++){
moves[i]=inf;
}
for(int i=0; i<fibs.length; i++){
if(fibs[i]-1<N && A[fibs[i]-1]==1){
moves[ fibs[i]-1 ] = 1;
}
if(fibs[i]-1==N){
moves[N] = 1;
}
}
for(int i=0; i<N; i++){
if(A[i]==1)
for(int j=0; j<fibs.length; j++){
if(i-fibs[j]>=0 && moves[i-fibs[j]]!=inf && moves[i]>moves[i-fibs[j]]+1){
moves[i]=moves[i-fibs[j]]+1;
}
}
System.out.println(i + " => " + moves[i]);
}
for(int i=N; i<=N; i++){
for(int j=0; j<fibs.length; j++){
if(i-fibs[j]>=0 && moves[i-fibs[j]]!=inf && moves[i]>moves[i-fibs[j]]+1){
moves[i]=moves[i-fibs[j]]+1;
}
}
System.out.println(i + " => " + moves[i]);
}
if(moves[N]==inf) return -1;
return moves[N];
}
public static void main(String[] args) {
int[] A = new int[4];
A[0] = 0;
A[1] = 0;
A[2] = 0;
A[3] = 0;
System.out.println(solution(A));
}
}
Javascript 100%
function solution(A) {
function fibonacciUntilNumber(n) {
const fib = [0,1];
while (true) {
let newFib = fib[fib.length - 1] + fib[fib.length - 2];
if (newFib > n) {
break;
}
fib.push(newFib);
}
return fib.slice(2);
}
A.push(1);
const fibSet = fibonacciUntilNumber(A.length);
if (fibSet.includes(A.length)) return 1;
const reachable = Array.from({length: A.length}, () => -1);
fibSet.forEach(jump => {
if (A[jump - 1] === 1) {
reachable[jump - 1] = 1;
}
})
for (let index = 0; index < A.length; index++) {
if (A[index] === 0 || reachable[index] > 0) {
continue;
}
let minValue = 100005;
for (let jump of fibSet) {
let previousIndex = index - jump;
if (previousIndex < 0) {
break;
}
if (reachable[previousIndex] > 0 && minValue > reachable[previousIndex]) {
minValue = reachable[previousIndex];
}
}
if (minValue !== 100005) {
reachable[index] = minValue + 1;
}
}
return reachable[A.length - 1];
}
Python 100% answer.
For me the easiest solution was to locate all leaves within one fib jump of -1. Then consider each of these leaves to be index[0] and find all jumps from there.
Each generation or jump is recorded in a set until a generation contains len(A) or no more jumps can be found.
def gen_fib(n):
fn = [0,1]
i = 2
s = 2
while s < n:
s = fn[i-2] + fn[i-1]
fn.append(s)
i+=1
return fn
def new_paths(A, n, last_pos, fn):
"""
Given an array A of len n.
From index last_pos which numbers in fn jump to a leaf?
returns list: set of indexes with leaves.
"""
paths = []
for f in fn:
new_pos = last_pos + f
if new_pos == n or (new_pos < n and A[new_pos]):
paths.append(new_pos)
return path
def solution(A):
n = len(A)
if n < 3:
return 1
# A.append(1) # mark final jump
fn = sorted(gen_fib(100000)[2:]) # Fib numbers with 0, 1, 1, 2.. clipped to just 1, 2..
# print(fn)
paths = set([-1]) # locate all the leaves that are one fib jump from the start position.
jump = 1
while True:
# Considering each of the previous jump positions - How many leaves from there are one fib jump away
paths = set([idx for pos in paths for idx in new_paths(A, n, pos, fn)])
# no new jumps means game over!
if not paths:
break
# If there was a result in the new jumps record that
if n in paths:
return jump
jump += 1
return -1
https://app.codility.com/demo/results/training4GQV8Y-9ES/
https://github.com/niall-oc/things/blob/master/codility/fib_frog.py
Got 100%- solution in C.
typedef struct state {
int pos;
int step;
}state;
int solution(int A[], int N) {
int f1 = 0;
int f2 = 1;
int count = 2;
// precalculating count of maximum possible fibonacci numbers to allocate array in next loop. since this is C language we do not have flexible dynamic structure as in C++
while(1)
{
int f3 = f2 + f1;
if(f3 > N)
break;
f1 = f2;
f2 = f3;
++count;
}
int fib[count+1];
fib[0] = 0;
fib[1] = 1;
int i = 2;
// calculating fibonacci numbers in array
while(1)
{
fib[i] = fib[i-1] + fib[i-2];
if(fib[i] > N)
break;
++i;
}
// reversing the fibonacci numbers because we need to create minumum jump counts with bigger jumps
for(int j = 0, k = count; j < count/2; j++,k--)
{
int t = fib[j];
fib[j] = fib[k];
fib[k] = t;
}
state q[N];
int front = 0 ;
int rear = 0;
q[0].pos = -1;
q[0].step = 0;
int que_s = 1;
while(que_s > 0)
{
state s = q[front];
front++;
que_s--;
for(int i = 0; i <= count; i++)
{
int nextpo = s.pos + fib[i];
if(nextpo == N)
{
return s.step+1;
}
else if(nextpo > N || nextpo < 0 || A[nextpo] == 0){
continue;
}
else
{
q[++rear].pos = nextpo;
q[rear].step = s.step + 1;
que_s++;
A[nextpo] = 0;
}
}
}
return -1;
}
//100% on codility Dynamic Programming Solution. https://app.codility.com/demo/results/training7WSQJW-WTX/
class Solution {
public int solution(int[] A) {
int n = A.length + 1;
int dp[] = new int[n];
for(int i=0;i<n;i++) {
dp[i] = -1;
}
int f[] = new int[100005];
f[0] = 1;
f[1] = 1;
for(int i=2;i<100005;i++) {
f[i] = f[i - 1] + f[i - 2];
}
for(int i=-1;i<n;i++) {
if(i == -1 || dp[i] > 0) {
for(int j=0;i+f[j] <n;j++) {
if(i + f[j] == n -1 || A[i+f[j]] == 1) {
if(i == -1) {
dp[i + f[j]] = 1;
} else if(dp[i + f[j]] == -1) {
dp[i + f[j]] = dp[i] + 1;
} else {
dp[i + f[j]] = Math.min(dp[i + f[j]], dp[i] + 1);
}
}
}
}
}
return dp[n - 1];
}
}
Ruby 100% solution
def solution(a)
f = 2.step.inject([1,2]) {|acc,e| acc[e] = acc[e-1] + acc[e-2]; break(acc) if acc[e] > a.size + 1;acc }.reverse
mins = []
(a.size + 1).times do |i|
next mins[i] = -1 if i < a.size && a[i] == 0
mins[i] = f.inject(nil) do |min, j|
k = i - j
next min if k < -1
break 1 if k == -1
next min if mins[k] < 0
[mins[k] + 1, min || Float::INFINITY].min
end || -1
end
mins[a.size]
end
I have translated the previous C solution to Java and find the performance is improved.
import java.util.*;
class Solution {
private static class State {
int pos;
int step;
public State(int pos, int step) {
this.pos = pos;
this.step = step;
}
}
public static int solution(int A[]) {
int N = A.length;
int f1 = 0;
int f2 = 1;
int count = 2;
while (true) {
int f3 = f2 + f1;
if (f3 > N) {
break;
}
f1 = f2;
f2 = f3;
++count;
}
int[] fib = new int[count + 1];
fib[0] = 0;
fib[1] = 1;
int i = 2;
while (true) {
fib[i] = fib[i - 1] + fib[i - 2];
if (fib[i] > N) {
break;
}
++i;
}
for (int j = 0, k = count; j < count / 2; j++, k--) {
int t = fib[j];
fib[j] = fib[k];
fib[k] = t;
}
State[] q = new State[N];
for (int j = 0; j < N; j++) {
q[j] = new State(-1,0);
}
int front = 0;
int rear = 0;
// q[0].pos = -1;
// q[0].step = 0;
int que_s = 1;
while (que_s > 0) {
State s = q[front];
front++;
que_s--;
for (i = 0; i <= count; i++) {
int nextpo = s.pos + fib[i];
if (nextpo == N) {
return s.step + 1;
}
//
else if (nextpo > N || nextpo < 0 || A[nextpo] == 0) {
continue;
}
//
else {
q[++rear].pos = nextpo;
q[rear].step = s.step + 1;
que_s++;
A[nextpo] = 0;
}
}
}
return -1;
}
}
JavaScript with 100%.
Inspired from here.
function solution(A) {
const createFibs = n => {
const fibs = Array(n + 2).fill(null)
fibs[1] = 1
for (let i = 2; i < n + 1; i++) {
fibs[i] = fibs[i - 1] + fibs[i - 2]
}
return fibs
}
const createJumps = (A, fibs) => {
const jumps = Array(A.length + 1).fill(null)
let prev = null
for (i = 2; i < fibs.length; i++) {
const j = -1 + fibs[i]
if (j > A.length) break
if (j === A.length || A[j] === 1) {
jumps[j] = 1
if (prev === null) prev = j
}
}
if (prev === null) {
jumps[A.length] = -1
return jumps
}
while (prev < A.length) {
for (let i = 2; i < fibs.length; i++) {
const j = prev + fibs[i]
if (j > A.length) break
if (j === A.length || A[j] === 1) {
const x = jumps[prev] + 1
const y = jumps[j]
jumps[j] = y === null ? x : Math.min(y, x)
}
}
prev++
while (prev < A.length) {
if (jumps[prev] !== null) break
prev++
}
}
if (jumps[A.length] === null) jumps[A.length] = -1
return jumps
}
const fibs = createFibs(26)
const jumps = createJumps(A, fibs)
return jumps[A.length]
}
const A = [0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0]
console.log(A)
const s = solution(A)
console.log(s)
You should use a QUEUE AND NOT A STACK. This is a form of breadth-first search and your code needs to visit nodes that were added first to the queue to get the minimum distance.
A stack uses the last-in, first-out mechanism to remove items while a queue uses the first-in, first-out mechanism.
I copied and pasted your exact code but used a queue instead of a stack and I got 100% on codility.
100% C++ solution
More answers in my github
Inspired from here
Solution1 : Bottom-Top, using Dynamic programming algorithm (storing calculated values in an array)
vector<int> getFibonacciArrayMax(int MaxNum) {
if (MaxNum == 0)
return vector<int>(1, 0);
vector<int> fib(2, 0);
fib[1] = 1;
for (int i = 2; fib[fib.size()-1] + fib[fib.size() - 2] <= MaxNum; i++)
fib.push_back(fib[i - 1] + fib[i - 2]);
return fib;
}
int solution(vector<int>& A) {
int N = A.size();
A.push_back(1);
N++;
vector<int> f = getFibonacciArrayMax(N);
const int oo = 1'000'000;
vector<int> moves(N, oo);
for (auto i : f)
if (i - 1 >= 0 && A[i-1])
moves[i-1] = 1;
for (int pos = 0; pos < N; pos++) {
if (A[pos] == 0)
continue;
for (int i = f.size()-1; i >= 0; i--) {
if (pos + f[i] < N && A[pos + f[i]]) {
moves[pos + f[i]] = min(moves[pos]+1, moves[pos + f[i]]);
}
}
}
if (moves[N - 1] != oo) {
return moves[N - 1];
}
return -1;
}
Solution2: Top-Bottom using set container:
#include <set>
int solution2(vector<int>& A) {
int N = A.size();
vector<int> fib = getFibonacciArrayMax(N);
set<int> positions;
positions.insert(N);
for (int jumps = 1; ; jumps++)
{
set<int> new_positions;
for (int pos : positions)
{
for (int f : fib)
{
// return jumps if we reach to the start point
if (pos - (f - 1) == 0)
return jumps;
int prev_pos = pos - f;
// we do not need to calculate bigger jumps.
if (prev_pos < 0)
break;
if (prev_pos < A.size() && A[prev_pos])
new_positions.insert(prev_pos);
}
}
if (new_positions.size() == 0)
return -1;
positions = new_positions;
}
return -1;
}

Why doesn't my program run correctly?

for my school project I have to create a program that outputs perfect numbers based on how many perfect numbers the user(teacher) want. The user can pick any number from 1-4 and it should display however many number the user chooses. Here is my current code. Please ignore the sumupTo, factorial, isprime, and the testGoldbach methods, please only look at the Perfect numbers method/code.
import java.util.Scanner;
public class MyMathB
{
public static int sumUpTo(int n)
{
int sum = 0;
for (int k = 1; k <= n; k++)
sum += k;
return sum;
}
public static long factorial(int n)
{
long f = 1;
for (int k = 2; k <= n; k++)
f *= k;
return f;
}
public static boolean isPrime(int n)
{
if (n <= 1)
return false;
int m = 2;
while (m * m <= n)
{
if (n % m == 0)
return false;
m++;
}
return true;
}
public static void PerfectNumbers(int number)
{
System.out.println("How many perfect numbers would you like to see? Please enter an integer from 1 to 4");
Scanner s = new Scanner(System.in);
int numbersToSee = s.nextInt();
int counts = 0;
for(counts = 0; counts <= numbersToSee; counts++)
{
for (int n = 5; n <= 10000; n++)
{
int temp = 0;
for(int i = 1; i <= number / 2; i++)
{
if (number % i == 0)
{
temp += i;
}
if (temp == number)
{
System.out.println(number);
}
}
}
}
}
public static boolean testGoldbach(int bigNum)
{
for (int n = 6; n <= bigNum; n += 2)
{
boolean found2primes = false;
for (int p = 3; p <= n/2; p += 2)
{
if (isPrime(p) && isPrime(n - p))
found2primes = true;
}
if (!found2primes)
{
System.out.println(n + " is not a sum of two primes!");
return false;
}
}
return true;
}
public static void main(String[] args)
{
Scanner kb = new Scanner(System.in);
int n;
do
{
System.out.print("Enter an integer from 4 to 20: ");
n = kb.nextInt();
} while (n < 4 || n > 20);
kb.close();
System.out.println();
System.out.println("1 + ... + " + n + " = " + sumUpTo(n));
System.out.println(n + "! = " + factorial(n));
System.out.println("Primes: ");
for (int k = 1; k <= n; k++)
if (isPrime(k))
System.out.print(k + " ");
System.out.println();
System.out.println("Goldbach conjecture up to " + n + ": " + testGoldbach(n));
}
}
you didn't declare the variable "number" in your method.
Edit: you didn't SET the variable number to anything, I misworded my last statement.

Prime Number in java

I wrote some code to find prime numbers up to a given number. Could you guys let me know ways to make my code more efficient or better? Or give insight on how I did? In addition, there is a problem in my code where certain numbers repeats twice or three times in a pattern. How do I fix this?
public class PrimeNumber2 {
public static void main(String[] args)
{
int max_prime = 10000;
for(int i = 3; i < max_prime; i+=2)
{
for(int j = 1; j < Math.sqrt(i); j++)
{
if(i % j == 0)
{
System.out.println(i);
}
}
}
}
}
Have a look at:
https://en.wikipedia.org/wiki/Sieve_of_Eratosthenes
This is quite a nice way of doing it.
Here is some code for you to look at:
public void runEratosthenesSieve(int upperBound) {
int upperBoundSquareRoot = (int) Math.sqrt(upperBound);
boolean[] isComposite = new boolean[upperBound + 1];
for (int m = 2; m <= upperBoundSquareRoot; m++) {
if (!isComposite[m]) {
System.out.print(m + " ");
for (int k = m * m; k <= upperBound; k += m)
isComposite[k] = true;
}
}
for (int m = upperBoundSquareRoot; m <= upperBound; m++) {
if (!isComposite[m]) {
System.out.print(m + " ");
}
}
Here´s a tuned version of yours.
I did put the check if the number is prime into a seperate method. That´s also a part of the reason why your version did print values multiple times, since if it found out that it has a divisor, then it would print the values. (Also you´r algorythm would print basicly everything despite it beeing prime or not, for example it prints 15 and 27).
The reason why it did print multiple values was, that once you found a divisor it would have printed i, but it would continue looping. If it would have found another divisor, it would print i again(you can notice that it does not only print prime numbers).
Here is the fixed version of your´s
public static void main(String[] args) {
if(isPrime(2)) {
System.out.println(2);
}
int max_prime = 10000;
for(int i = 3; i < max_prime; i+=2)
{
if(isPrime(i)) {
System.out.println(i);
}
}
}
private static boolean isPrime(int n) {
if(n<=1) return false;
if(n == 2) return true;
for(int i = 2;i*i<=n;++i) {
if(n%i == 0) return false;
}
return true;
}
Try this.
public class PrimeNumber2 {
public static void main(String[] args)
{
int max_prime = 10000;
System.out.println(2);
L: for (int i = 3; i < max_prime; i += 2)
{
for (int j = 3, max = (int)Math.sqrt(i); j <= max ; j += 2)
{
if(i % j == 0)
{
continue L;
}
}
System.out.println(i);
}
}
}
Here a way using parallelStream
System.out.println(2);
IntStream.range(1, 10000000)
.map(i -> i * 2 + 1)
.filter(i -> (i & 1) != 0 && IntStream.range(1, (int) (Math.sqrt(i)-1)/2)
.map(j -> j * 2 + 1)
.noneMatching(j -> i % j == 0)
.forEach(System.out::println);
Note: the ranges test the n-th odd number.
public static void main(String[] args) {
int upperBound = 30;
List<Integer> primes = new ArrayList<>();
// loop through the numbers one by one
for (int number = 2; number < upperBound; number++) {
boolean isPrimeNumber = true;
// check to see if the number is prime
for (int j = 2; j < number; j++) {
if (number % j == 0) {
isPrimeNumber = false;
break; // exit the inner for loop
}
}
// print the number if prime
if (isPrimeNumber) {
primes.add(number);
}
}
System.out.println("The number of prime is: " + primes.size() + ", and they are: " + primes.toString());
}
possible to dupplicate
get prime numbers and total prime numbers in range
public boolean isPrimeNumber(int number) {
for (int i=2; i<=number/2; i++) {
if (number % i == 0) {
return false;
}
}
return true;
}

beginner whats wrong with my method

public class assignment6part3 {
public static void main(String[] args) {
int q = 0;
for ( int count=1; count <= 10000; count++) {
if (Prime(count)) {
q = q + 1;
}
}
System.out.println("It comes out " + q + " times.");
}
public static boolean Prime(int n) {
if (n <= 1) {
return false;
}
for (int i = 1; i < Math.sqrt(n); i++) {
if (n % i == 0) {
return false;
}
}
return true;
}
}
I'm trying to get the number of prime numbers between 0 and 10000, but when I run this, it says there are 0 prime numbers. What part of the code is causing this error?
Inside your function Prime your for loop runs like ::
for(int i = 1; i < Math.sqrt(n); i++), starting from i = 1 and every number is divisible by 1 and hence 0 prime numbers.. :P
Initialization condition for i shall be i = 2
Other things you might consider changing ::
for (int i = 1; i < Math.sqrt(n); i++) shall be changed to
for (int i = 1; i <= Math.sqrt(n); i++)
NOTE :: A more optimal way to find Primes would be https://en.wikipedia.org/wiki/Sieve_of_Eratosthenes
The code is returning false before it actually checks the numbers, because every number is divisible by 1. Also, in some cases such as 25 and 49, the factors are not less than the square root. Try this:
for (int i = 2; i <= Math.sqrt(n); i++) {
if (n % i == 0) {
return false;
}
}

Perfect Number program java

I am supposed to create a perfect number class using the following pseudocode:
For i from 2 to “very large”,
For j from 2 to √i,
if (j evenly divides i),
accumulate the sum j and i/j
if √i is an integer
subtract √i ... you added it twice
if the sum of divisors == i
Print the number ... it’s perfect!
So here is my version. It runs, but it doesn't do what I want at all. It just runs and produces nothing as an output. Can someone tell me what is wrong with my program? It's bothering me so much.
import java.util.Scanner;
public class PerfectNumber {
public static void main(String[] args) {
double sum = 0
double newsum = 0;
for (int i = 2; i < 1000000; i++) {
for (int j = 2; i<Math.sqrt(i); j++){
if (i%j==0){
sum = j + (i%j);
}
if (Math.sqrt(i)==(int)i){
newsum = sum - Math.sqrt(i);
}
if (sum == 0) {
System.out.println(sum + "is a perfect number");
}
}
}
}
}
Few mistakes according to the algorithm:
sum = j + (i%j); should be changed to sum = j + (i/j);
This piece:
if (Math.sqrt(i)==(int)i){
newsum = sum - Math.sqrt(i);
}
if (sum == 0) {
System.out.println(sum + "is a prime number");
}
Should be under upper "for"
Math.sqrt(i)==(int)i would never be true unless i is 1. If you want to check this that way you should write Math.sqrt(i)==((int) Math.sqrt(i))
There are much more errors, the simplest way to do it is:
double sum = 0;
for (int i = 1; i <= 10000; i++) {
for (int j = 1; j < i; j++) {
if (i % j == 0) {
sum += j;
}
}
if (i == sum) {
System.out.println(sum + " is a prime number");
}
sum = 0;
}
Your code contains several mistakes. Here is the corrected code, commented with the changes.
// newsum isn't needed; declare sum to be int to avoid floating-point errors
int sum = 0;
for (int i = 2; i < 1000000; i++) {
// Start with 1; every natural number has 1 as a factor.
sum = 1;
// Test if j, not i, is less than the square root of i.
for (int j = 2; j <= Math.sqrt(i); j++){
if (i % j == 0){
// Add to sum; don't replace sum. Use i / j instead of i % j.
sum = sum + j + (i / j);
// Move test inside this if; test if j is square root of i
if (j*j == i){
// I used j because we know it's the square root already.
sum = sum - j;
}
}
// Move print outside of inner for loop to prevent multiple
// printings of a number.
// Test if sum equals the number being tested, not 0.
if (sum == i) {
// Space before is
System.out.println(sum + " is a perfect number");
}
}
}
Output:
6 is a perfect number
28 is a perfect number
496 is a perfect number
8128 is a perfect number
public static void main(String[] args){
int min = 2;
int max = 1000000;
int sum = 0;
for (; min <= max; min++,sum = 0) {
for (int e = 1; e < min; e++)
sum += ((min % e) == 0) ? e : 0;
if (sum == min){
System.out.println(sum);
}
}
}
for(n=1;n<=number;n++){ //calculates the sum of the number.
int i=1;
int sum = 0;
while(i<n){
if(n%i==0)
sum+=i;
i++;
}
if(sum==n){ //if the sum is equal to its sum :
System.out.print(n+": ");
for (int j = 1;j<n;j++){
if(n%j==0){
System.out.print(j+" ");
}
}
System.out.println();
}
}
Here is the simplest and easiest form you can write a program for perfect number....this code gives perfect number within 25 ...you can change as you want
import java.util.Scanner;
public class PerfectNumber {
public static void main(String[] args) {
int n,i,j,count=0;
for(i=2;i<=25;i++) {
for(j=1;j<=i;j++) {
if(i%j ==0) /*count increments if a reminder zero*/ {
count++;
}
}
/*since a perfect number is divided only by 1 and itself
if the count is 2 then its a prime number...*/
if(count==2)
System.out.println(i);
count=0;
}
return 0;
}
}
According to the pseudocode you want to move the second and third if test outside of the inner loop
for (int i = 2; i < 1000000; i++) {
double iroot = Math.sqrt(i);
int sum = 1;
for (int j = 2; j <= iroot; j++){
if (i % j == 0){
sum = sum + j + i / j;
}
}
if (iroot == (int) iroot) {
sum = sum - iroot;
}
if (sum == i) {
System.out.println(sum + "is a perfect number");
}
}
Thanks for watched
public boolean testPerfect(int n){
int i=1;
int sum=0;
while(i<n){
if(n%i==0)
{
sum+=i++;
}
else{
i++;}
}
if (sum==n){
return true;
}
return false;
}

Categories

Resources