カード組み合わせの総当りにCollections.shuffleを使う
Javaの小さなソース。
0以外の数字がひとつずつ書かれたカードをN枚並べて数を作る。
カードは重複する。
桁数を調節するための空白カードをN-1枚混ぜてランダムに抽選してN枚並べ、作った数を記録する。
数を作るたびにカードの状態は元に戻す。これを十分な回数繰り返す。
これまでに作られた数との同じ数が作られる(衝突)ことがあるので、それが連続して起こった回数を記録する。
最初のうちは衝突は稀にしか起こらないが、やがて十分な回数に近づくと新しい数は作られにくくなるので、連続して衝突が起こるようになる。
この仕組みで設定されたカードの並びで作ることができるすべての数を探す。
以下はN=6で1が3枚、2が1枚、3が2枚の場合で、十分な衝突の連続回数を1000000回として計算。
import java.util.*; import java.lang.*; import java.io.*; class Test { public static void main(String[] args) throws java.lang.Exception { HashSet<Long> fixNumbers = new HashSet<Long>(); List<String> cards = new ArrayList<String>(); cards.add("1"); cards.add("1"); cards.add("1"); cards.add("2"); cards.add("3"); cards.add("3"); cards.add(""); cards.add(""); cards.add(""); cards.add(""); cards.add(""); String word = ""; long number = 0; long collision = 0; while (true) { Collections.shuffle(cards); word = ""; for (int i = 0; i < Collections.frequency(cards, "") + 1; i++) { word += cards.get(i); } number = Long.parseLong(word); if (fixNumbers.add(number) != false) { collision = 0; } else { collision++; } if (collision >= 1000000) { System.out.println(fixNumbers.size()); break; } } } }