{"cells":[{"metadata":{"_uuid":"dd88f82b-534d-4cb2-b6b5-36a4f8486d4e","_cell_guid":"c990da7b-d291-4035-b709-03c3c6f76517","trusted":true},"cell_type":"code","source":"KAGGLE = True\nTIMEOUT = 30600 # 8h 30 minutes\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\n\nimport os\nfor dirname, _, filenames in os.walk('/kaggle/input'):\n    for filename in filenames:\n        print(os.path.join(dirname, filename))\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"%%writefile main-RT.cpp\n#include <map>\n#include <fstream>\n#include <iostream>\n#include <vector>\n#include <iomanip>\n#include <set>\n#include <cstring>\n\n#include <random>\n#include <algorithm>\n\n#include <mutex>\n#include <thread>\n#include <chrono>\n#include <boost/asio/thread_pool.hpp>\n#include <boost/asio/post.hpp>\n#include <boost/core/noncopyable.hpp>\n\nextern \"C\" {\n    #include \"kissat/src/kissat.h\"\n};\n\nusing namespace std;\n\nconstexpr int n = 25;\nconstexpr int N = n * n;\n\nusing CW = vector<uint8_t>;\nusing TStamp = std::chrono::time_point<std::chrono::system_clock>;\n\nstruct task {\n    string id;\n    CW field;\n    int steps;\n};\n\nrandom_device rd;\nmt19937 g(rd());\n\nstatic atomic<bool> is_stopped;\nstatic atomic<bool> is_timeouted;\ndouble total_timeout = 8.5 * 60 * 60;\n\nTStamp app_started = std::chrono::system_clock::now();\n\nvoid terminate(int code) {\n    is_stopped = true;\n    is_timeouted = true;\n    exit(code);\n}\n\nvector<string> split(std::string s, char delimiter) {\n    s += delimiter;\n\n    vector<string> result;\n    size_t start = 0;\n    for (size_t i = start; i < s.size(); ++i) {\n        while (s[i] != delimiter) {\n            ++i;\n        }\n        result.push_back(s.substr(start, i - start));\n        start = i + 1;\n    }\n    return result;\n}\n\nCW s2vec(const std::string& s) {\n    CW v(N);\n    if (static_cast<int>(s.size()) != N + N - 1) {\n        cerr << \"wtf s2vec format len\" << s.size() << endl;\n        terminate(1);\n    }\n    for (int i = 0; i < N; ++i) {\n        v[i] = s[i + i] == '1';\n    }\n    return v;\n}\n\nstring vec2s(const CW& v) {\n    string res;\n    for (int i = 0; i < N; ++i) {\n        if (v[i]) {\n            res += \"1,\";\n        } else {\n            res += \"0,\";\n        }\n    }\n    res.resize(res.size() - 1);\n    return res;\n}\n\nint weight(const task& t) {\n    int count = 0;\n    for (auto k : t.field) {\n        if (k) ++count;\n    }\n    return count;\n}\n\nvector<int> init_nums(int N) {\n    vector<int> values;\n    for (int i = 0; i < N; ++i) {\n        values.push_back(i);\n    }\n    return values;\n}\n\nconst vector<int> n_nums = init_nums(N);\n\nbool calc(const CW& field, int pos, int x, int y) noexcept {\n    static const int dx8[] = {-1, -1, -1,  0,  0,  1,  1,  1};\n    static const int dy8[] = {-1,  0,  1, -1,  1, -1,  0,  1};\n    int count = 0;\n    for (int i = 0; i < 8; ++i) {\n        int a = x + dx8[i];\n        int b = y + dy8[i];\n        if (a < 0) a += n;\n        else if (a >= n) a -= n;\n        if (b < 0) b += n;\n        else if (b >= n) b -= n;\n\n        if (field[b * n + a]) {\n            ++count;\n        }\n    }\n    return (count | field[pos]) == 3;\n}\n\nbool calc_left_line(const CW& field, size_t pos) noexcept {\n    static const size_t d_left8[] = { -1ULL, -25ULL, -24ULL, +24, +1, +25 + 24, +25, +26};\n\n    uint8_t count = 0;\n    for (int i = 0; i < 8; ++i) {\n        count += field[pos + d_left8[i]];\n    }\n    return (count | field[pos]) == 3;\n}\n\nbool calc_right_line(const CW& field, size_t pos) noexcept {\n    static const size_t d_right8[] = { -26ULL, -25ULL, - 49ULL, -1ULL, -24ULL, +24, +25, +1};\n\n    uint8_t count = 0;\n    for (int i = 0; i < 8; ++i) {\n        count += field[pos + d_right8[i]];\n    }\n    return (count | field[pos]) == 3;\n}\n\nbool calc_bottom_line(const CW& field, size_t pos) noexcept {\n    static const size_t d_bottom8[] = { -26ULL, -25ULL, -24ULL, -1ULL, 1, -599ULL, -600ULL, -601ULL};\n\n    uint8_t count = 0;\n    for (int i = 0; i < 8; ++i) {\n        count += field[pos + d_bottom8[i]];\n    }\n    return (count | field[pos]) == 3;\n}\n\nbool calc_top_line(const CW& field, size_t pos) noexcept {\n    static const size_t d_top8[] = { +599, +600, +601, -1ULL, 1, +24, +25, +26};\n\n    uint8_t count = 0;\n    for (int i = 0; i < 8; ++i) {\n        count += field[pos + d_top8[i]];\n    }\n    return (count | field[pos]) == 3;\n}\n\nbool calc_no_checks(const CW& field, size_t pos) noexcept {\n    static const size_t di8[] = {0, 1, 2, 25, 27, +50, +51, +52};\n\n    uint8_t count = 0;\n    for (int i = 0; i < 8; ++i) {\n        count += field[pos + di8[i]];\n    }\n    return (count | field[pos + 26]) == 3;\n}\n\nCW run_step(CW start) noexcept {\n    thread_local CW next(N);\n\n    for (int x = 1; x < n - 1; ++x) {\n        next[x] = calc_top_line(start, x);\n        next[600 + x] = calc_bottom_line(start, 600 + x);\n        next[x * 25] = calc_left_line(start, x * 25);\n        next[x * 25 + 24] = calc_right_line(start, x * 25 + 24);\n    }\n    size_t pos = 0;\n    for (int y = 1; y < n - 1; ++y) {\n        for (int x = 1; x < n - 1; ++x) {\n            next[pos + 26] = calc_no_checks(start, pos);\n            ++pos;\n        }\n        pos += 2;\n    }\n    for (auto i : {0, n-1, N - n, N - 1}) {\n        next[i] = calc(start, i, i % n, i / n);\n    }\n    return next;\n}\n\nvoid run_step_partial(CW* steps, int x, int y, int step, vector<pair<int, int>>& changelog) {\n    int range = step + 1;\n\n    for (int b = y - range; b <= y + range; ++b) {\n        int q = b;\n\n        if (q < 0) q += n;\n        else if (q >= n) q -= n;\n\n        for (int a = x - range; a <= x + range; ++a) {\n            int p = a;\n            if (p < 0) p += n;\n            else if (p >= n) p -= n;\n\n            size_t i = q * n + p;\n\n            bool not_vert_side = p > 0 && p + 1 < n;\n            bool not_hori_side = q > 0 && q + 1 < n;\n\n            bool value;\n            if (not_vert_side && not_hori_side) {\n                value = calc_no_checks(steps[step], i - 26);\n            } else {\n                bool not_vert_side = p > 0 && p + 1 < n;\n                bool not_hori_side = q > 0 && q + 1 < n;\n                if (not_vert_side && q + 1 == n) {\n                    value = calc_bottom_line(steps[step], i);\n                } else if (not_vert_side && q == 0) {\n                    value = calc_top_line(steps[step], i);\n                } else if (not_hori_side && p == 0) {\n                    value = calc_left_line(steps[step], i);\n                } else if (not_hori_side && p + 1 == n) {\n                    value = calc_right_line(steps[step], i);\n                } else {\n                    value = calc(steps[step], i, p, q);\n                }\n            }\n            bool previous = steps[step + 1][i];\n            if (value != previous) {\n                changelog.push_back({step + 1, i});\n                steps[step + 1][i] = value;\n            }\n        }\n    }\n}\n\nint run_step_partial_last(CW* steps, int x, int y, int step, vector<pair<int, int>>& changelog, const CW& original) {\n    int range = step + 1;\n\n    int diff = 0;\n    for (int b = y - range; b <= y + range; ++b) {\n        int q = b;\n\n        if (q < 0) q += n;\n        else if (q >= n) q -= n;\n\n        for (int a = x - range; a <= x + range; ++a) {\n            int p = a;\n            if (p < 0) p += n;\n            else if (p >= n) p -= n;\n\n            size_t i = q * n + p;\n\n            bool not_vert_side = p > 0 && p + 1 < n;\n            bool not_hori_side = q > 0 && q + 1 < n;\n\n            bool value;\n            if (not_vert_side && not_hori_side) {\n                value = calc_no_checks(steps[step], i - 26);\n            } else {\n                if (not_vert_side && q + 1 == n) {\n                    value = calc_bottom_line(steps[step], i);\n                } else if (not_vert_side && q == 0) {\n                    value = calc_top_line(steps[step], i);\n                } else if (not_hori_side && p == 0) {\n                    value = calc_left_line(steps[step], i);\n                } else if (not_hori_side && p + 1 == n) {\n                    value = calc_right_line(steps[step], i);\n                } else {\n                    value = calc(steps[step], i, p, q);\n                }\n            }\n            bool previous = steps[step + 1][i];\n            if (value != previous) {\n                if (value == original[i]) {\n                    ++diff;\n                } else {\n                    --diff;\n                }\n                changelog.push_back({step + 1, i});\n                steps[step + 1][i] = value;\n            }\n        }\n    }\n    return diff;\n}\n\nvoid revert_changes(CW* steps, const vector<pair<int, int>>& changelog) {\n    for (auto i : changelog) {\n        steps[i.first][i.second] = !steps[i.first][i.second];\n    }\n}\n\nvoid print(const CW& field) {\n    for (int pos = 0; pos < N; ++pos) {\n        cout << (field[pos] ? '*' : '.'); //static_cast<int>(field[pos]);\n        if (pos % n == n - 1) {\n            cout << endl;\n        }\n    }\n    cout << endl;\n}\nint validate(CW start, const task& t) {\n    for (int i = 0; i < t.steps; ++i) {\n        start = run_step(start);\n    }\n    int count = 0;\n    for (int i = 0; i < N; ++i) {\n        if (start[i] == t.field[i])\n            ++count;\n    }\n    return count;\n}\nint validate_partial(const task& t, CW* steps, int x, int y, vector<pair<int, int>>& changelog) {\n    changelog.clear();\n\n    for (int i = 0; i < t.steps - 1; ++i) {\n        run_step_partial(steps, x, y, i, changelog);\n    }\n    int diff = run_step_partial_last(steps, x, y, t.steps - 1, changelog, t.field);\n    return diff;\n}\n\nstatic class Cache : private boost::noncopyable {\nprivate:\n    map<string, pair<int, string>> cache;\n    mutex m;\n\npublic:\n    Cache() { }\n    auto get(const std::string& id) {\n        lock_guard<mutex> g(m);\n\n        return cache[id];\n    }\n    bool set(const pair<int, CW>& value, const task& t) {\n        const std::string& id = t.id;\n        {\n            lock_guard<mutex> g(m);\n\n            if (cache.find(id) != cache.end() && cache[id].first >= value.first) {\n                return false;\n            }\n        }\n        int score = validate(value.second, t);\n        if (score != value.first) {\n            cerr << \"wtf score for \" << id << \": \" << score << ' ' << value.first << endl;\n            for (auto i : value.second) {\n                cerr << (int) i << ' ';\n            }\n            cerr << endl;\n            throw std::runtime_error(\"wtf score\");\n        }\n        string s = vec2s(value.second);\n        {\n            lock_guard<mutex> g(m);\n            cache[id] = {value.first, s};\n            ofstream cache_file(\"processed/cache-real-time\", std::ofstream::app);\n            cache_file << id << ' ' << value.first << ' ' << s << endl;\n\n            return true;\n        }\n    }\n\n} global_cache;\n\nCW prepare_mask(CW solution, const task& t) {\n    for (int i = 0; i < t.steps; ++i) {\n        solution = run_step(solution);\n    }\n    vector<int> diff;\n    for (int i = 0; i < N; ++i) {\n        if (t.field[i] != solution[i]) {\n            diff.push_back(i);\n        }\n    }\n    for (int i = 0; i < t.steps; ++i) {\n        vector<int> next_diff;\n        for (auto pos : diff) {\n            next_diff.push_back(i);\n            int x = pos % n;\n            int y = pos / n;\n            static const int dx8[] = {-1, -1, -1,  0,  0,  1,  1,  1};\n            static const int dy8[] = {-1,  0,  1, -1,  1, -1,  0,  1};\n\n            for (int i = 0; i < 8; ++i) {\n                int a = x + dx8[i];\n                int b = y + dy8[i];\n                if (a < 0) a += n;\n                else if (a >= n) a -= n;\n                if (b < 0) b += n;\n                else if (b >= n) b -= n;\n                next_diff.push_back(b * n + a);\n            }\n        }\n        diff = next_diff;\n        sort(diff.begin(), diff.end());\n        {\n            auto last = std::unique(diff.begin(), diff.end());\n            diff.erase(last, diff.end());\n        }\n    }\n    CW result(N);\n    for (auto i : diff) {\n        result[i] = true;\n    }\n//    cerr << diff.size() << \" for \" << global_cache.get(t.id).first << endl;\n    return result;\n}\n\nCW shake_single_if_equal(CW _field, const task& t, bool fast = false) {\n    CW steps[t.steps + 1];\n    steps[0] = _field;\n    CW& field = steps[0];\n    vector<pair<int, int>> changelog;\n\n    int best_score = validate(field, t);\n    auto best_pos = field;\n    int score = best_score;\n    int current_score = best_score;\n\n    for (int i = 0; i < t.steps; ++i) {\n        steps[i + 1] = run_step(steps[i]);\n    }\n\n    CW mask_to_shake = prepare_mask(best_pos, t);\n    int default_tries = fast ? 39 : 99;\n    int default_range = fast ? 2 : 3;\n    int tries = default_tries;\n    int range = default_range;\n    do {\n        if (score != best_score) {\n            tries = default_tries;\n            score = best_score;\n            range = default_range;\n        }\n        if (tries % 50 == 0) range -= 1;\n        int shift = rand() % N;\n        bool dir = rand() % 2;\n        int i = shift;\n        int x = i % n;\n        int y = i / n;\n        for (int index = 0; index < N; ++index) {\n            if (dir) {\n                ++i;\n                ++x;\n                if (x == n) {\n                    x = 0;\n                    ++y;\n                    if (y == n) y = 0;\n                }\n                if (i == N) i = 0;\n            } else {\n                --i;\n                --x;\n                if (x == -1) {\n                    x = n - 1;\n                    --y;\n                    if (y == -1) y = n - 1;\n                }\n                if (i == N) i = 0;\n                if (i < 0) i = N - 1;\n            }\n\n            if (!mask_to_shake[i] && tries % 5 != 0) continue; /// _---------- RT_ADJ\n\n            bool value = field[i];\n            field[i] = !field[i];\n            int new_score = current_score + validate_partial(t, steps, x, y, changelog);\n            if (new_score > best_score) {\n                best_score = new_score;\n                best_pos = field;\n                global_cache.set({best_score, best_pos}, t);\n            } else if (new_score < best_score - range) {\n                field[i] = !field[i];\n            } else {\n                if (rand() % 4 == 0) {\n                    field[i] = !field[i];\n                }\n            }\n            if (value == field[i]) {\n                revert_changes(steps, changelog);\n            } else {\n                current_score = new_score;\n            }\n        }\n    } while (best_score != score || tries-- > 0);\n    return best_pos;\n}\n\nCW shake_k_and_single(const task &t, CW start, int tries, bool fast = false) {\n    auto next_start = start;\n    vector<int> indexes = n_nums;\n    shuffle(indexes.begin(), indexes.end(), g);\n    for (int i = 0; i < tries; ++i) {\n        next_start[indexes[i]] = !next_start[indexes[i]];\n    }\n    next_start = shake_single_if_equal(next_start, t, true);\n    return shake_single_if_equal(next_start, t, fast);\n}\n\nCW make_random() {\n    CW c(N);\n    auto indexes = n_nums;\n    shuffle(indexes.begin(), indexes.end(), g);\n    indexes.resize(N / 2);\n    for (auto i : indexes) {\n        c[i] = 1;\n    }\n    return c;\n}\n\nCW make_checked() {\n    CW c(N);\n    for (size_t i = 0; i < N; i += 2) {\n        c[i] = true;\n    }\n    return c;\n}\n\nnamespace CNF_solver {\nusing CNF = std::vector<std::vector<int>>;\n\nbool alive(const CW& field, int pos, int x, int y) {\n    static const int dx8[] = {-1, -1, -1,  0,  0,  1,  1,  1};\n    static const int dy8[] = {-1,  0,  1, -1,  1, -1,  0,  1};\n\n    int count = 0;\n    for (int i = 0; i < 8; ++i) {\n        int a = x + dx8[i];\n        int b = y + dy8[i];\n        if (a < 0) a += n;\n        else if (a >= n) a -= n;\n        if (b < 0) b += n;\n        else if (b >= n) b -= n;\n\n        if (field[b * n + a]) {\n            ++count;\n        }\n    }\n    return (count | field[pos]) == 3;\n}\n\nvector<int> generate_positions(int x, int y) {\n    static const int dx8[] = {-1, -1, -1,  0,  0,  1,  1,  1};\n    static const int dy8[] = {-1,  0,  1, -1,  1, -1,  0,  1};\n\n    vector<int> result;\n    result.push_back(-9999); // place holder\n\n    for (int i = 0; i < 8; ++i) {\n        int a = x + dx8[i];\n        int b = y + dy8[i];\n        if (a < 0) a += n;\n        else if (a >= n) a -= n;\n        if (b < 0) b += n;\n        else if (b >= n) b -= n;\n\n        result.push_back(b * n + a);\n    }\n    return result;\n}\n\n// CNF: all values false: through negative\nbool geti(uint32_t value, int index) {\n    return (value & (1 << index));\n}\n\nCNF universal_cnf() {\n    CNF result_cnf;\n\n    uint32_t mask = 0;\n    while (!geti(mask, 10)) {\n        int count = 0;\n        for (int i = 0; i < 8; ++i) {\n            if (geti(mask, i)) {\n                ++count;\n            }\n        }\n        bool alive = (count | geti(mask, 8)) == 3;\n        bool is_true = (alive == geti(mask, 9));\n        if (!is_true) {\n            vector<int> next;\n            for (int i = 0; i <= 9; ++i) {\n                if (geti(mask, i)) {\n                    next.push_back(-i - 1);\n                } else {\n                    next.push_back(i + 1);\n                }\n            }\n            result_cnf.push_back(next);\n        }\n        sort(result_cnf.begin(), result_cnf.end());\n\n        ++mask;\n    }\n    // 325065 CNF -> 160k CNF\n    // speed increased 1.6 ; 30 -> # 3.5; 60\n    // optimize_cnf(result_cnf);\n\n    // Optimized much better externally by python tool sympy:\n    // $ python3\n    // >>> from sympy import *\n    // >>> x, y, z = symbols('x y z')\n    // >>> simplify_logic((x & y & ~z) | (x & ~y & z), form=\"cnf\")\n    // x & (y | z) & (~y | ~z)\n    result_cnf = {{1, 2, 3, 4, 5, 6, 7, -10}, {1, 2, 3, 4, 5, 6, 8, -10}, {1, 2, 3, 4, 5, 6, 9, -10}, {1, 2, 3, 4, 5, 7, 8, -10}, {1, 2, 3, 4, 5, 7, 9, -10}, {1, 2, 3, 4, 5, 8, 9, -10}, {1, 2, 3, 4, 6, 7, 8, -10}, {1, 2, 3, 4, 6, 7, 9, -10}, {1, 2, 3, 4, 6, 8, 9, -10}, {1, 2, 3, 4, 7, 8, 9, -10}, {1, 2, 3, 5, 6, 7, 8, -10}, {1, 2, 3, 5, 6, 7, 9, -10}, {1, 2, 3, 5, 6, 8, 9, -10}, {1, 2, 3, 5, 7, 8, 9, -10}, {1, 2, 3, 6, 7, 8, 9, -10}, {1, 2, 4, 5, 6, 7, 8, -10}, {1, 2, 4, 5, 6, 7, 9, -10}, {1, 2, 4, 5, 6, 8, 9, -10}, {1, 2, 4, 5, 7, 8, 9, -10}, {1, 2, 4, 6, 7, 8, 9, -10}, {1, 2, 5, 6, 7, 8, 9, -10}, {1, 3, 4, 5, 6, 7, 8, -10}, {1, 3, 4, 5, 6, 7, 9, -10}, {1, 3, 4, 5, 6, 8, 9, -10}, {1, 3, 4, 5, 7, 8, 9, -10}, {1, 3, 4, 6, 7, 8, 9, -10}, {1, 3, 5, 6, 7, 8, 9, -10}, {1, 4, 5, 6, 7, 8, 9, -10}, {2, 3, 4, 5, 6, 7, 8, -10}, {2, 3, 4, 5, 6, 7, 9, -10}, {2, 3, 4, 5, 6, 8, 9, -10}, {2, 3, 4, 5, 7, 8, 9, -10}, {2, 3, 4, 6, 7, 8, 9, -10}, {2, 3, 5, 6, 7, 8, 9, -10}, {2, 4, 5, 6, 7, 8, 9, -10}, {3, 4, 5, 6, 7, 8, 9, -10}, {-1, -10, -2, -3, -4}, {-1, -10, -2, -3, -5}, {-1, -10, -2, -3, -6}, {-1, -10, -2, -3, -7}, {-1, -10, -2, -3, -8}, {-1, -10, -2, -4, -5}, {-1, -10, -2, -4, -6}, {-1, -10, -2, -4, -7}, {-1, -10, -2, -4, -8}, {-1, -10, -2, -5, -6}, {-1, -10, -2, -5, -7}, {-1, -10, -2, -5, -8}, {-1, -10, -2, -6, -7}, {-1, -10, -2, -6, -8}, {-1, -10, -2, -7, -8}, {-1, -10, -3, -4, -5}, {-1, -10, -3, -4, -6}, {-1, -10, -3, -4, -7}, {-1, -10, -3, -4, -8}, {-1, -10, -3, -5, -6}, {-1, -10, -3, -5, -7}, {-1, -10, -3, -5, -8}, {-1, -10, -3, -6, -7}, {-1, -10, -3, -6, -8}, {-1, -10, -3, -7, -8}, {-1, -10, -4, -5, -6}, {-1, -10, -4, -5, -7}, {-1, -10, -4, -5, -8}, {-1, -10, -4, -6, -7}, {-1, -10, -4, -6, -8}, {-1, -10, -4, -7, -8}, {-1, -10, -5, -6, -7}, {-1, -10, -5, -6, -8}, {-1, -10, -5, -7, -8}, {-1, -10, -6, -7, -8}, {-10, -2, -3, -4, -5}, {-10, -2, -3, -4, -6}, {-10, -2, -3, -4, -7}, {-10, -2, -3, -4, -8}, {-10, -2, -3, -5, -6}, {-10, -2, -3, -5, -7}, {-10, -2, -3, -5, -8}, {-10, -2, -3, -6, -7}, {-10, -2, -3, -6, -8}, {-10, -2, -3, -7, -8}, {-10, -2, -4, -5, -6}, {-10, -2, -4, -5, -7}, {-10, -2, -4, -5, -8}, {-10, -2, -4, -6, -7}, {-10, -2, -4, -6, -8}, {-10, -2, -4, -7, -8}, {-10, -2, -5, -6, -7}, {-10, -2, -5, -6, -8}, {-10, -2, -5, -7, -8}, {-10, -2, -6, -7, -8}, {-10, -3, -4, -5, -6}, {-10, -3, -4, -5, -7}, {-10, -3, -4, -5, -8}, {-10, -3, -4, -6, -7}, {-10, -3, -4, -6, -8}, {-10, -3, -4, -7, -8}, {-10, -3, -5, -6, -7}, {-10, -3, -5, -6, -8}, {-10, -3, -5, -7, -8}, {-10, -3, -6, -7, -8}, {-10, -4, -5, -6, -7}, {-10, -4, -5, -6, -8}, {-10, -4, -5, -7, -8}, {-10, -4, -6, -7, -8}, {-10, -5, -6, -7, -8}, {1, 10, 2, 3, 4, 5, -6, -7, -8}, {1, 10, 2, 3, 4, 6, -5, -7, -8}, {1, 10, 2, 3, 4, 7, -5, -6, -8}, {1, 10, 2, 3, 4, 8, -5, -6, -7}, {1, 10, 2, 3, 5, 6, -4, -7, -8}, {1, 10, 2, 3, 5, 6, -4, -7, -9}, {1, 10, 2, 3, 5, 6, -7, -8, -9}, {1, 10, 2, 3, 5, 7, -4, -6, -8}, {1, 10, 2, 3, 5, 7, -4, -6, -9}, {1, 10, 2, 3, 5, 7, -4, -8, -9}, {1, 10, 2, 3, 5, 7, -6, -8, -9}, {1, 10, 2, 3, 5, 8, -4, -6, -7}, {1, 10, 2, 3, 5, 8, -6, -7, -9}, {1, 10, 2, 3, 6, 7, -4, -5, -8}, {1, 10, 2, 3, 6, 7, -4, -5, -9}, {1, 10, 2, 3, 6, 7, -5, -8, -9}, {1, 10, 2, 3, 6, 8, -4, -5, -7}, {1, 10, 2, 3, 6, 8, -5, -7, -9}, {1, 10, 2, 3, 7, 8, -4, -5, -6}, {1, 10, 2, 3, 7, 8, -5, -6, -9}, {1, 10, 2, 4, 5, 6, -3, -7, -8}, {1, 10, 2, 4, 5, 7, -3, -6, -8}, {1, 10, 2, 4, 5, 8, -3, -6, -7}, {1, 10, 2, 4, 6, 7, -3, -5, -8}, {1, 10, 2, 4, 6, 8, -3, -5, -7}, {1, 10, 2, 4, 7, 8, -3, -5, -6}, {1, 10, 2, 5, 6, 7, -3, -4, -8}, {1, 10, 2, 5, 6, 7, -3, -4, -9}, {1, 10, 2, 5, 6, 7, -3, -8, -9}, {1, 10, 2, 5, 6, 8, -3, -4, -7}, {1, 10, 2, 5, 6, 8, -3, -7, -9}, {1, 10, 2, 5, 7, 8, -3, -4, -6}, {1, 10, 2, 5, 7, 8, -3, -6, -9}, {1, 10, 2, 6, 7, 8, -3, -4, -5}, {1, 10, 2, 6, 7, 8, -3, -5, -9}, {1, 10, 3, 4, 5, 6, -2, -7, -8}, {1, 10, 3, 4, 5, 7, -2, -6, -8}, {1, 10, 3, 4, 5, 8, -2, -6, -7}, {1, 10, 3, 4, 6, 7, -2, -5, -8}, {1, 10, 3, 4, 6, 8, -2, -5, -7}, {1, 10, 3, 4, 7, 8, -2, -5, -6}, {1, 10, 3, 5, 6, 7, -2, -4, -8}, {1, 10, 3, 5, 6, 7, -2, -4, -9}, {1, 10, 3, 5, 6, 7, -2, -8, -9}, {1, 10, 3, 5, 6, 8, -2, -4, -7}, {1, 10, 3, 5, 6, 8, -2, -7, -9}, {1, 10, 3, 5, 7, 8, -2, -4, -6}, {1, 10, 3, 5, 7, 8, -2, -6, -9}, {1, 10, 3, 6, 7, 8, -2, -4, -5}, {1, 10, 3, 6, 7, 8, -2, -5, -9}, {1, 10, 4, 5, 6, 7, -2, -3, -8}, {1, 10, 4, 5, 6, 8, -2, -3, -7}, {1, 10, 4, 5, 7, 8, -2, -3, -6}, {1, 10, 4, 6, 7, 8, -2, -3, -5}, {1, 10, 5, 6, 7, 8, -2, -3, -4}, {1, 10, 5, 6, 7, 8, -2, -3, -9}, {10, 2, 3, 4, 5, 6, -1, -7, -8}, {10, 2, 3, 4, 5, 7, -1, -6, -8}, {10, 2, 3, 4, 5, 8, -1, -6, -7}, {10, 2, 3, 4, 6, 7, -1, -5, -8}, {10, 2, 3, 4, 6, 8, -1, -5, -7}, {10, 2, 3, 4, 7, 8, -1, -5, -6}, {10, 2, 3, 5, 6, 7, -1, -4, -8}, {10, 2, 3, 5, 6, 7, -1, -4, -9}, {10, 2, 3, 5, 6, 7, -1, -8, -9}, {10, 2, 3, 5, 6, 8, -1, -4, -7}, {10, 2, 3, 5, 6, 8, -1, -7, -9}, {10, 2, 3, 5, 7, 8, -1, -4, -6}, {10, 2, 3, 5, 7, 8, -1, -6, -9}, {10, 2, 3, 6, 7, 8, -1, -4, -5}, {10, 2, 3, 6, 7, 8, -1, -5, -9}, {10, 2, 4, 5, 6, 7, -1, -3, -8}, {10, 2, 4, 5, 6, 8, -1, -3, -7}, {10, 2, 4, 5, 7, 8, -1, -3, -6}, {10, 2, 4, 6, 7, 8, -1, -3, -5}, {10, 2, 5, 6, 7, 8, -1, -3, -4}, {10, 2, 5, 6, 7, 8, -1, -3, -9}, {10, 3, 4, 5, 6, 7, -1, -2, -8}, {10, 3, 4, 5, 6, 8, -1, -2, -7}, {10, 3, 4, 5, 7, 8, -1, -2, -6}, {10, 3, 4, 6, 7, 8, -1, -2, -5}, {10, 3, 5, 6, 7, 8, -1, -2, -4}, {10, 3, 5, 6, 7, 8, -1, -2, -9}, {10, 4, 5, 6, 7, 8, -1, -2, -3}};\n\n    return result_cnf;\n}\n\n\n// 0...N-1: previous position\n// N...2N - 1: current position\nvector<std::vector<int>> cnf_universal() {\n    // universal \"conways rules\" CNF\n    CNF cnf;\n\n    CNF cnf_conway_cell = universal_cnf();\n    for (int y = 0; y < n; ++y) {\n        for (int x = 0; x < n; ++x) {\n            int pos_previous = y * n + x;\n            int pos_current = y * n + x + N;\n            vector<int> positions = generate_positions(x, y);\n            positions.push_back(pos_previous);\n            positions.push_back(pos_current);\n\n            for (auto& c : cnf_conway_cell) {\n                vector<int> next;\n                for (auto& p : c) {\n                    if (p < 0) {\n                        next.push_back(-positions[-p] - 1);\n                    } else {\n                        next.push_back(positions[p] + 1);\n                    }\n                }\n                cnf.push_back(next);\n            }\n        }\n    }\n    cout << \"CNF size: \" << cnf.size() << endl;\n    return cnf;\n}\n\nconst static CNF cnf_conway_rules = cnf_universal();\nCNF get_cnf(const task& t, const std::pair<int, int>& ignore_range = {0, 0}) {\n    int k = t.steps;\n\n    if (k == 1) {\n        int k = t.steps;\n        CNF cnf = cnf_conway_rules;\n        for (int iter = 1; iter < k; ++iter) {\n            CNF cnf_i = cnf_conway_rules;\n            for (auto& i : cnf_i) {\n                for (auto& j : i) {\n                    if (j > 0) j += N * iter;\n                    else j -= N * iter;\n                }\n                cnf.push_back(i);\n            }\n        }\n        // fulfill CNF for current field\n        for (int i = 0; i < N; ++i) {\n            int var = i + k * N + 1;\n            if (t.field[i]) {\n                cnf.push_back({var});\n            } else {\n                cnf.push_back({-var});\n            }\n        }\n        return cnf;\n    }\n\n    // First level\n    CNF cnf = cnf_conway_rules;\n\n    // Middle levels: not first, not last\n    for (int iter = 1; iter + 1 < k; ++iter) {\n        CNF cnf_i = cnf_conway_rules;\n        for (auto& i : cnf_i) {\n            for (auto& j : i) {\n                if (j > 0) j += N * iter;\n                else j -= N * iter;\n            }\n            cnf.push_back(i);\n        }\n    }\n    // fulfill CNF for current field\n    CNF cnf_last = cnf_conway_rules;\n    for (auto& i : cnf_last) {\n        int to_ignore = 0;\n        for (auto& j : i) {\n            for (int l = N + 1; l <= N + N; ++l) {\n                if (j == l || j == -l) {\n                    to_ignore = j;\n                }\n            }\n        }\n        int pos = -1;\n        if (to_ignore > 0) {\n            pos = to_ignore - N - 1;\n            if (t.field[pos]) continue;\n        }\n        if (to_ignore < 0) {\n            pos = -to_ignore - N - 1;\n            if (!t.field[-to_ignore - N - 1]) continue;\n        }\n\n        if (pos >= ignore_range.first && pos < ignore_range.second) {\n            continue;\n        }\n\n        std::vector<int> c;\n        for (auto& j : i) {\n            if (j == to_ignore) continue;\n\n            if (j > 0)\n                c.push_back(j + N * (k - 1));\n            else\n                c.push_back(j - N * (k - 1));\n        }\n        cnf.push_back(c);\n    }\n    return cnf;\n}\n} // namespace CNF_solver\n\nstruct KissatSolver {\n    KissatSolver(double timeout = 2.1)\n    : timeout(timeout)\n    , cleaner([this]() -> void {\n            cleanup();\n            })\n    {\n    }\n    ~KissatSolver() {\n        cleaner.join();\n    }\n\n    kissat* add(string id) {\n        kissat* solver = kissat_init();\n        {\n            lock_guard<mutex> g(m);\n            if (all.find(id) != all.end()) throw std::runtime_error(\"Kissat solver already contains\" + id);\n            all[id] = {solver, std::chrono::system_clock::now()};\n        }\n        return solver;\n    }\n\n    void notify_done(string id) {\n        lock_guard<mutex> g(m);\n        to_free.insert(id);\n    }\n\n    void cleanup() {\n        while (!is_stopped) {\n            this_thread::sleep_for(300ms);\n\n            lock_guard<mutex> g(m);\n\n            int to_clean = 0;\n            for (const auto& id : to_free) {\n                auto& item = all[id];\n                kissat* solver = item.first;\n                kissat_release(solver);\n                all.erase(id);\n                ++to_clean;\n            }\n            to_free.clear();\n\n            int to_terminate = 0;\n            TStamp now = std::chrono::system_clock::now();\n            for (const auto& i : all) {\n                auto item = i.second;\n                double running = std::chrono::duration_cast<std::chrono::seconds>(now - item.second).count();\n                if (running > timeout) {\n                    kissat_terminate(item.first);\n                    ++to_terminate;\n                }\n            }\n            if (to_terminate || to_clean) {\n                cout << \"terminated \" << to_terminate << \" cleaned \" << to_clean << endl;\n            }\n        }\n    }\n\nprivate:\n    double timeout;\n\n    map<string, std::pair<kissat*, TStamp>> all;\n\n    thread cleaner;\n    set<string> to_free;\n\n    mutex m;\n} kissat_solver;\n\nvoid sat_solver_k(const task& t) {\n    int k = t.steps;\n    CNF_solver::CNF cnf = CNF_solver::get_cnf(t);\n\n    kissat* solver = kissat_solver.add(t.id);\n    kissat_set_option (solver, \"quiet\", 1);\n    kissat_set_configuration(solver, \"sat\");\n    kissat_reserve(solver, N * k);\n\n    for (auto c : cnf) {\n        for (auto i : c) {\n            kissat_add(solver, i);\n        }\n        kissat_add(solver, 0);\n    }\n    int result = kissat_solve(solver);\n    switch (result) {\n    case 20:\n        cerr << \"wtf solver failed for \" << t.id << endl;\n        break;\n    }\n    CW solution;\n    bool at_least_one_true = 0;\n    for (int i = 1; i <= N; ++i) {\n        int next = kissat_value(solver, i);\n        if (next > 0) {\n            solution.push_back(1);\n            at_least_one_true = true;\n        } else {\n            solution.push_back(0);\n        }\n    }\n\n    kissat_solver.notify_done(t.id);\n    int score = validate(solution, t);\n\n    global_cache.set({score, solution}, t);\n    if (score != N && at_least_one_true) {\n        shake_single_if_equal(solution, t);\n    }\n}\n\nbool solve_sat(const task& t) {\n    auto it = global_cache.get(t.id);\n    if (is_timeouted) return false;\n    if (it.first == N) {\n        return true;\n    }\n\n    if (t.steps == 1) {\n        sat_solver_k(t);\n    } else if (t.steps == 2 && weight(t) < 100) { /// ------------ RT_ADJ\n        sat_solver_k(t);\n    }\n    return global_cache.get(t.id).first == N;\n}\n\nbool solve_fast(const task& t) {\n    if (is_timeouted) return false;\n    auto it = global_cache.get(t.id);\n    if (it.first == N) {\n        return true;\n    }\n\n    {\n        if (weight(t) < 200) {\n            shake_single_if_equal(CW(N), t, true);\n        } else {\n//            shake_single_if_equal(make_random(), t, true);\n        }\n        shake_single_if_equal(make_checked(), t, true);\n        if (t.steps % 2 == 0)\n            shake_single_if_equal(t.field, t, true);\n        else\n            shake_single_if_equal(run_step(t.field), t, true);\n    }\n    // enabled this only as efficient\n    int score = it.first;\n    size_t iters = 5;\n    CW next = s2vec(it.second);\n    while (iters--) {\n        CW next2 = shake_single_if_equal(next, t, true);\n\n        if (validate(next2, t) >= validate(next, t)) {\n            next = next2;\n        }\n        it = global_cache.get(t.id);\n        int new_score = it.first;\n        if (new_score == N) break;\n        if (new_score != score) {\n            score = new_score;\n            next = s2vec(it.second);\n            iters = 11;\n        }\n    }\n\n    return global_cache.get(t.id).first == N;\n}\nbool solve_slower(const task& t) {\n    if (is_timeouted) return false;\n    auto it = global_cache.get(t.id);\n    if (it.first == N) {\n        return true;\n    }\n\n    // enabled this only as efficient\n    int score = it.first;\n    size_t iters = 4;\n    CW next = s2vec(it.second);\n    while (iters--) {\n        CW next2 = shake_single_if_equal(next, t);\n\n        CW next3 = shake_k_and_single(t, next2, 8);\n        if (validate(next3, t) >= validate(next, t)) {\n            next = next3;\n        }\n\n        if (validate(next2, t) >= validate(next, t)) {\n            next = next2;\n        }\n        it = global_cache.get(t.id);\n        int new_score = it.first;\n        if (new_score == N) break;\n        if (new_score != score) {\n            score = new_score;\n            next = s2vec(it.second);\n            iters = 6;\n        }\n    }\n\n    /*\n    for (int i = 0; i < 4; ++i) {\n        CW next = make_random();\n        for (int j = 0; j < 5; ++j) {\n            next = shake_k_and_single(t, next, 30);\n        }\n    }\n    */\n\n    // trying to run upfront far\n    // run_upfront(id, end, steps);\n\n    return global_cache.get(t.id).first == N;\n}\n\nvoid validate_training(const std::string& file) {\n    ifstream input(file);\n\n    string line;\n    input >> line;\n\n    while (input >> line) {\n        vector<string> v = split(line, ',');\n        if (v.size() != static_cast<size_t>(N + N + 2)) {\n            cerr << \"incorrect input within line within validate: \" << line << endl;\n            terminate(1);\n        }\n        string id = v[0];\n        int steps = stoi(v[1]);\n        CW start(N);\n        CW end(N);\n        for (int i = 0; i < N; ++i) {\n            start[i] = (v[i + 2] == \"1\");\n            end[i] = (v[N + i + 2] == \"1\");\n        }\n        if (validate(start, {id, end, steps}) != N) {\n            cerr << \"validate failed at: \" << id << endl;\n            terminate(1);\n        }\n    }\n\n}\n\npair<int, int> calc_stats(const std::vector<task>& tasks) {\n    int count = 0;\n    int count_solved = 0;\n    int total_score = 0;\n    for (const task & t : tasks) {\n        ++count;\n        int score = global_cache.get(t.id).first;\n        total_score += score;\n        if (score == N) ++count_solved;\n    }\n    int max_score = count * N;\n    cout << \"Solved: \" << count_solved << \"/\" << count ;\n    cout << \" :<>: \" << total_score << \"/\" << max_score << \" = \" << static_cast<double>(total_score) / max_score << endl;;\n    return {count_solved, total_score};\n}\n\nvoid print_stats(const vector<task>& tasks) {\n    auto started = std::chrono::system_clock::now();\n    auto first_stats = calc_stats(tasks);\n    while (!is_stopped) {\n        sleep(9);\n        { // time-out for application ?\n            TStamp now = std::chrono::system_clock::now();\n            double total_running = std::chrono::duration_cast<std::chrono::seconds>(now - app_started).count();\n            if (total_running > total_timeout) {\n                is_timeouted = true;\n            }\n        }\n        double running = (std::chrono::system_clock::now() - started).count();\n\n        auto current = calc_stats(tasks);\n        double speed1 = (current.first - first_stats.first) / running * 1e9;\n        double speed2 = (current.second - first_stats.second) / running * 1e9;\n        cout << \"speed \" << std::fixed << std::setprecision(6) << speed1 << ' ' << speed2 << ' ';\n    }\n    calc_stats(tasks);\n}\n\nint main(int argc, char *argv[]) {\n    validate_training(\"train.csv\");\n\n    if (argc > 1 && strcmp(argv[1], \"--only-validate\") == 0) {\n        cerr << \"Validated train!\" << endl;\n        terminate(0);\n    }\n    if (argc > 1 && strcmp(argv[1], \"--timeout\") == 0) {\n        total_timeout = stoi(argv[2]);\n    }\n\n    ifstream input(\"test.csv\");\n    string line;\n    // header\n    input >> line;\n\n    std::vector<task> all_tasks;\n\n    while (input >> line) {\n        vector<string> v = split(line, ',');\n        if (v.size() != static_cast<size_t>(N + 2)) {\n            cerr << \"incorrect input within line: \" << line << endl;\n            terminate(1);\n        }\n        string id = v[0];\n        int steps = stoi(v[1]);\n//        if (id >= \"51000\") continue;\n//        if (steps != 3) continue;\n        CW field(N);\n        for (int i = 0; i < N; ++i) {\n            field[i] = v[i + 2] == \"1\";\n        }\n        task t{id, field, steps};\n\n        CW empty(N);\n        global_cache.set({validate(empty, t), empty}, t);\n\n        all_tasks.push_back(t);\n    }\n\n    if (argc > 1 && strcmp(argv[1], \"--shuffle\") == 0) {\n        cout << \"shuffle tasks randomly\" << endl;\n        shuffle(all_tasks.begin(), all_tasks.end(), g);\n    }\n    if (argc > 1 && strcmp(argv[1], \"--sort-score\") == 0) {\n        cout << \"sort by score\" << endl;\n        sort(all_tasks.begin(), all_tasks.end(), [](const auto& i, const auto& j) {\n                int score_a = global_cache.get(i.id).first;\n                int score_b = global_cache.get(j.id).first;\n                return score_a < score_b;\n            });\n    }\n    if (argc > 1 && strcmp(argv[1], \"--sort-score-reverse\") == 0) {\n        cout << \"sort by score (reverse\" << endl;\n        sort(all_tasks.begin(), all_tasks.end(), [](const auto& i, const auto& j) {\n                int score_a = global_cache.get(i.id).first;\n                int score_b = global_cache.get(j.id).first;\n                return score_a > score_b;\n            });\n    }\n    if (argc > 1 && strcmp(argv[1], \"--sort-weight\") == 0) {\n        cout << \"sort by weight\" << endl;\n        sort(all_tasks.begin(), all_tasks.end(), [](const auto& i, const auto& j) {\n                return (weight(i) < weight(j));\n            });\n    }\n\n    cout << \"solve SAT\" << endl;\n    {\n        boost::asio::thread_pool pool(std::thread::hardware_concurrency());\n\n        for (const auto& t : all_tasks) {\n            if (global_cache.get(t.id).first == N) continue;\n\n            boost::asio::post(pool, [t]() {\n                    solve_sat(t);\n                    }\n                    );\n        }\n        thread stats([all_tasks]() {print_stats(all_tasks); } );\n        pool.join();\n        is_stopped = true;\n        stats.join();\n    }\n\n\n    cout << \"solve fast\" << endl;\n    {\n        is_stopped = false;\n        boost::asio::thread_pool pool(std::thread::hardware_concurrency());\n\n        for (const auto& t : all_tasks) {\n            if (global_cache.get(t.id).first == N) continue;\n\n            boost::asio::post(pool, [t]() {\n                    solve_fast(t);\n                    }\n                    );\n        }\n        thread stats([all_tasks]() {print_stats(all_tasks); } );\n        pool.join();\n        is_stopped = true;\n        stats.join();\n    }\n    while (!is_timeouted) {\n        cout << \"solve slow\" << endl;\n        sort(all_tasks.begin(), all_tasks.end(), [](const auto& i, const auto& j) {\n                return (weight(i) > weight(j));\n                });\n\n\n        is_stopped = false;\n        boost::asio::thread_pool pool(std::thread::hardware_concurrency());\n\n        for (const auto& t : all_tasks) {\n            if (global_cache.get(t.id).first == N) continue;\n\n            boost::asio::post(pool, [t]() {\n                    solve_slower(t);\n                    }\n                    );\n        }\n        thread stats([all_tasks]() {print_stats(all_tasks); } );\n        pool.join();\n        is_stopped = true;\n        stats.join();\n    }\n}","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"!apt-get install libboost-all-dev -y\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# kissat @ data\nif KAGGLE:\n    pass\n    #!g++ -o main-RT main-RT.cpp -std=c++17 -g -O3 -lpthread -Wall -Wextra -march=native -funroll-loops -fno-omit-frame-pointer /kaggle/input/kissat-binary/libkissat.a /kaggle/input/kissat-binary/handle.o\nelse:\n    !g++ -o main-RT main-RT.cpp -std=c++17 -g -O3 -lpthread -Wall -Wextra -march=native -funroll-loops -fno-omit-frame-pointer kissat/build/libkissat.a kissat/build/handle.o","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"%%writefile dump.cpp\n\n#include <iostream>\n#include <vector>\n#include <string>\n#include <map>\n#include <fstream>\n\nusing namespace std;\n\nint N = 625;\n\nint main() {\n    map<string, pair<int, string>> cache;\n    {\n        ifstream cache_file(\"processed/cache\");\n        string id;\n        int score;\n        string field;\n        while (cache_file >> id >> score >> field) {\n\n            auto it = cache[id];\n            if (it.first < score) {\n                cache[id] = {score, field};\n            }\n        }\n    }\n\n    string time_suffix = to_string(time(nullptr));\n    ofstream dump_file(\"processed/dump-\" + time_suffix + \".csv\");\n    ofstream shrink_cache(\"processed/shrink-cache-\" + time_suffix);\n    dump_file << \"id\";\n    for (int i = 0; i < N; ++i) {\n        dump_file << \",start_\" << i;\n    }\n    dump_file << '\\n';\n    for (auto i : cache) {\n        dump_file << i.first << \",\" << i.second.second << '\\n';\n        shrink_cache << i.first << ' ' << i.second.first << ' ' << i.second.second << '\\n';\n    }\n}","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"!g++ -o dump dump.cpp -std=c++17 -g -O3 ","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"%%time\n\n\nimport os\nimport subprocess\n\nsrc_bin = '/kaggle/input/conwaysdata/main-realtime-v9'\ndst_bin = '/kaggle/working/main-RT'\n\nos.system(\"cp \" + src_bin + \" \" + dst_bin)\nos.system(\"cp /kaggle/input/conways-reverse-game-of-life-2020/test.csv /kaggle/working/test.csv\")\nos.system(\"rm -rf /kaggle/working/processed\")\nos.system(\"mkdir /kaggle/working/processed\")\nos.system(\"chmod +x \" + dst_bin)\n# cmd = [dst_bin, '--timeout', '31500'] # 8:45\ncmd = [dst_bin, '--timeout', str(TIMEOUT)]\n#cmd = [dst_bin, '--timeout', '600'] # (8:30 / 50) Hours\np = subprocess.Popen(cmd, stdout=subprocess.PIPE,\n                          stderr=subprocess.PIPE,\n                          stdin=subprocess.PIPE)\nout, err = p.communicate()\nprint(err.decode('ascii'))\nprint(out.decode('ascii'))\n","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"df4fc13b-a368-44b8-bb95-551f2dfb1d26","_cell_guid":"6e90dee5-6344-44e6-973a-71746312f6cc","trusted":true},"cell_type":"code","source":"%%time\n\nos.system(\"mv /kaggle/working/processed/cache-real-time /kaggle/working/processed/cache\")\nos.system(\"cp /kaggle/input/conwaysdata/dumper-static /kaggle/working/dumper\")\nos.system(\"chmod +x dumper\")\nos.system(\"./dumper\")\nos.system(\"cp $(ls processed/*.csv | tail -n 1) submission.csv\")\n\nimport os\nfor dirname, _, filenames in os.walk('/kaggle/working'):\n    for filename in filenames:\n        print(os.path.join(dirname, filename))","execution_count":null,"outputs":[]}],"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"}},"nbformat":4,"nbformat_minor":4}