• Source
    1.  
    2. import java.util.*;
    3.  
    4. /**
    5.  * General solution to generate matching patterns for a tuple:
    6.  *
    7.  * Given a Tuple for eg. (a, b, c)..
    8.  * Output : (*, *, *), (*, *, c), (*, b, *), (*, b, c), (a, *, *), (a, *, c), (a, b, *), (a, b, c)
    9.  *
    10.  * The core of the problem involves generating ordered permutations of the indexes
    11.  * to replace with '*' ...
    12.  *
    13.  */
    14.  
    15. class Generator
    16. {
    17. int _index = 0;
    18. int _pickCount = 0;
    19. boolean _isDone = false;
    20.  
    21. Integer _picks[];
    22.  
    23. Generator _outer;
    24.  
    25. public Generator(int pickCount, int populationSize)
    26. {
    27. _index = 0;
    28. _outer = null;
    29. _pickCount = pickCount;
    30.  
    31. _picks = new Integer[populationSize];
    32.  
    33. for (int x = 0; x < populationSize; x++)
    34. _picks[x] = x;
    35. }
    36.  
    37. public void setOuter(Generator g)
    38. {
    39. _outer = g;
    40. }
    41.  
    42. public Generator getOuter()
    43. {
    44. return _outer;
    45. }
    46.  
    47. public int getPick()
    48. {
    49. return _picks[_index];
    50. }
    51.  
    52. public boolean isDone()
    53. {
    54. return _isDone;
    55. }
    56.  
    57. Vector<Generator> getGenerators(Generator g)
    58. {
    59. if ( g.getOuter() == null )
    60. {
    61. Vector<Generator> v = new Vector<>();
    62. v.add(g);
    63.  
    64. return v;
    65. }
    66.  
    67. Vector<Generator> v = getGenerators(g.getOuter());
    68. v.add(g);
    69.  
    70. return v;
    71. }
    72.  
    73. public Vector<Generator> getGenerators()
    74. {
    75. return getGenerators(this);
    76. }
    77.  
    78. public int[] getPicks()
    79. {
    80. int[] picks = new int[_pickCount];
    81. int index = 0;
    82.  
    83. Vector<Generator> generators = getGenerators();
    84.  
    85. for ( Generator generator : generators )
    86. picks[index++] = generator.getPick();
    87.  
    88. return picks;
    89. }
    90.  
    91. public void advance()
    92. {
    93. _index++;
    94.  
    95. if ( _index >= _picks.length )
    96. {
    97. _index = 0;
    98. _isDone = true;
    99.  
    100. if ( _outer != null )
    101. {
    102. _outer.advance();
    103. }
    104. }
    105. }
    106. }
    107.  
    108. class OrderedPerms
    109. {
    110. Generator _innerMost = null;
    111. Generator _outerMost = null;
    112.  
    113. public OrderedPerms(int pickCount, int populationSize)
    114. {
    115. Vector<Generator> generators = new Vector<>();
    116.  
    117. for (int x = 0; x < pickCount; x++)
    118. {
    119. generators.add(new Generator(pickCount, populationSize));
    120.  
    121. if ( x > 0 )
    122. generators.get(x).setOuter(generators.get(x-1));
    123. }
    124.  
    125. if ( pickCount > 1 )
    126. {
    127. _outerMost = generators.get(0);
    128. _innerMost = generators.get(pickCount - 1);
    129. }
    130. else if ( pickCount > 0 )
    131. {
    132. _outerMost = generators.get(0);
    133. _innerMost = _outerMost;
    134. }
    135. }
    136.  
    137. public boolean isDone()
    138. {
    139. return _outerMost == null || _outerMost.isDone();
    140. }
    141.  
    142. boolean hasDuplicates(int[] picks)
    143. {
    144. HashSet<Integer> set = new HashSet<Integer>();
    145.  
    146. for (int pick : picks)
    147. set.add(pick);
    148.  
    149. return set.size() != picks.length;
    150. }
    151.  
    152. boolean outOfOrder(int[] picks)
    153. {
    154. for (int x = 1; x < picks.length; x++)
    155. {
    156. if ( picks[x-1] > picks[x] )
    157. return true;
    158. }
    159.  
    160. return false;
    161. }
    162.  
    163. public void advance()
    164. {
    165. _innerMost.advance();
    166. }
    167.  
    168. public int[] getPicks()
    169. {
    170. int picks[];
    171.  
    172. for(;;)
    173. {
    174. if (isDone())
    175. return new int[] { };
    176.  
    177. picks = _innerMost.getPicks();
    178.  
    179. if (hasDuplicates(picks) || outOfOrder(picks))
    180. {
    181. _innerMost.advance();
    182. continue;
    183. }
    184.  
    185. break;
    186. }
    187.  
    188. return picks;
    189. }
    190. }
    191.  
    192. class Main {
    193.  
    194. static void printErased(String target)
    195. {
    196. StringBuilder erased = new StringBuilder(target);
    197.  
    198. for(int x = erased.length()-1; x > 0; x--)
    199. {
    200. erased.insert(x, ',');
    201. }
    202.  
    203. System.out.println(erased);
    204. }
    205.  
    206. public static void eraseParts(String target, int parts)
    207. {
    208. if ( parts == 0 )
    209. {
    210. printErased(target);
    211. return;
    212. }
    213.  
    214. OrderedPerms perms = new OrderedPerms(parts, target.length());
    215. int picks[];
    216.  
    217. while (!perms.isDone())
    218. {
    219. StringBuilder erased = new StringBuilder(target);
    220.  
    221. picks = perms.getPicks();
    222. if ( picks.length == 0 )
    223. break;
    224.  
    225. for(int pick : picks)
    226. erased.setCharAt(pick, '*');
    227.  
    228. printErased(erased.toString());
    229.  
    230. perms.advance();
    231. }
    232. }
    233.  
    234. /**
    235. * Fix loop version for static sized data...
    236. */
    237. public static void generatePicks()
    238. {
    239. Integer one[] = new Integer[] { 0, 1, 2, 3, 4 };
    240. Integer two[] = new Integer[] { 0, 1, 2, 3, 4 };
    241. Integer three[] = new Integer[] { 0, 1, 2, 3, 4 };
    242.  
    243. for (int x = 0; x < one.length; x++)
    244. {
    245. for(int y = 0; y < two.length; y++)
    246. {
    247. for(int z = 0; z < three.length; z++)
    248. {
    249. if ( two[y] == one[x] )
    250. continue;
    251.  
    252. if ( three[z] == one[x] )
    253. continue;
    254.  
    255. if ( three[z] == two[y] )
    256. continue;
    257.  
    258. if ( two[y] == null )
    259. continue;
    260.  
    261. if ( three[z] == null )
    262. continue;
    263.  
    264. System.out.println(one[x] + ", " + two[y] + ", " + three[z]);
    265.  
    266. two[x] = null;
    267.  
    268. three[x] = null;
    269. three[y] = null;
    270. }
    271. }
    272. }
    273. }
    274.  
    275. public static void main(String[] args)
    276. {
    277. eraseParts("abc", 0);
    278. eraseParts("abc", 1);
    279. eraseParts("abc", 2);
    280. eraseParts("abc", 3);
    281.  
    282. eraseParts("abcd", 0);
    283. eraseParts("abcd", 1);
    284. eraseParts("abcd", 2);
    285. eraseParts("abcd", 3);
    286. eraseParts("abcd", 4);
    287. }
    288.  
    289. }