毛のはえたようなもの

インターネット的なものをつらつらとかきつらねる。

N-queens問題(エイトクイーンズ問題)

火曜日提出のプログラミング課題の一つにN-queens問題が出題されました。わたしは出題されるまで知りませんでした。うふ。アルゴリズム・もんだいについては以下をご覧ください。
N-queens

私のごみコード

一生懸命書いたけど、classでの配列の初期化がうまくゆかずつまってしまいました。それを解決しようと配列コピーなんぞの苦肉の策がいっぱいあってごみ化しているコード。ゴミというか完全にメモリリークしている。
端的には参考にしてはいけないコード例。

#include <iostream>
#include <algorithm>
#include <cstring>

using namespace std;

class Queens{
public:
    Queens(int n);
    void calc();
    int get_answer();

private:
    int boardSize;
    int answer;
    void set(int i ,int j,int matrix[]);
    int check(int i, int j,int matrix[]);
};

Queens::Queens(int n){
    this->answer = 0;
    this->boardSize = n;
}

void Queens::calc(){
    int matrix[this->boardSize];
    for(int i = 0; i<this->boardSize; i++){
        for(int j =0; j <this->boardSize; j++ ){
            matrix[j] = 0;
        }
        this->set(0,i,matrix);
    }
}

void Queens::set(int i, int j,int matrix[]){
     int *new_matrix = new int[this->boardSize];
    memcpy(new_matrix, matrix, this->boardSize*sizeof(int));

    int checkMatrics = check(i,j,new_matrix);
      
    if(checkMatrics == -1){      // collision
        return;
    }else if(checkMatrics ==1){  // have not filled all matrix yet
        new_matrix[i] = j+1;
          if(i == this->boardSize-1){
            this->answer++;
            return;
        }else{
              for(int k = 0;k < this->boardSize; k++){
                set(i+1,k, new_matrix);
            }
        }
    }
    return;
}

int Queens::check(int i, int j,int matrix[]){
    /* cout <<"    show;[";
    for(int p=0 ; p < this->boardSize;p++){
        cout << matrix[p]<<",";
    }
    cout<<"]";
    */
    int r_up= i+1+j;
    int r_down = i-j+this->boardSize;
 
    for(int k=0; k <i; k++){
        if( j == matrix[k]-1 ||
            r_up == (k+1 + matrix[k] -1)||
           r_down == (k+1 - matrix[k] +this->boardSize)){
            // collision
            return -1;
        }
    }
    return 1;
}


int Queens::get_answer(){
    return this->answer;
}
    

int main(int argc,char*  agrc[]){

    int n = 0; // size of board
    
    while(cin >> n){
        Queens* newGame;
        newGame  = new Queens(n);
        newGame->calc();
        cout << newGame->get_answer() << endl;
    }

    return 0;
}

もなえデバッガの吐いたコード

もなえデバッガとは私のコードを解読・解析して最適化もしくは修正してくれるデバッガです。もっと早く(解読不能になる前に)相談しろと怒られました。
完結でシンプル。素晴らしいコードをご堪能ください。

#include <iostream>
#include <algorithm>
#include <cstring>

using namespace std;

class Queens {
public:
    Queens(int n);
    ~Queens();
    void calc();
    int get_answer();

private:
    int boardSize;
    int answer;
    int* matrix;
    void calc(int i);
    bool check(int i, int j);
};

Queens::Queens(int n) {
    this->answer = 0;
    this->boardSize = n;
    this->matrix = new int[this->boardSize];
}
Queens::~Queens() {
    delete[] this->matrix;
}

void Queens::calc() {
    this->answer = 0;
    calc(0);
}
void Queens::calc(int i) {
    if (i == this->boardSize) {
        cout <<"    show_ans;[";
        for(int p = 0 ; p < this->boardSize; p++) {
            cout << this->matrix[p] <<",";
        }
        cout << "]" << endl;
        this->answer++;
        return;
    }
    
    for (int j = 0; j < this->boardSize; j++) {
        if (check(i, j)) {      // success
            this->matrix[i] = j;
            calc(i + 1);
        }
    }
}

bool Queens::check(int i, int j) {
    /*
    cout <<"    show;[";
    for(int p=0 ; p < this->boardSize;p++){
        cout << matrix[p]<<",";
    }
    cout<<"]";
    */
 
    for (int k = 0; k < i; k++) {
        if (j == matrix[k] ||
            (i + j) == (k + matrix[k]) ||
            (i - j) == (k - matrix[k])) {
            // collision
            return false;
        }
    }
    return true;
}


int Queens::get_answer() {
    return this->answer;
}
    

int main(int argc, char* argv[]) {

    int n = 0; // size of board
    
    while(cin >> n){
        Queens newGame(n);
        newGame.calc();
        cout << newGame.get_answer() << endl;
    }

    return 0;
}