patternMinor
Getting the index (x,y) of a char in a "2D" list in Haskell
Viewed 0 times
thechargettinghaskellindexlist
Problem
I have this working function
Basically, the function works like this: (ie: we search for the char '3')
Is there a better way to make this function more readable/shorter/... ?
All the relevant code here:
Some tests to illustrate the usage:
circuitFind that I really don't find nice because I feel there is a better and simpler way to accomplish what it does. circuitFind :: Circuit -> Tile -> Maybe Position
circuitFind c t = unpack . find (\ p -> fst p /= Nothing) . enumerate . map findTile $ c
where findTile = findIndex (==t)
enumerate = flip zip [0..]
unpack a = case a of
Just (Just x, y) -> Just (x,y)
_ -> NothingBasically, the function works like this: (ie: we search for the char '3')
["1stline", "2ndline", "3rdline"]
|
map findTile '3'
|
v
[Nothing, Nothing, Just 0]
|
enumerate
|
v
[(Nothing, 0), (Nothing, 1), (Just 0, 2)]
|
find (\ p -> fst p /= Nothing)
|
v
Just (Just 0, 2)
|
unpack
|
v
–– Just (0,2) ––Is there a better way to make this function more readable/shorter/... ?
All the relevant code here:
import Data.List
type Vec2D = (Int, Int)
type Position = Vec2D
type Circuit = [[Tile]]
type Tile = Char
basicCircuit :: Circuit
basicCircuit = ["------------",
"-b e-",
"------------"]
circuitFind :: Circuit -> Tile -> Maybe Position
circuitFind c t = unpack . find (\ p -> fst p /= Nothing) . enumerate . map findTile $ c
where findTile = findIndex (==t)
enumerate = flip zip [0..]
unpack a = case a of
Just (Just x, y) -> Just (x,y)
_ -> NothingSome tests to illustrate the usage:
Main> circuitFind basicCircuit 'e'
Just (10,1)
Main> circuitFind basicCircuit 'o'
NothingSolution
Disclaimer: I'm rusty with Haskell, there may be a cleaner way to do this.
Code review: your code looks fine to my eyes, it's just that
"Let us see whether we could, by chance, conceive some other general
problem that contains the original problem and is easier to solve." –
Leibnitz.
We start by solving the more general problem of finding all indices of
Let's look at the skeleton of our solution.
We can get
Now we can find
Thanks to lazy evaluation, and
Code review: your code looks fine to my eyes, it's just that
circuitFind is overly complex, as you suspected. Also note that findIndex (==t) can be written as elemIndex t (source)."Let us see whether we could, by chance, conceive some other general
problem that contains the original problem and is easier to solve." –
Leibnitz.
We start by solving the more general problem of finding all indices of
t in c.Let's look at the skeleton of our solution.
[ (x,y) | ??? ]We can get
y using zip [0..] as you have done.[ (x,y) | (y,line) <- zip [0..] c, ??? ]Now we can find
x using elemIndices.[ (x,y) | (y,line) <- zip [0..] c, x <- elemIndices t line ]Thanks to lazy evaluation, and
Data.Maybe, we get our solutioncircuitFind :: Circuit -> Tile -> Maybe Position
circuitFind c t = listToMaybe [ (x,y) | (y,line) <- zip [0..] c, x <- elemIndices t line ]Code Snippets
[ (x,y) | ??? ][ (x,y) | (y,line) <- zip [0..] c, ??? ][ (x,y) | (y,line) <- zip [0..] c, x <- elemIndices t line ]circuitFind :: Circuit -> Tile -> Maybe Position
circuitFind c t = listToMaybe [ (x,y) | (y,line) <- zip [0..] c, x <- elemIndices t line ]Context
StackExchange Code Review Q#58954, answer score: 3
Revisions (0)
No revisions yet.