計算機プログラムの構造と解釈(SICP)学習メモ
蒋 いつ峰 2008/09/21   |  プログラミング基礎
第二章 練習2.42~2.43 2008/09/21  |  PK:SICP 練習 2.42~2.43

SICP練習2.42~2.43です。Eight-queens 問題です。


問題

練習2.42:Eight-queens 問題。
練習2.43:Eight-queens 問題の時間コスト。


解答

練習2.42の解答

  1. import tango.util.container.LinkedList;  
  2. import tango.math.Math;  
  3. import tango.io.Stdout;  
  4.   
  5. /** 
  6.  * SICP練習2.42。 
  7.  */  
  8. LinkedList!(int[]) queens(int boardSize) {  
  9.     auto ls = new LinkedList!(int[]);  
  10.   
  11.     void adjoinPosition(int[] pos, int col, int row) {  
  12.         int[] newPos = new int[col];  
  13.         if (pos !is null) {  
  14.             for (int i = 0; i < pos.length; i++) {  
  15.                 newPos[i] = pos[i];  
  16.             }  
  17.         }  
  18.   
  19.         newPos[col - 1] = row;  
  20.         // 先頭に追加  
  21.         ls.add(newPos);  
  22.     }  
  23.   
  24.     bool safe(int[] pos, int col, int row) {  
  25.         if (col == 1) {  
  26.             // first col, 常に safe  
  27.             return true;  
  28.         }  
  29.         int colDiv, rowDiv;  
  30.         int preRow;  
  31.         for (int i = 0; i < pos.length; i++) {  
  32.             preRow = pos[i];  
  33.             if (preRow == row) {  
  34.                 return false;  
  35.             }  
  36.             colDiv = col - i - 1;  
  37.             rowDiv = abs(row - preRow);  
  38.             if (colDiv == rowDiv) {  
  39.                 return false;  
  40.             }  
  41.         }  
  42.         return true;  
  43.     }  
  44.   
  45.     LinkedList!(int[]) queenCols(int k) {  
  46.         if (k > boardSize) {  
  47.             return ls;  
  48.         }  
  49.   
  50.         int prePos = ls.size();  
  51.   
  52.         // 初回  
  53.         if (k == 1) {  
  54.             for (int i = 1; i <= boardSize; i++) {  
  55.                 adjoinPosition(null, k, i);  
  56.             }  
  57.         }  
  58.   
  59.         if (k > 1) {  
  60.             foreach (int[] pos ; ls) {  
  61.                 for (int i = 1; i <= boardSize; i++) {  
  62.                     if (safe(pos, k, i)) {  
  63.                         adjoinPosition(pos, k, i);  
  64.                     }  
  65.                 }  
  66.             }  
  67.         }  
  68.   
  69.         // 前回の位置情報を削除  
  70.         if (prePos > 0) {  
  71.             ls.removeRange(ls.size() - prePos, ls.size() - 1);  
  72.         }  
  73.   
  74.         return queenCols(k + 1);  
  75.     }  
  76.   
  77.     return queenCols(1);      
  78. }  
  79.   
  80. void main() {  
  81.     int boardSize = 8;  
  82.     LinkedList!(int[]) qs = queens(boardSize);  
  83.     int count;  
  84.     foreach (int[] pos ; qs) {  
  85.         foreach (int r ; pos) {  
  86.             Stdout.format("{}\t", r);  
  87.         }  
  88.         count++;  
  89.         Stdout.newline();  
  90.     }  
  91.     Stdout.formatln("全ての解の数: {}", count);  
  92. }  

実行結果

c:\home\sicp>q2_42.exe
1       7       4       6       8       2       5       3
1       7       5       8       2       4       6       3
1       6       8       3       7       4       2       5
1       5       8       6       3       7       2       4
2       8       6       1       3       5       7       4
2       7       3       6       8       5       1       4
2       7       5       8       1       4       6       3
2       6       1       7       4       8       3       5
2       6       8       3       1       4       7       5
2       5       7       4       1       8       6       3
2       5       7       1       3       8       6       4
2       4       6       8       3       1       7       5
3       8       4       7       1       6       2       5
3       7       2       8       5       1       4       6
3       7       2       8       6       4       1       5
3       6       2       7       1       4       8       5
3       6       2       7       5       1       8       4
3       6       2       5       8       1       7       4
3       6       4       2       8       5       7       1
3       6       4       1       8       5       7       2
3       6       8       2       4       1       7       5
3       6       8       1       4       7       5       2
3       6       8       1       5       7       2       4
3       5       2       8       1       7       4       6
3       5       2       8       6       4       7       1
3       5       7       1       4       2       8       6
3       5       8       4       1       7       2       6
3       1       7       5       8       2       4       6
4       8       1       5       7       2       6       3
4       8       1       3       6       2       7       5
4       8       5       3       1       7       2       6
4       7       1       8       5       2       6       3
4       7       3       8       2       5       1       6
4       7       5       3       1       6       8       2
4       7       5       2       6       1       3       8
4       6       1       5       2       8       3       7
4       6       8       3       1       7       5       2
4       6       8       2       7       1       3       5
4       2       5       8       6       1       3       7
4       2       7       5       1       8       6       3
4       2       7       3       6       8       1       5
4       2       7       3       6       8       5       1
4       2       8       6       1       3       5       7
4       2       8       5       7       1       3       6
4       1       5       8       2       7       3       6
4       1       5       8       6       3       7       2
5       8       4       1       3       6       2       7
5       8       4       1       7       2       6       3
5       7       1       4       2       8       6       3
5       7       1       3       8       6       4       2
5       7       2       6       3       1       4       8
5       7       2       6       3       1       8       4
5       7       2       4       8       1       3       6
5       7       4       1       3       8       6       2
5       3       1       7       2       8       6       4
5       3       1       6       8       2       4       7
5       3       8       4       7       1       6       2
5       2       4       7       3       8       6       1
5       2       4       6       8       3       1       7
5       2       6       1       7       4       8       3
5       2       8       1       4       7       3       6
5       1       4       6       8       2       7       3
5       1       8       6       3       7       2       4
5       1       8       4       2       7       3       6
6       8       2       4       1       7       5       3
6       4       1       5       8       2       7       3
6       4       2       8       5       7       1       3
6       4       7       1       3       5       2       8
6       4       7       1       8       2       5       3
6       3       1       8       4       2       7       5
6       3       1       8       5       2       4       7
6       3       1       7       5       8       2       4
6       3       5       8       1       4       2       7
6       3       5       7       1       4       2       8
6       3       7       4       1       8       2       5
6       3       7       2       4       8       1       5
6       3       7       2       8       5       1       4
6       2       7       1       3       5       8       4
6       2       7       1       4       8       5       3
6       1       5       2       8       3       7       4
7       5       3       1       6       8       2       4
7       4       2       8       6       1       3       5
7       4       2       5       8       1       3       6
7       3       1       6       8       5       2       4
7       3       8       2       5       1       6       4
7       2       4       1       8       5       3       6
7       2       6       3       1       4       8       5
7       1       3       8       6       4       2       5
8       4       1       3       6       2       7       5
8       3       1       6       2       5       7       4
8       2       4       1       7       5       3       6
8       2       5       3       1       7       4       6
全ての解の数: 92


練習2.43の解答

Louisの実装は、上記ソースの60と61行を入れ替えることです。そうすると、既に処理済みの位置を繰り返しチェックしてしまいます。queen-cols(8)は1(8^0)回、queen-cols(7)は8(8^1)回・・・queen-cols(k)は8^(8-k)回呼び出されます。従って、Louisの実装では、queen-cols は合計で (8^0 + 8^1 + ... + 8^7 = 8^8 - 1) 回呼び出されます。その一方、元々の実装は 8^2 回です。結局、Louis の実装は約 (8^6) * T の時間が要します。


閲覧  |  コメント  |  目次

 
ヘルプ  |  ご利用規約  |  相互リンク  |  問合せ
リンクはご自由に、問合せはお気軽に
©2007 Uprush