Creating sets of similar elements in a 2D array

后端 未结 4 1288
渐次进展
渐次进展 2020-12-28 23:51

I am trying to solve a problem that is based on a 2D array. This array contains different kinds of elements (from a total of 3 possible kinds). Lets assume the kind as X, Y,

4条回答
  •  陌清茗
    陌清茗 (楼主)
    2020-12-29 00:40

    I wrote something to find objects of just one type for another SO question. The example below adds two more types. Any re-iteration would examine the whole list again. The idea is to process the list of points for each type separately. The function solve groups any connected points and removes them from the list before enumerating the next group. areConnected checks the relationship between the points' coordinates since we are only testing points of one type. In this generalized version, the types (a b c) could be anything (strings, numbers, tuples, etc.), as long as they match.

    btw - here's a link to a JavaScript example of j_random_hacker's terrific algorithm: http://jsfiddle.net/groovy/fP5kP/

    Haskell code:

    import Data.List (elemIndices, delete) 
    
    example = ["xxyyyz"
              ,"xyyzzz"
              ,"yxxzzy"
              ,"yyxzxy"
              ,"xyzxyy"
              ,"xzxxzz"
              ,"xyzyyz"
              ,"xyzxyy"]
    
    objects a b c ws = [("X",solve xs []),("Y",solve ys []),("Z",solve zs [])] where
      mapIndexes s = 
        concatMap (\(y,xs)-> map (\x->(y,x)) xs) $ zip [0..] (map (elemIndices s) ws)
      [xs,ys,zs] = map mapIndexes [a,b,c]
      areConnected (y,x) (y',x') = abs (x-x') < 2 && abs (y-y') < 2
      solve []     r = r
      solve (x:xs) r =
        let r' = solve' xs [x]
        in solve (foldr delete xs r') (if null (drop 2 r') then r else r':r)
      solve' vs r =
        let ys = filter (\y -> any (areConnected y) r) vs
        in if null ys then r else solve' (foldr delete vs ys) (ys ++ r)
    

    Sample output:

    *Main> objects 'x' 'y' 'z' example
    [("X",[[(7,0),(6,0),(5,0),(4,0)]
          ,[(3,4),(5,2),(5,3),(4,3),(2,2),(3,2),(2,1),(0,1),(1,0),(0,0)]])
    ,("Y",[[(7,5),(6,4),(7,4),(6,3)],[(4,4),(4,5),(3,5),(2,5)]
          ,[(4,1),(3,0),(3,1),(0,4),(2,0),(0,3),(1,1),(1,2),(0,2)]])
    ,("Z",[[(5,5),(6,5),(5,4)]
          ,[(7,2),(6,2),(5,1),(4,2),(3,3),(1,3),(2,3),(2,4),(1,4),(1,5),(0,5)]])]
    (0.02 secs, 1560072 bytes)
    

提交回复
热议问题