ブログを始めました

技術的なことを説明するのにツイッターの140字だと足りないので、ブログを始めてみました。
まずはソースコードを表示するためのプラグイン「Syntax Highlighter」を入れてみたので以下でテスト。

【コードの内容】
CodeIQの「ディビジョン・ナイン」問題の回答(公開可の問題です)。C++。ひどいスパゲッティコード。
標準入力からnを受け取り、n桁(一桁に入る値は1,2,3,4のどれか)の整数で9の倍数になるものの数を標準出力で表示する。

#include <iostream>
#include <string>
#include <math.h>
#include <vector>
#include <algorithm>

using namespace std;

#define MAX 4

struct fdCache {
    public:
        int start;
        bool back;
        int depth;
        unsigned long long value;
        fdCache(int start, bool back, int depth, unsigned long long value) {
            this->start = start;
            this->back = back;
            this->depth = depth;
            this->value = value;
        }
};

vector<fdCache> fdCacheList;

void init_fdCacheList() {
    int start = 1;
    bool back = true;
 
    for(int i = 0; i < 8; i++) {
        fdCacheList.push_back(fdCache(start, back, 1, start));

        if(start == 4) {
            back = !back;
            start = 0;
        }
    
        start++;
    }
}

unsigned long long get_fdCache(int start, bool back, int depth) {
    if(depth == 1 && start <= 0) {
        return 0;
    }
    
    for(fdCache c : fdCacheList) {
        if(c.start == start && c.back == back && c.depth == depth) {
            return c.value;
        }
    }
    
    return -1;
}

unsigned long long fd(int start, bool back, int depth) {
    long long result = 0;
    
    for(int i = 0; i < MAX; i++) {
        unsigned long long cache = get_fdCache(start, back, depth - 1);
        
        if(cache == -1) {
            unsigned long long tmp = fd(start, back, depth - 1);
            
            fdCacheList.push_back(fdCache(start, back, depth - 1, tmp));
            result += tmp;
        } else {
            result += cache;
        }
        
        if(back && start == 1) {
            break;
        }
        
        if(back) {
            start--;
        } else {
            start++;
        }
        
        if(start == 4) {
            back = !back;
        }
    }
    
    return result;
}

int main() {
    string line;
    int n = 0;
 
    for(;getline(cin,line);){
        n = stoi(line);
    }
    
    int multipleOf9Size = MAX * n / 9 - (n - 1) / 9;
    
    if(multipleOf9Size <= 0) {
        cout<<0<<endl;
        return 0;
    }
    
    int *multipleOf9 = new int[multipleOf9Size];
    int j = 0;
    
    for(int i = 9; i <= MAX * n; i = i + 9) { if(i >= n + (int)ceil((MAX - 1) * n + 1) / 2) {
            multipleOf9[j++] = (MAX + 1) * n - i;
        } else if(i >= n) {
            multipleOf9[j++] = i;
        }
    }
    
    sort(multipleOf9, multipleOf9 + multipleOf9Size);
    
    bool back = true;
    int start = multipleOf9[0] - n + 1;
    
    if(start > MAX) {
        back = !back;
        start = 2 * MAX - start;
    }
    
    init_fdCacheList();
    
    unsigned long long result = 0;
    
    for(int i = 0; i < multipleOf9Size; i++) {
        result += fd(start, back, n - 1);

        if(i == multipleOf9Size - 1) {
            break;
        }

        if(back) {
            start += multipleOf9[i + 1] - multipleOf9[i];

            if(start > MAX) {
                back = !back;
                start = 2 * MAX - start;
            }
        } else {
            start -= multipleOf9[i + 1] - multipleOf9[i];
        }
    }
    
    cout<<result<<endl;
}

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です