Storing values in an N x N grid
up vote
1
down vote
favorite
I am trying to write a program to store/display a grid of size N x N with cells containing either a 1 or a 0 in preparation for further computation:
module Board where
import Data.List as List
data CellState = One | Zero deriving (Eq, Ord)
data Cell = Cell {cellPos :: (Int, Int), cellState :: CellState} deriving (Eq, Ord)
type Board = [Cell]
instance Show CellState where
show One = "1"
show Zero = "0"
instance Show Cell where
show (Cell c x) = show (c,x)
genPositions :: Int -> [(Int, Int)]
genPositions x = [ (a,b) | a <- [0..(x-1)], b <- [0..(x-1)] ]
genCellState :: Int -> CellState
genCellState 0 = Zero
genCellState 1 = One
newBoard :: Int -> [Int] -> Board
newBoard i [x] = [Cell (round $ sqrt(fromIntegral i), round $ sqrt(fromIntegral i)) (genCellState x)]
where positions = genPositions $ round $ sqrt(fromIntegral i)
newBoard i (x : xs) = [Cell (positions!!(i - 1 - length xs)) (genCellState x)] ++ newBoard i xs
where positions = genPositions $ round $ sqrt(fromIntegral i)
What improvements can I make to this, both in terms of good practises and performance? I don't like Board being a list of Cells. I posted this on Stack Overflow by accident (have since deleted it) and someone recommended changing type Board = [Cell]
to newtype Board = Board { getBoard :: Array (Int,Int) CellState }
but I'm not too familiar with arrays in Haskell so not sure how this would work exactly. From what I have read they apply a function to the elements in the range [Int..Int]
and return a list of tuples with the input and output.
array haskell
bumped to the homepage by Community♦ 2 days ago
This question has answers that may be good or bad; the system has marked it active so that they can be reviewed.
add a comment |
up vote
1
down vote
favorite
I am trying to write a program to store/display a grid of size N x N with cells containing either a 1 or a 0 in preparation for further computation:
module Board where
import Data.List as List
data CellState = One | Zero deriving (Eq, Ord)
data Cell = Cell {cellPos :: (Int, Int), cellState :: CellState} deriving (Eq, Ord)
type Board = [Cell]
instance Show CellState where
show One = "1"
show Zero = "0"
instance Show Cell where
show (Cell c x) = show (c,x)
genPositions :: Int -> [(Int, Int)]
genPositions x = [ (a,b) | a <- [0..(x-1)], b <- [0..(x-1)] ]
genCellState :: Int -> CellState
genCellState 0 = Zero
genCellState 1 = One
newBoard :: Int -> [Int] -> Board
newBoard i [x] = [Cell (round $ sqrt(fromIntegral i), round $ sqrt(fromIntegral i)) (genCellState x)]
where positions = genPositions $ round $ sqrt(fromIntegral i)
newBoard i (x : xs) = [Cell (positions!!(i - 1 - length xs)) (genCellState x)] ++ newBoard i xs
where positions = genPositions $ round $ sqrt(fromIntegral i)
What improvements can I make to this, both in terms of good practises and performance? I don't like Board being a list of Cells. I posted this on Stack Overflow by accident (have since deleted it) and someone recommended changing type Board = [Cell]
to newtype Board = Board { getBoard :: Array (Int,Int) CellState }
but I'm not too familiar with arrays in Haskell so not sure how this would work exactly. From what I have read they apply a function to the elements in the range [Int..Int]
and return a list of tuples with the input and output.
array haskell
bumped to the homepage by Community♦ 2 days ago
This question has answers that may be good or bad; the system has marked it active so that they can be reviewed.
add a comment |
up vote
1
down vote
favorite
up vote
1
down vote
favorite
I am trying to write a program to store/display a grid of size N x N with cells containing either a 1 or a 0 in preparation for further computation:
module Board where
import Data.List as List
data CellState = One | Zero deriving (Eq, Ord)
data Cell = Cell {cellPos :: (Int, Int), cellState :: CellState} deriving (Eq, Ord)
type Board = [Cell]
instance Show CellState where
show One = "1"
show Zero = "0"
instance Show Cell where
show (Cell c x) = show (c,x)
genPositions :: Int -> [(Int, Int)]
genPositions x = [ (a,b) | a <- [0..(x-1)], b <- [0..(x-1)] ]
genCellState :: Int -> CellState
genCellState 0 = Zero
genCellState 1 = One
newBoard :: Int -> [Int] -> Board
newBoard i [x] = [Cell (round $ sqrt(fromIntegral i), round $ sqrt(fromIntegral i)) (genCellState x)]
where positions = genPositions $ round $ sqrt(fromIntegral i)
newBoard i (x : xs) = [Cell (positions!!(i - 1 - length xs)) (genCellState x)] ++ newBoard i xs
where positions = genPositions $ round $ sqrt(fromIntegral i)
What improvements can I make to this, both in terms of good practises and performance? I don't like Board being a list of Cells. I posted this on Stack Overflow by accident (have since deleted it) and someone recommended changing type Board = [Cell]
to newtype Board = Board { getBoard :: Array (Int,Int) CellState }
but I'm not too familiar with arrays in Haskell so not sure how this would work exactly. From what I have read they apply a function to the elements in the range [Int..Int]
and return a list of tuples with the input and output.
array haskell
I am trying to write a program to store/display a grid of size N x N with cells containing either a 1 or a 0 in preparation for further computation:
module Board where
import Data.List as List
data CellState = One | Zero deriving (Eq, Ord)
data Cell = Cell {cellPos :: (Int, Int), cellState :: CellState} deriving (Eq, Ord)
type Board = [Cell]
instance Show CellState where
show One = "1"
show Zero = "0"
instance Show Cell where
show (Cell c x) = show (c,x)
genPositions :: Int -> [(Int, Int)]
genPositions x = [ (a,b) | a <- [0..(x-1)], b <- [0..(x-1)] ]
genCellState :: Int -> CellState
genCellState 0 = Zero
genCellState 1 = One
newBoard :: Int -> [Int] -> Board
newBoard i [x] = [Cell (round $ sqrt(fromIntegral i), round $ sqrt(fromIntegral i)) (genCellState x)]
where positions = genPositions $ round $ sqrt(fromIntegral i)
newBoard i (x : xs) = [Cell (positions!!(i - 1 - length xs)) (genCellState x)] ++ newBoard i xs
where positions = genPositions $ round $ sqrt(fromIntegral i)
What improvements can I make to this, both in terms of good practises and performance? I don't like Board being a list of Cells. I posted this on Stack Overflow by accident (have since deleted it) and someone recommended changing type Board = [Cell]
to newtype Board = Board { getBoard :: Array (Int,Int) CellState }
but I'm not too familiar with arrays in Haskell so not sure how this would work exactly. From what I have read they apply a function to the elements in the range [Int..Int]
and return a list of tuples with the input and output.
array haskell
array haskell
edited Nov 22 '17 at 1:00
Jamal♦
30.2k11115226
30.2k11115226
asked Nov 22 '17 at 0:54
user6731064
61
61
bumped to the homepage by Community♦ 2 days ago
This question has answers that may be good or bad; the system has marked it active so that they can be reviewed.
bumped to the homepage by Community♦ 2 days ago
This question has answers that may be good or bad; the system has marked it active so that they can be reviewed.
add a comment |
add a comment |
1 Answer
1
active
oldest
votes
up vote
0
down vote
By defining r = round . sqrt . fromIntegral, newBoard fits on the screen. positions doesn't appear to be used in newboard's first case. Half the code disappears if we interpret Cell as ((Int, Int), Int). newBoard's first case can be pushed one recursion call deeper, mapping to instead of [x] to the current right hand side. [_] ++ _ ~> _ : _. positions is only used once, therefore I inline it.
type Cell = ((Int, Int), Int) -- (position, state)
genPositions :: Int -> [(Int, Int)]
genPositions x = [ (a,b) | a <- [0..(x-1)], b <- [0..(x-1)] ]
r = round . sqrt . fromIntegral
newBoard :: Int -> [Int] -> [Cell]
newBoard i =
newBoard i (x : xs) = (genPositions (r i)!!(i - 1 - length xs), x) : newBoard i xs
Successive elements of the list returned by genPositions and xs are zipped together; zip
captures this pattern. i is now not needed in its non-rooted form and I recommend changing the interface to take N as an argument instead. Non-square arguments can currently crash !! anyway. genPositions is only used once, therefore I inline it.
type Cell = ((Int, Int), Int) -- (position, state)
newBoard :: Int -> [Int] -> [Cell]
newBoard n = zip $ liftA2 (,) [0..n-1] [0..n-1]
For type Board = Array (Int, Int) Int
, Data.Array allows newBoard n = listArray ((0,0),(n-1,n-1))
.
add a comment |
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
0
down vote
By defining r = round . sqrt . fromIntegral, newBoard fits on the screen. positions doesn't appear to be used in newboard's first case. Half the code disappears if we interpret Cell as ((Int, Int), Int). newBoard's first case can be pushed one recursion call deeper, mapping to instead of [x] to the current right hand side. [_] ++ _ ~> _ : _. positions is only used once, therefore I inline it.
type Cell = ((Int, Int), Int) -- (position, state)
genPositions :: Int -> [(Int, Int)]
genPositions x = [ (a,b) | a <- [0..(x-1)], b <- [0..(x-1)] ]
r = round . sqrt . fromIntegral
newBoard :: Int -> [Int] -> [Cell]
newBoard i =
newBoard i (x : xs) = (genPositions (r i)!!(i - 1 - length xs), x) : newBoard i xs
Successive elements of the list returned by genPositions and xs are zipped together; zip
captures this pattern. i is now not needed in its non-rooted form and I recommend changing the interface to take N as an argument instead. Non-square arguments can currently crash !! anyway. genPositions is only used once, therefore I inline it.
type Cell = ((Int, Int), Int) -- (position, state)
newBoard :: Int -> [Int] -> [Cell]
newBoard n = zip $ liftA2 (,) [0..n-1] [0..n-1]
For type Board = Array (Int, Int) Int
, Data.Array allows newBoard n = listArray ((0,0),(n-1,n-1))
.
add a comment |
up vote
0
down vote
By defining r = round . sqrt . fromIntegral, newBoard fits on the screen. positions doesn't appear to be used in newboard's first case. Half the code disappears if we interpret Cell as ((Int, Int), Int). newBoard's first case can be pushed one recursion call deeper, mapping to instead of [x] to the current right hand side. [_] ++ _ ~> _ : _. positions is only used once, therefore I inline it.
type Cell = ((Int, Int), Int) -- (position, state)
genPositions :: Int -> [(Int, Int)]
genPositions x = [ (a,b) | a <- [0..(x-1)], b <- [0..(x-1)] ]
r = round . sqrt . fromIntegral
newBoard :: Int -> [Int] -> [Cell]
newBoard i =
newBoard i (x : xs) = (genPositions (r i)!!(i - 1 - length xs), x) : newBoard i xs
Successive elements of the list returned by genPositions and xs are zipped together; zip
captures this pattern. i is now not needed in its non-rooted form and I recommend changing the interface to take N as an argument instead. Non-square arguments can currently crash !! anyway. genPositions is only used once, therefore I inline it.
type Cell = ((Int, Int), Int) -- (position, state)
newBoard :: Int -> [Int] -> [Cell]
newBoard n = zip $ liftA2 (,) [0..n-1] [0..n-1]
For type Board = Array (Int, Int) Int
, Data.Array allows newBoard n = listArray ((0,0),(n-1,n-1))
.
add a comment |
up vote
0
down vote
up vote
0
down vote
By defining r = round . sqrt . fromIntegral, newBoard fits on the screen. positions doesn't appear to be used in newboard's first case. Half the code disappears if we interpret Cell as ((Int, Int), Int). newBoard's first case can be pushed one recursion call deeper, mapping to instead of [x] to the current right hand side. [_] ++ _ ~> _ : _. positions is only used once, therefore I inline it.
type Cell = ((Int, Int), Int) -- (position, state)
genPositions :: Int -> [(Int, Int)]
genPositions x = [ (a,b) | a <- [0..(x-1)], b <- [0..(x-1)] ]
r = round . sqrt . fromIntegral
newBoard :: Int -> [Int] -> [Cell]
newBoard i =
newBoard i (x : xs) = (genPositions (r i)!!(i - 1 - length xs), x) : newBoard i xs
Successive elements of the list returned by genPositions and xs are zipped together; zip
captures this pattern. i is now not needed in its non-rooted form and I recommend changing the interface to take N as an argument instead. Non-square arguments can currently crash !! anyway. genPositions is only used once, therefore I inline it.
type Cell = ((Int, Int), Int) -- (position, state)
newBoard :: Int -> [Int] -> [Cell]
newBoard n = zip $ liftA2 (,) [0..n-1] [0..n-1]
For type Board = Array (Int, Int) Int
, Data.Array allows newBoard n = listArray ((0,0),(n-1,n-1))
.
By defining r = round . sqrt . fromIntegral, newBoard fits on the screen. positions doesn't appear to be used in newboard's first case. Half the code disappears if we interpret Cell as ((Int, Int), Int). newBoard's first case can be pushed one recursion call deeper, mapping to instead of [x] to the current right hand side. [_] ++ _ ~> _ : _. positions is only used once, therefore I inline it.
type Cell = ((Int, Int), Int) -- (position, state)
genPositions :: Int -> [(Int, Int)]
genPositions x = [ (a,b) | a <- [0..(x-1)], b <- [0..(x-1)] ]
r = round . sqrt . fromIntegral
newBoard :: Int -> [Int] -> [Cell]
newBoard i =
newBoard i (x : xs) = (genPositions (r i)!!(i - 1 - length xs), x) : newBoard i xs
Successive elements of the list returned by genPositions and xs are zipped together; zip
captures this pattern. i is now not needed in its non-rooted form and I recommend changing the interface to take N as an argument instead. Non-square arguments can currently crash !! anyway. genPositions is only used once, therefore I inline it.
type Cell = ((Int, Int), Int) -- (position, state)
newBoard :: Int -> [Int] -> [Cell]
newBoard n = zip $ liftA2 (,) [0..n-1] [0..n-1]
For type Board = Array (Int, Int) Int
, Data.Array allows newBoard n = listArray ((0,0),(n-1,n-1))
.
answered Nov 22 '17 at 23:49
Gurkenglas
2,728511
2,728511
add a comment |
add a comment |
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f181029%2fstoring-values-in-an-n-x-n-grid%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown