Odd and Even HackerRank challenge [closed] - python

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 1 year ago.
Improve this question
I'm trying to solve a problem on HackerRank and I sent the code, it worked in amost all the scnarios except for scnario 7 and 3 where they insert 18 and it should return "Weird" and when they insert 20 it should return "Weird" as well according to the website.
The rules of the challenge are:
Given an integer, n, positive number from 1 to 100 , perform the following conditional actions:
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 Input Format
A single line containing a positive integer, .
Constraints
Output Format
Print Weird if the number is weird. Otherwise, print Not Weird.
And my code was:
n = 0
n = int(input('Type a number between 1 and 100: '))
odd = False
even = True
# ODD / EVEN
if (n%2) == 0:
n = even #True
else:
n = odd #False
# Is this odd or is this even?
if n == odd:
print ('Weird')
if n == even > 5 < 20:
print('Weird')
elif n == even > 1 < 6:
print ('Not Weird')
else:
print('Not Weird')
I can't see what I did wrong, can you help me to solve it so it can work in all scnarios?

There's a lot to unpick here. As this is an assignment, I'm not going to print the full solution out here, but I will point out the mistakes you've made so you can come to the correct solution.
First issue: reassigning 'n'.
You assign the value from the input to n, then subsequently replace it with the value of odd or even. This means you have lost the original input number. Instead you should assign the result to a new variable (such as 'isEven').
Second issue: uneccesarry 'if'
The result of 'n%2 == 0' is already True/False, depending if n is an even/odd number. So you can simply assign the result, rather than use an 'if' block.
Third issue: multiple operators
Logical operators have an order of operation, and resolution. The statement 'n == even > 5 < 20' makes no logical sense. Instead you should do independent Boolean comparisons, and join them with "and" or "or". E.g. 'if isEven and n < 5 and n> 20'.

Related

Print prime numbers within an interval [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 11 months ago.
Improve this question
This code is running for the 1-10 interval but for interval 20-30 it is writing 21 and 27 and I am unable to understand what's wrong in the code. I don't want to know other code; I want to know what's wrong in my code.
start = int(input("Enter the first number of the interval")) #starting of interval
end = int(input("Enter the last number of the interval")). #end of interval
for i in range(start, end+1):
for x in range (2,end):
if (i == 0 or i==1):
break
elif (i % x != 0):
print(i)
break
else:
break
for x in range (2,end):
if (i == 0 or i==1):
break
elif (i % x != 0):
print(i)
break
else:
break
This part of code should
print a number if it's prime, otherwise break
but it doesn't.
Do you notice something strange in your code? I do, and it's the fact that in every case the inner for loop breaks after the first iteration, rethink this aspect of your code, and it will work fine.
First, I am not sure whether you want the period after the inputting for the end. Also, your code checks if i is not divisible by x, then print. So for example, your code checks if 21 is divisible by 2. It is not, so your code prints it out and breaks.
Introduction
Your code is effectively testing if a number is odd and if it is, it prints it out.
If start is 1 and end is any number greater than 1, your code is printing every odd number greater than 2 in the interval [1, end].
It is printing all odd numbers, but not all odd numbers are prime!
Dissecting your code
Let's consider the [1, 20] interval. Your code outputs every odd number greater than 2 in the interval [1, 20].
3, 5, 7, 9, 11, 13, 15, 17, 19.
2 is prime and is missing from this list. We can fix that by writing the following within the outer loop but above the inner loop:
if i == 2:
print(i)
Now the output is `
2, 3, 5, 7, 9, 11, 13, 15, 17, 19.
This is better but 9, 15 are not prime numbers.
The if statement with condition (i == 0 or i == 1) inside of your inner loop is not causing any problems. Let's simplify the inner loop by moving this just outside of the inner loop (just above) so that your code becomes
for i in range(start, end+1):
if (i == 0 or i == 1):
# 0 and 1 are not prime
continue
if (i == 2):
# 2 is prime
print(i)
for x in range (2,end):
if (i % x != 0):
print(i)
break
else:
break
All that remains as the potential culprit for your problems is the inner loop so let's focus on that.
Whenever i is even, in the first iteration of the inner loop, we
have x = 2. We know that if i is even that i % 2 is 0 and so i % x != 0 is False and so we move onto the else, in which case we
break out of the inner for loop. This is all fine because no even
integer greater than 2 is prime!
Whenever i is odd, in the first iteration of the inner loop, we
have x = 2. We know that if i is odd that i % 2 is NOT 0 and so
i % x != 0 is True and then we print i and then break out of
the for loop.
We never once have x = 3 or x = 4 and so on!
The above describes precisely what you code is doing, which is ignoring even integers and simply printing out every odd integer.
Solution that outputs what you want
It would help me if I knew what definition of a prime number you have and/or what algorithm you are trying to implement. But since I don't have this information, I can only suggest a solution.
In order to solve your problem, you need to clearly have in mind what a prime number is. There are many equivalent definitions of a prime number (see the Wikipedia prime number page for examples of definitions). I chose a definition that suggests a natural algorithm for finding prime numbers. Whatever definition of prime number you were given, it is possible to prove mathematically that it is equivalent to this (for some this is the first definition of a prime number that they see!):
An integer i is prime if and only if i > 1 AND for all k in {2, 3,
..., i - 1}, i % k != 0.
In words this says that an integer i is prime iff i is strictly greater than 1 and for all integers k from 2 up until i - 1, k does not divide i evenly.
Here it is
start = int(input("Enter Start: "))
end = int(input("Enter End: "))
print(f"\nPrime numbers between [{start}, {end}]:")
for i in range(start, end + 1):
if (i == 0 or i == 1):
# i is not prime
continue
if (i == 2):
# i is prime
print(i)
continue
for x in range(2, i):
if (i % x) == 0:
break
if (i % x) != 0:
print(i)
Example session:
Enter Start: 20
Enter End: 30
Prime numbers between [20, 30]:
23
29
The (i == 0 or i == 1) check should be placed outside the inner for loop. Otherwise, for all i greater than or equal to 2, for every iteration in the inner loop, you will be checking to see if it is less than 2 or not. You are doing this check too much.
We know that when i == 2 that i is prime.
For i > 2, we appeal to the definition of a prime number above.
The inner loop and the last statement applies the second part of the prime definition.

Understanding a code about multiples of numbers

Lately am trying to do some Python programming, so am doing some mathematical exercices in some website.
I came across this example and at first I didn't understand the exercise. So I checked the solution to at least understand the question. As a consequence I found myself learning some coding tricks (like the while True loop).
The exercise is simple:
Write a Python program to find the smallest multiple of the first n numbers. Also, display the factors.
Below is the code:
def smallest_multiple(n):
if (n<=2):
return n
i = n * 2
factors = [number for number in range(n, 1, -1) if number * 2 > n]
print(factors)
while True:
for a in factors:
if i % a != 0:
i += n
break
if (a == factors[-1] and i % a == 0):
return i
My questions are:
Why does he create a list of numbers that are superior to the input by a factor of 2?
And then the while loop is just difficult to undestand. Could someone please explain it to me (I mean the content of the loop)?
I think we have here a tiny mixture of mathematic question and programming.
first of all, please note that the spaces are important in coding. see how the code should look like. (with the spaces)
def smallest_multiple(n):
if (n<=2):
return n
i = n * 2
factors = [number for number in range(n, 1, -1) if number * 2 > n]
print(factors)
while True:
for a in factors:
if i % a != 0:
i += n
break
if (a == factors[-1] and i % a == 0):
return i
1- Why does he create a list of numbers that are superior to the input by a factor of 2 ?
Answer : because the numbers that have their double smaller than the highest number will not affect / change the result. (This is a maths question) you can check that by removing the condition and you will see that you will get the same result (same smallest multiple)
2-And then the while loop is just difficult to understand. Could someone please explain it to me (I mean the content of the loop)? Thanks for your response?
Answer : The loop is using the boolean True as the code will only stops until it finds the smallest multiple for the first n numbers. the reason of the coder doing this because he has used the keyword return that will help him to exit the function, ultimately exiting the while loop.
The loop uses the value i which is the first multiple of the highest number of the first n numbers, meaning the double of the value n. Then will check if this first multiple (meaning i) is not dividable (i % a != 0) by the numbers in the list starting from the highest.
if i % a != 0:
i += n
break
this condition is there to increase the value of i as soon as i is not dividable by any number of the first n numbers meaning that the code keeps searching through the multiples of n (n being the highest number of the list) until i is dividable by all the numbers in the list
once the i value is able to satisfy the condition below
if (a == factors[-1] and i % a == 0):
then the while loop is exited through the keyword return which exits the function and the i value is sent as a response to the function call through the line return i
also note that factors[-1] is the last item (number) of the list.
I hope the above make sense and is clear to you.

Is there something wrong with my if-else statements?

Given an integer, , perform the following conditional actions:
If is odd, print Weird
If is even and in the inclusive range of 2 to 5, print Not Weird
If is even and in the inclusive range of 6 to 20, print Weird
If is even and greater than 20, print Not Weird
Every time I run the code, it only executes the else statement else: print("lol") , whether I type any value from 1 to 25.
What's wrong?
n = input("Enter a number here: ")
num = int(n)
if (num % 2) == 0 >= 2 and (num % 2) == 0 <= 5:
print("Not Weird")
elif num % 2 == 0 >= 6 and num % 2 == 0 <= 20:
print("Weird")
elif num % 2 == 0 > 20:
print("Not Weird")
else:
print("lol")
(num % 2) == 0 >= 2 is not the correct way to check if a number is even and in the range you want. If you want to check if num is even and in that range, you'd do something like:
(((num % 2) == 0) and (1 < num <= 5))
As others have pointed out your conditions are not written correctly. Here's the first part to get you started (if the number is odd, and if the number is even and between 2 and 5):
n = input("Enter a number here: ")
num = int(n)
isEven = (num % 2) == 0
if not isEven:
print("Weird")
elif 2 <= num <= 5:
print("Not Weird")
Just as Random Davis said , the problem is in precedence(or whatever it is called sorry XD) so what it does is :
when you check for [(num % 2) == 0 >= 2] : what it does is first checks if num is even[(num % 2)] and then it checks the relation between 0 and 2[0 >= 2] and then equates [ [(num % 2){maybe true or false} == (0 >= 2){always false}]] which results in a LOGICAL ERROR
Rather what you should do is this
(((num % 2) == 0) and (1 < num <= 5)) {just as Random Davis said.}
what it does is checks whether number is even or not[(num % 2) == 0)] and then if number is between 1 and 5[(1 < num <= 5)] and then cheks if both are true or not.
Hope you understand what I am trying to say.
There are a couple of problems with your solution. There is nothing wrong with your if-else statements. They are valid, but are not doing what you want. Looking at the first if:
if (num % 2) == 0 >= 2 and (num % 2) == 0 <= 5:
print("Not Weird")
You first use modulo and test for equality with 0, which is a reasonable test for even vs odd. However, you then compare the boolean result of the even-add test with the number 2. You want to test num with 2, not the boolean of evenness with 2. Testing a boolean result for >= 2 always comes out false. That is True >= 2 is False; and False >=2 is False. Python is smart enough to know that False and (anything else) will be false, so Python won't even evaluate the rest of the statement.
So to test if a number is even and in the range of 2 to 5 inclusive you should want to do:
if num % 2 == 0 and 2 <= num <= 5 :
print("Not Weird")
A few words about Python: Python differs from other languages in that the form "2 <= num <= 5" is a legal construct. It is darn convenient, but atypical among languages. In other languages the initial 2<=num results in a boolean and then then you would get an error comparing a boolean to 5. It is interesting that Python does not throw an error but results in a boolean. Though Python is atypical it is useful. Other languages would require something like
if (2 <= num) and (num <= 5) then # Not a Python statement!
Another oddity is that the and operator is lower precedence than the other comparison operators. In other languages and is higher or equal. The Python rules of precedence let you use "num % 2 == 0 and 2 <= num <= 5", so the evenness test and the double inequality run before the "and", so you get a natureal human result. BUT IT IS DIFFERENT FROM OTHER LANGUAGES. You will probably learn a lot of languages over the years. Appreciate how they work.
I'll let you figure out the rest of the statements in your original solution. However, there is another problem: You don't handle odd numbers in your solution correctly, since you are printing out lol. For debugging you are doing the correct thing, since the printing of "Weird" for odd numbers is an ambiguous result. If you did that on purpose for debugging, CONGRATULATIONS!, you are thinking like a programmer digging through your program.
I submit that your approach is a bit of a brute force approach. The directions do say:
If is odd, print Weird
If is even and in the inclusive range of 2 to 5, print Not Weird
If is even and in the inclusive range of 6 to 20, print Weird
If is even and greater than 20, print Not Weird
As a programmer, you do not have to follow the given directions. You need to formulate a solution that results in an algorithm that meets the specifications. Part of the art of programming is to recognize whether the specs are subject to change, anticipate needs for updates, and even correct some assumptions that the specs make that might be in error. So while this is a simple task, it is rich in teaching. (Kudo's to your instructor).
One way to look at the specs is that it implies non-negative inputs. What is one to do with -4 or 0? Not in the specs. It is fair to look at proposed input and see what it is so you can handle that case. Sometimes other logic is added to reject illegal entries. It isn't specified here, so I would handle it with a comment in the code that input is expected to be a positive non-zero integer.
In addition, there is a certain approach that is a bit more wholistic: If odd print Weird and quit, otherwise you know num is even, so further checking is not needed for evenness. So then you print Weird for num in the range [6..20], otherwise print Not Weird. The big picture is odds print Weird, any number [6..20] prints Weird, everything else prints Not Weird.
if num % 2 == 1 : # Handle odd num
print("Weird") # Any odd prints Weird
else: # Handle even num
if 6 <= num <= 20:
print("Weird")
else:
print("Not Weird")
The point is once you do a test you know womething that can be carried forward in your code. Once you test that something is odd, handle it, and after that the code knows the number if not odd is even, and you don't have to keep testing it. Logically, if odd print and be done. Otherwise (num is even) print "Weird" for num in [6..20], print "Not Weird" otherwise. Rather than 3 tests when a number is even now there is just the one test for num being in the range [6..20].
A few comments are sprinkled in. No testing for input less than 1.
The whole thing could be simplified further
if num % 2 == 1 or 6 <= num <= 20: print("Weird")
else:print("Not Weird")
That does simplify the whole thing.
It is interesting that in programming the simple question of "what is wrong with my statement" can sometimes be addressed with "should I be using this approach?" I've gone far afield with this answer. Originally, what's with my if statement was the issue, but this little gem of a problem is really teaching a lot. (Again, Kudo's to the teacher!)
So, do you transform thw whole question and use an or, or does the first approach work better. In the real world you might have a sense of how the specification may be changed and your solution will be best when it is correct, uses reasonable resources, and is maintainable.

Python: Adding odd numbers together from an input

Have a little problem. I'm writing a simple program that takes an input of numbers (for example, 1567) and it adds the odd numbers together as well as lists them in the output. Here is my code:
import math
def oddsum(n):
y=n%10
if(y==0):
return
if(y%2!=0):
oddsum(int(n/10))
print (str(y),end="")
print (" ",end="")
else:
oddsum(int(n/10))
def main():
n=int(input("Enter a value : "))
print("The odd numbers are ",end="")
oddsum(n)
s = 0
while n!=0:
y=n%10
if(y%2!=0):
s += y
n //= 10
print("The sum would be ",end=' ')
print("=",s)
return
main()
It outputs just fine, in the example it will print 1 5 and 7 as the odd numbers. However, when it calculates the sum, it just says "7" instead of 13 like it should be. I can't really understand the logic behind what I'm doing wrong. If anyone could help me out a bit I'd appreciate it :)
I understand it's an issue with the "s += y" as it's just adding the 7 basically, but I'm not sure how to grab the 3 numbers of the output and add them together.
As #Anthony mentions, your code forever stays at 156 since it is an even num.
I would suggest you directly use the string input and loop through each element.
n = input("Enter a value : ") #'1567'
sum_of_input = sum(int(i) for i in n if int(i)%2) #1+5+7=13
[print(i, end="") for i in n if int(i)%2] #prints '157'
Note that int(i)%2 will return 1 if it is odd.
1567 % 10 will return 7. You might want to add the numbers you printed in oddsum to a list, and use the sum function on that list to return the right answer.
The immediate issue is that n only changes if the remainder is odd. eg 1,567 will correctly grab 7 and then n=156. 156 is even, so s fails to increment and n fails to divide by 10, instead sitting forever at 156.
More broadly, why aren't you taking advantage of your function? You're already looping through to figure out if a number is odd. You could add a global parameter (or just keep passing it down) to increment it.
And on a even more efficient scale, you don't need recursion to do this. You could take advantage of python's abilities to do lists. Convert your number (1567) into a string ('1567') and then loop through the string characters:
total = 0
for c in '1567':
c_int = int(c)
if c_int%2!= 0:
total += c_int
print(c)
print(total)

Can This Solution to the Google Foobar "Re-ID" be more efficient? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 2 years ago.
Improve this question
I'm looking for guidance on a better way to solve Google's Re-ID problem. Instead of typing out the "Re-ID" description here, I will simply list the pertinent parts:
There are 10,000 "Minions" each of which are assigned an integer randomly between 0 and 10000 inclusive.
The Minion will look up his integer as an index in a string of concatenated prime numbers - i.e. 2357111317192329...
His new "ID" is generated by finding the index value in the string according to the Minion's integer assignment and concatenating the next 4 numbers with it - i.e. if the Minion's integer assignment is 3 his new ID would be 71113 (7 is the value at index 3 of the string, then we add the next 4 digits/characters)
To solve this I:
Utilized (thanks again, SO) a function to identify if a number is prime or not: is_prime()
Generated a string of all prime numbers concatenated together which facilitates a Minion with assignment "10000" plus the next 4 characters.
Created a function to generate the new ID based on the Minion's assignment and the string of concatenated values: answer()
import math
def is_prime(n):
if n % 2 == 0 and n > 2:
return False
return all(n % i for i in range(3, int(math.sqrt(n)) + 1, 2))
primes = ''
for i in range(2,21000,1):
if len(primes) < 10005:
if is_prime(i):
primes = primes + str(i)
else:
break
def answer(n):
re_id = primes[n:n+5:1]
return(re_id)
Areas of possible improvement
The 21000 in my for loop is completely arbitrary. By trial and error I found 21,000 facilitates a Minion integer assignment of 10000 plus the 5 additional digits/characters.
Is it necessary to create this long string of concatenated prime numbers before hand? Could it not be done dynamically based on the Minion ID?
Thanks for your insights. Happy Friday.
I have used this code to complete the challenge..
def solution(b):
bag = "2"
for num in range(0,20500):
if num > 1:
for j in range(2,num):
if (num % j) == 0:
break
elif len(bag) >= 10006:
break
elif j==num-1:
bag += str(num)
break
else:
continue
return bag[b:b+5]

Categories

Resources