Reversing a number using recursion - python-3.x

I was tasked with reversing an integer recursively. I have an idea of how to formulate my base case but I'm unsure of what to put outside of the if statement. The parts I was unsure about are commented with question marks. With the first part, I don't know what to put and with the second part I'm unsure about whether it is correct or not.Thank you for the help.
Note: I'd like to avoid using external functions such as imports and things like these if possible.
def reverseDisplay(number):
if number < 10:
return number
return # ??????????
def main():
number = int(input("Enter a number: "))
print(number,end="") #???????????
reverseDisplay(number)
main()

I'm not going to give you the answer, but I'll give some hints. It looks like you don't want to convert it to a string -- this makes it a more interesting problem, but will result in some funky behavior. For example, reverseDisplay(100) = 1.
However, if you don't yet have a good handle on recursion, I would strongly recommend that you convert the input to a string and try to recursively reverse that string. Once you understand how to do that, an arithmetic approach will be much more straightforward.
Your base case is solid. A digit reversed is that same digit.
def reverseDisplay(n):
if n < 10:
return n
last_digit = # ??? 12345 -> 4
other_digits = # ??? You'll use last_digit for this. 12345 -> 1234
return last_digit * 10 ** ??? + reverseDisplay(???)
# ** is the exponent operator. If the last digit is 5, this is going to be 500...
# how many zeroes do we want? why?
If you don't want to use any string operations whatsoever, you might have to write your own function for getting the number of digits in an integer. Why? Where will you use it?
Imagine that you have a string 12345.
reverseDisplay(12345) is really
5 + reverseDisplay(1234) ->
4 + reverseDisplay(123) ->
3 + reverseDisplay(12) ->
2 + reverseDisplay(1) ->
1

Honestly, it might be a terrible idea, but who knows may be it will help:
Convert it to string.
Reverse the string using the recursion. Basically take char from the back, append to the front.
Parse it again.
Not the best performing solution, but a solution...
Otherwise there is gotta be some formula. For instance here:
https://math.stackexchange.com/questions/323268/formula-to-reverse-digits

Suppose you have a list of digits, that you want to turn into an int:
[1,2,3,4] -> 1234
You do this by 1*10^3 + 2*10^2 + 3*10^1 + 4.*10^0. The powers of 10 are exactly reversed in the case that you want to reverse the number. This is done as follows:
def reverse(n):
if n<10:
return n
return (n%10)*10**(int(math.log(n,10))) + reverse(n//10)
That math.log stuff simply determines the number of digits in the number, and therefore the power of 10 that should be multiplied.
Output:
In [78]: reverse(1234)
Out[78]: 4321
In [79]: reverse(123)
Out[79]: 321
In [80]: reverse(12)
Out[80]: 21
In [81]: reverse(1)
Out[81]: 1
In [82]: reverse(0)
Out[82]: 0

Does exactly what #GregS suggested in his comment. Key to reverse is to extract the last digit using the modulos operator and convert each extracted digit to a string, then simply join them back into the reverse of the string:
def reverseDisplay(number):
if number < 10:
return str(number)
return str(number % 10) + reverseDisplay(number / 10)
def main():
print (reverseDisplay(int(input("Enter a number: "))))
main()
Alternative method without using recursion:
def reverseDisplay(number):
return str(number)[::-1]

Related

Issue with ASCii in Python3

I am trying to convert a string of varchar to ascii. Then i'm trying to make it so any number that's not 3 digits has a 0 in front of it. then i'm trying to add a 1 to the very beginning of the string and then i'm trying to make it a large number that I can apply math to it.
I've tried a lot of different coding techniques. The closest I've gotten is below:
s = 'Ak'
for c in s:
mgk = (''.join(str(ord(c)) for c in s))
num = [mgk]
var = 1
num.insert(0, var)
mgc = lambda num: int(''.join(str(i) for i in num))
num = mgc(num)
print(num)
With this code I get the output: 165107
It's almost doing exactly what I need to do but it's taking out the 0 from the ord(A) which is 65. I want it to be 165. everything else seems to be working great. I'm using '%03d'% to insert the 0.
How I want it to work is:
Get the ord() value from a string of numbers and letters.
if the ord() value is less than 100 (ex: A = 65, add a 0 to make it a 3 digit number)
take the ord() values and combine them into 1 number. 0 needs to stay in from of 65. then add a one to the list. so basically the output will look like:
1065107
I want to make sure I can take that number and apply math to it.
I have this code too:
s = 'Ak'
for c in s:
s = ord(c)
s = '%03d'%s
mgk = (''.join(str(s)))
s = [mgk]
var = 1
s.insert(0, var)
mgc = lambda s: int(''.join(str(i) for i in s))
s = mgc(s)
print(s)
but then it counts each letter as its own element and it will not combine them and I only want the one in front of the very first number.
When the number is converted to an integer, it
Is this what you want? I am kinda confused:
a = 'Ak'
result = '1' + ''.join(str(f'{ord(char):03d}') for char in a)
print(result) # 1065107
# to make it a number just do:
my_int = int(result)

Convert S to T by performing K operations (HackerRank)

I was solving a problem on HackerRank. It required me to see if it is possible to convert string s to string t by performing k operations.
https://www.hackerrank.com/challenges/append-and-delete/problem
The operations we can perform are: appending a lowercase letter to the end of s or removing a lowercase letter from the end of s. For example Ash Ashley 2 would return No since we need 3 operations, not 2.
I tried solving the problem as follows:
def appendAndDelete(s, t, k):
if len(s) > len(t):
maxs = [s,t]
else:
maxs = [t,s]
maximum = maxs[0]
minimum = maxs[1]
k -= len(maximum) - len(minimum)
substr = maximum[len(minimum): len(maximum)]
maximum = maximum.replace(substr, '')
i = 0
while i < len(maximum):
if maximum[i] != minimum[i]:
k -= (len(maximum)-i)*2
break
i += 1
if k < 0:
return 'No'
else:
return 'Yes'
However, it fails at this weird test case. y yu 2. The expected answer is No but according to my code, it would return Yes since only one operation was required. Is there something I do not understand?
Since you don't explain your idea, it's difficult for us to understand
what you mean in your code and debug it to tell you where you went wrong.
However, I would like to share my idea(I solved this on the website too)-
len1 => Length of first string s.
len2 => Length of second/target string t.
Exactly K makes it a bit tricky. So, if len1 + len2 <= k, you can blindly assume it can be accomplished and return true since we can delete empty string many times to get an empty string(as it says) and we can delete characters of one string entirely and keep appending new letters to get the another.
When we start matching s with t from left to right, this looks more like longest common prefix but this is NOT the case. Let's take an example -
aaaaaaaaa (source)
aaaa (target)
7 (k)
Here, up till aaaa it's common and looks like there are additional 5 a's in the source. So, we can delete those 5 a's and get the target but 5 != 7, hence it appears to be a No. But this ain't the case since we can delete an a from the source just like that and append it again(2 operations) just to satisfy k. So, it need not be longest common prefix all the time, however it gets us closer to the solution.
So, let's match both strings from left to right and stop when there is a mismatch. Let's assume we got this index in a variable called first_unmatched. Initialize first_unmatched = min(len(s),len(t)) at the beginning of your method itself.
Let
rem1 = len1 - first_unmatched
rem2 = len2 - first_unmatched
where rem1 is remaining substring of s and rem2 is the remaining substring of t.
Now, comes the conditions.
if(rem1 + rem2 == k) return true-
This is because rem1 characters to delete and rem2 characters to add. If both sum up to k then it's possible.
if(rem1 + rem2 > k) return false-
This is because rem1 characters to delete and rem2 characters to add. If both sum greater than k then it's not possible.
if(rem1 + rem2 < k) return (k - (rem1 + rem2)) % 2 == 0-
This is because rem1 characters to delete and rem2 characters to add. If both sum less than k, then it depends.
Here, (k - (rem1 + rem2)) will give you the extra in k. This extra can or cannot depends upon whether it's divisible by 2 or not. Here, we do %2 because we have 2 operations in our question - delete and append. If the extra k falls short of any operation, then the answer is No, else it's a Yes.
You can cross check this with above example.

Making one string the anagram of other

I have a problem where two strings of same length are given, and I have to tell how many letters I have to change in the first string to make it an anagram of the second.
Here is what I did:
count = 0
Mutable_str = ''.join(sorted("hhpddlnnsjfoyxpci"))
Ref_str = ''.join(sorted("ioigvjqzfbpllssuj"))
i = 0
while i < len(Mutable_str):
if Mutable_str[i] != Ref_str[i]:
count += 1
i += 1
print(count)
My algorithm in this case returned 16 as result. But the correct answer is 10. Can someone tell me what is wrong in my code?
Thank you very much!
You need to use str.count
So you need to add up the differences between the number of occurrences of each character in the different strings. This can be done with str.count(c) where c is each distinct character in the second string (got with set()). We then need to use max() on the difference with 0 so that if the difference is negative this doesn't effect the total differences.
So as you can see, it boils down to one neat little one-liner:
def changes(s1, s2):
return sum(max(0, s2.count(c) - s1.count(c)) for c in set(s2))
and some tests:
>>> changes("hhpddlnnsjfoyxpci", "ioigvjqzfbpllssuj")
10
>>> changes("abc", "bcd")
1
>>> changes("jimmy", "bobby")
4

Python - Iterate through a list, swapping alphbets by indexes?

I need to write a code that makes alphabets rotate, through 2 lists.
So I need to define a function, let's say it is called rotate_text.
2 parameters are passed, 1 is string and 1 is integer.
This is my code so far:
def rotate_text(text, n):
plaintext = ['ABCDEFGHIJKLMNOPQRSTUVWXYZ']
ciphertext = ['FGHIJKLMNOPQRSTUVWYXZABCDE']
rotated_text = []
for i in plaintext:
rotated_text = ciphertext[plaintext[i + n]]
result = ''.join(rotated_text)
return result
So what it needs to do is, if I put ABC for the parameter text and for 2 for the parameter n,
A should return CDE as the result. Or DOG and 11 should return OBK. I don't really think I need that cipertext list so I think I will take that out, but how do I make this code work?
If the program gets ABC as the text, it should find A's index from plaintext list and + n to that index, and find the letter satisfies with plused n index from plaintext list and then.... I am getting a headache.
Can anyone help?
How about this code? A text should be only capital character.
def rotate_text(text, n):
for i in len(text):
number = ord(text[i]) - ord('A')
number = (number + n) % 26
text[i] = chr(number + ord('A'))
return text
If you want to use lower case too, you should use if statements.

How to turn a random 3 digit input (numbers) to 3 seperate integers in Python 3

So as the title says, I need to take a user input (e.g. 456) and seperate those numbers so I end up with 4, 5 and 6. The input won't ever be more than 3 digits, however it could be any 3 digits, and it is always going to be numbers. I am very new to Python and coding in general, so my code is sloppy, messy and probably (very) wrong.
The code I have currently is as follows:
`
myint=input
mystr=str(myint)
print(mystr)
mystr[0]
mystr[1]
mystr[2]
int(mystr[0])
int(mystr[1])
int(mystr[2])
globals() mystr[0] = a mystr[1] = b mystr[2] = c
`
This all takes place within my first function
x = raw_input("Please enter a number")
y = [int(x[0]), int(x[1]), int(x[2])]
You can access the different digits using y[0], y[1] and y[2]
create a string from the input like: str(number)
and then iterate through
number = 456
number = str(number)
for i in range(len(number)):
print(number[i])
you should take a look at "strings" "lists" and "arrays" in python and how to handle them. It's pretty basic stuff
You should always remember that a string is an array of chars. That is how Python handles them and you can always call a position of the array.
In order to separate an integer into separate digits, you can use this one-liner:
digits = [int(i) for i in str(original_number)]
This way is more flexible than the accepted answer above, which hard-codes the indexes. Not that it's wrong, but just not as flexible in the case that you have a much larger amount of numbers. At some point, you'll want to do it more programmatically. Hope this helps too!

Resources