I was trying to solve Project Euler problem 10 using python, but my program gave a wrong result. Since I am a complete noob to python and I could not find any fault in my (apparently brute-force) logic, I wrote a program in java (almost translated it), and it gave a different result, which turned out to be right.
Here is the python code:
from math import *
limit = 2000000
def isPrime(number):
if number == 2: return 1
elif number % 2 == 0: return 0
elif number == 3: return 1
elif number == 5: return 1
elif number == 7: return 1
else:
rootOfNumber = sqrt(number)
tag = 3
while tag < rootOfNumber:
if number % tag != 0:
tag += 2
else:
break ###
if tag >= rootOfNumber: ###EDIT: it should by only tag > rootOfNumber here
return 1 ### Thats what the problem was.
else:
return 0
sum = 2 # 2 is an even prime, something we are not iterating for
for i in range(3, limit, 2):
if isPrime(i) == 1:
sum += i
print(sum)
print('done...')
The equivalent java code is:
public class Prob10{
static int limit = 2000000;
static long sum = 2L; // 2 is an even prime, something we are not iterating for
public static void main (String[] args) {
for(int i = 3; i < limit; i+=2) {
if( isPrime(i) )
sum += i;
}
System.out.println(sum);
}
private static boolean isPrime (int number) {
if (number == 2) return true;
else if (number == 3 || number == 5 || number == 7) return true;
else {
double rootOfNumber = Math.sqrt(number);
int tag = 3;
while (tag < rootOfNumber) {
if (number % tag != 0)
tag +=2;
else
break;
}
if (tag > rootOfNumber)
return true;
else
return false;
}
}
}
I think I am doing some silly mistake or missing some subtle point.
p.s. I know my isPrime implementation is not too good. I am not printing the outputs because it may spoil the problem for others.
Any comments about (bad) style in the python program are welcome.
Try running with your code for example isPrime(49). You should figure out your problem from there. You have replaced a > with a >= in if (tag > rootOfNumber)
.Also as some coding style, you could just replace the first lines with:
if i in (2, 3, 5, 7): return 1
elif number % 2 == 0: return 0
else:
......
After a quick skim it appears to me that this line in the Python version is superfluous and it might be the cause of the problem:
elif number % 2 == 0: return 0
Why don't you return False for return value of 0? That would make it more simple.
Related
Everybody knows that FizzBuzz question that interviewers ask students.
Basically, when you have an incrementor and for each number which is a divisible of 3 you say fizz, for a number divisible by 5 you say buzz, while if it is divisible by both(3 and 5) you say FizzBuzz, hence the name.
It is a relatively easy problem to solve and I have done it, but I think my solution is a bit clunky. This is it:
int[] numbers = new int[100];
for (int i = 0; i < numbers.length; i++) {
numbers[i] = i;
}
for (int i : numbers) {
if (i % 3 == 0) {
System.out.println("Fizz");
} else if(i % 5 == 0) {
System.out.println("Buzz");
} else {
System.out.println("FizzBuzz");
}
}
But the problem is that when the number is divisible by both 3 and 5 it gives me "Fizz" for some reason. Can somebody explain to me, because I'm new to java programming. Thanks in advance!
The problem lies in the order of your if statements. Lets take a look at the number 15, which is the first number divisible by both 3 and 5. Because of the order in which you have your if statements, the first statement that is checked is
if ( 15 % 3 == 0)
The result of the operation is indeed equal to 0, as 15 is divisible by 3 and so "Fizz" is printed and your else is ignored.
Think about how you should structure the order of your if statements and which additional condition should you introduce to catch the specific case of being divisible by both i % 3 == 0 && i % 5 == 0.
When you enter the if statement and your number is 15 for exemple, you enter the first if statement and.. prints "Fizz" as you stated, because 15 % 3 == 0 returns true. Then it ignores the else.
You want the first if to be
if (i % 3 == 0 && i % 5 == 0) {
System.out.println("FizzBuzz");*
}
Try this code
public static void main(String[] args) {
int[] numbers = new int[100];
for (int i = 0; i < numbers.length; i++) {
numbers[i] = i;
}
for (int i : numbers) {
if ((i % 3 == 0) && (i % 5 == 0)) {
System.out.println("FizzBuzz");
} else if(i % 5 == 0) {
System.out.println("Buzz");
} else if (i % 3 == 0){
System.out.println("Fizz");
}
}
}
I'm doing a hackernet challenge where n is an int input. The conditions are:
If n is odd, print Weird
If n is even and in the inclusive range of 2 to 5, print Not Weird
If n is even and in the inclusive range of 6 to 20, print Weird
If n is even and greater than 20, print Not Weird.
Im sure the code makes logic and dont think theres syntax. It gives the correct responses and hackernet still says its incorrect so ive come here to see if anyone can see what the problem is
public static void main(String[] args)
{
int N = scanner.nextInt();
scanner.skip("(\r\n|[\n\r\u2028\u2029\u0085])?");
if (N % 2 != 0 || N % 2 == 0 && N >= 6 && N <= 20)
{
System.out.print("weird");
}
else
{
System.out.print("not weird");
}
}
The problem is the logic in your else condition, which would also catch values of N which are less than 2. Try this version:
if (N % 2 != 0)
{
System.out.print("weird");
}
else if (N >= 2 && N <= 5 || N > 20)
{
System.out.print("not weird");
}
else if (N >= 6 && N <= 20)
{
System.out.print("weird");
}
else
{
// NOTE: if the code still fails, remove this else condition
System.out.print("unexpected value of N");
}
Note: To get your code to pass the Hackernet task, you might have to completely remove the else condition. I added it for completeness, but Hackernet might test N=1 to see if nothing gets printed.
Read this condition :
if (N % 2 != 0 || N % 2 == 0 && N >= 6 && N <= 20)
as
if (N % 2 != 0 || (N % 2 == 0 && N >= 6 && N <= 20))
Then see how operator precedence changes the behaviour and yield desired results.
Check the following one
public static void main(String[] args)
{
int N = scanner.nextInt();
scanner.skip("(\r\n|[\n\r\u2028\u2029\u0085])?");
if(N%2!=0) {
System.out.print("weird");
}else if(N>=2 && N<=5) {
System.out.print("not weird");
}else if(N>=6 && N<=20) {
System.out.print("weird");
}else if(N>20) {
System.out.print("not weird");
}
}
For the technical part: start by reading about
precedence of java operators and then make your code easier to read.
Pushing that many conditions into a single if is not helpful. You see it yourself: you think the code is correct, but probably it isn't. And now you look to other people to explain your overly complex code back to you. And of course, all the other answers do all that for you ... but beyond that:
The "real" answer here is: learn how to test your code.
Instead of having a main that somehow asks for a number, and then makes decisions, write a method boolean isWeird() that takes a number and returns true/false according to your requirements.
And then simply test that method with all reasonable cases. And then check if that result is as expected.
Using JUnit, you could write something like
assertThat(isWeird(1), true);
assertThat(isWeird(21), true);
assertThat(isWeird(22), true);
...
Ideally, you write such tests before you implement that method. And then you implement all the conditions, and any check that fails tells you that you got something wrong.
I feel, In the if (N % 2 != 0 || N % 2 == 0 && N >= 6 && N <= 20) condition, you are verifiying the odd and even values at same time using && and || operator. Can you modify the condition into like this if (N % 2 != 0 || (N % 2 == 0 && N >= 6 && N <= 20)) and check? If N is odd weird will be printed or if N is even and it falls under the 6 and 20 inclusive, weird will be printed.
You already have a good few answers here but if you think logically about what you actually need, you can break it down easier.
It looks like the only "Not Weird" print out is 2, 4 and even numbers > 20
So an example could be something like:
if (n % 2 == 0) {
if ((n >= 2 && n <= 5) || (n > 20)) {
return "Not Weird";
}
}
return "Weird";
You can try this
private static final Scanner scanner = new Scanner(System.in);
public static void main(String[] args) {
int n = scanner.nextInt();
scanner.skip("(\r\n|[\n\r\u2028\u2029\u0085])?");
if (n % 2 == 1 || (n >= 6 && n <= 20)) {
System.out.println("Weird");
} else {
System.out.println("Not Weird");
}
scanner.close();
}
I hope someone can help. My problem is with using the modulus operator in a for loop. My code is as follows:
for (int i = 0; i < 10; i++)
if (i % 2 == 0) {
method1();
}
else {
method2();
}
I understand how this loop works in that it iterates between if and else because of the even and odd numbers created by the condition that uses
the modulus operator (i % 2 == 0)
However, I want to create a condition using the modulus operator so that my loop iterates through 4 methods - as in:
loop starts{
method1();
method2();
method3();
method4();
loop repeats
}
I can't work out how to accomplish this. I would appreciate any help and advice.
Thanks in advance.
Put j = i % 4
And check for method1() j should be equal to j = 0, similarly for
Method2() check j = 1. And so on. Put for range conditions to 1 for infinite loop or desired range.
You could be looking to use the switch statement. More on that here.
Basically it takes a variable to switch between cases.
For example:
for(int i = 0; i < 10; i++){
switch(i%2) {
case 0: method0();
break;
case 1: method1();
break;
}
}
Here is the out put if method0 printed 0, and method1 printed 1:
1
0
1
0
1
0
1
0
1
0
You can edit the modulus to whatever number you want, you just have to account for the different possibilities.
Do you mean something like this?
for(int i = 0; i < 10; i++)
{
if(i%4 == 0)
{
condition
}
else if(i%4 == 1)
{
condition
}
else if(i%4 == 2)
{
condition
}
else if(i%4 == 3)
{
condition
}
}
Remember to put it on paper if you're confused and loop through your head (as a beginner)
Problem: check if a number is a power of 4.
my solution in java:
public static boolean isPowerOfFour(int num) {
return (Math.log(num) % Math.log(4) == 0);
}
But it seems off in some cases, for example when num is 64.
I found out that if I change the code a little bit, it works well.
public static boolean isPowerOfFour(int num) {
return (Math.log(num) / Math.log(4) %1 == 0);
}
I think both solutions do the same thing, check if the remaining of logNum/logBase is 0. But why the first solution doesn't work? Is it because the solution is incorrect or relative to some low level JVM stuff?
Thanks.
Building on #dasblinkenlight's answer, you can easily combine both conditions (first, a power of 2, then any power of 4 among all possible powers of 2) with a simple mask:
public static boolean isPowerOfFour(int num) {
return ((( num & ( num - 1 )) == 0 ) // check whether num is a power of 2
&& (( num & 0xaaaaaaaa ) == 0 )); // make sure it's an even power of 2
}
No loop, no conversion to float.
Checking if a number is a power of 4 is the same as checking that the number is an even power of 2.
You can check that a number x is a power of two by verifying that x & (x-1) is zero (here is the explanation of how this works)
If your number is not a power of 2, return false. Otherwise, shift the number right until you get to one, and count the number of shifts. If you shifted an odd number of times, return false; otherwise, return true:
public static boolean isPowerOfFour(int num) {
if ((num & (num-1)) != 0) {
return false;
}
int count = 0;
while (num != 1) {
num >>= 1;
count++;
}
return count % 2 == 0;
}
Demo.
Functions like Math.log return floating point numbers with a rounding error. So when num = 64 for example, Math.log (num) / Math.log (4) is not exactly 3, but a number close to 3.
public static boolean isPowerOfFour(int num) {
if (num > 0) {
while (num % 4 == 0) num /= 4;
}
return (num == 1);
}
This solution can be quite easily adapted to check whether num is a power of some other integer greater than 1.
The reason it doesn't work is because Math.log() returns a double. The answer of false is reflective of rounding errors; log(64) base e is an irrational number but Java needs to truncate it to fit it's width.
I'm writing a simple algorithm to check the primality of an integer and I'm having a problem translating this Java code into Python:
for (int i = 3; i < Math.sqrt(n); i += 2) {
if (n % i == 0)
return false;
}
So, I've been trying to use this, but I'm obviously skipping the division by 3:
i = 3
while (i < int(math.sqrt(n))):
i += 2 # where do I put this?
if (n % i == 0):
return False
The only for-loop in Python is technically a "for-each", so you can use something like
for i in xrange(3, int(math.sqrt(n)), 2): # use 'range' in Python 3
if n % i == 0:
return False
Of course, Python can do better than that:
all(n % i for i in xrange(3, int(math.sqrt(n)), 2))
would be equivalent as well (assuming there's a return true at the end of that Java loop). Indeed, the latter would be considered the Pythonic way to approach it.
Reference:
for Statements
xrange
all
A direct translation would be:
for i in range(3, int(math.sqrt(n)), 2):
if n % i == 0:
return False
In a Java for loop, the step (the i += 2 part in your example) occurs at the end of the loop, just before it repeats. Translated to a while, your for loop would be equivalent to:
int i = 3;
while (i < Math.sqrt(n)) {
if (n % i == 0) {
return false;
}
i += 2;
}
Which in Python is similar:
i = 3
while i < math.sqrt(n):
if n % i == 0:
return False
i += 2
However, you can make this more "Pythonic" and easier to read by using Python's xrange function, which allows you to specify a step parameter:
for i in xrange(3, math.sqrt(n), 2):
if n % i == 0:
return False
Use a basic Python for i in range loop:
for i in range(3, math.round(math.sqrt(x)), 2):
if (n % i == 0):
return false
I get this answer from an automatic translation by AgileUML:
def op(self, n) :
result = False
i = 0
i = 3
while i < math.sqrt(n) :
if n % i == 0 :
return False
else :
pass
i = (i + 2)
return True
It seems to be semantically correct?