Project Euler 22

http://projecteuler.net/index.php?section=problems&id=22


単語を拾うのをiterableになるように実装して、単語をソートする。しかし、iterableのsortedがあったほうが便利なので作ってみた。

    cout << sum(map(score, zip(itertools::count<>(1),
                            sorted(list(cSplit(str)))))) << endl;

countが衝突している。
こうすると逆順になる。

    cout << sum(map(score, zip(itertools::count<>(1),
                sorted(list(cSplit(str)), greater<string>())))) << endl;

こういうときいつも()を忘れる。


itertools.h

#include <fstream>
#include <iostream>
#include "itertools.h"

using namespace std;
using namespace itertools;

class cSplit {
    const string&   str;
    int k;
    int mode;
    
public:
    cSplit(const string& s) : str(s), k(0), mode(0) { }
    string next() {
        return next_word("");
    }
    bool exists_next() { return k < str.length(); }
    
private:
    string next_word(const string& s) {
        const char  c = str[k];
        if(mode == 0) {
            k++;
            if(c == '"')
                mode = 1;
            return next_word(s);
        }
        else {
            if(c == '"') {
                k++;
                mode = 0;
                return s;
            }
            else {
                const string    s2 = s + str[k];
                k++;
                return next_word(s2);
            }
        }
    }
};

int score(tuple<int,const string&> t) {
    const string&   s = get<1>(t);
    return fst(t) * sum(map([&s] (int k) { return s[k] - 'A' + 1; },
                                                range<>(s.length())));
}

int main() {
    string      str;
    ifstream    ifs("names.txt");
    ifs >> str;
    ifs.close();
    cout << sum(map(score, zip(itertools::count<>(1),
                            sorted(list(cSplit(str)))))) << endl;
}