Problem:
パズル

1 〜 9 の数字を 14 個組み合わせて完成させるパズルがあります。与えられた 13 個の数字にもうひとつ数字を付け加えて完成させます。

パズルの完成条件は

同じ数字を２つ組み合わせたものが必ずひとつ必要です。

残りの12 個の数字は、３個の数字の組み合わせ４つです。

３個の数字の組み合わせ方は、同じ数字を３つ組み合わせたものか、または３つの連続する数字を組み合わせたものです。ただし、9 1 2 のような並びは連続する数字とは認められません。

同じ数字は4 回まで使えます。

13 個の数字からなる文字列を読み込んで、パズルを完成することができる数字を昇順に全て出力するプログラムを作成してください。なお、1〜9 のどの数字を付け加えてもパズルを完成させることができないときは 0 を出力してください。

例えば与えられた文字列が 3456666777999 の場合

「2」があれば、　234 567 666 77 999

「3」があれば、　33 456 666 777 999

「5」があれば、　345 567 666 77 999

「8」があれば、　345 666 678 77 999

というふうに、2 3 5 8 のいずれかの数字が付け加えられるとパズルは完成します。「6」でも整いますが、5 回目の使用になるので、この例では使えないことに注意してください。

Input

入力は複数のデータセットからなります。各データセットとして、13 個の数字が１行に与えられます。データセットの数は 50 を超えません。

Output

データセットごとに、パズルを完成させることができる数字を昇順に空白区切りで１行に出力します。

Sample Input

3649596966777
6358665788577
9118992346175
9643871425498
7755542764533
1133557799246

Output for the Sample Input

2 3 5 8
3 4
1 2 3 4 5 6 7 8 9
7 8 9
1 2 3 4 6 7 8
0

Solution in JAVA (judge verdict: Wrong Answer)

import java.util.*;
public class Main{
    public static void main(String[] args){
	new Main().run();
    }
    Scanner kbd = new Scanner(System.in);

    String n;
    boolean[] ans;
    int count;

    void run(){
	while(kbd.hasNext()){
	    n = kbd.next();
	    int[] num = new int[10]; // 何が何枚あるか、0は未使用
	    for(int i=0; i<n.length(); i++){
		int a = Integer.parseInt(n.substring(i, i+1));
		num[a]++;
	    }
	    ans = new boolean[10];
	    count = 0;
	    solve(num);

	    if(count!=0){
		for(int i=0; i<num.length; i++){
		    if(ans[i]) System.out.print(i+" ");
		}
	    }
	    else System.out.print("0");
	    System.out.println();
	}
    }

    void solve(int[] num){
	/*
	  牌の追加の仕方は9通りなので、全パターン試す
	*/
	for(int k=1; k<10; k++){
	    int[] n = Arrays.copyOf(num, 10);
	    n[k] += 1;
	    /*
	      もし追加したのが5枚目だったら、なかったことにして次へ
	      そうでなければ、成り立っているか確かめる
	    */
	    if(n[k]<5){
		/*
		System.out.println("--- k = "+k+" ---");
		for(int i=0; i<n.length; i++){
		    System.out.println(i+" : "+n[i]);
		}
		*/
		check(n, 0, k, false);
		if(ans[k]) count++;
	    }
	    n[k] -= 1;
	}
    }

    void check(int[] num, int level, int k, boolean f){
	if(level >= num.length){ // 完成の時
	    boolean tf = true;
	    for(int i=0; i<num.length; i++)
		tf = tf && num[i]==0;
	    if(tf) ans[k] = true;
	    return;
	}
	else{ 
	    boolean flag = false;

	    // 1. 刻子ケース
	    if(num[level]>=3){
		flag = true;
		num[level] -= 3;
		if(num[level]==0)
		    check(num, level+1, k, f);
		else
		    check(num, level, k, f);
	    }
	    if(flag){
		num[level] += 3;
		flag = false;
	    }

	    // 2. 雀頭ケース
	    if(num[level]>=2 && !f){
		flag = true;
		f = true;
		num[level] -= 2;
		if(num[level]==0)
		    check(num, level+1, k, f);
		else
		    check(num, level, k, f);
	    }
	    if(flag){
		num[level] += 2;
		flag = false;
	    }

	    // 3. 順子ケース
	    if(level+2<num.length && num[level]>=1 &&
	       num[level+1]>=1 && num[level+2]>=1){
		flag = true;
		num[level] -= 1;
		num[level+1] -= 1;
		num[level+2] -= 1;
		if(num[level]==0)
		    check(num, level+1, k, f);
		else
		    check(num, level, k, f);
	    }
	    if(flag){
		num[level] += 1;
		num[level+1] += 1;
		num[level+2] += 1;
		flag = false;
	    }	

	    check(num, level+1, k, f);
	}
    }
}