how to understand happy number from leetcode - python

Here is the problem from leetcode:
Write an algorithm to determine if a number is "happy".
A happy number is a number defined by the following process: Starting with any positive integer, replace the number by the sum of the squares of its digits, and repeat the process until the number equals 1 (where it will stay), or it loops endlessly in a cycle which does not include 1. Those numbers for which this process ends in 1 are happy numbers.
Example: 19 is a happy number
12 + 92 = 82
82 + 22 = 68
62 + 82 = 100
12 + 02 + 02 = 1
question 1: from my understanding, if 1 happens,return True else it will infinitely runs the loop where i understand from this sentence "or it loops endlessly in a cycle which does not include 1."
However,after i found some answer to this questions from internet, i found my understanding was wrong.It is supposed to be if 1 happens return True,**also if any number repeats in the set, then end the loop and return False.**Well, be honestly, the problem says "or it loops endlessly in a cycle which does not include 1." why we just let the program run endlessly in a cycle as it states??
questions 2: For the second question, i think it is about understanding the codes.This is what i found from internet:
def isHappy(n):
stop = {1}
while n not in stop:
stop.add(n)
n = sum(int(d)**2 for d in str(n))
return n == 1
From this codes, i can understand that if 1 happens, it will stop running the while loop and return True.However, if repeat number happens in the set, i think it also will stop running the while loop and return True,becuase next line followed by while statement is still return n==1.However, in fact it will output False.e.g
since 89 repeats again in the set, output False.
Sorry for my wordy description.Simply speaking, my questions is how this false comes out? in the coding, there is no place explicitly return False

The isHappy function you posted is correct.
This is how it works -
It will calculate the squares of the digits and save it in n.
If n is 1 it stops. Else, it appends n to change list and loops. But as soon as n is any number which is there in the change list, the loop breaks.
In Python, when control comes out of the loop, it has the last values stored in variables. So, n has the last calculation stored.
Now, if n is 1, n == 1 returns True else False.
Hope that helps.

This is how I did , even though it is a bit messy
#Python program to check if a number is a happy number
#Creating an user defined function which returns True if the number is happy else False
def happy(num) :
#Creating a copy of the number in a string and a iterating point
copy = str(num)
square = num
#Proceeding with while loop due to unknown iterations
while True : #inifinte loop
square = sum(int(j) ** 2 for j in list(str(square))) #Sum of the number's digit squares
if square == 1:
test = True
break
elif square == 4:
test = False
break
return test
check = int(input('Enter the number: '))
print('The number {} {} a happy number'.format(check, ('is') if happy(check) == True else ('is not')))

below is a popular solution to the happy number problem. this key is the sum of square of each digit did not appear in the past, otherwise, there will be an endless loop.
class Solution:
# #param {integer} n
# #return {boolean}
def isHappy(self, n):
s=set()
while n!=1 and n not in s:
s.add(n)
n= sum([int(x)**2 for x in str(n)])
return n==1

Related

WAP in python script to input a multidigit number and find each of the number's factorial

The output shows a different result. Yes, the factorials of those numbers are right but the numbers outputted aren't right.
Here's the code:
input:
n = int(input("Enter a number: "))
s = 0
fact = 1
a = 1
for i in range(len(str(n))):
r = n % 10
s += r
n //= 10
while a <= s:
fact *= a
a += 1
print('The factorial of', s, 'is', fact)
Output:
Enter a number: 123
The factorial of 3 is 6
The factorial of 5 is 120
The factorial of 6 is 720
You're confusing yourself by doing it all in one logic block. The logic for finding a factorial is easy, as is the logic for parsing through strings character by character. However, it is easy to get lost in trying to keep the program "simple," as you have.
Programming is taking your problem, designing a solution, breaking that solution down into as many simple, repeatable individual logic steps as possible, and then telling the computer how to do every simple step you need, and what order they need to be done in to accomplish your goal.
Your program has 3 functions.
The first is taking in input data.
input("Give number. Now.")
The second is finding individual numbers in that input.
for character in input("Give number. Now."):
try:
int(character)
except:
pass
The third is calculating factorials for the number from step 2. I won't give an example of this.
Here is a working program, that is, in my opinion, much more readable and easier to look at than yours and others here. Edit: it also prevents a non numerical character from halting execution, as well as using only basic Python logic.
def factorialize(int_in):
int_out = int_in
int_multiplier = int_in - 1
while int_multiplier >= 1:
int_out = int_out * int_multiplier
int_multiplier -= 1
return int_out
def factorialize_multinumber_string(str_in):
for value in str_in:
print(value)
try:
print("The factorial of {} is {}".format(value, factorialize(int(value))))
except:
pass
factorialize_multinumber_string(input("Please enter a series of single digits."))
You can use map function to get every single digit from number:
n = int(input("Enter a number: "))
digits = map(int, str(n))
for i in digits:
fact = 1
a = 1
while a <= i:
fact *= a
a += 1
print('The factorial of', i, 'is', fact)
Ok, apart from the fact that you print the wrong variable, there's a bigger error. You are assuming that your digits are ever increasing, like in 123. Try your code with 321... (this is true of Karol's answer as well). And you need to handle digit zero, too
What you need is to restart the calculation of the factorial from scratch for every digit. For example:
n = '2063'
for ch in reversed(n):
x = int(ch)
if x == 0:
print(f'fact of {x} is 1')
else:
fact = 1
for k in range(2,x+1):
fact *= k
print(f'fact of {x} is {fact}')

Change in variable values upon recursion, Python 3

Hey so im pretty new to programming in general and I was having a crack at a question I found for the collatz function,
The code I wrote after some trial and error is as follows:
def collatz(number):
if number % 2 == 0:
number = number//2
print(number)
return number
elif number%2 != 0:
number = 3*number + 1
print(number)
return number
n = int(input("plz enter the number:"))
while n != 1:
n = collatz(n)
Output:
plz enter the number:3
10
5
16
8
4
2
1
This code works but im not sure how the variable values are being alloted, cuz after running this program I can see that in the shell "number = 3" but "n = 1", why is this the case? Shouldnt "number" also equal to 1? Because I am returning the value of number within the function?
Also just to clear my concepts, at the initial moment when I input n = 3, at that moment n = number = 3, then does this returned value of "number" automatically become the new value of n, when i call it in the while loop?
Just wanted to check cuz im a little weak when it comes to doing stuff that needs to pass parameters.
edit:
Why is this case diff then what was just answered?
def testfile(number):
number = number -1
print(number)
return number
n = int(input("enter:"))
while n != 2:
n = testfile(n)
Output:
enter:5
4
3
2
When the input is given as n = 5, then why does number = 3 instead of 5 as was just explained below?
Here's how your program works.
You ask for a number and store it in variable n.
You open a loop which continues until n is 1
Every time the loop repeats, you're calling your function and passing a COPY of n. If you add one to the copy inside the function, your original n will not change.
The COPY is called number. You perform your little tricks with number, output it to the screen, and here's the confusing part: you return a copy of number right back to your loop. And where does it go? It goes right back to n. This overwrites whatever was in n previously.

I have some problem with my homework. It's about stop the loops

I'm in the middle of my homework. And i can't find out how to do this solution.
I have tried to used the break under for-statement but nothing return.
The problem is "Complete the following program so that the loop stops when it has found the smallest positive integer greater than 1000 that is divisible by both 33 and 273."
This is my code that i have tried to do it
n = 1001 #This one is required
while True: #This one too
for i in range(n,___): # I don't know what should i put in the blank
if i%33 == 0 and i%273 == 0: # I really confused about this line
break # Should i break it now?, or in the other lines?
print(f"The value of n is {n}") #This one is also required
I don't know that i should put break in which lines (or i don't have to used it?) or i should created a function that called a minimum number of the list?
I'm sorry about my language and how silly i am at my programming skill
I would accept every comment. Thank you
You already have a while True: loop, you don't need the inner for loop to search for your number, just keep incrementing n in the while loop instead of adding a new counter, when the number you're looking for is found, the infinite while True: loop will stop (using break), and so your print statement will be executed:
n = 1001 # start at 1001
while True: # start infinite loop
if n % 33 == 0 and n % 273 == 0: # if `n` found
break # exit the loop
n += 1 # else, increment `n` and repeat
print(f"The value of n is {n}") # done, print the result
Output:
The value of n is 3003
Thanks for saying it's homework! Makes it better to explain things in more detail than just giving an answer.
There are few things to explain:
1) n%33 is the remainder of dividing n by 33. So 66%33 is 0 and 67%33 is 1.
2) For loops are generally when you need to loop over a defined range (not always, but usually). E.g. "add up the first 100 integers". A while loop makes more sense here. It will definitely terminate, because at some point you'll get to 33 * 237.
3) if i%33 == 0 and i%237 == 0: means we want to do something when the number can be divided evenly (no remainder) by both 37 and 237.
n=1001
while True:
if n%33==0 and n%237==0:
print(n)
break
n+=1
A for loop will not help you here, because you don't know when to end the loop. You usually use for loops when the range of things you want to loop over is already known.
Instead, do the following:
before starting your while: True loop: set i to 0,
then increase i with 1 every time to the loop
also, don't forget to stop the loop when i>1000!
Well you could still use a for loop, as long as the upper limit is at least as high as the maximum possible result. The result would be in i, not in n, and the for loop will suffice, not an additional while loop. The for loop will break when the remainder when dividing by both 33 and 237 is zero (i.e. they are both factors).
n = 1001 #This one is required
for i in range(n, 33 * 237 + 1): # I don't know what should i put in the blank
if i % 33 == 0 and i % 237 == 0: # I really confused about this line
break #
print(f"The value of i is {i}") #This one is also required
You could also use a while loop and use the same logic for the condition. In this case we test that at least one is not a factor and continue the loop until both 33 and 237 are evenly divisible into i.
n = 1001 #This one is required
i = n
while i % 33 or i % 237:
i += 1
print(f"The value of i is {i}")

While loop ignores conditionals (if, else) and just prints first suggested print option

I am trying to create a program that prints out a list of numbers starting at 0 and leading up to a number the user inputs (represented by the variable "number"). I am required to use "while" loops to solve this problem (I already have a functional "for" loop version of the assignment). The program should mark anything in that list divisible by 3 with the word "Fizz," divisible by 5 with the word "Buzz," and anything divisible by both with "FizzBuzz" while also including unlabeled numbers outside of those specifications.
Every time I run this program, it ignores the conditions and just prints the word "FizzBuzz" however many times is represented by the number inputted. (I typically use 15 because it has at least one example of each condition, so that means I get 15 "FizzBuzz"s in a row).
To find out why it was doing that, I used print(i) instead of the rest of the program under the first conditional and it gave me 15 counts of the number 0, so there is reason to believe the program is completely ignoring the range I gave it and just outputting copies of i based on the user number input.
Any help would be appreciated!
number = int(input("Enter a Number"))
i = 0
while(i < number + 1):
if number % 3 == 0 and number % 5 == 0:
print("Fizzbuzz")
elif number % 5 == 0:
print("Buzz")
elif number % 3 == 0:
print("Fizz")
else:
print(number)
i += 1
print ("Done!")
You meant to check the divisibility of i, which increments every loop, not of number which doesn't change.
You also meant to print(i) in the else clause.

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)

Categories

Resources