recursive algorithm for 2D array in Python - python

a = [
[1, 2, 3, 4],
[5, 6, 7, 8],
[9, 8, 1, 2],
[6, 3, 1, 4],
]
I have a 2D array and given cell indexs(i,j).
for e.g. we are given x,y=(2,3) so this is for a[2][3].
What I want to do using dynamic programming or recursion(prefer) is that I will traverse the whole matrix (until a given condition satisfy) by moving up, down, left and right.
I mean , I will go from (x,y) to all 4 adjacent cell, and then do this recursively for all 4 cell(until some condition). but this is not guaranteed that all 4 cell will be covered(there is algorithm for that, if that satisfy then only I will move to that cell and further from that cell using same algo.
I'm able to implement algorithm but I'm having hard time to implement recursive solution in Python.
can you please suggest something, link to some similar recursive code.
I tried to find same on stackoverflow but not success. I'm not sure if this is violating the question posting rule, if so I will remove but please try to help me with this first.

What you are trying to do is very similar to a flood fill. Check the Wikipedia page to learn the algorithm. It is common enough that it should not be hard to find code for it in multiple languages.

Related

Python: Is this array element replacement correct?

I wanted to change all the negative values of an array to be 0. Will the following expression do what I expect?
import numpy as np
x = np.array([3, -3], [5, 2], [1, -5])
x[x < 0] = 0
I know this could be done manually, but I want to know that because I need it for a larger personal project.
In short, yes it will, if you provide a valid array. However, the array you are trying to construct is not valid, as np.array does not accept multiple array-like parameters. Maybe you meant to write this instead?
x = np.array([[3, -3], [5, 2], [1, -5]])
Note the extra pair of brackets surrounding your arguments to create a 2D array.
As others pointed out though, please don't ask simple questions like this on StackOverflow which can easily be confirmed with less than a minute of your own trial and error in a Python shell. The intent is generally to ask about specific problems you run into, and to show your attempts at a solution, so you can then be guided into accomplishing what you want.

Gale-Shapley Algorithm Stability Test

I'm a beginner in python coding and am trying to figure out how to test the stability of the Gale-Shapley Algorithm. I understand that for a stable pairing to be made, this means that there's no situation whereby there's 2 people who prefers each other over their assigned partner.
The data of participants' preferences is as follows:
preference = [["boy1",1,3,2,4], ["boy2",1,2,4,3],["boy3",1,2,3,4],["boy4",2,3,1,4],["girl1",2,1,3,4],["girl2",4,3,2,1],["girl3",1,2,3,4],["girl4",3,4,2,1]]
For example, for preference[0], boy1's ranking for girl1 is 1, girl2 is 3, girl3 is 2, girl 4 is 4. This means that the list goes: ["boy1", (ranking of girl1), (ranking of girl2), (ranking of girl3), (ranking of girl 4)].
An example of a solution of pairings is as follows:
solution1 = [["boy1","girl1"],["boy2","girl3"],["boy3","girl2"],["boy4","girl4"]
I'm trying to come up with a function that produces true if solution is stable and false if the solution isn't stable, given the preference, solution and number of couples.
I've tried using pandas and numpy but I keep getting stuck with many for loops and if and problems with indexing as I'm not very familiar with any of these python libraries. I'm now trying to go back to basic and see if it's possible to do it. However, as I'm doing it, I realize that I kept using for loops and it won't be as efficient. Below is my incomplete code, please do advise on what I should do to improve the efficiency of this incomplete code - and if it's possible to execute my current incomplete code once it's complete. Please do suggest any python libraries that I can use too, any suggestions are greatly appreciated!
def teststability(n, preference, solution):
for i in solution[i]:
fpo = solution[i][1][1]
for j in preference[j]:
if solution[i][0] == preference[j][0]:
rank = preference[j][fpo]
if rank == 1:
continue
else:
for k in pref[j][k]:
if pref[j][k] < rank:
lst.append("girl"+str(k))
else:
continue
You don't Pandas or Numpy for this, as it's a classic algorithmic SAT problem, and not one of data. (If you need to apply a given solution algorithm to a large array of pairs, then Pandas might be useful.)
The algorithm is implemented in the QuantEcon/MatchingMarkets package.
Lastly, I'd note that it's a little confusing that you're using lists made of strings and integers. I'd suggest dict of male-to-female and female-to-male preferences, eg:
female_prefs = {1: [2, 1, 3, 4], 2: [4, 3, 2, 1], 3: [1, 2, 3, 4], 4: [3, 4, 2, 1]}

How to join random lines, defined by two points, into a single path? A traveling salesman like problem

I am attempting to generate at single continuous line from a set of lines that have been defined by two points.
Currently I generate a subset of random lines as follows:
[ [0, 0] [2, 2], [2, 1] [0, 1], [0, 1] [2, 2], ... ]
Next, I want to trace along these lines to make the longest unbroken path possible. Since there would be hundreds to thousands of these lines some will end up not be connected which is okay. The reason being that they can have the following properties among each other:
Same starting point
Same ending point
Same starting and ending point
The resulting output will look like a matrix which traces the optimal path that should be taken such as:
[ [0, 0], [2, 2], [0, 1], [2, 1] ]
I don't care to optimize the path length (because the length will already be predefined by the total length of the lines that were produced) but I would like to minimize the number of break points. Also the continuous line does not have to start and end at the same position.
Coding in python I initially started from the guide here I can use an array of arrays as my "cities". I'm not sure that this is the best method since it is trying to reduce the distance. Therefore, I feel like there might be a similar problem for analysis of genetic sequencing data; having many fragments which must be aligned to form a continuous stretch of DNA.
Ultimately I am looking for any suggestions on aligning these paths into a single continuous stretch using previously published python packages. In the end, should I code this myself, I will publish my results here.

Advice for script to solve color tile matching puzzle

I have a game that I'm trying to devise a script to find the solution for. I'm using python because that's what I'm most familiar with.
Here's the gist, the game is a 10 x 14 board made up of 5 different color tiles. The mechanics are you can select any group of 2 or more tiles of the same color that are touching on the horizontal or vertical axis (diagonals do not count). That group will then disappear and all the tiles above will fall down to take their place. If a column is completely empty of tiles any remaining columns of tiles to the right will move to the left to fill in the gap. You win by clearing the board and not leaving any tiles behind.
Small example of the game board, the actual one is 10 x 14
First step - Write a python script to respect the rules of the game. Fairly easy.
I map the colors of the tiles to number values and create a matrix like this:
test_game_board = [
[2, 2, 2, 1, 1, 1, 5],
[2, 2, 2, 3, 3, 1, 5],
[3, 2, 4, 5, 3, 3, 5],
[3, 3, 4, 5, 5, 3, 5],
[1, 1, 1, 1, 1, 3, 5],
[1, 1, 5, 5, 1, 4, 4]]
I parse the matrix and find all consecutive tiles of the same color and create an object for every possible move currently on the board.
I then have a block of code given a certain eligible move (see later comment on logic to pick moves) to update a copy of the game board and shuffle tiles down and over where needed.
Check the board again to refresh the list of eligible moves since tiles have moved around.
If there are eligible moves left then keep on picking new moves.
If no more eligible moves are found then I check the board to see if I lost or won the game.
If game lost then I start over and reset to the original game board layout.
Performance of the above seems to run through 30-40 moves and complete a single attempt of the game in about 0.0350 seconds.
Second step - Picking the sequence of moves
I've tried a few approaches:
randomly picking a move each turn: Even after running the script for hours it hasn't repeated an exact sequence of moves out of several million moves attempted.
I tried weighting the moves selected by how many tiles were in each move and picking the larger ones.
Going through the possible moves sequentially. Same as the random option but this way I can see some sort of progress it's making. I've tried running this on a spare machine for a few days and it's gotten through 15 million sequences and still not very far along the unknown number of total possible moves.
So I guess my question out there to the world is if someone has any resources or ideas on how I could devise an algorithm for solving this other than my current approach of brute forcing. I can post the script on pastebin or something didn't want to bloat my post more than it already is :P
EDIT: So I've gone with the brute force sequential route. I'm picking the first move in the list of eligible moves. If that sequence of moves fails I'll start over and increment the last eligible move. So I'm working on some optimizations for the brute force method:
caching results from N set of moves in a sequence so it's faster to loop through.
if a move creates an un-winnable board skip it (ex: if a move color has a lone tile on the board)
I think if I find a few more optimizations I can get this to solve a puzzle in a reasonable amount of time :)
It's a not a simple problem at all.) I think that this task belongs to NP-complete class, so there is no easy way of solving it.
What can you do? Try using A* search. As a heuristic, you can try picking a number of elements that could be removed by an action (I'm not sure that it's correct/optimal, you'll have to study it yourself).
There are other approaches, for example, constraint satisfaction, but I think it will be very difficult to implement a solver for your puzzle with it. However, look at Minizinc for insights. I would generate a task in the form of 'is it possible to empty current board in K steps?'. If not, increase K and run Minizinc again.

Graph Theory: Finding all possible paths of 'n' length (with some constraints)

I was given a sample challenge question by one of my friends. I would like to hear some advice on how to best approach finding a solution.
The problem involves calculating all possible patterns of traversing a series of points on a grid-like scale. I will simply be given a number 'n' that represents how many times I must move, and I must determine the number of ways I can traverse the grid moving n times. The starting point can be any of the points so I must run my calculation on every starting point with my answer being the sum of the results of each starting point.
I am still a bit of a beginner is some regards to programming, and my best guess as to how to approach this problem is to use graph theory. I have started by creating a graph to represent the nodes as well as their neighbors. I am leaving this problem intentionally vague because I want to learn how to approach these kinds of problems rather than having some expert swoop in and simply solve the entire thing for me. Here is an example representation of my graph in Python 3 (a dictionary).
graph = {'a':['b','c']
'b':['a','e','f']
'c':['a','d']
'd':['c']
'e':['b','g'] and etc.
My real graph is significantly bigger with each node typically having at least 3-4 neighbors. Let's pretend the 'n' given is 6, meaning I need to return all possible valid paths that involve moving 6 times. I am allowed to revisit nodes, so a valid path could simply be a-b-a-b-a-b. Another example of a 'valid' path is a-b-a-c-d-c or e-b-a-c-a-b since we can start from any starting point.
I am at a bit of a loss as to how to best approach this problem. Recursion has crossed my mind as a possible solution where I traverse all possible paths and increment a counter each time I hit the 'end' of a path. Another possible solution I have considered is at each node, calculate the possible moves and multiply it with a running tally. For example, starting at 'a', I have two moves. If I navigate to 'b', I have 3 moves. If I navigate to 'c', I have 2 moves. At this point, I have 1*3*2 moves. This could be a completely wrong approach...just an idea I had.
The actual problem is a lot more complex with constraints for certain nodes (how many times you can visit it, rules against visiting it if a certain sequence of nodes were hit prior, etc.) but I will omit the details for now. What I will say is that given these constraints, my algorithm must know what the previous pattern of visited nodes was. At the 5th move, for example, I must be able to refer to the previous 4 moves at any time.
I would love to hear advice on how you would best approach solving the 'simpler' problem I outlined above.
Check out Depth First Search (DFS). Just off the top of my head: Use recursive DFS, use a counter for saving each node found after making 'n' moves. You would need to build an undirected graph representation of the given data, so that you could run the DFS algorithm on the graph.
Here's the simplest answer for the case you gave. Once you have you graph in the form of a "transition map" (which can just be a dictionary, like you've shown), then the following code will work:
def myDFS(trans_dict,start,length,paths,path=[]):
path=path+[start]
if len(path)==length:
paths.append(path)
else:
for node in trans_dict[start]:
myDFS(trans_dict,node,length,paths,path)
If you want the number of ways you can traverse the map with a path of a given length, then that would just be len(paths).
Example:
trans_dict = {0:[1,2],1:[2,3],2:[0,3],3:[3]}
paths = []
length = 3
for a in trans_dict:
myDFS(trans_dict,a,length,paths)
print paths # [[0, 1, 2], [0, 1, 3], [0, 2, 0], [0, 2, 3], [1, 2, 0], [1, 2, 3], [1, 3, 3], [2, 0, 1], [2, 0, 2], [2, 3, 3], [3, 3, 3]]
print len(paths) # 11
Answer was inspired by this Q&A: trying to find all the path in a graph using DFS recursive in Python

Categories

Resources