Python Forum
Matrix understanding in Python
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Matrix understanding in Python
#1
Hi,
this is text of exercise:
Quote:Given a 2D grid, each cell is either a zombie 1 or a human 0. Zombies can turn adjacent (up / down / left / right) human beings into zombies every hour. Find out how many hours does it take to infect all humans?
I haven't found many resources on the 2d matrices in python ,so
I tried to break it down by thinking if I had a list rather than a matrix:
if I had only one list and had to change the element with a value of 0 to 1 I found this solution that works and returns a list with all the values ​​1

a = [0,1,1,0,1]
contagion = [1 if x == 0 else x for x in a]
print(contagion)
It also works for others (I did the tests)

But how do I get a matrix and then "calculate" how long it takes for it to become all of them?
Reply
#2
(Nov-13-2019, 11:35 AM)RavCOder Wrote: But how do I get a matrix and then "calculate" how long it takes for it to become all of them?

I think that your code don't do what is expected in this assignment.

In order to calculate hours you loop over matrix until there all only zombies. How many loops, so many hours.
I'm not 'in'-sane. Indeed, I am so far 'out' of sane that you appear a tiny blip on the distant coast of sanity. Bucky Katt, Get Fuzzy

Da Bishop: There's a dead bishop on the landing. I don't know who keeps bringing them in here. ....but society is to blame.
Reply
#3
I know it's not correct, but doing nested loops without knowing what I should be looping is difficult
Reply
#4
You can use numpy to create your 2D array, or perhaps a bit easier is an array of arrays.
So, assume a 10 by 10 array. Build it by creating a 10 element list, and append that list to your array 10 times creating 10 rows. You then access each row and column as ary[row][col].
Now, you need to avoid a gotcha. When appending each row to your array, you need a copy of that list, otherwise you can end up with 10 references to the same list.
Done this a couple times as early projects, once making the board for Conway's Game of Life and once for making the board for a Sudoku solver.
Reply
#5
Looping of matrix is simple. Some examples:

>>> m = [[1, 0, 0, 0, 1], 
...      [0, 0, 0, 0, 0], 
...      [0, 1, 0, 0, 0], 
...      [0, 1, 0, 0, 0]]
>>> for row in m: 
...     print(row) 
...                                                                                        
[1, 0, 0, 0, 1]
[0, 0, 0, 0, 0]
[0, 1, 0, 0, 0]
[0, 1, 0, 0, 0]
>>> for col in zip(*m): 
...     print(col) 
...                                                                                        
(1, 0, 0, 0)
(0, 0, 1, 1)
(0, 0, 0, 0)
(0, 0, 0, 0)
(1, 0, 0, 0)  
Your actual problem is how to change values adjacent to zombie values. As this includes next/previous rows you should figure out when to make 'infection' happen.
I'm not 'in'-sane. Indeed, I am so far 'out' of sane that you appear a tiny blip on the distant coast of sanity. Bucky Katt, Get Fuzzy

Da Bishop: There's a dead bishop on the landing. I don't know who keeps bringing them in here. ....but society is to blame.
Reply
#6
I think about when scrolling through the list finds the number 0 and make it number 1, but my problem is how do I scroll an array of an array. the indexes I think are just the lists of matrix.
 matrix =   [[1, 0, 0, 0, 1], # matrix[0] index
             [0, 0, 0, 0, 0], # matrix[1] index
             [0, 1, 0, 0, 0], # matrix[2] index
             [0, 1, 0, 0, 0]] # matrix[3] index
I should do something like that (I know my logic is wrong and my syntax is also)
for i in zip(*list_zombies_human):
  print(i)

for j , n in i:
  if j == 1:
    i[n] = 0
print(j)
Reply
#7
Task is described as:

Quote:Given a 2D grid, each cell is either a zombie 1 or a human 0. Zombies can turn adjacent (up / down / left / right) human beings into zombies every hour. Find out how many hours does it take to infect all humans?

So subtasks can be defined as:

- find zombies
- infect neighbours adjacent to zombies
- repeat until all are zombies

You must separate finding zombies and infecting neighbours otherwise you will get incorrect result (how to separate existed zombies and newly created zombies).

Finding zombies is relatively easy. As we need to infect neighbours we should use indices to identify the location. For achieving that we can 'iterate over enumerated rows and for every enumerated item in row we return row-item number pair if item value is 1'

zombies = ((i, j) for i, row in enumerate(m) for j, item in enumerate(row) if item == 1)
Now we have locations (row, col) of zombies.

How to find neighbours?

If we have coordinate of zombie, then to get previous (to the left of zombie) we should change coordinates (0, -1), to get next (to the right of zombie) we shold change (0, 1), for row above (-1, 0) and row below (1, 0).

So we calculate coordinates of infected cells and change their values. What we should take into consideration: we shouldn't allow negative values (it will start counting from end); we will get IndexError for values in first and last row and column. Both of these are easily mitigated.

If we have 'infected' neighbours we should check whether humans are still present and if so repeat.
I'm not 'in'-sane. Indeed, I am so far 'out' of sane that you appear a tiny blip on the distant coast of sanity. Bucky Katt, Get Fuzzy

Da Bishop: There's a dead bishop on the landing. I don't know who keeps bringing them in here. ....but society is to blame.
Reply
#8
Meanwhile I found this to get inside the matrix and scroll through it
list_zombies_human =[[0,1,1,0,1],[0,1,0,1,0],[0,0,0,0,1],[0,1,0,0,0]]

for mat , arr in enumerate(list_zombies_human):
  for row_1, row in enumerate(arr):     
        print(row)
        for e in row:
            if e == 0:
              e = 1
            print(e)
but I have error in the last loop
Error:
TypeError: 'int' object is not iterable
Reply
#9
I don't know how familiar you are with matrices, but:

>>> list_zombies_human =[[0,1,1,0,1],[0,1,0,1,0],[0,0,0,0,1],[0,1,0,0,0]]                  
>>> list_zombies_human[1][1]        # item in second row in second position (0-based index)                                                             
1
>>> list_zombies_human[1][2] = 1    # turn right neighbour into zombie; (0, 1) change in coordinates                                                           
>>> list_zombies_human                                                                     
[[0, 1, 1, 0, 1], [0, 1, 1, 1, 0], [0, 0, 0, 0, 1], [0, 1, 0, 0, 0]]
I'm not 'in'-sane. Indeed, I am so far 'out' of sane that you appear a tiny blip on the distant coast of sanity. Bucky Katt, Get Fuzzy

Da Bishop: There's a dead bishop on the landing. I don't know who keeps bringing them in here. ....but society is to blame.
Reply
#10
I don't have much experience with it but I'm learning now doing this exercise.
Why my approach isn't correct?
I tried also to replace with this:
[1 if x == 0 else x for x in range(len(row))]
but I had the same error.
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  define a diagonal matrix from a matrix amalalaoui 1 2,318 May-15-2019, 01:12 PM
Last Post: ichabod801

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020