/* package whatever; // don't place package name! */
import java.util.*;
import java.lang.*;
import java.io.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
/* Name of the class has to be "Main" only if the class is public. */
class TuplesM
{
final int k; // alphabet size
final int n; // tple sise
final int[] a; // available len: t
Map
<String, Integer
> histo
= new HashMap
<>(); // for computing stats tests
public TuplesM(int[] ax, int n) {
this.
a = Arrays.
copyOf(ax, ax.
length); k = ax.length;
this.n = n;
}
public void addhistoTup(int[] tup) {
StringBuilder sb = new StringBuilder();
for( int t : tup )
sb.append(t).append(":");
if( !histo.containsKey(key) ) histo.put(key, 1);
else histo.put(key, histo.get(key) + 1);
}
/* generates a random integer in 0... weight.length-1, according to the given weights */
public int genRandom(int[] weight) {
int ac = 0;
for( int w : weight )
ac += w;
int r = rand.nextInt(ac);
for( int i = 0, z = 0; i < weight.length; i++ ) {
z += weight[i];
if( r < z ) return i;
}
}
public int[] genTup() {
int[] res = new int[n];
int[] ac
= Arrays.
copyOf(a, a.
length); int[] w = new int[k];
for( int t = 0; t < n; t++ ) {
for( int i = 0; i < k; i++ ) {
ac[i] = ac[i] - 1;
w[i] = ac[i] < 0 ? 0 : computeTups(ac, n - t - 1);
ac[i] = ac[i] + 1;
}
int s = genRandom(w);
res[t] = s;
ac[s]--;
}
return res;
}
void printHisto() {
int s = histo.size();
ArrayList<String> ks = new ArrayList<>(histo.keySet());
System.
out.
printf("%s : %.3f\n", kss, histo.
get(kss
) / (1.0 * s
)); }
}
public static int computeTups(int[] avail, int n) {
if( n == 0 ) return 1;
int ac = 0;
int[] availc
= Arrays.
copyOf(avail, avail.
length); for( int i = 0; i < avail.length; i++ ) {
if( availc[i] == 0 ) continue;
availc[i]--;
ac += computeTups(availc, n - 1);
availc[i]++;
}
return ac;
}
private static void test1(int [] a, int n) {
TuplesM tm = new TuplesM(a,n);
int tries = 100000;
for( int k = 0; k < tries; k++ ) {
int[] tup = tm.genTup();
tm.addhistoTup(tup);
}
tm.printHisto();
}
{
int n = 2;
int[] a=new int[] { 1, 2, 3 };
test1(a,n);
}
}
LyogcGFja2FnZSB3aGF0ZXZlcjsgLy8gZG9uJ3QgcGxhY2UgcGFja2FnZSBuYW1lISAqLwoKaW1wb3J0IGphdmEudXRpbC4qOwppbXBvcnQgamF2YS5sYW5nLio7CmltcG9ydCBqYXZhLmlvLio7CmltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OwppbXBvcnQgamF2YS51dGlsLkFycmF5czsKaW1wb3J0IGphdmEudXRpbC5Db2xsZWN0aW9uczsKaW1wb3J0IGphdmEudXRpbC5IYXNoTWFwOwppbXBvcnQgamF2YS51dGlsLk1hcDsKaW1wb3J0IGphdmEudXRpbC5SYW5kb207CgovKiBOYW1lIG9mIHRoZSBjbGFzcyBoYXMgdG8gYmUgIk1haW4iIG9ubHkgaWYgdGhlIGNsYXNzIGlzIHB1YmxpYy4gKi8KY2xhc3MgVHVwbGVzTQp7CgoJZmluYWwgaW50IGs7IC8vIGFscGhhYmV0IHNpemUKCWZpbmFsIGludCBuOyAvLyB0cGxlIHNpc2UKCWZpbmFsIGludFtdIGE7IC8vIGF2YWlsYWJsZSBsZW46IHQgCglmaW5hbCBSYW5kb20gcmFuZCA9IG5ldyBSYW5kb20oKTsKCglNYXA8U3RyaW5nLCBJbnRlZ2VyPiBoaXN0byA9IG5ldyBIYXNoTWFwPD4oKTsgLy8gZm9yIGNvbXB1dGluZyBzdGF0cyB0ZXN0cwoKCXB1YmxpYyBUdXBsZXNNKGludFtdIGF4LCBpbnQgbikgewoJCXRoaXMuYSA9IEFycmF5cy5jb3B5T2YoYXgsIGF4Lmxlbmd0aCk7CgkJayA9IGF4Lmxlbmd0aDsKCQl0aGlzLm4gPSBuOwoJfQoKCXB1YmxpYyB2b2lkIGFkZGhpc3RvVHVwKGludFtdIHR1cCkgewoJCVN0cmluZ0J1aWxkZXIgc2IgPSBuZXcgU3RyaW5nQnVpbGRlcigpOwoJCWZvciggaW50IHQgOiB0dXAgKQoJCQlzYi5hcHBlbmQodCkuYXBwZW5kKCI6Iik7CgkJU3RyaW5nIGtleSA9IHNiLnRvU3RyaW5nKCk7CgkJaWYoICFoaXN0by5jb250YWluc0tleShrZXkpICkgaGlzdG8ucHV0KGtleSwgMSk7CgkJZWxzZSBoaXN0by5wdXQoa2V5LCBoaXN0by5nZXQoa2V5KSArIDEpOwoJfQoKCS8qIGdlbmVyYXRlcyBhIHJhbmRvbSBpbnRlZ2VyIGluIDAuLi4gd2VpZ2h0Lmxlbmd0aC0xLCBhY2NvcmRpbmcgdG8gdGhlIGdpdmVuIHdlaWdodHMgKi8KCXB1YmxpYyBpbnQgZ2VuUmFuZG9tKGludFtdIHdlaWdodCkgewoJCWludCBhYyA9IDA7CgkJZm9yKCBpbnQgdyA6IHdlaWdodCApCgkJCWFjICs9IHc7CgkJaW50IHIgPSByYW5kLm5leHRJbnQoYWMpOwoJCWZvciggaW50IGkgPSAwLCB6ID0gMDsgaSA8IHdlaWdodC5sZW5ndGg7IGkrKyApIHsKCQkJeiArPSB3ZWlnaHRbaV07CgkJCWlmKCByIDwgeiApIHJldHVybiBpOwoJCX0KCQl0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigiPyIpOwoJfQoKCXB1YmxpYyBpbnRbXSBnZW5UdXAoKSB7CgkJaW50W10gcmVzID0gbmV3IGludFtuXTsKCQlpbnRbXSBhYyA9IEFycmF5cy5jb3B5T2YoYSwgYS5sZW5ndGgpOwoJCWludFtdIHcgPSBuZXcgaW50W2tdOwoJCWZvciggaW50IHQgPSAwOyB0IDwgbjsgdCsrICkgewoJCQlmb3IoIGludCBpID0gMDsgaSA8IGs7IGkrKyApIHsKCQkJCWFjW2ldID0gYWNbaV0gLSAxOwoJCQkJd1tpXSA9IGFjW2ldIDwgMCA/IDAgOiBjb21wdXRlVHVwcyhhYywgbiAtIHQgLSAxKTsKCQkJCWFjW2ldID0gYWNbaV0gKyAxOwoJCQl9CgkJCWludCBzID0gZ2VuUmFuZG9tKHcpOwoJCQlyZXNbdF0gPSBzOwoJCQlhY1tzXS0tOwoJCX0KCQlyZXR1cm4gcmVzOwoJfQoKCXZvaWQgcHJpbnRIaXN0bygpIHsKCQlpbnQgcyA9IGhpc3RvLnNpemUoKTsKCQlBcnJheUxpc3Q8U3RyaW5nPiBrcyA9IG5ldyBBcnJheUxpc3Q8PihoaXN0by5rZXlTZXQoKSk7CgkJQ29sbGVjdGlvbnMuc29ydChrcyk7CgkJZm9yKCBTdHJpbmcga3NzIDoga3MgKSB7CgkJCVN5c3RlbS5vdXQucHJpbnRmKCIlcyA6ICUuM2ZcbiIsIGtzcywgaGlzdG8uZ2V0KGtzcykgLyAoMS4wICogcykpOwoJCX0KCX0KCglwdWJsaWMgc3RhdGljIGludCBjb21wdXRlVHVwcyhpbnRbXSBhdmFpbCwgaW50IG4pIHsKCQlpZiggbiA9PSAwICkgcmV0dXJuIDE7CgkJaW50IGFjID0gMDsKCQlpbnRbXSBhdmFpbGMgPSBBcnJheXMuY29weU9mKGF2YWlsLCBhdmFpbC5sZW5ndGgpOwoJCWZvciggaW50IGkgPSAwOyBpIDwgYXZhaWwubGVuZ3RoOyBpKysgKSB7CgkJCWlmKCBhdmFpbGNbaV0gPT0gMCApIGNvbnRpbnVlOwoJCQlhdmFpbGNbaV0tLTsKCQkJYWMgKz0gY29tcHV0ZVR1cHMoYXZhaWxjLCBuIC0gMSk7CgkJCWF2YWlsY1tpXSsrOwoJCX0KCQlyZXR1cm4gYWM7Cgl9CgoJcHJpdmF0ZSBzdGF0aWMgdm9pZCB0ZXN0MShpbnQgW10gYSwgaW50IG4pIHsKCQlUdXBsZXNNIHRtID0gbmV3IFR1cGxlc00oYSxuKTsKCQlpbnQgdHJpZXMgPSAxMDAwMDA7CgkJZm9yKCBpbnQgayA9IDA7IGsgPCB0cmllczsgaysrICkgewoJCQlpbnRbXSB0dXAgPSB0bS5nZW5UdXAoKTsKCQkJdG0uYWRkaGlzdG9UdXAodHVwKTsKCQl9CgkJdG0ucHJpbnRIaXN0bygpOwoJfQoKCgoJcHVibGljIHN0YXRpYyB2b2lkIG1haW4gKFN0cmluZ1tdIGFyZ3MpIHRocm93cyBqYXZhLmxhbmcuRXhjZXB0aW9uCgl7CgkJaW50IG4gPSAyOwoJCWludFtdIGE9bmV3IGludFtdIHsgMSwgMiwgMyB9OwoJCXRlc3QxKGEsbik7Cgl9Cn0=