Assign string X to index of multidimensional data based on user directions. - python

grid = int(input("Grid size: "))
x = []
for i in range(grid):
y = []
for j in range(grid):
e = '.'
y.append(e)
x.append(y)
x[0][0] = 'X'
for row in x:
print(*row)
d = input("Direction: ")
I'm trying to work out how to assign X to the index of the grid position which the user input gives. Below is the question.
You're familiar with the story of Hansel and Gretel, so when you decide to go exploring you always make sure to keep track of where you've come from. Since you know how unreliable leaving a trail of breadcrumbs is, you decide to write a program to help you map out your trail.
Your program should first read in the size of the grid that you will be exploring, and then read in directions: left, right, up or down. You always start exploring at the top left of your map. After every step, you should print out the trail, reading in directions until a blank line is entered. You will never be directed off the edges of the map.

Related

Tetris remove completed line and shift all the remaining block

For now the code i'm using is this one:
self.board = numpy.delete(self.board, row, 0)
new_row = [0 for _ in range(configuration.config["cols"])]
self.board = numpy.vstack([new_row, self.board])
The code corretly remove the row(an index) in question from self.board(2d numpy array), then add a new empty row shifting every piece down one.
The problem is when a piece should fall more than one single row, like in this situation:
The yellow piece should go all the way to the bottom since the rest of his tetramino is gone with the row
And i have no idea on how i could implement something like this
Full example:
import numpy
if __name__ == '__main__':
board = numpy.array([
[6,0,0,0,0,5,0,0,0,0],
[6,6,1,1,2,5,5,5,1,2],
[6,6,1,1,1,0,1,0,0,0]
])
expected_result = numpy.array([
[0,0,0,0,0,0,0,0,0,0],
[6,0,0,0,0,0,0,0,0,0],
[6,6,1,1,1,5,1,0,0,0]
])
for y,row in enumerate(board):
if not 0 in row:
board = numpy.delete(board, y, 0)
new_row = [0 for _ in range(10)]
board = numpy.vstack([new_row, board])
print(board)
print("--------")
print(expected_result)
It isn't clear exactly what you're trying to achieve. For what it's worth, the way you have it currently is how the "real" Tetris works. Blocks are left floating.
If you want pieces to fall, how to you want it to work?
Only pieces on the row immediately above? This would leave strange voids in the field but would be achieved by comparing each element in the row with the row below, and if the row below contains a 0 in that place then replace it with the row above. You'd get behaviour like this:
All pieces in rows above the break? This would make an interesting game that would snowball quickly, but would be very different from traditional Tetris (traditional 2nd, all falling 3rd). You would need to loop over all of the rows with the same logic as the single row until you don't find any more elements to move.
If you want to try to reinvent the game you're going to come into some balancing issues - I get that this is a programming exersize but its worth considering that it will probably take more time to make the game playable with falling blocks as it will to work out how to make the blocks fall.

python go board game, struggling to figure out how to capture multiple stones

I've been trying to make a board game of GO, in python with pygame and a numpy array for storing the board locations and stone colors (0, 1, 2). My issue is that I've been using a for loop to examine each index at a time, and examining the adjacent indexes by adding or taking away an int:
columns = 5
rows = 5
def create_board():
board = np.zeros((row,col))
return board
board = create_board()
def libertyCheck():
for c in range(columns):
for r in range(rows):
if board[c][r+1] == 0:
x = 1
(lots more ifs, then add x's to see if all spaces are occupied)
This method seems to be OK for capturing a single stone (as long as its not on the edges of the board, because it also starts causing out of bounds issues), but becomes very convoluted once several stones of the same color are next to each other and may or may not need to be captured.
There has to be a better way of searching these indexes without causing out of bounds? one that will allow me to keep track of all of the stones and their adjacent spaces?

Vectorised Marching cubes (squares) - connecting the lines into curves

I am drawing a metaball with marching cubes (squares as it is a 2d) algorithm.
Everything is fine, but I want to get it as a vector object.
So far I've got a vector line or two from each active square, keeping them in list lines. In other words, I have an array of small vector lines, spatially displaying several isolines (curves) - my aim is to rebuild those curves back from lines.
Now I am stuck with fast joining them all together: basically I need to connect all lines one by one all together into several sequences (curves). I don't know how many curves (sequences) will be there, and lines could be in different directions and I need to process lines into sequences of unique points.
So far I wrote something obviously ugly and half-working (here line is a class with list of points as attribute points, and chP is a function checking if points are close enough, t definies this 'enough') :
def countur2(lines):
'''transform random list of lines into
list of grouped sequences'''
t = 2 # tolerance
sqnss = [[lines[0]]] # sequences
kucha = [lines[0]] #list of already used lines
for l in lines:
for i,el in enumerate(lines):
print 'working on el', i
ss = sqnss[-1][0]
ee = sqnss[-1][-1]
if el not in kucha:
if chP(el.points[0],ee.points[1],t):
sqnss[-1].append(el)
kucha.append(el)
break
elif chP(el.points[1],ee.points[1],t):
sqnss[-1].append(el.rvrse())
kucha.append(el)
break
elif chP(el.points[1],ss.points[0],t):
sqnss[-1] = [el] + sqnss[-1]
kucha.append(el)
break
elif chP(el.points[0],ss.points[0],t):
sqnss[-1] = [el.rvrse()] + sqnss[-1]
kucha.append(el)
break
print 'new shape added, with el as start'
sqnss.append([el])
kucha.append(el)
#return sqnse of points
ps = []
for x in sqnss: ps.append([el.points[0] for el in x])
return ps
I know this is such a big question, but please give me any clue on right direction to handle this task
A first option is to number all cell sides uniquely, and associate to every vector the pair of edges it joins.
Enter all pairs in a dictionary, both ways: (a,b) and (b,a). Then, starting from an arbitrary pair, say (a,b), you will find the next pair through b, say (b,c). You will remove both (b,c) and (c,b) from the dictionary, and continue from c, until the chain breaks on a side of the domain, or loops.
A second option is to scan the whole domain and when you find a cell crossed by an isocurve, compute the vector, and move to the neighboring cell that shares an edge crossed by the isocurve, and so on. To avoid an infinite scanning, you will flag the cell as already visited.
By contrast with the first approach, no dictionary is required, as the following of the chain is purely based on the local geometry.
Beware that there are two traps:
cells having one or more corner values equal to the iso-level are creating trouble. A possible cure is by slightly modifying the values corner; this will create a few tiny vectors.
cells can be crossed by two vectors instead of one, and require to be visited twice.

Project Euler #82 (Python)

First of all this is the problem : https://projecteuler.net/problem=82 .
This is my code :
# https://projecteuler.net/problem=82
matrice = open('matrix3.txt','r').read().split('\n')
m = []
for el in matrice:
if el=='':
continue
tmp = el.split(',')
m.append(tmp)
matrix = [[0 for i in range(80)]for j in range(80)]
x,y = 0,0
while(True):
matrix[x][y]=int(m[x][y])
y+=1
if y==80:
y=0
x+=1
if x==80:
break
tmp = [0]*80
x,y = 0,78
while(True):
if x==0:
tmp[x]=min(matrix[x][y+1],matrix[x+1][y]+matrix[x+1][y+1])
if x==79:
tmp[x]=min(matrix[x][y+1],matrix[x-1][y]+matrix[x-1][y+1])
else:
tmp[x]=min(matrix[x][y+1],matrix[x-1][y]+matrix[x-1][y+1],matrix[x+1][y]+matrix[x+1][y+1])
x+=1
if x==80:
for e in range(80):
matrix[e][y]+=tmp[e]
tmp = [0]*80
x=0
y+=-1
if y<0:
break
minimo = 10**9
for e in range(80):
if matrix[e][0]<minimo:
minimo=matrix[e][0]
print(minimo)
The idea behind this code is the following:
I start from the 79th column(78th if you start counting from 0) and I calculate the best(the minimal) way to get from any given entry in that column to the column to the right.
When the column is over I replace it with the minimal results I found and I start doing the same with the column to the left.
Is anyone able to help me understand why I get the wrong answer?(I get 262716)
The same code works for the matrix in the example(It works if you change the indeces of course).
If I understand the question, your code, and your algorithm correctly, it looks like you aren't actually calculating the best way to get from one column to the next because you're only considering a couple of the possible ways to get to the next column. For example, consider the first iteration (when y=78). Then I think what you want is tmp[0] to hold the minimum sum for getting from matrix[0][78] to anywhere in the 79th column, but you only consider two possibilities: go right, or go down and then go right. What if the best way to get from matrix[0][78] to the next column is to go down 6 entries and then go right? Your code will never consider that possibility.
Your code probably works on the small example because it so happens that the minimum path only goes up or down a single time in each column. But I think that's a coincidence (also possibly a poorly chosen example).
One way to solve this problem is using the following approach. When the input is a NxN matrix, define a NxN array min_path. We're going to want to fill in min_path so that min_path[x][y] is the minimum path sum starting in any entry in the first column of the input matrix and ending at [x][y]. We fill in one column of min_path at a time, starting at the leftmost column. To compute min_path[i][j], we look at all entries in the (j-1)th column of min_path, and the cost of getting from each of those entries to (i, j). Here is some Python code showing this solution: https://gist.github.com/estark37/5216851. This is an O(N^4) solution but it can probably be made faster! (maybe by precomputing the results of the sum_to calls?)

select the bigger ball

I've got an array of data filled with "#" and "." for example it display something like this :
...........#############..............................
.........################..................#######....
........##################................#########...
.......####################..............###########..
........##################................#########...
.........################..................#######....
...........#############..............................
I want to create an algorithm that find the bigger ball and erase the smaller one.
I was thinking of using the longest sequence of "#" to know what is the diameter.
So i've got something like this :
x = 0
longest_line = 0
for i in range(0, nbLine) :
for j in range(0, nbRaw) :
if data[i, j] = red :
x = x+1
if data[i, j+1] != red:
And i don't know what to do next..
I would use some sort of a segmentation algorithm, and then simply count the number of pixels in each object. Then simply erase the smaller one, which should be easy as you have a tag of the object.
The segmentation algorithms typically work like this.
Perform a raster scan, starting upper left, working towards bottom right.
As you see a #, you know you have an object. Check it's neighbors.
If the neighbors have a previously assigned value, assign that value to it
If there there are multiple values, put that into some sort of a table, which after you are done processing, you will simplify.
So, for a very simple example:
...##...
.######.
...##...
Your processing will look like:
00011000
02111110
00011000
With a conversion such that:
2=>1
Apply the look up table, and all objects will be tagged with a 1 value. Then simply count the number of pixels, and you are done.
I'll leave the implementation to you;-)
Get your data into a nicer array structure
Perform connected component labelling
Count the number of elements with each label (ignoring the background label)
Choose the label with the largest number of elements
Do you olways have only 2 shapes like this? Because in this case, you could also use the python regular expression library. This code seems to do the trick for your example (I copied your little drawing in a file and named it "balls.txt"):
import re
f = open("balls.txt", "r")
for line in f :
balls = re.search("(\.+)(#+)(\.+)(#*)(\.+)", line)
dots1 = balls.groups()[0]
ball1 = balls.groups()[1]
dots2 = balls.groups()[2]
ball2 = balls.groups()[3]
dots3 = balls.groups()[4]
if len(ball1) < len(ball2):
ball1 = ball1.replace('#', '.')
else:
ball2 = ball2.replace('#', '.')
print "%s%s%s%s%s" % (dots1, ball1, dots2, ball2, dots3)
And this is what I get:
...........#############..............................
.........################.............................
........##################............................
.......####################...........................
........##################............................
.........################.............................
...........#############..............................
I hope this can give you some ideas for the resolution of your problem
Assuming the balls don't touch:
Assuming exactly two balls
Create two ball objects, (called balls 0 and 1) each owns a set of points. Points are x,y pairs.
scan each row from top to bottom, left to right within each line.
When you see the first #, assign it to ball 0 (add it’s x,y cords to the set owned by the ball 0 object).
When you see any subsequent #, add it to ball 0 if it is adjacent to any point already in ball 0; otherwise add it to ball 1. (If the new # is at x, y we just test (x+1,y) is in set, (x-1, y) is in set, (x, y+1) is in set, (x, y-1) is in set, and the diagonal neighbors)
When the scan is complete, the list sizes reveal the larger ball. You then have a list of the points to be erased in the other ball’s points set.

Categories

Resources