I am trying to learn python. So, I have a following Java code to print the list of the factors of the entered number. I am trying to implement the same logic in python. But getting some errors. The java code is as follows:
public final class PrintFactors {
private PrintFactors() {}
public static void printFactors(int number) {
if (number <= 0) throw new IllegalArgumentException("The number should be greater than 0.");
printFactorsList(number, number + "*" + 1 + "\n", number);
}
private static void printFactorsList(int dividend, String factorString, int prevDivisor) {
for (int divisor = dividend - 1; divisor >= 2; divisor--) {
if (dividend % divisor != 0)
continue;
if (divisor > prevDivisor)
continue;
int quotient = dividend / divisor;
if (quotient <= divisor) {
if (quotient <= prevDivisor) {
System.out.println(factorString + divisor + "*" + quotient);
}
}
printFactorsList(quotient, factorString + divisor + "*", divisor);
}
}
public static void main(String[] args) {
printFactors(12);
System.out.println();
printFactors(32);
}
}
The above code outputs the result as follows:
$ java -cp . PrintFactors 32
32 * 1
16 * 2
8 * 4
8 * 2 * 2
4 * 4 * 2
4 * 2 * 2 * 2
2 * 2 * 2 * 2 * 2
My python code is as follows:
def print_factors_list(dividend, factorstring, predivisor):
divisor = dividend - 1
for i in range(int(divisor), 2, -1 ):
if dividend % i != 0:
continue
if divisor > predivisor:
continue
quotient = dividend / divisor
if quotient <= divisor:
if quotient <= predivisor:
print factorstring + str(divisor) + "*" + str(quotient)
print_factors_list(quotient, str(factorstring) + str(divisor) + "*", divisor)
def print_factors(x):
if (x < 0):
print "Enter a positive interger"
else:
print_factors_list(x, str(x) + "*" + str(1) + "\n", x )
num = int(input("Enter a number: "))
print_factors(num)
I am getting the following error:
undefined: Error: local variable 'quotient' referenced before assignment
Please can someone help me with this where am I going wrong. Is there a logic error as I have implemented the steps as the Java code? Thanks.
Python is indentation-sensitive. You had your print_factors_list recursive call at the outermost indentation level, thus it's outside of the for loop. This is different behaviour from your Java code.
Related
I wrote a program where function isHappy takes in a long value and returns a statement of either True or False based on what the output number is... (1 means True; 4 means false).
The way my program reaches the output is by squaring each digit of the input n and adding them repeatedly until the output is only 1 digit
For instance, if n = 19, the code would return 1 because:
1^2 + 9^2 = 82, from which digits 8 and 2 would do: 8^2 + 2^2 = 68, from which digits 6^2 + 8^2 = 100, from which 1^2 + 0^2 + 0^2 = 1. <== 1 is only one digit, therefore, it shall be the answer.
Please note that every input I get will end up with either 1 or 4
Anyways, here is my code so far,
public class Happy
{
public static void main(String args[])
{
System.out.println(isHappy(989));
}
public static boolean isHappy(long n) {
long sum = 0;
boolean l = true;
boolean j = false;
while (n != 0) {
sum = sum + ((n % 10) * (n % 10));
n = n / 10;
}
if (sum == 1) {
return l;
} else {
return j;
}
}
}
When my plug in test case inputs like isHappy(100), isHappy(111), isHappy(1234), the program seems to work where
1 = True, 4 means false
isHappy(100) == true
isHappy(111) == false
isHappy(1234) == false
However, when I plug in specific numbers like isHappy(989), the program should be true since
9^2 + 8^2 + 9^2 = 226; 2^2 + 2^2 + 6^2 = 44; 4^2 + 4^2 = 32; 3^2 + 2^2 = 13; 1^2 + 3^2 = 10 and lastly 1^2 + 0^2 = 1; which is True.
However, after running my code, my output prints false instead.
I've tried debugging my code but I can't seem to find a problem. Any help on what changes to my code do I have to make would be greatly appreciated :)
You're mixing the two parts of the algorithm: calculating the sum of squared digits and verifying if the number is a "happy number".
After calculating the sum for the given number in case when the sum is naughtier 1, no 4, the sum becomes a new number to check, and we need to continue with calculating its sum.
So basically we need two loops, or two separate methods.
That that's how it can be implemented.
public static boolean isHappy(long n) {
while (n != 1 && n != 4) { // given number is naughtier `1`, no `4`
n = getHappySum(n); // calculating the sum
}
return n == 1;
}
public static int getHappySum(long n) {
int sum = 0;
while (n != 0) {
sum += Math.pow(n % 10, 2);
n /= 10;
}
return sum;
}
main()
public static void main(String[] args) {
System.out.println(isHappy(100));
System.out.println(isHappy(111));
System.out.println(isHappy(1234));
}
Output:
true
false
false
This question already has answers here:
Differences between System.out.println() and return in Java
(4 answers)
Closed 3 years ago.
I have to write a method int sumBeyond(int k) to find the least n such that the sum of the natural numbers smaller than n exceeds k.
However, when I try to test the method it doesn't return any value.
public static int sumBeyond(int k){
int i=1;
int sum=0;
while(i<k){
sum=sum+i;
i=i+1;
}
return sum;
}
I tried calling the function this way, in the main method:
sumBeyond(100);
int sum100 = sumBeyond(100);
System.out.println("Sum is " + sum100);
Then small improvements:
public static int sumBeyond(int k) {
int i = 1;
int sum = 0;
while (i < k) {
sum += i;
++i;
}
return sum;
}
public static int sumBeyond(int k) {
int sum = 0;
for (int i = 1; i < k; ++i) {
sum += i;
}
return sum;
}
public static int sumBeyond(int k) {
// return (k - 1) * (1 + k - 1) / 2;
return (k - 1) * k / 2;
}
To solve the problem stated:
Find n such that sum upto n-1 >= k' where k' is k - 1.
Sum upto n-1 is (n - 1) * n / 2 >= k'
So we get:
x² - x - 2k'
------------ >= 0
2
Solution for = 0:
a = 1/2
b = -1/2
c = -2k'
_________
-b +/- V b² - 4ac
x = ------------------
2a
x = 1/2 +/- sqrt(1/4 + 4k'/4) =
= 1/2 +/- 1/2 . sqrt(1 + 4k')
Positive x
x = 1/2 + 1/2 . sqrt(4k' + 1)
public static int sumBeyond(int k) {
double x = (Math.sqrt(4 * (k-1) + 1) + 1) / 2;
return (int) Math.ceil(x);
}
The solution should be given the math as comment.
If I got your question right, you want to find the least n such that the sum of the natural numbers smaller than n exceeds k and thus, you shouldn't return the sum itself, because it is not n but needs to be calculated in order to find the smallest n.
You can do it the following way:
public static int sumBeyond(int k) {
int n = 0;
int sum = 0;
for (int i = 0; i < k; i++) {
// provide an intermediate sum (the one before this step) for logging purpose
int intermediateSum = sum;
// sum up
sum += i;
// set the return value to the current "natural number"
n = i;
// print some detailed debug log
System.out.println("sum:\t" + sum +
" (" + intermediateSum + " + " + i + ")\t——>\tn = " + n);
// exit the loop if the sum is greater than k
if (sum >= k) {
break;
}
}
return n + 1;
}
Calling it in a main like this
public static void main(String[] args) {
int k = 100;
System.out.println("The least n" +
+ "such that the sum of the natural numbers smaller than n exceeds "
+ k + " is " + sumBeyond(k));
}
will print
sum: 0 (0 + 0) ——> n = 0
sum: 1 (0 + 1) ——> n = 1
sum: 3 (1 + 2) ——> n = 2
sum: 6 (3 + 3) ——> n = 3
sum: 10 (6 + 4) ——> n = 4
sum: 15 (10 + 5) ——> n = 5
sum: 21 (15 + 6) ——> n = 6
sum: 28 (21 + 7) ——> n = 7
sum: 36 (28 + 8) ——> n = 8
sum: 45 (36 + 9) ——> n = 9
sum: 55 (45 + 10) ——> n = 10
sum: 66 (55 + 11) ——> n = 11
sum: 78 (66 + 12) ——> n = 12
sum: 91 (78 + 13) ——> n = 13
sum: 105 (91 + 14) ——> n = 14
The least n such that the sum of the natural numbers smaller than n exceeds 100 is 15
I really hope I got this right, still not sure...
Oh, and if 0 is not a natural number, start iterating at 1.
So as has been noted above, the issue was not that your method was not returning something, but that you were doing nothing with what was returned. Also, as noted above, you were focused on finding the sum, but that is not actually what the question asked.
I am sympathetic to your use of a while loop here since it may not execute at all and since you don't know a priori how many times it will run. So I rewrote it to check the right things and adapted the main from deHaar to exercise it. That allowed me to hand check the answers, because some of the cases of equality and need for "numbers less than" rather than "numbers less than or equal to" were subtle.
The math teacher in me really likes the quadratic formula approach from Joop Eggen; it's just harder to get right (and indeed, if I were going to do it, I would end up testing that it's consistent with what I have here).
public class ShadesOfLittleGauss {
public static int sumBeyond(int k) {
int i = 1; //have summed (trivially) all natural numbers less than 1 so far
int sum = 0;
while (sum <= k) { //needs to exceed, so <=
sum = sum + i;
i = i + 1;
}
return i;
}
public static void main(String[] args) {
for (int k = -1; k < 10; k++) {
System.out.println("The least number " +
"such that the sum of the natural numbers smaller than n exceeds " +
k + " is " + sumBeyond(k));
}
}
}
output (you can hand check these are correct as stated):
The least number such that the sum of the natural numbers smaller than n exceeds -1 is 1
The least number such that the sum of the natural numbers smaller than n exceeds 0 is 2
The least number such that the sum of the natural numbers smaller than n exceeds 1 is 3
The least number such that the sum of the natural numbers smaller than n exceeds 2 is 3
The least number such that the sum of the natural numbers smaller than n exceeds 3 is 4
The least number such that the sum of the natural numbers smaller than n exceeds 4 is 4
The least number such that the sum of the natural numbers smaller than n exceeds 5 is 4
The least number such that the sum of the natural numbers smaller than n exceeds 6 is 5
The least number such that the sum of the natural numbers smaller than n exceeds 7 is 5
The least number such that the sum of the natural numbers smaller than n exceeds 8 is 5
The least number such that the sum of the natural numbers smaller than n exceeds 9 is 5
UPDATE: I did solve the quadratic and came up with the following which agrees with the simpler approach.
public static int sumBeyond2(int k) {
if (k < 0) { //do not take squareroots of negatives
return 1;
}
double x = -1.0 / 2 + Math.sqrt(1 + 8 * k) / 2; //from solving quadratic inequality n(n+1)/2.0 > k
if (Math.abs(Math.round(x) - x) < 0.0000001) { //special case, it is an integer, so ceil won't reliably add 1
return 1 + 1 + (int) Math.round(x);
}
return 1 + (int) Math.ceil(x); //adding 1 because of wording, integers less than, ceil because needs to exceed k
}
I am in a Java class and it's still early in the class. The assignment is to:
e^x Approximations
The value ex can be approximated by the following sum:
1 + x + x^2/2! + x^3/3! + …+ x^n/n!
The expression n! is called the factorial of n and is defined as: n! = 1*2*3* …*n.
Write a program that takes a value of x as input and outputs four approximations of ex done using four different values of n: 5, 10, 50, and 100. Output the value of x the user entered and the set of all four approximations into the screen.
Sample formula use: calculating e^7 using approximation with n = 5
1 + 7 + 7^2/2! + 7^3/3! + 7^4/4! + 7^5/5!
I've got all the rest to work, including getting n to be 5, 10, 50 and 100. I thought I had the factorial formula figured out and I used the number 4 like the sample we were show and my numbers done match. Could really use another set of eyes.
Here's my code with forumla (x is the value the user enters and n is the 5, 10, 50 and 100):
/**
* myFact takes in x and calculates the factorial
* #param x
* #param n
* #return the factorial as a long
*/
public static long myFact(int x, int n) {
//declare variables
long sum = x;
for (int i=2; i <= n; i++) {
sum += ((Math.pow(x, i))/i);
}
return (sum + 1);
}
}
Here's the main class where I am calling the function. The error I suppose could be there too:
public static void main(String[] args) {
//declare variable for user input and call method to initialize it
int x = getNumber();
long fact;
int n;
//Output first line
System.out.println("N\t approximate e^" + x);
for (n = 5; n <= 100; n *= 2) {
if (n == 10) {
fact = myFact(x, n);
System.out.println(n + "\t " + fact);
n += 15;
} else {
fact = myFact(x, n);
System.out.println(n + "\t " + fact);
}
}
}
Thanks for taking a look at this, it's taken me hours to get this as the teacher gave us very little help.
You did a mistake in
sum += ((Math.pow(x, i))/i);
here you need to calculate the i!. Add below method in your code
public static int fact(int i){
int fact = 1;
for (int n = i; n > 0; n--) {
fact = fact * n;
}
return fact;
}
Also change sum += ((Math.pow(x, i))/i) to
sum += ((Math.pow(x, i))/fact(i));
This question already has answers here:
Number of consectuive sums error?
(2 answers)
Closed 5 years ago.
I am working on a program that takes an integer and finds the number of combinations of consecutive sums that the integer has:
The number 13 can be expressed as a sum of consecutive positive
integers 6 + 7. Fourteen can be expressed as 2 + 3 + 4 + 5, also a sum
of consecutive positive integers. Some numbers can be expressed as a
sum of consecutive positive integers in more than one way. For
example, 25 is 12 + 13 and is also 3 + 4 + 5 + 6 + 7.
I researched and read that it's the number of odd factors minus one. So I wrote a program that finds the number of odd factors and my answer is still wrong in certain cases. Any insight?
Code seems to work fine but there is a crash due to Timeout which is probably due to optimization error.
The constraints for possible input size is
1 to 10^(12)
static int consecutive(long num) {
while (num % 2 == 0) num /= 2; // 1st opt.
return consecutiveHelper(num)-1;
}
public static int consecutiveHelper(long num) {
long factorNumber = 1;
int count = 0;
while(factorNumber <= num / 2) { // 2nd opt.
if(num % factorNumber == 0) {
count++;
}
factorNumber += 2; // 3rd opt.
}
if (num % 2 != 0) {
count++;
}
return count;
}
Let's try to find a pseudo-optimized method to resolve your problem :
What you need to do is to decompose your number in prime factors.
For example, if you take 1200 :
1200 = 2*2*2*2*3*5*5 = 1 * 2^4 * 3^1 * 5^2
You can then analyze how you could get odd factors with those prime factors. A quick analyze will tell you that :
odd * odd = odd
odd * even = even
even * even = even
With that in mind, let's find all the factors we get with odd * odd :
1 * 1 = 1
3 * 1 = 3
5 * 1 = 5
5 * 3 = 15
5 * 5 = 25
5 * 5 * 3 = 75
A quick way to find these combinations without writing them all is the "plus 1 method" : add 1 to the number of occurences of each prime odd factor, and multiply them together :
We found that 1200 = 1 * 2^4 * 3^1 * 5^2, so we can do :
("number of 3" + 1) ("number of 5" + 1) = (1 + 1) ( 2 + 1) = 6
There are 6 odd factors for the number 1200, and as you stated, remove 1 from that number to get the number of combinations of consecutive sums that 1200 has :
6 - 1 = 5 <-- woohoo ! finally got the result !
Now, let's look at the code. What we want to have is a Map, the keys being the prime factors and the values being the number of their occurences :
/*
If number is odd,
find the number in the keys and add 1 to its value.
If the number is not in the keys, add it with value = 1.
*/
public static void addValue(Map<Integer, Integer> factors, int i) {
if(i % 2 != 0) {
int count = factors.containsKey(i) ? factors.get(i) : 0;
factors.put(i, ++count);
}
}
/*
Classic algorithm to find prime numbers
*/
public static Map<Integer, Integer> oddPrimeFactors(int number) {
int n = number;
Map<Integer, Integer> factors = new HashMap<>();
for (int i = 2; i <= n / i; i++) {
while (n % i == 0) {
addValue(factors, i);
n /= i;
}
}
if(n > 1) addValue(factors, n);
return factors;
}
With that, let's try to print what the map contains for number 1200 :
public static void main(String[] args) {
int n = 1200;
System.out.println(oddPrimeFactors(n));
}
$n : {3=1, 5=2}
Good ! Now let's finish the program with the method we developed before :
public static int combinations = 1;
public static void main(String[] args) {
int n = 1200;
oddPrimeFactors(n).forEach((key, value) -> combinations *= (value + 1));
combinations--;
System.out.println(combinations);
}
$combinations = 5
Finished ! feel free to ask if you did not understand something !
Note : I tried my program with the max value Integer can handle and it took less than one second for my program to proceed, which seems pretty fast to me. It could probably be faster though, it's up to you to find the most optimized version of this code !
Hello i need to build a recursion that replace the even digits with zero:
for exmaple - the number 1254 will be 1050
the number 332- will be 330
and the number 24 - will be 0
i started working on it but got pretty clueless after a while
public static int replaceEvenDigitsWithZero(int number){
if(number<1)
return number;
if(number%2==0 && number%10!=0){
int temp=number%10;
return(number/10+replaceEvenDigitsWithZero(number-temp));
}
return(replaceEvenDigitsWithZero(number/10));
}
public static void main(String[] args) {
int num1 = 1254;
System.out.println(num1 + " --> " + replaceEvenDigitsWithZero(num1));
int num2 = 332;
System.out.println(num2 + " --> " + replaceEvenDigitsWithZero(num2));
int num3 = 24;
System.out.println(num3 + " --> " + replaceEvenDigitsWithZero(num3));
int num4 = 13;
System.out.println(num4 + " --> " + replaceEvenDigitsWithZero(num4));
}
}
Since your method only looks at the last digit, it should always call itself with input / 10 when input >= 10.
You then take the value returned by the recursion, multiply it by 10 and add the last digit back, if odd.
public static int replaceEvenDigitsWithZero(int number) {
int result = 0;
if (number >= 10)
result = replaceEvenDigitsWithZero(number / 10) * 10;
if (number % 2 != 0)
result += number % 10;
return result;
}
In case you need a 1-liner, here it goes: ;)
public static int replaceEvenDigitsWithZero(int number) {
return (number%2 == 0 ? 0 : number % 10) + (number<10 ? 0 : 10 * replaceEvenDigitsWithZero(number / 10));
}
Well ... designing a recursive algorithm has always the same steps:
Identify the base case, that is the scenario that will terminate the recursive calls.
Reduce the problem to being smaller (towards the base case).
For this requirement the problem can easily be made smaller by dividing by 10. That also easily leads to the base case: A single digit is the base case. So a quick implementation can be:
public static int replaceEvenDigitsWithZero(int number) {
// I added handling of negative numbers ...
if (number < 0) {
return -replaceEvenDigitsWithZero(-number);
}
// base case
if (number < 10) {
return replaceOneDigit(number);
}
// recursion
int lastDigit = number % 10;
int remainder = number / 10;
return replaceEvenDigitsWithZero(remainder) * 10 + replaceOneDigit(lastDigit);
}
public static int replaceOneDigit(int digit) {
return (digit % 2 == 0) ? 0 : digit;
}
I added a helper method for converting even digits to zero.
The output now is:
1254 --> 1050
332 --> 330
24 --> 0
13 --> 13
You need to take track of the current position in your number.
In your current function, you will return only the first digit of your number (because you divide it by 10 everytime the recursion is called).
public static int replaceEvenDigitsWithZero(int number, int position){
// cancel condition:
if(number < 10 * position) {
return number;
}
// edit number:
if (position > 0) {
int currentNumber = number / (10 * position);
} else {
currentNumber = number;
}
if(currentNumber%2==0){ //even?
int multiplyValue = currentNumber % 10; // get rest of division by 10 (== digit in current position)
number = number - (multiplyValue * (10 * position)); // set current position to zero
}
// recursive call:
return replaceEvenDigitsWithZero(number,position+1);
}
Didn't test my code, but I hope you get an idea of how to do it.
Use replaceEvenDigitsWithZero(num1,0) to start.
1 convert to String
2 F(string): take the first number: replace 2,4,6,8 characters by 0
3 concatenate to F(the remaining string)
4 convert to int