How many non diagonal moves from origin point? - python-3.x

87 76 67 58 49 40 31 22 13 4
77 68 59 50 41 32 23 14 5 -4
69 60 51 42 33 24 15 6 -3-12
61 52 43 34 25 16 7 -2-11-20
53 44 35 26 17 8 -1-10-19-28
45 36 27 18 9 0 -9-18-27-36
37 28 19 10 1 -8-17-26-35-44
29 20 11 2 -7-16-25-34-43-52
21 12 3 -6-15-24-33-42-51-60
I am using this grid of numbers to define levels in a pygame tile based dictionary of maps. Each number is a dictionary key defining a maps location in reference to each other map with the value being a 2d list. I need a function that returns the number of non diagonal moves away from 0 each number in the grid is. I am going to use this number to calculate difficulty level. So the farther the player gets from the origin point of 0 the more difficult the game gets. To better understand how these numbers are generated... A move North increments by 8, a move south increments by -8, a move east increments by -9, and a move west increments by 9. So for example maps 17,-1,1,and -17 would equal 2 while maps 8,9,-9,-8 would equal 1 and so on. I am making some headway learning to write decent code, but sometimes the math required is beyond my capabilities.

Okay so I figured out a much less complicated way to solve my problem. I used a list of 2 values. I incremented or decremented position 0 by 1 for north,south moves and incremented or decremented position 1 by 1 for west,east moves respectively. I then added the absolute value of position 0 and the absolute value of position 1 and returned the answer. This seems to be giving me an accurate distance from 0. YAY!
dif_list =[0,0]
if move == 'north':
dif_list[0] += 1
if move == 'south':
dif_list[0] -= 1
if move == 'west':
dif_list[1] += 1
if move == 'east':
dif_list[1] -= 1
def difficulty():
num = abs(dif_list[0])+abs(dif_list[1])
return num

Related

Diagonals in North East Direction - Time Limit Exceeded in Python 3.8.3

The program must accept an integer matrix of size RxC as the input. The program must print the integers in the diagonals in the North-East directions of the matrix in the seprate line as output.
Boundary:
2<=R,C<=100
Time Limit : 500ms
Example 1:
Input:
3 3
73 77 76
71 17 87
37 73 98
Output:
73
71 77
37 17 76
73 87
98
Example 2:
Input:
4 6
97 78 7 39 92 45
68 100 49 95 97 100
59 41 81 22 26 100
46 37 81 12 93 10
Output:
97
68 78
59 100 7
46 41 49 39
37 81 95 92
81 22 97 45
12 26 100
93 100
10
My Code:
row,col = map(int,input().split())
matrix = [list(map(int,input().split())) for i in range(row)]
# Redundancy of row and col
rep = []
for i in range(row):
for j in range(col):
b = []
for k in range(i,row):
if (j,k) not in rep:
b.append(matrix[k][j])
rep.append((j,k))
j-=1
if j<0:break
if len(b):print(*(b[::-1]))
My code works well but when the matrix is of size (100,100) it exceeds the given time limit, is there a way to reduce it. Thanks in advance
Note : No External Libraries should be used!
The trick here is to realize that because each number only appears in the solution once, so we really only need to evaluate each value once.
We can also see that each matrix will result in row + col - 1 number of North-East direction diagonals, which will help us.
# Original code
row,col = map(int,input().split())
# I won't turn them into ints, strings actually make it easier for my work
matrix = [input().split() for i in range(row)]
diagonals = [""] * (row + col - 1)
for i in range(row):
for j in range(col):
# determine which diagonal the number belongs to, and prepend it
diagonals[i + j] = "%s %s" % (matrix[i][j], diagonals[i + j])
# print out diagonals one at a time
for diagonal in diagonals: print(diagonal)
I never got the chance to run it, but this should give the general idea!
(new to SO, plz be nice :D)

Python 3 script uses too much memory

As homework for IT lessons I need to write a script which will check for the highest power of 4 which is in modified input number, but I can use only 8MB of RAM. I used for this logarithmic function, so my code looks like this:
from math import log, floor
n = int(input())
numbers = []
for i in range (0, n):
numbers.append(floor(int(input()) / 10))
for i in numbers:
print(4 ** floor(log(i, 4)))
But I checked this script on my PC and it uses more than 8MB!
Partition of a set of 74690 objects. Total size = 8423721 bytes.
Index Count % Size % Cumulative % Kind (class / dict of class)
0 23305 31 2100404 25 2100404 25 str
1 19322 26 1450248 17 3550652 42 tuple
2 5017 7 724648 9 4275300 51 types.CodeType
3 9953 13 716915 9 4992215 59 bytes
4 742 1 632536 8 5624751 67 type
5 4618 6 628048 7 6252799 74 function
6 742 1 405720 5 6658519 79 dict of type
7 187 0 323112 4 6981631 83 dict of module
8 612 1 278720 3 7260351 86 dict (no owner)
9 63 0 107296 1 7367647 87 set
<197 more rows. Type e.g. '_.more' to view.>
On my phone, however, this script uses only 2.5MB:
Partition of a set of 35586 objects. Total size = 2435735 bytes.
Index Count % Size % Cumulative % Kind (class / dict of class)
0 9831 28 649462 27 649462 27 str
1 9014 25 365572 15 1015034 42 tuple
2 4669 13 261232 11 1276266 52 bytes
3 2357 7 198684 8 1474950 61 types.CodeType
4 436 1 166276 7 1641226 67 type
5 2156 6 155232 6 1796458 74 function
6 436 1 130836 5 1927294 79 dict of type
7 93 0 87384 4 2014678 83 dict of module
8 237 1 62280 3 2076958 85 dict (no owner) 9 1091 3 48004 2 2124962 87 types.WrapperDescriptorType
<115 more rows. Type e.g. '_.more' to view.>
I tried changing list to tuple, but it didn't make any difference.
Is there any possibility to decrease/limit RAM usage?

Plot individuals home-range with Adehabitat

I am trying to put the name from the individuals of my research in a polygons home-range plot, but after many attempts I still can not achieve it.
Here and example of my data: X and Y are coordinates and id are individuals
X Y id
29 29 4
44 28 7
57 57 5
60 81 11
32 41 4
43 29 7
57 57 5
46 83 11
32 41 4
43 29 7
57 56 5
60 82 11
35 40 4
43 28 7
62 55 5
54 73 11
27 40 4
43 28 7
61 54 5
First, i calculated the home-range of my data with MPC
cp <- mcp((data)[,1],percent=95, unin = c("m"), unout = c("m2"))
And the plot it
plot(cp, axes=TRUE, border = rainbow(12))
But i don´t kown which polygons correspond to each individual, and if possible i need to include the id of my individuals inside each polygon
Any help would be appreciated!!
Thanks
Juan
Here is an example using the example data from the adehabitatHR package, since you not really providing a reproducible example.
library(adehabitatHR)
data("puechabonsp")
cp <- mcp(puechabonsp$relocs[, 1], percent=95, unin = c("m"), unout = c("m2"))
One way would be to use ggplot2 and sf:
library(sf)
library(tidyverse)
st_as_sf(cp) %>% ggplot(., aes(fill = id)) + geom_sf(alpha = 0.5) +
scale_fill_discrete(name = "Animal id")

How to format a number to appear as percentage in Excel

So lets say I have a few numbers in a sheet
a b c d
1 33 53 23 11
2 42 4 83 64
3 75 3 48 38
4 44 0 22 45
5 2 34 76 6
6
7 Total 85
I would like to display those numbers so that the cell value still holds the original figure (A1 = 33)
but the cell displays both the number and a percentage from the total (B7) eg
a b c d
1 33 (39%) 53 (62%) 23 (27%) 11 (13%)
2 42 (49%) 4 (5%) 83 (98%) 64 (75%)
3 75 (88%) 3 (4%) 48 (56%) 38 (45%)
4 44 (52%) 0 (0%) 22 (26%) 45 (53%)
5 2 (2%) 34 (40%) 76 (89%) 6 (7%)
6
7 Total 85
I know how to format a cell as a percentage, but I can't figure out how to display both original values, the calculated percentage value (value/total*100), but not change the cell value so I could still sum the cells in the end (eg. A6 =SUM(A1:A5) = 196)
Does anyone have an idea? I was hoping there could be a way to duplicate and calculate the figure using text formatting, but I can't get anything to work.
I'm guessing this is a trivial answer and maybe not what you're looking for, but why not just add a column for each of the columns you have now?
a a' b b' c c' d d'
1 33 (39%) 53 (62%) 23 (27%) 11 (13%)
2 42 (49%) 4 (5%) 83 (98%) 64 (75%)
3 75 (88%) 3 (4%) 48 (56%) 38 (45%)
4 44 (52%) 0 (0%) 22 (26%) 45 (53%)
5 2 (2%) 34 (40%) 76 (89%) 6 (7%)
6
7 Total 85
#Ari’s answer seems to meet to meet the requirements in your question, not repeat information more than the example you gave for output requirement and be viable for up to around 8000 or so columns to start with (unless a very old version of Excel) and Jerry’s comment is also correct that what you want to achieve the way you want to achieve it is not possible.
However there are other approaches that might be acceptable substitutes. One is to copy your data and Paste Special with Operation Divide, either elsewhere or over the top of your data. If over the top this either shows the values or the percentages otherwise duplicates your data. Over the top would also require something like Operation Multiply to revert back to values, and reformatting each time if to appear as in your example.
Another is to use a PivotTable with some calculated fields and both are shown below:
I appreciate neither is exactly what you are asking for.

MS Excel: how can I make Max() more efficient?

I have a set of data that looks like this:
ID Value MaxByID
0 32 80
0 80 80
0 4 80
0 68 80
0 6 80
1 32 68
1 54 68
1 56 68
1 68 68
1 44 68
2 54 92
2 52 92
2 92 92
4 68 68
4 52 68
5 74 74
5 22 74
6 52 94
6 52 94
6 46 94
6 94 94
6 56 94
6 14 94
I am using {=MAX(IF(A$2:A$100=A2,B$2:B$100))} to calculate the MaxByID column. However, the dataset has >100k rows, with mostly unique IDs: this seems to be a really inefficient way to do this, as each cell in C:C has to iterate through every cell in A:A.
The ID field is numeric and can be sorted- is there a way of more intelligently finding the MaxByID?
You may be able to use a pivot table to find the maximum for each unique ID: see this link for an example.
Once you have that table, VLOOKUP should enable you to quickly find MaxByID for each ID.
Once you have sorted by ID you could add columns to get the start row number and count for each unique. These 2 numbers allow you to calculate the size and position of the range of Unique values. So then you can use MAX(OFFSET(StartValueCell,StartThisUnique-1,0,CountThisUnique,1)) to get the max
This might be faster
{=IF(A2=A1,C1,MAX(($A$2:$A$24=A2)*($B$2:$B$24)))}
Since your data appears to be sorted, you could see if the ID matches the row above and simply copy the max down.

Resources