/** * 櫛形ボード組み合わせパズルを解く * 2018/10/20 rikunora */ import jp.kobe_u.copris._ import jp.kobe_u.copris.dsl._ class CrossBoard { val N_UNIT: Int = 5 def run() : Unit = { init // 初期化 // N_UNIT * N_UNIT の変数を用意 for( row <- 0 until N_UNIT; col <- 0 until N_UNIT ){ int('x(row, col), lo = -1, hi = 1) } // 条件:横の合計は0 for( row <- 0 until N_UNIT ){ var lst = List[Term]() for( col <- 0 until N_UNIT ){ lst :+= 'x(row, col) } add( Add(lst) === 0 ) } // 条件:横の絶対値の合計は2( Abs(+1) + Abs(-1) ) for( row <- 0 until N_UNIT ){ var lst = List[Term]() for( col <- 0 until N_UNIT ){ lst :+= Abs('x(row, col)) } add( Add(lst) === 2 ) } // 条件:縦の合計は0 for( col <- 0 until N_UNIT ){ var lst = List[Term]() for( row <- 0 until N_UNIT ){ lst :+= 'x(row, col) } add( Add(lst) === 0 ) } // 条件:縦の絶対値の合計は2( Abs(+1) + Abs(-1) ) for( col <- 0 until N_UNIT ){ var lst = List[Term]() for( row <- 0 until N_UNIT ){ lst :+= Abs('x(row, col)) } add( Add(lst) === 2 ) } // 縦横パターンが全部違っている var alllst = List[Term]() // 横について for( row <- 0 until N_UNIT ) { var lst = List[Term]() var lstr = List[Term]() // 反転パターン var pow2: Int = 1 var pow2r: Int = 1 << (N_UNIT-1) // ビットシフト for (col <- 0 until N_UNIT) { lst :+= 'x (row, col) * pow2 lstr :+= 'x (row, col) * pow2r pow2 *= 2 pow2r /= 2 } alllst :+= Add(lst) alllst :+= Add(lstr) } // 縦について // 縦は上下をひっくり返すので値がマイナスとなるのだ for( col <- 0 until N_UNIT ) { var lst = List[Term]() var lstr = List[Term]() // 反転パターン var pow2: Int = 1 var pow2r: Int = 1 << (N_UNIT-1) // ビットシフト for (row <- 0 until N_UNIT) { lst :+= - 'x (row, col) * pow2 lstr :+= - 'x (row, col) * pow2r pow2 *= 2 pow2r /= 2 } alllst :+= Add(lst) alllst :+= Add(lstr) } add( Alldifferent(alllst)) // 全てのパターンが異なる show // 条件表示 if (find) { // 最初の解を発見 var n_sol: Int = 0 // 解の数 do { // println(solution) n_sol += 1 printf("Solution[ %d ] ----------------\n", n_sol) for (row <- 0 until N_UNIT) { for (col <- 0 until N_UNIT) { printf("%d ", solution('x (row, col))) } println() } } while( findNext && n_sol <= 3 ) // 解が見つかる間 && 3つまで } } // END run }