I am writing one java program. Arthur defines a function f(k) to be the number of (p,q) pairs such that:
1< p <= q <= k
p and q are coprimes
p.q=k
I am supposed to write one program for a given integer n and help Arthur find and print the result of (Σ k=1 to n) f(k)
Constraints:
1<=n<=pow(10,9)
For e.g
(Input)Let's say n = 12
For the value of f(k) for 1<=k<=12
For k=6 there is one valid pair (2,3), so f(6) = 1
For k=10 there is one valid pair (2,5), so f(10) = 1
For k=12 there is one valid pair (3,4), so f(12) = 1
For all other 1<=k<=12 the function return 0
So, other final sum is the result of 1+1+1 = 3 (Final output)
Here is my code:
import java.util.Scanner;
class ArthurFunction{
public static boolean areCoPrime(int a, int b){
int max = 0;
boolean flag = true;
if(a>=b)
max = a;
else
max = b;
for(int i=2;i<=max;i++)
if((a%i==0)&&(b%i==0))
flag = false;
return flag;
}
public static void main(String[] args){
Scanner scan = new Scanner(System.in);
int n = scan.nextInt();
int sum = 0;
for(int k = 1;k<=n;k++){
for(int p=2;p<=k;p++){
for(int q=2;q<=k;q++){
if(areCoPrime(p,q)&&(p*q==k)&&(p<=q))
sum+=sum;
}
}
}
System.out.println(sum);
}
}
When I run this code the output should be 3 but I am getting 0 and also unable to find the solution.
You can improve your program by
Making a faster areCoPrime() method
Decrease the number of nested loops in main()
For (1), we know 2 numbers are coprime when their greatest common divisor (GCD) is 1. Their is an efficient method to find GCD called Euclidean algorithm.
For (2), you can remove the 3rd loop, p in the 2nd loop only need to go to sqrt(k)
Refer to my revised code below (Tested: n = pow(10,6) runs less than 2 secs on my PC)
import java.util.Scanner;
class ArthurFunction{
public static boolean areCoPrime(int a, int b){
if (GCD(a,b)==1) return true;
return false;
}
public static int GCD(int a, int b) {
if (b==0) return a;
return GCD(b,a%b);
}
public static void main(String[] args){
Scanner scan = new Scanner(System.in);
int n = scan.nextInt();
int sum = 0;
for(int k=1;k<=n;k++){
for(int p=2;p*p<k;p++){
if(k%p==0) {
int q = k/p;
if (areCoPrime(p,q)) sum++;
}
}
}
System.out.println(sum);
}
}
Related
Ok so I been working on this assignment all day for the past 3 days but I haven't had any luck. I wasn't going to ask for help but I finally gave up. But there is also one more thing I need to implement to the code. This is what I gotta implement "Find the length of the longest continuous series of positive numbers in the array data. If the contents were: 4 5 0 2 . . . -1 88 78 66 -6. The length would be 3. For this problem, 0 is considered non-negative but not positive". Plus I have an issue where I can't print the largest int in the array of 20.
import java.util.Random;
import java.util.ArrayList;
public class arrayops {
public static int findLargest(ArrayList<Integer> nums) {
int greatestnum = nums.get(0);
for (Integer item : nums) {
if (item > greatestnum) {
greatestnum = item;
}
}
return greatestnum;
}
public static int randomData(ArrayList<Integer> nums) {
int[] array = new int [20];
Random random = new Random();
for (int i = 0; i < array.length; i++) {
array[i] = -100 + random.nextInt(201);
}
return -100 + random.nextInt(201);
}
public static void main(String[] args) {
ArrayList<Integer> nums = new ArrayList<Integer>();
nums.add(1);
nums.add(4);
nums.add(13);
nums.add(43);
nums.add(-25);
nums.add(17);
nums.add(22);
nums.add(-37);
nums.add(29);
System.out.println("The Greatest Number from the hardcoded numbers " + findLargest(nums));
System.out.println("The Greatest number from the random numbers " + randomData(nums));
}
}
The findLargest method:
public static int findLargest(ArrayList<Integer> nums) {
int greatestnum = 0;
int greatestLen = 0;
for (Integer item : nums) {
if (item > 0) {
greatestLen++ ;
if(greatestLen > greatestnum)
greatestnum = greatestLen;
}
else
greatestLen = 0;
}
return greatestnum;
}
Logic used:
Keep the length of the longest chain encountered, and the length of current chain, in two separate variables (greatestnum and greatestLen respectively)
Increment greatestLen every time a positive number is encountered. If the number if less than or equal to zero, reset this count.
If the length of current chain is greater than the previous longest chain, sent the longest chain size to current chain size.
The problem is you created a list with random numbers but never put that list into the findLargest method. You also never created a method to find the consecutive positive numbers. If you didn't know how to go about coding it, I recommend drawing out an algorithm on paper.
Largest value in ArrayList...
public static int findL(ArrayList<Integer> nums)
{
int top = nums.get(0);
for(int i = 0; i<nums.size(); i++)
{
if(nums.get(i)>top)
{
top = nums.get(i);
}
}
return top;
}
Largest number of consecutive positives...
public static int positiveString(ArrayList<Integer> nums)
{
int longest = 0;
int count = 0;
for(int i = 0; i<nums.size(); i++)
{
if(nums.get(i) > 0)
{
count++;
}
else
{
if(longest<count)
{
longest = count;
}
count = 0;
}
}
return longest;
}
If you want to arrange the numbers into order you can simply use java.util.TreeSet. Then use the method last() to get the largest number.
public static int findLargest(ArrayList<Integer> nums) {
return new TreeSet<Integer>(nums).last();
}
I've been working on this code for class that needs to find the users desired number of palindromic prime numbers. Everything works fine when I have the while(primeCounter < desiredNumPrimes) except that it outputs one less than the desired number of prime numbers. I attempt to correct this by having the while statement be "<=" instead, but then I get an Array Index Out Of Bounds Exception. As you can see, I even check to make sure that the index of the array is not less that the index I am attempting to use in the if statement
Any help is appreciated.
import java.util.Scanner;
public class PalPrimes
{
public static void main(String [] args){
Scanner scan = new Scanner(System.in);
int primeCounter=1, numberToCheck=2; //start checking at 2 because primes >1
System.out.println("Please enter the desired number of palindromic primes");
int desiredNumPrimes = scan.nextInt();
int[] palPrimes = new int[desiredNumPrimes-1];
System.out.print(palPrimes.length);
//find palindromic primes
while(primeCounter<desiredNumPrimes){
if(isPrime(numberToCheck)==true && isPalindrome(numberToCheck)==true){
palPrimes[primeCounter-1]= numberToCheck;
numberToCheck++;
primeCounter++;
}
else{
numberToCheck++;
}
}
//display palindromic primes
if(primeCounter==desiredNumPrimes){
for(int i = 0; i<palPrimes.length; i++){
if(i%10==0){
System.out.println();
}
System.out.print(palPrimes[i] + " ");
}
}
}
//Check if number is a prime
public static boolean isPrime(int num){
if(num == 2){
return true;
}
for( int divisor = 2; divisor <= num/2; divisor++){
if (num % divisor ==0){
return false;
}
}
return true;
}
//reverse number to begin testing if palindrome
public static int reverse(int num){
int testNum = 0;
while(num !=0){
int lastDigit = num%10;
testNum = testNum*10+lastDigit;
num = num/10;
}
return testNum;
}
//Check if number is a palindrome
public static boolean isPalindrome( int num){
return num == reverse(num);
}
}
The issues are with initializations. The below 3 changes will resolve the issue. You are getting arrayindexoutofbounds since you are trying to change only the initialization but not the assignment
int primeCounter with 0
int[] palPrimes = new int[desiredNumPrimes];
palPrimes[primeCounter]= numberToCheck;
Start the prime counter at 0 as you haven't found any primes yet.
int primeCounter=0, numberToCheck=2;
You're making the size of palPrimes 1 less than the desired number of primes, so it will never be able to contain the desired number of primes. Instead, make it
int[] palPrimes = new int[desiredNumPrimes];
Then, you check for palPrimes[primeCounter-1] = numberToCheck;
Seeing as we started the counter at 0, this should be changed to:
palPrimes[primeCounter] = numberToCheck;
And the program should work.
How would i prevent duplicating numbers from random numbers.
I need to generate 5 numbers between 1 and 9 that are each different.
I would often get same numbers like 23334, how can i prevent that?
Any help would be great!
int num2 = (int) Math.round((Math.random()*9) +1);
int num1 = (int) Math.round((Math.random()*9) +1);
int num5 = (int) Math.round((Math.random()*9) +1);
int num3 = (int) Math.round((Math.random()*9) +1);
int num4 = (int) Math.round((Math.random()*9) +1);
One option is to use shuffle algorithm (e.g. Fisher-Yates shuffle ) to generate random sequence from 1 to 9, then take first 5 numbers of the sequence
Further explanation on StackOverflow: https://stackoverflow.com/a/196065/950427
Set<Integer> set=new HashSet<>();
while (set.size()<5) {
set.add( Math.round((Math.random()*9) +1));
}
After the set is filled you have 5 unique random numbers.
UPDATE: just to illustrate Jared Burrows' comment
Create a List includes the numbers that you want (1 to 9).
Generate random number from 0 to (size of the list minus 1).
Remove one element by index from the above generated random number. And add the removed element to a array which to be returned as a results
public static void main(String[] args) {
int []answers= returnRandomNonRepeatingNumbers(5,0,9);
for(int answer: answers) {
System.out.println(answer);
}
}
public static int[] returnRandomNonRepeatingNumbers(int sizeYouWant, int poolStart, int poolEnd) {
List<Integer> pool=new ArrayList<Integer>();
for(int i=poolStart;i<=poolEnd;i++) {
pool.add(i);
}
int []answers=new int[sizeYouWant];
for(int i=0;i<sizeYouWant;i++) {
//random index to be pick and remove from pool
int randomIndex = (int) Math.round((Math.random()*(pool.size()-1)));
answers[i]=pool.remove(randomIndex);
}
return answers;
}
If the number of possible random values is small, you want to use shuffle.
List<Integer> values = IntStream.range(0, 10).boxed().collect(toList());
Collections.shuffle(values);
values = values.subList(0, 5);
If the number of possible random values is large, you want to test adding them to a Set (or the original list if small enough)
Set<Integer> valueSet = new HashSet<>();
Random rand = new Random();
while(valuesSet.size() < 5) valuesSet.add(rand.nextInt(9) + 1);
List<Integer> values = new ArrayList<>(valueSet);
Collections.shuffle(values, rand);
Note: you need to shuffle the set as it doesn't preserve order. e.g. the numbers 1,2,3 will always come out in that order with HashSet, not 3,2,1.
Floyd's subset selection algorithm is designed to do exactly what you want, and is extremely efficient even for large sets. Selecting m items from a set of n is O(m) average running time, independent of n. Here's a Java implementation.
/*
* Floyd's algorithm to chose a random subset of m integers
* from a set of n, zero-based.
*/
public static HashSet<Integer> generateMfromN(int m, int n) {
HashSet<Integer> s = new HashSet<Integer>();
for (int j = n-m; j < n; ++j) {
if(! s.add((int)((j+1) * Math.random()))) {
s.add(j);
}
}
return s;
}
One possible approach to this problem can be divide & conquer. Step of following describes the approach:
Say m is the minimum & n is the maximum, within what i wanna get x number of randoms
Choose a random p between m & n. Save it to an array of answer. decrease x by 1 as we get one answer to our problem.
Now take a q a random number between m & p-1, another r a random number between p+1 & n. Fill up the answer array with q & r decrease x 1 for q and another 1 for the r.
Now carry on this process recursively, until the lower bound (m) & higher bound (n) becomes equal or x becomes 0.
Benefit: benefit of this approach is that, in worst case, it's runtime will be O(x), where x is the number of random number required. The best case scenarion is also o(x), as i have to find at least n number of random. These two comprise average case to θ(x) complexity.
import java.util.Random;
class GenerateDistinctRandom{
static int alreadyPut = 0;
static Random rand = new Random();
public static int[] generateDistinctRandom(int howMany, int rangeMin, int rangeMax)
{
int randomNumbers[] = new int[howMany];
GenerateDistinctRandom.recursiveRandomGenerator(rangeMin, rangeMax, randomNumbers, howMany);
return randomNumbers;
}
private static void recursiveRandomGenerator(int rangeMin, int rangeMax, int[] storage ,int storageSize)
{
if(rangeMax - rangeMin <= 0 || GenerateDistinctRandom.alreadyPut == storageSize)
{
return ;
}
int randomNumber = GenerateDistinctRandom.rand.nextInt(rangeMax-rangeMin) + rangeMin;
storage[GenerateDistinctRandom.alreadyPut] = randomNumber;
GenerateDistinctRandom.alreadyPut++;
//calling the left side of the recursion
recursiveRandomGenerator(rangeMin, randomNumber - 1, storage, storageSize);
recursiveRandomGenerator(randomNumber + 1, rangeMax, storage, storageSize);
}
public static void main(String []args){
int howMany = 5;
int distinctNumber[] = GenerateDistinctRandom.generateDistinctRandom(howMany 0, 9);
for(int i = 0;i < howMany;i++)
{
System.out.println(distinctNumber[i]);
}
}
}
I suppose you would need to store the ones that have been generated into an array and compare the new random number to the list to ensure it is unique.
public static void main (String[] args) throws java.lang.Exception
{
// your code goes here
int[] numbers = new int[5];
int tempNumber = 0;
for(int numberCounter = 0; numberCounter < numbers.length;)
{
tempNumber = (int) Math.round((Math.random()*9) +1);
if(!contains(numbers, tempNumber)){
numbers[numberCounter++] = tempNumber;
}
}
}
public static boolean contains(final int[] numbersArray, final int tempNumber) {
for (final int numberFromArray : numbersArray) {
if (numberFromArray == tempNumber) {
return true;
}
}
return false;
}
I notice you did not use an array in your example, so in case you do not know how to use them yet, you could also make 5 variables.
int randomNumber = 0;
int firstNumber = Math.round((Math.random()*9) +1);
int secondNumber = 0;
while(secondNumber == 0){
randomNumber = Math.round((Math.random()*9) +1)l
if(randomNumber != firstNumber){
secondNumber = randomNumber;
}
}
And you could continue making while statements like that. But if you are supposed to know about arrays, you should definitely be using one to store the numbers.
How about this?
package com.se;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
public class TestRandom {
List<Integer> comp = new ArrayList<>();
int listSize = 20;
public void doTask() {
Random ran = new Random();
int i = 0;
while(i < listSize){
int randomNumber = ran.nextInt(80) + 1;
if(!comp.contains(randomNumber)){
comp.add(randomNumber);
i++;
}
}
for(Integer num : comp){
System.out.println(num);
}
}
public static void main(String[] args) {
TestRandom testRandom = new TestRandom();
testRandom.doTask();
}
}
My program is meant to take in file in the current format with the top number being the max length of the words, the second number being the number of words that are there, and the rest being the numbers to be sorted.
4
10
437 1807 3218 1791 9058 9322 766 9977 16 7143
And then sort it so from lowest to highest. But every time i try to get it working i generally get the highest number in the first spot and the rest is just a jumbled mess. The final three for loops where meant to resemble this pseudo code:
the first power of ten = 10;
for each i up to the maximum number of digits+1
1. for each value v in the array, starting at position 0:
a. isolate the “ith” digit from v (call this digit d) – use the current power
of ten to do this
b. add v to bin[d]
2. for each bin (that is, each bin[j], starting with j=0)
a. while bin[j] is not empty
i. remove the first value from bin[j] and copy it back into the next
position in the array
3. Increase the power of ten to the next power of ten
Any help would be appreciated.
import java.io.*;
import java.util.*;
public class BinSort {
public static void main(String[] args) throws FileNotFoundException {
Scanner sc = new Scanner(new File(args[0]));
int length = sc.nextInt();
int size = sc.nextInt();
int[] temp = new int[size];
sc.nextLine();
for(int i = 0;i < temp.length;i++){
temp[i] = sc.nextInt();
}
sort(temp,size,length);
}
public static void sort(int[] input, int length,int size){
ArrayList<Integer>[]bin=(ArrayList<Integer>[]) new ArrayList[10];
for(int i = 0;i<length;i++){
bin[i] = new ArrayList<Integer>();
}
int power = 10;
for(int i = 0;i<size+1;i++){
for(int v = 0;v<input.length;v++){
int d = input[v] % power;
if(power>10)
d = d/ (power/10);
bin[d].add(input[v]);
}
for(int j = 0;j<10;j++){
while(!bin[j].isEmpty()){
int temp = bin[j].get(0);
bin[j].remove(0);
input[j] = temp;
}
}
power = power*10;
}
System.out.println("Final result");
System.out.println(Arrays.toString(input));
}
}
input[j] = temp;
should read
input[pos] = temp;
public class FibonacciGenerator
{
//instance variables
private int recent ; //one values ago
private int previous ; //two values ago
private int n ; // the number of values returned so far
/**
Constructs the generator by setting the instance variables to 1
*/
public FibonacciGenerator()
{
recent = 1 ;
previous = 1 ;
n = 0 ;
}
/**
Produces the next Fibonacci number
#return the next in the Fibonacci sequence
*/
public int next()
{
n ++ ;
if (n == 1) return 1 ;
if (n == 2) return 1 ;
int result = recent + previous ;
//----------------Start below here. To do: approximate lines of code = 3
// 1. Update previous and recent, and 2. return result.
previous++;
recent++;
return result;
//----------------------End here. Please do not remove this comment. Reminder: no changes outside the todo regions.
}
}
import java.util.* ;
public class FibonacciGeneratorTester
{
public static void main(String[] args)
{
System.out.println("The 1st Fibonacci number is: "
+ getFibonacci(1)) ;
System.out.println("The 10th Fibonacci number is: "
+ getFibonacci(10)) ;
}
/**
A static method to return the n'th Fibonacci number
#param n the index of the Fibonacci number
#return the n'th Fibonacci number
*/
public static int getFibonacci(int n)
{
FibonacciGenerator generator = new FibonacciGenerator() ;
int result = 0 ;
//----------------Start below here. To do: approximate lines of code = 4
// 1. Write a for-loop that calls the generator n times 2 . return the last result of the call.
for (int i = 1; i <= n; i++){
generator.next();
return result;
}
}
}
missing return statement second last curly brace highlighted. Is my for loop correct?.......................................................................................................................................................
Your for loop begins:
for (int i = 1; i <= n; i++){
If n was less than 1, it would immediately exit, and there is no return statement between the end of the loop and the end of the method. That is the missing return statement.
Look at this:
public static int getFibonacci(int n)
{
FibonacciGenerator generator = new FibonacciGenerator() ;
int result = 0 ;
//----------------Start below here. To do: approximate lines of code = 4
// 1. Write a for-loop that calls the generator n times 2 . return the last result of the call.
for (int i = 1; i <= n; i++){
generator.next();
return result;
}
}
It must return an int. Look closer at your loop. What is n = 0?
That's right it won't return anything. That is not allowed here.
public static int getFibonacci(int n)
{
FibonacciGenerator generator = new FibonacciGenerator() ;
int result = 0 ;
//----------------Start below here. To do: approximate lines of code = 4
// 1. Write a for-loop that calls the generator n times 2 . return the last result of the call.
for (int i = 1; i <= n; i++){
generator.next();
}
return result;
//put a return statement here, instead of in your loop.
}
TRY THIS CODE:
import java.util.*;
public class Fibonnacci{
public static void main(String args[]){
int num;
Scanner in=new Scanner(System.in);
System.out.println("Enter an integer");
num = in.nextInt();
System.out.println("Fibonacci Series");
int sum=0,a=0,b=1;
for(int i=0;i<num;i++){
System.out.print(" "+sum);
a = b;
b = sum;
sum = a + b;
}
}
}