Advertisement
Guest User

Untitled

a guest
Nov 23rd, 2014
131
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.57 KB | None | 0 0
  1. FloodFillExtractTile[gt_, {sr_, sc_}] :=
  2. Module[{r, c, toExplore, visited = {}},
  3. toExplore = {{sr, sc}};
  4. While[Length@toExplore > 0,
  5. (* Pop *)
  6. {r, c} = Last@toExplore;
  7. toExplore = Most[toExplore];
  8. AppendTo[visited, {r, c}];
  9. (* Down-left *)
  10.  
  11. If[c > 1 && r < h &&
  12. gt[[r + 1, c - 1]] == gt[[r, c]] && !
  13. MemberQ[visited, {r + 1, c - 1}],
  14. AppendTo[toExplore, {r + 1, c - 1}];
  15. ];
  16. (* Down-right *)
  17.  
  18. If[ r < h &&
  19. gt[[r + 1, c]] == gt[[r, c]] && ! MemberQ[visited, {r + 1, c}],
  20. AppendTo[toExplore, {r + 1, c}];
  21. ];
  22. (* Up-right *)
  23.  
  24. If[r > 1 && c < w &&
  25. gt[[r - 1, c + 1]] == gt[[r, c]] && !
  26. MemberQ[visited, {r - 1, c + 1}],
  27. AppendTo[toExplore, {r - 1, c + 1}];
  28. ];
  29. (* Up-left *)
  30.  
  31. If[ r > 1 &&
  32. gt[[r - 1, c]] == gt[[r, c]] && ! MemberQ[visited, {r - 1, c}],
  33. AppendTo[toExplore, {r - 1, c}];
  34. ];
  35. ];
  36. Return@visited;
  37. ];
  38.  
  39. GetGTTiles[gtp_] :=
  40. Module[{testSame, testEdge, h, w, pts, sameClusters, getEdges,
  41. tiles},
  42. {h, w} = Dimensions[gtp];
  43. pts = Join @@ Table[{r, c}, {r, h}, {c, w}];
  44. testSame[{r1_, c1_}, {r2_, c2_}] := (gtp[[r1, c1]] ==
  45. gtp[[r2, c2]]);
  46. testEdge[{r1_, c1_}, {r2_,
  47. c2_}] := (gtp[[r1, c1]] ==
  48. gtp[[r2, c2]]) &&
  49. ((c1 == c2 &&
  50. Abs[r1 - r2] <= 1) || (c1 == c2 - 1 &&
  51. r1 == r2 + 1) || (c1 == c2 + 1 && r1 == r2 - 1));
  52. sameClusters = Gather[pts, testSame];
  53. getEdges[clust_] :=
  54. Join @@ Outer[If[testEdge[#1, #2], #1 -> #2, Sequence @@ {}] &,
  55. clust, clust, 1];
  56. tiles =
  57. Join @@ (ConnectedComponents[Graph@getEdges[#]] & /@ sameClusters);
  58. Return@tiles;
  59. ];
  60.  
  61. {{{1, 1}}, {{1, 2}, {2, 1}},
  62. {{1, 3}, {2, 3}, {3, 2}, {4, 1}, {3, 1}, {2, 2}},
  63. {{1, 4}},
  64. {{2, 4}, {3, 4}, {4, 4}, {5, 4}, {5, 3}, {4,3}},
  65. {{3, 3}, {4, 2}, {5, 2}, {5, 1}}}
  66.  
  67. GTTiles[gtp_List] := Module[{fromEuclidean, toEuclidean,
  68. getOneTile, elements, elmPos, pts, tile, tiles},
  69.  
  70. (* This is used to changefrom different coordinate systems. *)
  71.  
  72. fromEuclidean[{r_, c_}] := {r, (c - r)/2 + 1};
  73. toEuclidean[{r_, c_}] := {r, 2 c + r - 2};
  74.  
  75. getOneTile[pts_List, maxDist_?NumericQ] := Module[{f},
  76. f = Nearest[pts];
  77. FixedPoint[
  78. Union@Flatten[f[#, {Infinity, maxDist}] & /@ #, 1] &, {First@
  79. pts}]];
  80.  
  81. elements = Union @@ gtp;
  82. elmPos = (toEuclidean /@ Position[gtp, #]) & /@ elements;
  83. (* This is really strange code. *)
  84. tiles = Flatten[Flatten[
  85. Reap[NestWhile[Complement[#,
  86. Sow@getOneTile[#, N@Sqrt@2]] &, #, # != {} &]][[2]],
  87. 1] & /@ elmPos, 1];
  88. tiles = Map[fromEuclidean, tiles, {2}];
  89. Return@tiles;
  90. ];
  91.  
  92. l1 = {{6, 3, 2, 1}, {3, 2, 2, 0}, {2, 2, 1, 0}, {2, 1, 0, 0}, {1, 1, 0, 0}};
  93. l = Riffle[#, ""] & /@ l1;
  94. els = Union @@ l;
  95. par = MapIndexed[PadRight[PadLeft[#1, #2[[1]] + Length@#1 - 1, ""],
  96. Length@l + Length@#1 - 1, ""] &, l];
  97. eachElm = Position[par, #] & /@ els;
  98. getOneCluster[pts_List, maxDist_?NumericQ] :=
  99. Module[{f},
  100. f = Nearest[pts];
  101. FixedPoint[Union@Flatten[f[#, {Infinity, maxDist}] & /@ #, 1] &, {First@pts}]];
  102. clusters =
  103. Flatten[Flatten[
  104. Reap[NestWhile[
  105. Complement[#,
  106. Sow@getOneCluster[#, N@Sqrt@2]] &, #, # != {} &]][[2]], 1] & /@ eachElm, 1];
  107. Grid[par,
  108. ItemStyle -> {Automatic, Automatic, Flatten@MapIndexed[#1 -> Hue[#2[[1]]/3] &,
  109. clusters, {2}]}]
  110.  
  111. weirdNeighbors3[array_, output_: "components"] :=
  112.  
  113. Module[{t = 0, cnt = 1, dims = Dimensions[array],
  114. lt = Rest[array][[All, ;; -2]], rt = Most[array][[All, 2 ;;]],
  115. check, a, ruls, clusts},
  116.  
  117. clusts =
  118. Transpose[Flatten /@ MapAt[Replace[#, _ -> cnt++, 1] &,
  119. Split /@ Transpose[array], {All, All}]];
  120.  
  121. check = Boole[MapThread[SameQ, {lt, rt}, 2]];
  122.  
  123. While[t =!= {},
  124.  
  125. t = DeleteCases[
  126. Transpose[{Flatten[Pick[Rest[clusts][[All, ;; -2]], check, 1]],
  127. Flatten[Pick[Most[clusts][[All, 2 ;;]], check, 1]]}], {} | {a_,
  128. a_}, 1];
  129.  
  130. If[(t =
  131. DeleteDuplicates[Flatten[ReplacePart[#, {a_, 1} /;
  132. a > 1 && a <= Length[#] :> #[[a - 1, 2]]] & /@
  133. GatherBy[t, First], 1]]) === {}, Continue[]];
  134.  
  135. clusts =
  136. clusts //. Dispatch[
  137. Rule @@@ (Module[{f, g}, g[_] = True; f[{x_, _}] := (g[x] = False; True);
  138. Cases[t, {_, _?g}?f]])];
  139.  
  140. ];
  141. Switch[output, "tuples",
  142. GatherBy[Flatten[Array[{##} &, dims], 1], Extract[clusts, #] &],
  143. "raw", clusts, "components", ArrayComponents[clusts]]
  144. ]
  145.  
  146. makearrayD[dims_] := Module[{toprow = RandomInteger[dims[[1]]*5, dims[[2]]]},
  147. Table[toprow - 2 row, {row, 1, dims[[1]]}]]
  148.  
  149. weirdNeighbors5[arg_] := Module[{dims = Dimensions[arg], cd, dd, p},
  150.  
  151. cd = {#, # + {1, 0}} & /@ SparseArray[Unitize[Most[arg] - Rest[arg]], Automatic, 1][
  152. "NonzeroPositions"];
  153.  
  154. dd = {# + {0, 1}, # + {1, 0}} & /@
  155. SparseArray[Unitize[Most[arg][[All, 2 ;;]] - Rest[arg][[All, ;; -2]]],
  156. Automatic, 1]["NonzeroPositions"];
  157.  
  158. Switch[Length[p = Join[cd, dd]],
  159. 0, {{}, Flatten[Array[{##} &, dims], 1]},
  160. Times @@ dims, {p, {}}, _,
  161. {ConnectedComponents@Graph[UndirectedEdge @@@ p],
  162. Complement[Flatten[Array[{##} &, dims], 1], Flatten[p, 1]]}]]
  163.  
  164. ClearAll[neighs, trace, weirdNeighbors]
  165.  
  166. (* get possible "neighbors" helper function *)
  167. neighs[arr_, place_] := Module[{dims = Dimensions[arr], n},
  168. n = DeleteCases[place + # & /@ {{1, 0}, {-1, 0}, {1, -1}, {-1, 1}},
  169. {a_, b_} /; a == 0 || b == 0 || a > dims[[1]] || b > dims[[2]]]];
  170.  
  171. (* trace potential "neighbor" paths helper funtion *)
  172. trace[list_, ele_] := Module[{results = {ele}},
  173. If[MemberQ[list, ele + {1, 0}], results = Join[results, trace[list, ele + {1, 0}]]];
  174. If[MemberQ[list, ele + {1, -1}], results = Join[results, trace[list, ele + {1, -1}]]];
  175. DeleteDuplicates[results]];
  176.  
  177. (* do the work function *)
  178. weirdNeighbors[array_] :=
  179. Module[{local, td = Dimensions[array], ta, localc, prelim, tu, got, ss, fu, sets, f},
  180.  
  181. local = array /. (0 -> Max[array] + 1);
  182. ta = Flatten[Array[{##} &, td], 1];
  183. localc = ArrayComponents[local];
  184. prelim = GatherBy[ta, localc[[Sequence @@ #]] &];
  185. tu = Union @@ localc;
  186.  
  187. got = {ss = Select[prelim[[#]],
  188. Function[arg, MemberQ[Extract[localc, neighs[localc, arg]],
  189. Extract[localc, arg]]]], Complement[prelim[[#]], ss]} & /@ tu;
  190.  
  191. fu = Function[arg, trace[got[[arg, 1]], #] & /@ got[[arg, 1]]] /@ tu;
  192.  
  193. sets = Function[arg, Union @@@ Gather[arg, Intersection[#1, #2] != {} &]] /@ fu;
  194.  
  195. Transpose[{tu, Flatten[array] // DeleteDuplicates, got[[All, 2]], sets}]]
  196.  
  197. test = RandomInteger[{0, 5}, {5, 5}];
  198.  
  199. {time, result} = Timing[weirdNeighbors[test]];
  200.  
  201. Column[{time, test // MatrixForm, result}, Left, 2]
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement