Suppose a and b are odd integers. Then a^2 + b^2 is either 2 or 10 modulo 16. My question is the following: Is there a way of writing a script whose assumptions are a%2 == 1 and b%2 == 1 so that the output (a^2 + b^2) % 16 gives the tuple (2,10)?
Edit: Here's my unsuccessful approach:
def test():
aList=[]
bList=[]
for a in range(0,16):
for b in range(0,16):
if a%2==1 and b%2==1:
aList.append(a)
bList.append(b)
print a^2+b^2%16
This of course will not return a tuple. My hope is to output the tuple (2,10).
As I understand, you want to collect the distinct residues modulo 16 of a**2 + b**2 (note the ^ operator is not what you want here) into a tuple. So instead of printing each residue out, you should add them to a set in order to collect the distinct values. The set can then be converted to a tuple, using sorted to get them in order:
residues = set()
for a in range(0, 16):
for b in range(0, 16):
if a % 2 == 1 and b % 2 == 1:
residues.add((a**2 + b**2) % 16)
residues = tuple(sorted(residues))
print(residues)
The result is (2, 10) as expected.
This code can be simplified somewhat: instead of generating all integers in the range and just keeping the odd ones, you can generate odd integers using a range starting from 1 with a step size of 2; and you can use a set comprehension for brevity.
residues = {
(a**2 + b**2) % 16
for a in range(1, 16, 2)
for b in range(1, 16, 2)
}
residues = tuple(sorted(residues))
print(residues)
Related
We are given a number N and we have to find pairs i and j where i^3=j^2
For example, let N=50 so for this we will have 3 pairs (1,1),(4,8),(9,27)
basically, we have to find pairs where the cube of one number is the same as the square of the other number in a given pair
the constraint is
1<=N<10^6
1<=i,j<N
Naive approach use 2 for loops iterate through each element and get those pairs where cube is equal to sum time complexity is O(n*2)
def get_pair(N):
for i in range(1,N):
for j in range(1,N):
if i*i*i==j*j:
print(i,j)
N=50
get_pair(N)
what will be an optimal way to solve this problem with a better time complexity?
Since you're working with integers, if there exists some number M = i^3 = j^2 for i and j between 1 and N, then that means there exists a k such that M = k^6. To find i and j, simply compare the representations of M:
(1) M = k^6 = i^3 = (k^2)^3 therefore i = k^2
(2) M = k^6 = j^2 = (k^3)^2 therefore j = k^3
Since j is always greater than or equal to i, you only need to check if 1 < k^3 < N. In other words, k should be less than the cube root of N.
k
M = k^6
i = k^2
j = k^3
2
64
4
8
3
729
9
27
4
4,096
16
64
5
15,625
25
125
6
46,656
36
216
...
...
...
...
97
8.329x10^11
9409
912,673
98
8.858x10^11
9604
941,192
99
9.415x10^11
9801
970,299
Note that 100 isn't a valid candidate for k because that would make j less than or equal to N instead of strictly less than N (if we're going with N = 10^6).
So to get the list of tuples that satisfy your problem, find the values of k such that 1 < k^3 < N and return its square and cube in a tuple.
import math
from typing import List, Tuple
N: int = 10**6
pairs: List[Tuple[int, int]] = [(k * k, k * k * k) for k in range(2, math.ceil(N**(1 / 3)))]
print(pairs)
This is a list comprehension, a shorthand for a for-loop.
I'm basically asking Python to generate a list of tuples over an index k that falls in the range defined as range(2, math.ceil(N**(1 / 3)). That range is exactly the first column of the table above.
Then, for every k in that range I make a tuple of which the first item is k^2 and the second item is k^3, just like the last two columns of the table.
Also threw in the typing library in there for good measure. Clear code is good code, even for something as small as this. Python can figure out that pairs is a list of tuples without anyone telling it, but this way I've explicitly enforced that variable to be a list of tuples to avoid any confusion when someone tries to give it a different value or isn't sure what the variable contains.
Another naive approach could be to use the "basic" values ?
def get_pair(N):
for i in range(N):
if(i**3 > MAX):
break # Limit to the max you want, and i**3 > i**2 if i > 1
print(i**2, i**3)
Time complexity seems to be O(n) (Not an expert, so correct me if i'm wrong)
This is made so that the first element cubed == second element squared:
first = a^2
second = a^3
first^3 = a^(2*3) = a^6
second^2 = a^(3*2) = a^6
You can use itertool's combinations_with_replacement function.
from itertools import combinations_with_replacement as combinations
def get_pair(N):
for i, j in combinations(range(1,N), 2):
if i*i*i==j*j:
print(i,j)
N=50
get_pair(N)
You do this with one loop (and minimal iterations) if you know that that pairs (x, y) are always y = x * i, this means you can use:
def get_pair(N):
i = 1
a = 1
while a * i < N:
b = a * i
print(a,b)
i += 1
a = i**2
N=50
get_pair(N)
This gets all 3 pairs:
1 1
4 8
9 27
In only 3 total iterations.
I am trying to write code which gives you numbers which are less than given or entered number , and their GCD equal to 1 . I wrote this code but I don't know if works or why not . For example I chose number 6. array will be like [1,2,3,4,5]. And my point is to filter numbers that GCD equals to 1. So it will be [1,5]. And their amount is two.
a is input number and b is list numbers that are less than entered one and not equal to zero . And then print it .
a = int(input("enter number \n"))
b = list(range(1,a))
print (b)
Then I convert list to array
for i in range(1, len(b)):
b[i] = int(b[i])
and then this
r = a % b[i]
q = int ( a / b[i])
while(r!=0):
a = b[i]
b[i] = r
q = int ( a / b[i])
r = a - (b[i] * q)
print ( a , b[i], r )
break
I am beginner .
A few comments about your code:
You should always encapsulate code like this in a function; write a function find_coprimes which takes an argument n and returns the list you want;
In order to test the correctness of your function, write a reference function find_coprimes_ref which does the same thing, but uses library functions to make sure there is no error; this will teach you to look for relevant library functions, and you can compare the results of the two functions;
The initial loop for i in range(1, len(b)): b[i] = int(b[i]) is wrong for two reasons; 1) It has no effect, as b is already a list of integers. 2) Lists are 0-indexed, so a correct iterations on every element of b would be for i in range(0, len(b)): or simply for i in range(len(b)):;
Your code has two nested loops: a while-loop executing repeatedly inside a for-loop; whenever there are nested loops like this, you must make sure that variables are reinitialised the way you intend them to at the beginning of the outer loop; in your case, variable a is modified inside the while-loop, and as a result, its value is wrong at the beginning of the next iteration of the for-loop.
The break statement at the end of the while-loop makes no sense; in general, break statements only make sense if they are encapsulated in an if conditional, and they act as a substitute for the loop condition; but it's always possible to write loops without using break at all and I recommend you forget about break entirely.
After performing the gcd calculation using q and r, your code is missing something to tell it whether or not to keep b[i] or not in the final result;
For integer division in python, it is better to use // rather than int(... / ...).
Code
import math
def find_coprimes_ref(n):
return [x for x in range(1,n) if math.gcd(x,n) == 1]
def find_coprimes(n):
result = []
for x in range(1, n):
a = n
b = x
r = a % b
q = a // b
while (r > 1):
a = b
b = r
q = a // b
r = a - b * q
if (r == 1):
result.append(x)
return result
# TESTING
for n in range(1, 31):
coprimes_ref = find_coprimes_ref(n)
coprimes = find_coprimes(n)
if coprimes_ref != coprimes:
print(n, coprimes_ref, coprimes)
Note how my code never modifies n or x in the loop; instead, I make copies called a and b and modify the copies.
Encapsulating even further
Note how function find_coprimes_ref is so much easier to read than function find_coprimes? This is not just because we used library function math.gcd. It's because library function math.gcd is a cleanly-encapsulated function with a name that explains clearly what it does. Your code contains a while loop inside a for loop and it's a bit hard to keep track of every variable and everything that is going on and not lost track of our sub-objective and overall objective.
To make your function both easier to read, easier to code and easier to debug, You should encapsulate the gcd calculation inside a function called gcd:
def gcd(a, b):
r = a % b
q = a // b
while (r > 1):
a = b
b = r
q = a // b
r = a - b * q
return r
def find_coprimes(n):
result = []
for x in range(1, n):
if gcd(a, b) == 1:
result.append(x)
return result
# TESTING GCD
for b in range(1, 31):
for a in range(b, 31):
r1 = math.gcd(a, b)
r2 = gcd(a, b)
if r1 != r2:
print(a, b, r1, r2)
# TESTING FIND_COPRIMES
for n in range(1, 31):
coprimes_ref = find_coprimes_ref(n)
coprimes = find_coprimes(n)
if coprimes_ref != coprimes:
print(n, coprimes_ref, coprimes)
There are two reasons why the code is easier to debug now:
The logic for gcd and for find_coprimes is cleanly separated, which means you can reason about gcd clearly without any risk of messing up the list and the other variables used in find_coprimes;
You can test separately your function gcd and your function find_coprimes; and if something doesn't work correctly, you'll know more precisely where to look for the issue rather than just thinking "well, something is wrong somewhere in the code but I have no idea where".
There are a few errors in your code like, break inside while loop. I have refactored your code and also added inbuilt math.gcd function to compare results.
import math
def math_inbuilt_gcd(a, b):
gcd_one = []
for x in b:
if math.gcd(x, a) == 1:
gcd_one.append(x)
print("gcd_one_math_fun:", gcd_one)
def gcd_my_fun(a, b):
gcd_arr = []
for i in range(len(b)):
x, y = a, b[i] # taking x, y just to make things clear
r = x % y # remainder
q = int(x / y) # quotient
while(r != 0):
x = y
y = r
q = int(x/y)
r = x % y
if y == 1:
gcd_arr.append(b[i])
print("gcd_one_my_fun:", gcd_arr)
a = int(input("Enter number: "))
b = list(range(1, a))
print("b:", b)
math_inbuilt_gcd(a, b)
gcd_my_fun(a, b)
Output:
Enter number: 10
b: [1, 2, 3, 4, 5, 6, 7, 8, 9]
gcd_one_math_fun: [1, 3, 7, 9]
gcd_one_my_fun: [1, 3, 7, 9]
I'm new to Python and I don't understand an instruction in the following program:
n = int(input("enter an number : ")
b = 3
p = 1
while n > 0:
n,r = n//2,n%2
p* = b**r
b = b*b
print(p)
I don't understand this statement: n,r = n//2,n%2. What does it do?
Most of the answers are incorrect.
a, b = c, d is a Pythonic concept called "tuple unpacking".
n,r=n//2,n%2 does mean "assign n//2 to n" and "assign n % 2 to r" but n,r is a tuple. In tuple unpacking, all expressions on the RHS are evaluated before assignments. Thus n is not mutated by n//2 before n%2 is evaluated.
Proof of concept for order of operations in tuple unpacking:
a = 1
b = 2
a, b = b, a
if (a==2 and b==1):
print("look ma, I can swap values without needing a temporary variable!")
It is tuple assignment. The each value in the tuple on the left is assigned to the respective value in the tuple on the right. Since the values on the right side are evaluated before any assignment occurs, the value of n before the statement is used. So the line is equivalent to:
tmp = n
n = tmp // 2
r = tmp % 2
It's a parallel assignment:
n, r = n // 2, n % 2
n equals n divided by 2 using integer division, and r equals n modulo 2. It's the same as:
t1 = n // 2
t2 = n % 2
n = t1
r = t2
The values to the right are evaluated, and after that they're assigned, to defer overwriting the original values until we no longer need them.
I want to solve the TSP problem using a dynamic programming algorithm in Python.The problem is:
Input: cities represented as a list of points. For example, [(1,2), (0.3, 4.5), (9, 3)...]. The distance between cities is defined as the Euclidean distance.
Output: the minimum cost of a traveling salesman tour for this instance, rounded down to the nearest integer.
And the pseudo-code is:
Let A = 2-D array, indexed by subsets of {1, 2, ,3, ..., n} that contains 1 and destinations j belongs to {1, 2, 3,...n}
1. Base case:
2. if S = {0}, then A[S, 1] = 0;
3. else, A[S, 1] = Infinity.
4.for m = 2, 3, ..., n: // m = subproblem size
5. for each subset of {1, 2,...,n} of size m that contains 1:
6. for each j belongs to S and j != 1:
7. A[S, j] = the least value of A[S-{j},k]+the distance of k and j for every k belongs to S that doesn't equal to j
8.Return the least value of A[{1,2..n},j]+the distance between j and 1 for every j = 2, 3,...n.
My confusions are:
How to index a list using subset, that is how to implement line 5 in the pseudo-code efficiently.
You can encode sets as integers: i'th bit of the integer will represent the state of i'th city (i.e. do we take it in the subset or not).
For example, 3510 = 1000112 will represent cities {1, 2, 6}. Here I count from the rightmost bit, which represents city 1.
In order to index a list using such representation of a subset, you should create 2D array of length 2n:
# Assuming n is given.
A = [[0 for i in xrange(n)] for j in xrange(2 ** n)]
This comes from the fact that with n-bit integer you can represent every subset of {1, 2, ..., n} (remember, each bit corresponds to exactly one city).
This representation gives you a number of nice possibilities:
# Check whether some city (1-indexed) is inside subset.
if (1 << (i - 1)) & x:
print 'city %d is inside subset!' % i
# In particular, checking for city #1 is super-easy:
if x & 1:
print 'city 1 is inside subset!'
# Iterate over subsets with increasing cardinality:
subsets = range(1, 2 ** n)
for subset in sorted(subsets, key=lambda x: bin(x).count('1')):
print subset,
# For n=4 prints "1 2 4 8 3 5 6 9 10 12 7 11 13 14 15"
# Obtain a subset y, which is the same as x,
# except city #j (1-indexed) is removed:
y = x ^ (1 << (j - 1)) # Note that city #j must be inside x.
This is how I would implement your pseudocode (warning: no testing was done):
# INFINITY and n are defined somewhere above.
A = [[INFINITY for i in xrange(n)] for j in xrange(2 ** n)]
# Base case (I guess it should read "if S = {1}, then A[S, 1] = 0",
because otherwise S = {0} is not a valid index to A, according to line #1)
A[1][1] = 0
# Iterate over all subsets:
subsets = range(1, 2 ** n)
for subset in sorted(subsets, key=lambda x: bin(x).count('1')):
if not subset & 1:
# City #1 is not presented.
continue
for j in xrange(2, n + 1):
if not (1 << (j - 1)) & subset:
# City #j is not presented.
continue
for k in xrange(1, n + 1):
if k == j or not (1 << (k - 1)) & subset:
continue
A[subset][j] = min(A[subset][j], A[subset ^ (1 << (j - 1))][k] + get_dist(j, k))
Besides having all needed functionality to implement your pseudocode, this approach is going to be faster than with tuples\dicts.
I'm a stumped on how to speed up my algorithm which sums multiples in a given range. This is for a problem on codewars.com here is a link to the problem
codewars link
Here's the code and i'll explain what's going on in the bottom
import itertools
def solution(number):
return multiples(3, number) + multiples(5, number) - multiples(15, number)
def multiples(m, count):
l = 0
for i in itertools.count(m, m):
if i < count:
l += i
else:
break
return l
print solution(50000000) #takes 41.8 seconds
#one of the testers takes 50000000000000000000000000000000000000000 as input
# def multiples(m, count):
# l = 0
# for i in xrange(m,count ,m):
# l += i
# return l
so basically the problem ask the user return the sum of all the multiples of 3 and 5 within a number. Here are the testers.
test.assert_equals(solution(10), 23)
test.assert_equals(solution(20), 78)
test.assert_equals(solution(100), 2318)
test.assert_equals(solution(200), 9168)
test.assert_equals(solution(1000), 233168)
test.assert_equals(solution(10000), 23331668)
my program has no problem getting the right answer. The problem arises when the input is large. When pass in a number like 50000000 it takes over 40 seconds to return the answer. One of the inputs i'm asked to take is 50000000000000000000000000000000000000000, which a is huge number. That's also the reason why i'm using itertools.count() I tried using xrange in my first attempt but range can't handle numbers larger than a c type long. I know the slowest part the problem is the multiples method...yet it is still faster then my first attempt using list comprehension and checking whether i % 3 == 0 or i % 5 == 0, any ideas guys?
This solution should be faster for large numbers.
def solution(number):
number -= 1
a, b, c = number // 3, number // 5, number // 15
asum, bsum, csum = a*(a+1) // 2, b*(b+1) // 2, c*(c+1) // 2
return 3*asum + 5*bsum - 15*csum
Explanation:
Take any sequence from 1 to n:
1, 2, 3, 4, ..., n
And it's sum will always be given by the formula n(n+1)/2. This can be proven easily if you consider that the expression (1 + n) / 2 is just a shortcut for computing the average, or Arithmetic mean of this particular sequence of numbers. Because average(S) = sum(S) / length(S), if you take the average of any sequence of numbers and multiply it by the length of the sequence, you get the sum of the sequence.
If we're given a number n, and we want the sum of the multiples of some given k up to n, including n, we want to find the summation:
k + 2k + 3k + 4k + ... xk
where xk is the highest multiple of k that is less than or equal to n. Now notice that this summation can be factored into:
k(1 + 2 + 3 + 4 + ... + x)
We are given k already, so now all we need to find is x. If x is defined to be the highest number you can multiply k by to get a natural number less than or equal to n, then we can get the number x by using Python's integer division:
n // k == x
Once we find x, we can find the sum of the multiples of any given k up to a given n using previous formulas:
k(x(x+1)/2)
Our three given k's are 3, 5, and 15.
We find our x's in this line:
a, b, c = number // 3, number // 5, number // 15
Compute the summations of their multiples up to n in this line:
asum, bsum, csum = a*(a+1) // 2, b*(b+1) // 2, c*(c+1) // 2
And finally, multiply their summations by k in this line:
return 3*asum + 5*bsum - 15*csum
And we have our answer!