I've Found How to do it for normal numbers which gives quotient above 1
How to find value for which we will get quotient below 1
For example if 28 divided by 500 it gives 0.056
How to implement above example without using division operator
There is not a way to do this, unless you count reciprocals. However, these are fractions which means they use divide.
For example:
>>> 30 / 5 # original calculation
6
>>> 30 * 0.2 # using the reciprocal of 5 – but no division sign visible!
6
However, this option clearly uses division. If you don't see it, here's how:
def divide(x, y):
return x * (1/y)
Because to make a number a reciprocal, you have to divide. But take into consideration that every whole number uses divide: 5 = 5/1, so it's just the same with a different denominator...
#in this case 18/2
e=18
t=2
o=0
l=t
count=0
t=0
for i in range(0,e):
t+=l
count+=1
if t==e:
o=1
print(count)
break
if (t+l) > e:
break
if o!=1:
c=e-t
print(count,'reminder of',c)
You indicate you already have something without division that handles cases with quotients greater than 1. If so, you can reduce your as yet unsolved case like 28/500 by doing 2800/500 and then getting around dividing by 100 (at least directly) by adding two decimal places. Since you want two significant figures, it seems, you actually would want to do 28000/500, at least if you did things as I am guessing you did.
Here's how that plays out in code:
def algorithm_you_already_have(a, b):
"""I assume a>b>0 you can add logic to handle negatives or check for b == 0
you say you already have something that works if a divided by b is greater than 1
Here is one thing you might have done, repeated subtraction"""
assert a > b # this was only working and for use when quotient was greater than 1, you said
assert b > 0 # cannot divide by 0, and not dealing with negatives here, could higher up
result = 0
while a >= b:
a -= b
result += 1
if a + a >= b: # round up if remainder is at least half of divisor
result += 1
return result
# assumes positives, you can add cases as needed
def algorithm_you_need(a, b):
assert a > 0
assert b > 0
temp_result = 0
if a == b:
return 1
if a > b:
return algorithm_you_already_have(a, b)
# still here, then a < b, which is the new case you need
places_shifted = 0
while a < b:
a *= 10
places_shifted += 1
if a == b:
temp_result = 1
else:
temp_result = algorithm_you_already_have(10 * a, b) # times 10 to get a second figure as desired
# but do not count is as a shift, because you are putting the next figure, if any, beyond the first
# process as string
temp_result = str(temp_result)
while places_shifted > 1:
temp_result = '0' + temp_result
places_shifted -= 1
temp_result ="0." + temp_result
return float(temp_result)
print(algorithm_you_need(28,500))
Related
I am solving a problem where I am given three integers (a,b,c), all three can be very large and (a>b>c)
I want to identify for which base between b and c, produces the smallest sum of digits, when we convert 'a' to that base.
For example a = 216, b=2, c=7 -> the output= 6, because: 216 base 2 = 11011000, and the sum of digits = 4, if we do the same for all bases between 2 and 7, we find that 216 base 6 produces the smallest sum of digits, because 216 base 6 = 1000, which has sum 1.
My question is, is there any function out there that can convert a number to any base in constant time faster than the below algorithm? Or any suggestions on how to optimise my algorithm?
from collections import defaultdict
n = int(input())
for _ in range(n):
(N,X) = map(int,input().split())
array = list(map(int,input().split()))
my_dict = defaultdict(int)
#original count of elements in array
for i in range(len(array)):
my_dict[array[i]] +=1
#ensure array contains distinct elements
array = set(array)
count = max(my_dict.values()) #count= max of single value
temp = count
res = None
XOR_count = float("inf")
if X==0:
print(count,0)
break
for j in array:
if j^X in my_dict:
curr = my_dict[j^X] + my_dict[j]
if curr>=count:
count = curr
XOR_count = min(my_dict[j],XOR_count)
if count ==temp:
XOR_count = 0
print(f"{count} {XOR_count}")
Here are some sample input and outputs:
Sample Input
3
3 2
1 2 3
5 100
1 2 3 4 5
4 1
2 2 6 6
Sample Output
2 1
1 0
2 0
Which for the problem I am solving runs into time limit exceeded error.
I found this link to be quite useful (https://www.purplemath.com/modules/logrules5.htm) in terms of converting log bases, which I can kind of see how it relates, but I couldn't use it to get a solution for my above problem.
You could separate the problem in smaller concerns by writing a function that returns the sum of digits in a given base and another one that returns a number expressed in a given base (base 2 to 36 in my example below):
def digitSum(N,b=10):
return N if N<b else N%b+digitSum(N//b,b)
digits = "0123456789abcdefghijklmnopqrstuvwxyz"
def asBase(N,b):
return "" if N==0 else asBase(N//b,b)+digits[N%b]
def lowestBase(N,a,b):
return asBase(N, min(range(a,b+1),key=lambda c:digitSum(N,c)) )
output:
print(lowestBase(216,2,7))
1000 # base 6
print(lowestBase(216,2,5))
11011000 # base 2
Note that both digitSum and asBase could be written as iterative instead of recursive if you're manipulating numbers that are greater than base^1000 and don't want to deal with recursion depth limits
Here's a procedural version of digitSum (to avoid recursion limits):
def digitSum(N,b=10):
result = 0
while N:
result += N%b
N //=b
return result
and returning only the base (not the encoded number):
def lowestBase(N,a,b):
return min(range(a,b+1),key=lambda c:digitSum(N,c))
# in which case you don't need the asBase() function at all.
With those changes results for a range of bases from 2 to 1000 are returned in less than 60 milliseconds:
lowestBase(10**250+1,2,1000) --> 10 in 57 ms
lowestBase(10**1000-1,2,1000) --> 3 in 47 ms
I don't know how large is "very large" but it is still sub-second for millions of bases (yet for a relatively smaller number):
lowestBase(10**10-1,2,1000000) --> 99999 in 0.47 second
lowestBase(10**25-7,2,1000000) --> 2 in 0.85 second
[EDIT] optimization
By providing a maximum sum to the digitSum() function, you can make it stop counting as soon as it goes beyond that maximum. This will allow the lowestBase() function to obtain potential improvements more efficiently based on its current best (minimal sum so far). Going through the bases backwards also gives a better chance of hitting small digit sums faster (thus leveraging the maxSum parameter of digitSum()):
def digitSum(N,b=10,maxSum=None):
result = 0
while N:
result += N%b
if maxSum and result>=maxSum:break
N //= b
return result
def lowestBase(N,a,b):
minBase = a
minSum = digitSum(N,a)
for base in range(b,a,-1):
if N%base >= minSum: continue # last digit already too large
baseSum = digitSum(N,base,minSum)
if baseSum < minSum:
minBase,minSum = base,baseSum
if minSum == 1: break
return minBase
This should yield a significant performance improvement in most cases.
I found this task and completely stuck with its solution.
A non-empty zero-indexed string S consisting of Q characters is given. The period of this string is the smallest positive integer P such that:
P ≤ Q / 2 and S[K] = S[K+P] for 0 ≤ K < Q − P.
For example, 7 is the period of “abracadabracadabra”. A positive integer M is the binary period of a positive integer N if M is the period of the binary representation of N.
For example, 1651 has the binary representation of "110011100111". Hence, its binary period is 5. On the other hand, 102 does not have a binary period, because its binary representation is “1100110” and it does not have a period.
Consider above scenarios & write a function in Python which will accept an integer N as the parameter. Given a positive integer N, the function returns the binary period of N or −1 if N does not have a binary period.
The attached code is still incorrect on some inputs (9, 11, 13, 17 etc). The goal is to find and fix the bugs in the implementation. You can modify at most 2 line.
def binary_period(n):
d = [0] * 30
l = 0
while n > 0:
d[l] = n % 2
n //= 2
l += 1
for p in range(1, 1 + l):
ok = True
for i in range(l - p):
if d[i] != d[i + p]:
ok = False
break
if ok:
return p
return -1
I was given this piece of code in an interview.
The aim of the exercice is to see where lies the bug.
As an input of the function, you will type the integer to see the binary period of it. As an example solution(4) will give you a binary number of 0011.
However, the question is the following: What is the bug?
The bug in this occasion is not some crash and burn code, rather a behavior that should happen and in the code, do not happen.
It is known as a logical error in the code. Logical error is the error when code do not break but doesn't fullfill the requirements.
Using a brute force on the code will not help as there are a billion possibilities.
However if you run the code, let's say from solutions(1) to solutions(100), you will see that the code runs without any glitch. Yet if you are looking at the code, it should return -1 if there are errors.
The code is not givin any -1 even if you run solutions to a with bigger number like 10000.
The bug here lies in the -1 that is not being triggered.
So let's go step by step on the code.
Could it be the while part?
while n > 0:
d[l] = n % 2
n //= 2
l += 1
If you look at the code, it is doing what it should be doing, changing the number given to a binary number, even if it is doing from a backward position. Instead of having 1011, you have 1101 but it does the job.
The issue lies rather in that part
for p in range(1, 1 + l):
ok = True
for i in range(l - p):
if d[i] != d[i + p]:
ok = False
break
if ok:
return p
return -1
It is not returning -1.
if you put some print on some part of the code like this, this would give you this
for p in range(1, 1 + l):
ok = True
for i in range(l - p):
print('l, which works as an incrementor is substracted to p of the first loop',p,l-p)
if d[i] != d[i + p]:
ok = False
break
if ok:
return p
return -1
If you run the whole script, actually, you can see that it is never ending even if d[i] is not equal anymore to d[i+p].
But why?
The reason is because l, the incrementor was built on an integer division. Because of that, you need to do a 1+l//2.
Which gives you the following
def solution(n):
d = [0] * 30
l = 0
while n > 0:
d[l] = n % 2
n //= 2
l += 1
for p in range(1, 1 + l//2): #here you put l//2
ok = True
print('p est ',p)
for i in range(l - p):
if d[i] != d[i + p]:
ok = False
break
if ok:
return
Now if you run the code with solutions(5) for example, the bug should be fixed and you should have -1.
Addendum:
This test is a difficult one with a not easy algorithm to deal with in very short time, with variables that does not make any sense.
First step would be to ask the following questions:
What is the input of the algorithm? In this case, it is an integer.
What is the expected output? In this case, a -1
Is it a logical error or a crash and burn kind of error? In this case, it is a logical error.
These step-by-step (heuristic) will set you on the right direction to debug a problem.
Following up Andy's solution and checking #hdlopez comment, there is a border case when passing int.MaxVal=2147483647
and if you do not increase the array size to 31 (instead of 30). The function throws an index out of range, so two places need to be modified:
1- int[] d = new int[31]; //changed 30 to 31 (unsigned integer)
2- for (p = 1; p < 1 + l / 2; ++p) //added division to l per statement, P ≤ Q / 2
Hello I have solved this leetcode question https://leetcode.com/problems/single-number-ii. The objective is to solve the problem in O(n) time and 0(1) space. The code I wrote is the following:
class Solution:
def singleNumber(self, nums: List[int]) -> int:
counter = [0 for i in range(32)]
result = 0
for i in range(32):
for num in nums:
if ((num >> i) & 1):
counter[i] += 1
result = result | ((counter[i] % 3) << i)
return self.convert(result)
#return result
def convert(self,x):
if x >= 2**31:
x = (~x & 0xffffffff) + 1
x = -x
return x
Now the interesting part is in the convert function, since python uses objects to store int as opposed to a 32 bit word or something, it does not know that the result is negative when the MSB of my counter is set to 1. I handle that by converting it to its 2's complement and returning the negative value.
Now someone else posted their solution with:
def convert(self, x):
if x >= 2**31:
x -= 2**32
return x
And I can't figure out why that works. I need help understanding why this subtraction works.
The value of the highest bit of an unsigned n-bit number is 2n-1.
The value of the highest bit of a signed two's complement n-bit number is -2n-1.
The difference between those two values is 2n.
So if a unsigned n-bit number has the highest bit set, to convert to a two's complement signed number subtract 2n.
In a 32-bit number, if bit 31 is set, the number will be >= 231, so the formula would be:
if n >= 2**31:
n -= 2**32
I hope that makes it clear.
Python integers are infinitely large. They will not turn negative as you add more bits so two's complement may not work as expected. You could manage negatives differently.
def singleNumber(nums):
result = 0
sign = [1,-1][sum(int(n<0) for n in nums)%3]
for i in range(32):
counter = 0
for num in nums:
counter += (abs(num) >> i) & 1
result = result | ((counter % 3) << i)
return result * sign
This binary approach can be optimized and simplified like this:
def singleNumber(nums):
result = 0
for i in range(32):
counter = sum(1 for n in nums if (n>>i)&1)
if counter > 0: result |= (counter % 3) << i
return result - 2*(result&(1<<31))
If you like one liners, you can implement it using reduce() from functools:
result = reduce(lambda r,i:r|sum(1&(n>>i) for n in nums)%3<<i,range(32),sum(n<0 for n in nums)%3*(-1<<32))
Note that this approach will always do 32 passes through the data and will be limited to numbers in the range -2^31...2^31. Increasing this range will systematically augment the number of passes through the list of numbers (even if the list only contains small values). Also, since you're not using counter[i] outside of the i loop, you don't need a list to store the counters.
You could leverage base 3 instead of base 2 using a very similar approach (which also responds in O(n) time and O(1) space):
def singleNumber(nums):
result = sign = 0
for num in nums:
if num<0 : sign += 1
base3 = 1
num = abs(num)
while num > 0 :
num,rest = divmod(num,3)
rest,base3 = rest*base3, 3*base3
if rest == 0 : continue
digit = result % base3
result = result - digit + (digit+rest)%base3
return result * (1-sign%3*2)
This one has the advantage that it will go through the list only once (thus supporting iterators as input). It does not limit the range of values and will perform the nested while loop as few times as possible (in accordance with the magnitude of each value)
The way it works is by adding digits independently in a base 3 representation and cycling the result (digit by digit) without applying a carry.
For example: [ 16, 16, 32, 16 ]
Base10 Base 3 Base 3 digits result (cumulative)
------ ------ ------------- ------
16 121 0 | 1 | 2 | 1 121
16 121 0 | 1 | 2 | 1 212
32 2012 2 | 0 | 1 | 2 2221
16 121 0 | 1 | 2 | 1 2012
-------------
sum of digits % 3 2 | 0 | 1 | 2 ==> 32
The while num > 0 loop processes the digits. It will run at most log(V,3) times where V is the largest absolute value in the numbers list. As such it is similar to the for i in range(32) loop in the base 2 solution except that it always uses the smallest possible range. For any given pattern of values, the number of iterations of that while loop is going to be less or equal to a constant thus preserving the O(n) complexity of the main loop.
I made a few performance tests and, in practice, the base3 version is only faster than the base2 approach when values are small. The base3 approach always performs fewer iterations but, when values are large, it loses out in total execution time because of the overhead of modulo vs bitwise operations.
In order for the base2 solution to always be faster than the base 3 approach, it needs to optimize its iterations through the bits by reversing the loop nesting (bits inside numbers instead of numbers inside bits):
def singleNumber(nums):
bits = [0]*len(bin(max(nums,key=abs)))
sign = 0
for num in nums:
if num<0 : sign += 1
num = abs(num)
bit = 0
while num > 0:
if num&1 : bits[bit] += 1
bit += 1
num >>= 1
result = sum(1<<bit for bit,count in enumerate(bits) if count%3)
return result * [1,-1][sign%3]
Now it will outperform the base 3 approach every time. As a side benefit, it is no longer limited by a value range and will support iterators as input. Note that the size of the bits array can be treated as a constant so this is also a O(1) space solution
But, to be fair, if we apply the same optimization to the base 3 approach (i.e. using a list of base 3 'bits'), its performance comes back in front for all value sizes:
def singleNumber(nums):
tribits = [0]*len(bin(max(nums,key=abs))) # enough base 2 -> enough 3
sign = 0
for num in nums:
if num<0 : sign += 1
num = abs(num)
base3 = 0
while num > 0:
digit = num%3
if digit: tribits[base3] += digit
base3 += 1
num //= 3
result = sum(count%3 * 3**base3 for base3,count in enumerate(tribits) if count%3)
return result * [1,-1][sign%3]
.
Counter from collections would give the expected result in O(n) time with a single line of code:
from collections import Counter
numbers = [1,0,1,0,1,0,99]
singleN = next(n for n,count in Counter(numbers).items() if count == 1)
Sets would also work in O(n):
distinct = set()
multiple = [n for n in numbers if n in distinct or distinct.add(n)]
singleN = min(distinct.difference(multiple))
These last two solutions do use a variable amount of extra memory that is proportional to the size of the list (i.e. not O(1) space). On the other hand, they run 30 times faster and they will support any data type in the list. They also support iterators
32-bit signed integers wrap around every 2**32, so a positive number with the the sign bit set (ie >= 2**31) has the same binary representation as the negative number 2**32 less.
That is the very definition of two's complement code of a number A on n bits.
if number A is positive use the binary code of A
if A is negative, use the binary code of 2^n+A (or 2^n-|A|). This number is the one you have to add to |A| to get 2^n (i.e. the complement of |A| to 2^n, hence the name of the two's complement method).
So, if you have a negative number B coded in two's complement, what is actually in its code is 2^N+B. To get its value, you have to substract 2^N from B.
There are many other definitions of two's complement (~A+1, ~(A-1), etc), but this one is the most useful as it explains why adding signed two's complement numbers is absolutely identical to adding positive numbers. The number is in the code (with 2^32 added if negative) and the addition result will be correct, provided you ignore the 2^32 that may be generated as a carry out (and there is no overflow). This arithmetic property is the main reason why two's complement is used in computers.
I just started a course in Python and trying this code:
import math
c = int(input('Enter number: '))
a = 1
counter = 0
while counter != 2:
a = a + 1
b = round((c-(a**3))**(1/3.0))
if a < b and a**3 + b**3 == c:
counter = counter + 1
print(a,b)
My problem is that python cant round the 'b' since it is viewed as a complex number...
The program is supposed to find two sets of a & b that satisfie a^3+b^3=c, any feed back on my code is appreciated.
Basically, raising a negative number to a fractional power always yields a complex number. For example, sqrt(-1) (which is (-1)**(1/2)), is clearly complex.
So, if you try to raise -8 to the 1/3th power, you'll get a complex number. For example:
a = (-8)**(1/3)
print(a)
print(a**3)
Will print
(1.0000000000000002+1.7320508075688772j)
(-8+3.1086244689504383e-15j)
That gives back -8 when raised to the 3rd power, give or take some rounding.
This rounding is the real issue here. You could well say that -8 to the power 1/3 is -2, as -2 to the 3rd power is -8. However - and this is the crux - that only works if the power is actually 1/3. In a floating point number it will actually be 0.33333 (with some more threes), which is not exactly the same. Hence the exponentiation is done with complex numbers.
You'll either have to work with complex numbers, or rewrite your maths to not use fractional powers of negative numbers.
You need to guard your computation against a^3 being larger than c; that's what returns a complex number. Make sure that you move the increment of a, so that the while uses that same value. Perhaps
while counter != 2 and c >= a**3:
b = round((c-(a**3))**(1/3.0))
if a < b and a**3 + b**3 == c:
counter = counter + 1
print(a,b)
a = a + 1
Output with c = 1729, the Ramanujan-Hardy number:
1 12
9 10
Also, why are you waiting for two solutions? "counter" puzzles me ... you could use a Boolean flag if you need only one solution.
This question already has answers here:
What is the purpose of the return statement? How is it different from printing?
(15 answers)
Closed 4 months ago.
Write a simple procedure, myLog(x, b), that computes the logarithm of a number x relative to a base b.n other words, myLog should return the largest power of b such that b to that power is still less than or equal to x.
x and b are both positive integers; b is an integer greater than or equal to 2. Your function should return an integer answer.
Do not use Python's log functions; instead, please use an iterative or recursive solution to this problem that uses simple arithmatic operators and conditional testing.
What is wrong in the below code? As they have not mentioned what to return when the condition fails, so had kept false
def myLog(x, b):
count = 1
while x > 0 and b >= 2:
ans = b ** count
if (ans == x):
print str(count)
break
elif (ans > x):
print str(count-1)
break
count += 1
else:
return False
Since you haven't explained what problem you're trying to solve, all I can do is guess. But…
Your function never returns a number. If it succeeds, it prints out a number, then falls off the end of the function and returns None. If it fails, it returns False. And there's no other return anywhere in the code.
That's easy to fix: just return the value instead of print-ing it:
def myLog(x, b):
count = 1
while x > 0 and b >= 2:
ans = b ** count
if (ans == x):
return count
elif (ans > x):
return count-1
count += 1
else:
return False
You can improve performance by doing ans *= b each time through the loop instead of ans = b ** count. If the numbers are huge, dividing x by b might be better—division is usually slower than multiplication, but getting out of the huge-number domain early might help more than avoiding division.
It's also got some style problems, like the unnecessary parentheses some (but not all) of your conditions.
And finally, you may want to consider writing a "test driver". For example:
repcount = 100
errcount = 0
for _ in range(repcount):
x = generate_nice_random_x()
b = generate_random_base()
log1, log2 = myLog(x, b), int(math.log(x, b))
if log1 != log2:
print('log({}, {}): {} != {}'.format(x, b, log1, log2))
errcount += 1
print('{}/{} errors'.format(errcount, repcount))
Start with a small repcount to make sure you don't spam the screen; when you're happier with it, use a much larger one. Meanwhile, I'll leave it to you to figure out a good domain to choose from for testing log functions.
This is a question on an exam, that is currently ongoing.MITx: 6.00.1x Introduction to Computer Science and Programming