This question already has answers here:
How to take the nth digit of a number in python
(7 answers)
Closed 8 months ago.
I want to check if there is a specific digit (let's say 8) in a specific integer (let's say 83) at a specific place (let's say second place). In this example, the answer is True. I wrote the following function :
def check_number(integer: int, digit: int, place: int) -> bool:
if str(integer)[::-1][place-1] == str(digit) :
return True
return False
I want to have the more optimized way (in terms of speed) to do it as possible. Is my algorithm good or is there is better ?
A more optimized (though slightly uglier) approach would be to iterate over the integer and use division along with the modulus to check each digit:
import math
def check_number(integer: int, digit: int, place: int) -> bool:
while place > 1:
integer = math.floor(integer / 10)
place -= 1
if integer == 0:
return False
if integer % 10 == digit:
return True
else:
return False
print(check_number(12345, 3, 3)) # True
print(check_number(12345, 1, 5)) # True
print(check_number(12345, 4, 1)) # False
In the above in order to "queue up" the digit to be checked, we iterate in a while loop and divide the input by 10 however many times is required to put the digit to be examined in place into the tens position. Then we check that value using the modulus. Should the input not have a digit in that place, we return false, and likewise we return false should the digit exist but not match the input.
Note that in general the above solution is preferable to a string based solution, because the overhead in creating and manipulating a string is fairly high, much higher than doing simple division of the input integer.
Related
I was doing a programming challenge question where you need to found out if a given number (n) is equal to 3 raised to some exponent(x)
9 is True since 3^x -> 3^3 = 9
10 is False since no x for 3^x is equal to 10
my problem occurred when 243 was entered into my code, which returned a result of 4.999 repeating.
my solution was to simply add a round function, in which I arbitrarily decided on 5 decimal places, this solved the problem.
now another problem occurred when the input was 531440, this returns an x value of 11.999998287222695 which, according to the challenge, was false, but with my code returned a true since I rounded to the fifth decimal place. I then changed my round to 10 decimal places and this fixed the code.
I was wondering if there was a way to implement my solution without having to round, as I'm sure if I plugged in enough numbers eventually another one would need to round past >10 decimal places and cause my code to fail. Please see the code below.
import math as math
def isPowerOfThree(n):
print(math.log(n,3)) #this line prints the unrounded log result
print(round((math.log(n,3)),10)) #this line prints the rounded result
return n>0 and round((math.log(n,3)),10).is_integer()
n = 243
print(isPowerOfThree(n))
The 'trick' allowing to avoid problems with chosen precision is to round to an integer and then check if this exponent gives the required result. The code below implements this approach:
import math
def isPowerOfThree(N):
if 3**round(math.log(N,3)) == N:
return True
return False
N = 531440 # 243
print(isPowerOfThree(N)) # gives False
Another approach will be to check all powers of 3 against the target number:
def isPowerOfThree(N):
x = 1
while True:
n = 3**x
if n == N:
return True
elif n > N:
return False
x += 1
And here an approach detecting directly without the need to run multiple loop runs if a number is not a power of 3:
def isPowerOfThree(N):
while True:
N , r = divmod(N, 3)
if r != 0:
return False
if N == 1:
return True
P.S. the two last approaches provide code to what Karl Knechtel mentioned in his comment to the question.
My problem is that I'm trying to write a function PlusMinus(num) which will read the integer being passed, and determine if it's possible to separate the digits of the integer with either a plus or minus sign to form an expression which evaluates to zero.
For example: if num is 35132 then it's possible to separate the digits the following way, 3 - 5 + 1 + 3 - 2, and this expression equals 0.
The function should return a string of the signs used, so for this example the program should return "-++-". If it's not possible to get the digit expression to equal zero, it should return the string "not possible". If there are multiple ways to get the final expression to equal zero, it should return the one that contains more minus characters. For example: if num is 26712 the function should return "-+--" and not "+-+-".
Sample Test Cases:
Input: 199
Output: not possible
Input: 26712
Output: -+--
My code:
num=int(input())
PlusMinus(num)
def PlusMinus(num):
s=str(num)
l=len(s)
rs=''
r=0
if(l<2):
print("not possible")
else:
for i in range(1,l):
if i<2:
r=int(s[0])-int(s[1])
rs='-'
else:
if r<=0:
r=int(r)+int(s[i])
rs+='+'
else:
r=int(r)-int(s[i])
rs+='-'
if(r==0):
print(rs)
else:
print("not possible")
This is a fun problem. Your code works for the test cases you've outlined in your post, but the logic falls down in some cases. For example, your code naively attempts to add a subtract sign if the current sum is greater than 0, and a plus sign if not. This means that if we try:
945
--
We get the correct answer, however if we try:
459
not possible
We get an incorrect answer, as clearly 4 + 5 - 9 = 0, so we expect to get +-.
My approach to the problem would be to use itertools.product to generate all possible combinations of plus and minus signs, starting with ---... and ending with +++..., and loop through them in order, breaking if we find a solution. This brute force solution is also naive, as with some analysis & heuristics, we could eliminate a fair few solutions, but it does work and will provide the correct answer.
Code:
import itertools
def PlusMinus(num):
# make our num into a string
s=str(num)
# For each possible operations combination:
for op in itertools.product('-+', repeat=len(s)-1):
# If when applied, we make 0
if apply_ops(s, op) == 0:
# Return the operations as a string
return ''.join(op)
# If we've exhausted all possibilities, it's not possible
return 'not possible'
# Apply a series of operations op to a string s
def apply_ops(s, op):
# Set return val to the first digit of s
rv = int(s[0])
# For each remaining digit, either increment or decrement according to the
# operation
for i, n in enumerate(s[1:]):
if op[i] == '+':
rv += int(n)
else:
rv -= int(n)
# Return result
return rv
num=int(input())
print(PlusMinus(num))
Tests:
945
--
459
+-
26712
-+--
199
not possible
This question already has answers here:
What exactly does += do?
(17 answers)
Closed 3 years ago.
I am new to Python and found a function that checks to see if an array of arguments can be made equal by only multiplying the number by 2. However, there is some notation that I do not understand.
Function:
def isEqual(a,n): # a is an arrary, n is the length of array
for i in range(0,n):
while a[i]%2==0:
a[i]//=2 # this is the part I do not understand
print(a[i])
if a[i] != a[0]:
return print("False")
# Otherwise, all elements equal, return true
return print("True")
When I step through the function I see that it replaces the a[i] number by a[i]//2, but I do not understand why you would write // equals to number
I understand the // is "floor" division, but not why someone would write a[i]//=2. I would have thought to write it as a[i]=a[i]//2. I can only assume these are the same things, I just never saw it written this way.
Test code:
a = [50, 4, 2]
n = len(a)
isEqual(a, n)
You might have came across operations that also assign value. Think
a += 1 # same as: a = a + 1
This is exactly the same. It integer divides and assigns the value. Probably better understood with proper spacing:
a //= 2 # same as: a = a // 2
This question already has answers here:
Check if a digit is present in a list of numbers
(3 answers)
Closed 4 years ago.
I need to write function which can check if there is a specific digit in some entered number.
def number(m):
while (m>0):
n=m%10
m = m/100
if n==2:
return True
return False
some_number = 223
number(some_number)
For example I'm searching for number 2. But with this code it returns True only if number 2 is on last place.
Thanks.
You should divide by 10 instead of 100 in your code.
Also as Tilman B. aka Nerdyyy mention, you can just convert the integer to str, and search using in opearator:
def number(m):
return '2' in str(m)
You are close. Why do steps of 100? Do instead steps of 10 using floor division , otherwise you'll miss some algorisms and your loop will be waaay deeper than it should (for example, for the number 123, your loop as of now would check 12.3, 1.23, 0.123, 0.0123, 0.00123...... until it is so small that its computationally 0 - You don't want that, because you'd just be adding more and more zeros to your m and a 2 would never show up anyway).
def number(m):
while (m>0):
n = m%10
m = m//10
if n==2:
return True
return False
Checking
>> print(number(1))
False
>> print(number(2))
True
>> print(number(13))
False
>> print(number(12))
True
>> print(number(21))
True
>> print(number(11))
False
>> print(number(121))
True
I was doing an assignment question.
Write a program, divisible_by_11(num), to return the divisibility of num
by 11. i.e. divisible_by_11(num) should return True is num is divisible by 11,
or False otherwise. Implement this function recursively and using the following algorithm.
Note: a number is divisible by 11 if the difference between the sum of odd digits
and the sum of even digits is divisible by 11. Note that 0 is divisible by 11.
def divisible_by_11(num):
def helper(num,i):
if num==0:
return 0
elif i%2:
return helper(num//10,i+1)-num%10
Question is about replacing the above line with return -num%10+ helper(num//10,i+1)
elif i%2==0:
return num%10+helper(num//10,i+1)
return helper(num,0)%11==0
this code works, however if I wrote return -num%10+ helper(num//10,i+1) instead of return helper(num//10,i+1)-num%10, my code would fail. Can anyone tell me what's happening?
The issue with the alternate form is due to order of operations. The unary-minus operator binds more tightly than the mod operator. That is, the expression -num%10 is interpreted as (-num) % 10, and the modulus of a negative number is not the same thing as its last digit.
There are a few ways you could fix it. The easiest would probably be to add your own parentheses so that the mod happens first: return -(num%10) + helper(num//10,i+1) should work as expected.
Unrelated to that issue, I'm very skeptical that your assignment allows you to do %11 in the final return, since that operation is all you would need to solve the whole problem without the rest!
Instead, I suspect it wants you to use recursion for that part too (and maybe not for adding up the digits). Instead of return helper(num,0)%11==0, try:
while num > 10:
num = helper(num, 0)
return num == 0