Generate 2D list with given dimensions in Haskell - haskell

I am trying to generate a list of lists with a specified dimension.
the data type of this list looks something like this:
data A = X | Y | Z
so the list is of type [[A]]. (A is an instance of the Show type class so don't worry about that).
The user gives in a certain dimension (lets say width = 3 and height = 4), so the content could look like this:
[[X,Y,Z],
[Y,Y,X],
[Y,X,Z],
[X,Z,Z]]
How can I generate a width X height 'matrix', the values aren't all that important at the moment.
thanks in advance.
EDIT: (for clarity reasons)
I just want to know how to generate a 'matrix' of type [[A]] with the width and height as user input.
So width = number of elements in the inner list, height = number of lists in the outer list.

To generate a 3x4 nested list filled by a certain element, you can use:
data A = X | Y | Z deriving (Show)
generate width height = replicate height . replicate width
main = print $ generate 3 4 X
to get [[X,X,X],[X,X,X],[X,X,X],[X,X,X]].
Note that nested lists are not a great substitute for a 2D array in C/Java if the goal is to do frequent point updates. In those cases, use Data.Map or Data.Array.

Related

How to plot best fit line for values in a list less than an integer?

I'm trying to plot a best fit line for when values in my list x are less than x_c (in this case 20).
plt.scatter(x,tf)
x_c = (20)
filter1 = [a < x_c for a in x]
m, b = np.polyfit(x[filter1], tr[filter1], 1)
plt.plot(x[filter1], m*x[filter1]+ b)
When I do that I get this error: TypeError: list indices must be integers or slices, not list
I also tried it with
filter = [x < x_c]
and that also did not work
Python lists do not support boolean indexing. (But numpy arrays do!) You must select the items from your list that match your condition, and then use the new list for plotting:
good_x = [a for a in x if a < x_c]
....
plt.plot(good_x, ...)

Breadth-first search with spiral ordered list of coordinates in Haskell

edit: This is getting down voted but it's not been made clear what data structure I should be using instead of a list of coordinates. Unfortunately my data comes as a flat list and it needs to be distributed with in an outwards clockwise spiral. Then run a BFS on that to work out islands. I used coordinates which is what the C++ code tutorial seem to do (I have zero C++ experience though) but seems that was a bad route to take in Haskell
I'm trying to accumulate a list of touching land cells grouped by islands.
Looking at the image bellow I'd expect 5 islands and each with the cells on that island. [[Cell]].
My input is currently a flat list of cells ordered in a clockwise spiral (red dotted line) and a number of the population of the cell. 0 making it sea and any >= 1 is the population.
data Cell = Cell
{ cellLoc :: (Int, Int)
, cellpop :: Int -- 0 sea, >= 1 population of land
}
startingCellList :: [Cell]
startingCellList =
[(Cell (1,0) 0)
,(Cell (1,-1) 0)
,(Cell (0,-1) 0)
,(Cell (-1,-1) 4)
]
The cellLoc gives me coordinates of cell in an X Y plane with (0,0) being at the centre of the grid. Am I right in thinking I can use the those coordinates to run my BSF?
Or do I need to rethink the use of coordinates to achieving my grid?
I've also found this great example but I'm not grasping it's use of vertexes and how or if I can relate it to using coordinates.
You can convert the list [(Int,Int)] into a Data.Set (Int,Int). Then you can quickly compute adjacency for your graph in the following way. Using this you can build your graph algorithm that finds components (in the complement of the graph, whatever).
import Data.Set
-- compute all possible neighbours as difference vectors
let adjDiff = [(dx,dy) | dx <- [-1..1], dy <- [-1..1], (dx,dy) /= (0,0)]
-- given a cell, compute all potential neighbouring cells
let adjFull (x,y) = [(x',y') | (dx,dy) <- adjDiff, let x'=x+dx, let y'=y+dy]
-- given a set of valid cells and a cell, compute all valid neighbours of this cell
let adj validCells cell = [n | n <- adjFull cell, member ValidCells n]

counting results from a defined matrix

So I am very new to programming and Haskell is the first language that I'm learning. The problem I'm having is probably a very simple one but I simply can not find an answer, no matter how much I search.
So basically what I have is a 3x3-Matrix and each of the elements has a number from 1 to 3. This Matrix is predefined, now all I need to do is create a function which when I input 1, 2 or 3 tells me how many elements there are in this matrix with this value.
I've been trying around with different things but none of them appear to be allowed, for example I've defined 3 variables for each of the possible numbers and tried to define them by
value w =
let a=0
b=0
c=0
in
if matrix 1 1==1 then a=a+1 else if matrix 1 1==2 then b=b+1
etc. etc. for every combination and field.
<- ignoring the wrong syntax which I'm really struggling with, the fact that I can't use a "=" with "if, then" is my biggest problem. Is there a way to bypass this or maybe a way to use "stored data" from previously defined functions?
I hope I made my question somewhat clear, as I said I've only been at programming for 2 days now and I just can't seem to find a way to make this work!
By default, Haskell doesn't use updateable variables. Instead, you typically make a new value, and pass it somewhere else (e.g., return it from a function, add it into a list, etc).
I would approach this in two steps: get a list of the elements from your matrix, then count the elements with each value.
-- get list of elements using list comprehension
elements = [matrix i j | i <- [1..3], j <- [1..3]]
-- define counting function
count (x,y,z) (1:tail) = count (x+1,y,z) tail
count (x,y,z) (2:tail) = count (x,y+1,z) tail
count (x,y,z) (3:tail) = count (x,y,z+1) tail
count scores [] = scores
-- use counting function
(a,b,c) = count (0,0,0) elements
There are better ways of accumulating scores, but this seems closest to what your question is looking for.
Per comments below, an example of a more idiomatic counting method, using foldl and an accumulation function addscore instead of the count function above:
-- define accumulation function
addscore (x,y,z) 1 = (x+1,y,z)
addscore (x,y,z) 2 = (x,y+1,z)
addscore (x,y,z) 3 = (x,y,z+1)
-- use accumulation function
(a,b,c) = foldl addscore (0,0,0) elements

Pygame blitting only updated surfaces

Right now I have an x by y array to hold integers that decide which tile to draw to the screen. (The integers choose which tile in my tile_arr to blit)
For better performance, I only want the ints that changed to be blit'ed again.
EXAMPLE 1:
For example right now I have something like:
tile_arr = [image1,image2,image3,image4]
arr = [[2,2,2],[2,2,2],[2,2,2]]
Then depending on what the user does, some values in arr might change, so lets say:
arr[0][0]=1
arr[2][1]=1
Which would give us the array:
arr=[[1,2,2],[2,2,2],[2,1,2]]
now when blitting to the screen, I would blit images from the tile_arr: image numbers 1,2,2 to the top row, 2,2,2, to the middle row, and 2,1,2 to the bottom row. When I blit the array, I use a screen.blit for each value or arr, that's nine blits. I would rather only do two blits. (Use screen.blit only twice)
EXAMPLE 2:
tile_arr = [green.bmp, red.bemp, blue.bmp]
feild_arr = [[0,0,0], [0,0,0], [0,0,0]]
Output:
G G G
G G G
G G G
User changes feild_arr to [[1,0,1], [0,2,0], [0,1,2]]
Output:
R G R
G B G
G R B
Now I only want to call sceen.blit() 5 times, leaving the 4 Green sqaures green, because nothing changed.
I thought of making another array, which would be just a copy of the first. Then run through it and compare to the new array to see what changed, but I think there is a better and faster way to this. Now the example is only 3x3 so making a duplicate array isn't too bad, but I'm working with a lot bigger arrays, and when you're blitting a 30x20 array, I need all the shortcuts I can get.
How do I only blit when the interger values in an array have been changed, and skip (don't blit) the values that have not changed?
You can use screen.blit only once, calling with a list of the rectangles that changed.
I think the best aproach is to create you own class deriving from DirtySprite:
class Cell: pygame.sprite.DirtySprite
which already has attributes for holding an image and a rectangle and you can add an attributes to hold the number and a method to change de number that will set it as dirty.
Then you can use LayeredDirty class to render the dirty sprites on the screen.

Filling up an output vector with stata loop

When you take centiles of a variable in Stata, for eg.
*set directory
cd"C:\Etc\Etc Etc\"
*open data file
use "dataset.dta",clear
*get centiles
centile var1, centile(1,5(5)95,99)
is there some way to record the resulting centile table to excel? The centile values are stored in r(c_#), where # indicates the centile at which you want the data. But I need a vector of the values at all the centiles, more or less as it appears in the output window.
I have attempted to use foreach loop to get the centiles into a vector, as follows:
*Create column of centiles
foreach i in r(centiles) {
xx[1,`i']=r(c_`i')
}
without success.
Thanks
EDIT:
I've since found this to work:
matrix X = 0,0
forvalues i=1/21 {
matrix X = `i',round(r(c_`i'),.001)\ X
}
Only inconveniences are 1) I have to include a a first row of 0,0 in the output, which I will then subsequently drop. 2) In this case I have 21 centiles, but it would be nice to automate the number of centiles in case I want to change it, for example something like this:
forvalues i=1/r(n_cent) {
matrix X = `i',round(r(c_`i'),.001)\ X
}
But the "i=1/r(n_cent)" is invalid syntax. Any advice as to how I might overcome these two inconveniences would be much appreciated.
Thanks
You can use the following syntax.
Load some data and compute the percentiles.
sysuse auto, clear
centile price, centile(1,5(5)95,99)
The matrix that is supposed to contain the results has to be initialized. This matrix is called X. It has as many rows as there are centiles requested via the centile command. It has two columns. At this stage, the matrix is populated with zeroes.
matrix X = J(`=wordcount("`r(centiles)'")', 2, 0)
The following loop is stepping through the results of the centile command and is replacing the zeroes in matrix X with the appropriate results. The first column of the matrix contains the number of the centile (1, 5, 10, ...) and the second column contains the result
forvalues i = 1 / `=wordcount("`r(centiles)'")' {
local cent: word `i' of `r(centiles)'
matrix X[`i', 1] = `cent'
matrix X[`i', 2] = r(c_`i')
}
Print the results:
matrix list X
If you are using round(), you are likely doing something wrong. There are few reasons to deliberately lose precision in the data; you can always display as many digits as you like using format this way or another (either applied to the data, or as an option of list or matrix list).
I wrote epctile command that returns percentiles as an estimation command, i.e., in the e(b) vector. This can be usable immediately; findit epctile to download.
You can modify your proposal as follows:
local thenumlist 1, 5(5)95, 99
centile variable, centile(`thenumlist')
forvalues i=1/`=r(n_cent)' {
matrix X = nullmat(X) \ r(c_`i')
}
numlist "`thenumlist'"
matrix rownames X = `r(numlist)'
matrix list X, format(%9.3f)

Resources