Python: how to compute the distance between cells? - python

Let's suppose I want to compute the distance between cells in a square grid 5x5. The distance between two cells is 100m.
Each cell of the grid is number between 0 and 24
0 1 2 3 4
5 6 7 8 9
10 11 12 13 14
15 16 17 18 19
20 21 22 23 24
For instance:
distance between cell 0 and 3 is 300
distance between cell 2 and 7 is 100
distance between cell 11 and 19 is 400
I have to count the distance as different between x and y location of the cells.
gs = 5 ## Cells per side
S = gs*gs ## Grid Size
r0 = 100 ## distance between two cells
for i in range(0, S):
for j in range(0, S):
if i == j: continue
x = int(floor(i/gs))
y = int(floor(j/gs))
dist = x*r0 + abs(j-i)*r0
but it is not the right solution

# n1, n2 = cell numbers
cellsize = 100.0
x1,x2 = n1%gs, n2%gs
y1,y2 = n1//gs, n2//gs
dist = sqrt( float(x1-x2)**2 + float(y1-y2)**2) # pythagoras theorem
dist *= cellsize

you should consider co-ordinate and not the cell number
gs = 5 ## Cells per side
S = gs*gs ## Grid Size
r0 = 100 ## distance between two cells
for i in range(0, S):
for j in range(0, S):
if i == j: continue
xi = int(i/gs)
yi = i % gs
xj = int(j/gs)
yj = j % gs
dist = r0 * (abs(xi-xj) + abs(yi-yj))

this is a way to do that:
r = 100
grid = ((0, 1, 2, 3, 4),
(5, 6, 7, 8, 9),
(10, 11, 12, 13, 14),
(15, 16, 17, 18, 19),
(20, 21, 22, 23, 24))
def coord(n):
for x, line in enumerate(grid):
if n not in line:
continue
y = line.index(n)
return x, y
def dist(n, m):
xn, yn = coord(n)
xm, ym = coord(m)
return r * (abs(xn - xm) + abs(yn - ym))
print(dist(0, 3)) # 300
print(dist(2, 7)) # 100
print(dist(11, 19)) # 400
the idea is to get the coordinates of your numbers first and then calculating the 'distance'.

This should work for you
n = 5 # row length in array
def distance(a, b):
distance = (abs(a // n - b // n) + abs(a % n - b % n)) * 100
return "distance between cell %s and %s is %s" % (a, b, distance)
print(distance(0, 3))
print(distance(2, 7))
print(distance(11, 19))
Output:
distance between cell 0 and 3 is 300
distance between cell 2 and 7 is 100
distance between cell 11 and 19 is 400
Where a and b are your cells, and n is a length of the row in array, in your example is 5.

We just need to get the row and column number of every number. Then a difference b/w the two and multiplied by 100 will give you answer
def get_row_col(num):
for i,g in enumerate(grid):
if num in g:
col = g.index(num)
row = i
return row, col
num1 = get_row_col(11)
num2 = get_row_col(19)
print (abs(num1[0] - num2[0])*100) + (abs(num1[1]-num2[1])*100)
One can enhance this code to check if number is present or not.

Related

I want to create a squares with 5 by 5 squares with a space but I am not sure how to?This is what I tried

y = topLeft.getY()
for i in range(5):
x = topLeft.getX()
for c in range(5):
cellButton = CellButton(window,x,y,size,cellID=(i,c))
self._buttons.append(cellButton)
x= x + (size+padding)
y = y + (size + padding)
#padding being space between each squares
I was expecting a 25 cell which is 5 by 5 with a space between them

Is there a way to list super primes between 1 and n in NumPy

Is there a way to list super primes (primes in a prime position wikipedia article) between 1 and n using NumPy.
I got this without Numpy, is that okay?
here is the code based on
Sieve of Atkin
import math
is_prime = list()
limit = 100
for i in range(5, limit):
is_prime.append(False)
for x in range(1, int(math.sqrt(limit)) + 1):
for y in range(1, int(math.sqrt(limit)) + 1):
n = 4 * x ** 2 + y ** 2
if n <= limit and (n % 12 == 1 or n % 12 == 5) and n <= len(is_prime):
# print "1st if"
is_prime[n] = not is_prime[n]
n = 3 * x ** 2 + y ** 2
if n <= limit and n % 12 == 7:
# print "Second if"
is_prime[n] = not is_prime[n]
n = 3 * x ** 2 - y ** 2
if x > y and n <= limit and n % 12 == 11:
# print "third if"
is_prime[n] = not is_prime[n]
for n in range(5, int(math.sqrt(limit))):
if is_prime[n]:
for k in range(n ** 2, limit + 1, n ** 2):
if k <= len(is_prime):
is_prime[k] = False
for n in range(5, limit):
if n < len(is_prime) and is_prime[n]:
print(n)
Numpy Code Version
Sieve modification of Numpy Sieve by user2357112 supports Monica
import numpy as np
def sieve(n):
'''
Sieve of Erastosenes using numpy
'''
flags = np.ones(n, dtype=bool) # Set all values to True
# Set 0, 1, and even numbers > 2 to False
flags[0] = flags[1] = False
flags[4:n:2] = False
for i in range(3, n, 2):
# Check for odd primes
if flags[i]:
flags[i*i::i] = False
return np.flatnonzero(flags) # Indexes of True are prime
def superPrimes(n):
'''
Find superprimes
'''
# Find primes up to n using sieve
p = sieve(n)
# p(i) denotes the ith prime number, the numbers in this sequence are those of the form p(p(i))
# Want to find numbers we can index in the list (i.e. has to be less than len(p))
indexes = p[p < len(p)] # base 1 indexes within range
return p[indexes-1] # Subtract 1 since primes array is base 0 indexed
Test
print(superPrimes(200))
# Output: [ 3 5 11 17 31 41 59 67 83 109 127 157 179 191]

simulate the spiral shape pattern in the matrix

We have a matrix with dimensions n and n (n is an odd number and the user enters it) Write a program to simulate the spiral shape pattern in the matrix.
The pattern is such that starting from the central part of the matrix, whose value is equal to zero, 1 unit to the right and up (odd number) and then 2 We move the unit left and down (even number) and repeat this pattern n-1 times according to whether the number is even or odd. 0 to n-1 to be replaced according to the pattern)
6 6 6 6 6 6 5
6 4 4 4 4 3 5
6 4 2 2 1 3 5
6 4 2 0 1 3 5
6 4 2 3 3 3 5
6 4 5 5 5 5 5
6 7 7 7 7 7 7
First of all we get a number from user then assuming you have to draw the spiral out. Start by generating a list of the sequence (from the center to the end) , then write a function to put that list into the spiral
bellow link can explain it in more detail.
I change the directions of it's solution.
newbedev.com/creating-a-spiral-array-in-python
NORTH, S, W, E = (0, 1), (0, -1), (-1, 0), (1, 0) # directions
turn_left = {NORTH: E, E: S, S: W, W: NORTH} # old -> new direction
def spiral(width, height, matrixList):
if width < 1 or height < 1:
raise ValueError
x, y = width // 2, height // 2 # start near the center
dx, dy = NORTH # initial direction
matrix = [[None] * width for _ in range(height)]
count = 0
while True:
matrix[y][x] = matrixList[count] # visit
count += 1
# try to turn left
new_dx, new_dy = turn_left[dx, dy]
new_x, new_y = x + new_dx, y + new_dy
if (0 <= new_x < width and 0 <= new_y < height and
matrix[new_y][new_x] is None): # can turn left
x, y = new_x, new_y
dx, dy = new_dx, new_dy
else: # try to move straight
x, y = x + dx, y + dy
if not (0 <= x < width and 0 <= y < height):
return matrix # nowhere to go
def print_matrix(matrix):
width = len(str(max(el for row in matrix for el in row if el is not None)))
fmt = "{:0%dd}" % width
for row in matrix:
print(" ".join("_"*width if el is None else fmt.format(el)
for el in row))
n = int(input())
totalRecord = n*n
numberOfOccurance = 2
numberOfOccuranceIndex = 1
number = 1
index = 1
row = [0]
while index < totalRecord:
while numberOfOccuranceIndex <= numberOfOccurance:
row.append(number)
index += 1
numberOfOccuranceIndex += 1
if index >= totalRecord:
break
numberOfOccurance += 2
numberOfOccuranceIndex = 1
number += 1
print_matrix(spiral(n, n,row))

Print spiral square matrix in python

Here's a python code that prints the square matrix from interior to outer. How can I reverse to print from outer to interior clockwise
# Function to prints a N x N spiral matrix without using any extra space
# The matrix contains numbers from 1 to N x N
def printSpiralMatrix(N):
for i in range(N):
for j in range(N):
# x stores the layer in which (i, j)'th element lies
# find minimum of four inputs
x = min(min(i, j), min(N - 1 - i, N - 1 - j))
# print upper right half
if i <= j:
print((N - 2 * x) * (N - 2 * x) - (i - x) - (j - x), end='')
# print lower left half
else:
print((N - 2 * x - 2) * (N - 2 * x - 2) + (i - x) + (j - x), end='')
print('\t', end='')
print()
if __name__ == '__main__':
N = 4
printSpiralMatrix(N)
The output should be like that
1 2 3 4
12 13 14 5
11 16 15 6
10 9 8 7
Try with this:
def printSpiralMatrix(N):
for i in range(N):
for j in range(N):
# x stores the layer in which (i, j)'th element lies
# find minimum of four inputs
x = min(min(i, j), min(N - 1 - i, N - 1 - j))
# print upper right half
if i <= j:
print(abs((N - 2 * x) * (N - 2 * x) - (i - x) - (j - x) -(N**2 + 1)), end='')
# print lower left half
else:
print( abs((N - 2 * x - 2) * (N - 2 * x - 2) + (i - x) + (j - x) - (N**2 + 1)), end='')
print('\t', end='')
print()
printSpiralMatrix(4)
1 2 3 4
12 13 14 5
11 16 15 6
10 9 8 7
def generateMatrix(n):
if n<=0:
return []
matrix=[row[:] for row in [[0]*n]*n]
row_st=0
row_ed=n-1
col_st=0
col_ed=n-1
current=1
while (True):
if current>n*n:
break
for c in range (col_st, col_ed+1):
matrix[row_st][c]=current
current+=1
row_st+=1
for r in range (row_st, row_ed+1):
matrix[r][col_ed]=current
current+=1
col_ed-=1
for c in range (col_ed, col_st-1, -1):
matrix[row_ed][c]=current
current+=1
row_ed-=1
for r in range (row_ed, row_st-1, -1):
matrix[r][col_st]=current
current+=1
col_st+=1
return matrix
print(list(generateMatrix(3)))
Output
[[1, 2, 3], [8, 9, 4], [7, 6, 5]]

Python: keep the number in a specific range

I have a problem that runs like this:
I have an integer n, let n = 30.
I add n with another integer k. Say, k = 19
However, I want to keep n between x and y, say 20 and 35. So if n+k > 35 it jumps back to 20 at 36, then continue to add 13 (19-6=13), which the final answer is 33.
I have already done the problem from scratch, and it's lengthy. It looks like this:
def plus(n,k,x,y):
result= n+k
if result > y: #do sth
if result < x: #do sth
return result
My question is, is there any build-in method, in any library, that helps me to do this problem? Thanks a lot.
The modulo operator % performs the kind of wrapping you're looking for. a % b gives the remainder from dividing a by b, resulting in the following wraparound pattern:
>>> for i in range(-2, 12):
... print(f"{i} % 5 = {i % 5}")
...
-2 % 5 = 3
-1 % 5 = 4
0 % 5 = 0
1 % 5 = 1
2 % 5 = 2
3 % 5 = 3
4 % 5 = 4
5 % 5 = 0
6 % 5 = 1
7 % 5 = 2
8 % 5 = 3
9 % 5 = 4
10 % 5 = 0
11 % 5 = 1
(The results you see with a negative left operand aren't what you get in most languages. Most languages would give you -2 and -1 instead of 3 and 4, but the 3 and 4 answers turn out to be more useful.)
You want to stay in a range from x to y inclusive instead of 0 to y-1, so we need to add and subtract x to adjust the range % gives us:
def plus(n,k,x,y):
modulus = y-x+1
return (n+k-x) % modulus + x
Sample output:
>>> plus(30, 19, 20, 35)
33
>>> plus(30, 0, 20, 35)
30
>>> plus(30, 5, 20, 35)
35
>>> plus(30, 6, 20, 35)
20
>>> plus(30, -10, 20, 35)
20
>>> plus(30, -11, 20, 35)
35
You’re looking for the modulo operator: %
result = x + (n + k - x) % (y - x + 1)
After reading your response, you can try that loop
def plus(a, b, minvalue, maxvalue):
plusresult = a + b
while plusresult > maxvalue:
plusresult -= maxvalue - minvalue
return max(plusresult, minvalue)

Categories

Resources