import java.util.*;
/**
* General solution to generate matching patterns for a tuple:
*
* Given a Tuple for eg. (a, b, c)..
* Output : (*, *, *), (*, *, c), (*, b, *), (*, b, c), (a, *, *), (a, *, c), (a, b, *), (a, b, c)
*
* The core of the problem involves generating ordered permutations of the indexes
* to replace with '*' ...
*
*/
class Generator
{
int _index = 0;
int _pickCount = 0;
boolean _isDone = false;
Generator _outer;
public Generator(int pickCount, int populationSize)
{
_index = 0;
_outer = null;
_pickCount = pickCount;
_picks
= new Integer[populationSize
];
for (int x = 0; x < populationSize; x++)
_picks[x] = x;
}
public void setOuter(Generator g)
{
_outer = g;
}
public Generator getOuter()
{
return _outer;
}
public int getPick()
{
return _picks[_index];
}
public boolean isDone()
{
return _isDone;
}
Vector<Generator> getGenerators(Generator g)
{
if ( g.getOuter() == null )
{
Vector<Generator> v = new Vector<>();
v.add(g);
return v;
}
Vector<Generator> v = getGenerators(g.getOuter());
v.add(g);
return v;
}
public Vector<Generator> getGenerators()
{
return getGenerators(this);
}
public int[] getPicks()
{
int[] picks = new int[_pickCount];
int index = 0;
Vector<Generator> generators = getGenerators();
for ( Generator generator : generators )
picks[index++] = generator.getPick();
return picks;
}
public void advance()
{
_index++;
if ( _index >= _picks.length )
{
_index = 0;
_isDone = true;
if ( _outer != null )
{
_outer.advance();
}
}
}
}
class OrderedPerms
{
Generator _innerMost = null;
Generator _outerMost = null;
public OrderedPerms(int pickCount, int populationSize)
{
Vector<Generator> generators = new Vector<>();
for (int x = 0; x < pickCount; x++)
{
generators.add(new Generator(pickCount, populationSize));
if ( x > 0 )
generators.get(x).setOuter(generators.get(x-1));
}
if ( pickCount > 1 )
{
_outerMost = generators.get(0);
_innerMost = generators.get(pickCount - 1);
}
else if ( pickCount > 0 )
{
_outerMost = generators.get(0);
_innerMost = _outerMost;
}
}
public boolean isDone()
{
return _outerMost == null || _outerMost.isDone();
}
boolean hasDuplicates(int[] picks)
{
HashSet<Integer> set = new HashSet<Integer>();
for (int pick : picks)
set.add(pick);
return set.size() != picks.length;
}
boolean outOfOrder(int[] picks)
{
for (int x = 1; x < picks.length; x++)
{
if ( picks[x-1] > picks[x] )
return true;
}
return false;
}
public void advance()
{
_innerMost.advance();
}
public int[] getPicks()
{
int picks[];
for(;;)
{
if (isDone())
return new int[] { };
picks = _innerMost.getPicks();
if (hasDuplicates(picks) || outOfOrder(picks))
{
_innerMost.advance();
continue;
}
break;
}
return picks;
}
}
class Main {
static void printErased
(String target
) {
StringBuilder erased = new StringBuilder(target);
for(int x = erased.length()-1; x > 0; x--)
{
erased.insert(x, ',');
}
}
public static void eraseParts
(String target,
int parts
) {
if ( parts == 0 )
{
printErased(target);
return;
}
OrderedPerms perms = new OrderedPerms(parts, target.length());
int picks[];
while (!perms.isDone())
{
StringBuilder erased = new StringBuilder(target);
picks = perms.getPicks();
if ( picks.length == 0 )
break;
for(int pick : picks)
erased.setCharAt(pick, '*');
printErased(erased.toString());
perms.advance();
}
}
/**
* Fix loop version for static sized data...
*/
public static void generatePicks()
{
for (int x = 0; x < one.length; x++)
{
for(int y = 0; y < two.length; y++)
{
for(int z = 0; z < three.length; z++)
{
if ( two[y] == one[x] )
continue;
if ( three[z] == one[x] )
continue;
if ( three[z] == two[y] )
continue;
if ( two[y] == null )
continue;
if ( three[z] == null )
continue;
System.
out.
println(one
[x
] + ", " + two
[y
] + ", " + three
[z
]);
two[x] = null;
three[x] = null;
three[y] = null;
}
}
}
}
public static void main
(String[] args
) {
eraseParts("abc", 0);
eraseParts("abc", 1);
eraseParts("abc", 2);
eraseParts("abc", 3);
eraseParts("abcd", 0);
eraseParts("abcd", 1);
eraseParts("abcd", 2);
eraseParts("abcd", 3);
eraseParts("abcd", 4);
}
}