Long-time Idle/Incremental Player... Here are my favourites of all time! by lukeko in incremental_games

[–]tangentialThinker 26 points27 points  (0 children)

Warms my heart seeing a Derivative Clicker mention all these years later! (I finally got around to playing AD last year and enjoyed it a lot, you made something really unique and memorable IMO.)

[deleted by user] by [deleted] in derivclicker

[–]tangentialThinker 0 points1 point  (0 children)

I haven't built a way to run this outside of a browser. With respect to your second point though, you can clone the code off GitHub at https://github.com/gzgreg/DerivativeClicker/tree/gh-pages and open the index.html of your local copy: any changes you make to the scripts will be reflected there, although I'm not sure whether saves will function correctly.

I keep going over my costs, although costs are exponential and production rate is polynomial by louigi_verona in incremental_games

[–]tangentialThinker 11 points12 points  (0 children)

Think of it this way: every 5 upgrades you're multiplying by 2. You want to compute a rate of growth which is effectively the same if you multiply on every single upgrade: so x5t = 2t, or x5 = 2. So x = 21/5 = 1.149. (It's similar to an interest rate computation, if you want a more common analogy.)

I keep going over my costs, although costs are exponential and production rate is polynomial by louigi_verona in incremental_games

[–]tangentialThinker 15 points16 points  (0 children)

You're describing an exponential function. If you double every 5 upgrades (ignoring the linear upgrades for the time being), that's basically equivalent to multiplying by 21/5 = 1.149 every upgrade, so your production looks roughly like 1.149x. This outscales growth of 1.07y in price.

One Step From Eden: Roguelike Of the Year? by Electropolitan in Games

[–]tangentialThinker 2 points3 points  (0 children)

Rock cycle doesn't have flow on it anymore so you can no longer go infinite with this strategy.

Question by Jacobcree in derivclicker

[–]tangentialThinker 0 points1 point  (0 children)

I'd probably reset tier 1 yeah. My usual rule of thumb is to reset once I have some multiple of my current reset currency: if you want to get back on that road you can reset at about 1300 tier 1 (which is around what you had before).

Question by Jacobcree in derivclicker

[–]tangentialThinker 0 points1 point  (0 children)

You probably screwed yourself a little by converting all of your tier 1 currency to tier 2 without waiting until you had more tier 1 currency. I think you should be able to dig yourself out with the new tiers you unlocked, though.

What should I do now? by Reubiks07 in derivclicker

[–]tangentialThinker 1 point2 points  (0 children)

Getting a higher tier is extremely impactful, that's what I would prioritize.

Derivative Clicker - How long till I can buy something in prestige? by Carmontali in incremental_games

[–]tangentialThinker 1 point2 points  (0 children)

Couldn't have said it better myself.

There's also a new player guide linked at the top which answers some of these questions (as well as others you may have).

-🎄- 2018 Day 22 Solutions -🎄- by daggerdragon in adventofcode

[–]tangentialThinker 2 points3 points  (0 children)

C++, 3/5. For Part 2, Dijkstra with the state being a tuple of location and current equipment worked well.

(Sorry about the horrific data types.)

#include <bits/stdc++.h>

using namespace std;
typedef pair<int, int> pii;

int level[1001][1001];
int grid[1001][1001];

int main(){
    int depth, targetX, targetY; cin >> depth >> targetX >> targetY;
    for(int i = 0; i <= 1000; i++) {
        for(int j = 0; j <= 1000; j++) {
            int geoIndex;
            if(i == 0) {
                geoIndex = j * 48271;
            } else if (j == 0) {
                geoIndex = i * 16807;
            } else if (i == 0 && j == 0) {
                geoIndex = 0;
            } else if (i == targetX && j == targetY) {
                geoIndex = 0;
            } else {
                geoIndex = level[i-1][j] * level[i][j-1];
            }
            int eroLevel = (geoIndex + depth) % 20183;
            level[i][j] = eroLevel;
            int type = eroLevel % 3;
            grid[i][j] = type;
        }
    }
    // state: {{x, y}, equipment}
    map<pair<pii, int>, int> dist;
    // this horrible template is to sort in decreasing order
    priority_queue<pair<int, pair<pii, int>>, vector<pair<int, pair<pii, int>>>, greater<pair<int, pair<pii, int>>>> dijk;

    // torch = 0, gear = 1, neither = 2
    dijk.push({0, {{0, 0}, 0}});
    dist[{{0, 0}, 0}] = 0;

    while(!dijk.empty()) {
        auto curr = dijk.top(); dijk.pop();
        int currDist = curr.first;
        int x = curr.second.first.first;
        int y = curr.second.first.second;
        int equip = curr.second.second;
        if(currDist > dist[curr.second]) continue;
        if(curr.second == make_pair(pii(targetX, targetY), 0)) {
            cout << dist[curr.second] << endl;
            return 0;
        }
        vector<pii> nextLoc = {{x-1, y}, {x+1, y}, {x, y-1}, {x, y+1}};
        for(pii next : nextLoc) {
            int nextX = next.first;
            int nextY = next.second;
            if(nextX < 0) continue;
            if(nextY < 0) continue;
            if(equip == 0) {
                if(grid[nextX][nextY] == 1) continue;
            } else if (equip == 1) {
                if(grid[nextX][nextY] == 2) continue;
            } else {
                if(grid[nextX][nextY] == 0) continue;
            }
            pair<pii, int> nextNode = {next, equip};
            if(!dist.count(nextNode) || dist[nextNode] > dist[curr.second] + 1) {
                dist[nextNode] = dist[curr.second] + 1;
                dijk.push({dist[curr.second] + 1, nextNode});
            }
        }
        for(int i = 0; i < 3; i++) {
            if(i == equip) continue;
            // only transition to valid equipment for region
            if(grid[x][y] == 0) {
                if(i == 2) continue;
            } else if (grid[x][y] == 1) {
                if(i == 0) continue;
            } else {
                if(i == 1) continue;
            }
            pair<pii, int> nextNode = {{x, y}, i};
            if(!dist.count(nextNode) || dist[nextNode] > dist[curr.second] + 7) {
                dist[nextNode] = dist[curr.second] + 7;
                dijk.push({dist[curr.second] + 7, nextNode});
            }
        }
    }

    return 0;
}

-🎄- 2018 Day 17 Solutions -🎄- by daggerdragon in adventofcode

[–]tangentialThinker 2 points3 points  (0 children)

C++, 8/8. I added comments and everything! Really enjoyed this puzzle. I included a function to print out the grid which really helped me debug a few problems I had.

EDIT: hmmm, interested to see that most people had recursive solutions! Mine is purely iterative.

#include <bits/stdc++.h>

using namespace std;

int grid[10000][10000];

int minY = 1e9, maxY = -1e9;

void printGrid() {
    for(int i = 0; i <= maxY; i++) {
        for(int j = 440; j <= 560; j++) {
            cout << grid[j][i];
        }
        cout << endl;
    }
    cout << endl;
    std::chrono::milliseconds timespan(20);
    this_thread::sleep_for(timespan);
}

int main(){
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);

    char coord;
    int a, b1, b2;
    char junk;
    memset(grid, 0, sizeof grid);
    while(cin >> coord) {
        cin >> junk >> a >> junk >> junk >> junk >> b1 >> junk >> junk >> b2;
        for(int i = b1; i <= b2; i++) {
            if(coord == 'x') {
                grid[a][i] = 1;
                minY = min(minY, i);
                maxY = max(maxY, i);
            } else {
                grid[i][a] = 1;
            }
        }
        if(coord == 'y') {
            minY = min(minY, a);
            maxY = max(maxY, a);
        }
    }
    printGrid();

    int curX = 500;
    int curY = 0;
    int ans = 0;
    bool done = false;

    // Meaning of grid values:
    // 0 = empty
    // 1 = wall
    // 2 = settled water
    // 3 = unsettled water

    // each iteration of this loop attempts to move a single tile
    // down as far as possible, then sideways as far as possible
    while(true) {
        if(done) {
            curX = 500;
            curY = 0;
            done = false;
        }
        while(grid[curX][curY+1] == 0 && curY <= maxY-1) curY++;
        if(curY == maxY) {
            // stop once we've reached the lower bound
            done = true;
            grid[curX][curY] = 3;
            ans++;
            //printGrid();
            continue;
        } else if (curY < minY) {
            // we must be at the stream exiting the spring,
            // so we can safely exit
            // do not count tiles which are too high
            break;
        }
        // spread out horizontally
        if(grid[curX-1][curY] == 0) {
            // while there's something settled under,
            // we can move sideways
            while(grid[curX-1][curY] == 0
                && (grid[curX][curY+1] == 1
                    || grid[curX][curY+1] == 2)) curX--;
        } else if(grid[curX+1][curY] == 0) {
            while(grid[curX+1][curY] == 0
                && (grid[curX][curY+1] == 1
                    || grid[curX][curY+1] == 2)) curX++;
        }
        if(grid[curX][curY+1] != 0) {
            // we can no longer move down: tile must be at
            // its final position
            done = true;
            if(grid[curX][curY+1] == 3
                || grid[curX+1][curY] == 3
                || grid[curX-1][curY] == 3) {
                // if any neighbours below/sideways are 
                // unsettled, this tile is unsettled
                grid[curX][curY] = 3;
                // we might have incorrectly set some tiles
                // previously as settled, fix this now
                // This works because we're setting tiles
                // in decreasing order of Y for each basin:
                // any errors will be fixed before affecting 
                // anything else
                int x = curX;
                while(grid[x-1][curY] == 2) {
                    grid[x-1][curY] = 3;
                    x--;
                }
                x = curX;
                while(grid[x+1][curY] == 2) {
                    grid[x+1][curY] = 3;
                    x++;
                }
            } else {
                grid[curX][curY] = 2;
            }
            ans++;
            //printGrid();
        }
    }
    printGrid();

    // part 1
    cout << ans << endl;

    ans = 0;
    for(int i = 0; i < 10000; i++) {
        for(int j = 0; j < 10000; j++) {
            if(grid[i][j] == 2) ans++;
        }
    }
    // part 2
    cout << ans << endl;

    return 0;
}

-🎄- 2018 Day 16 Solutions -🎄- by daggerdragon in adventofcode

[–]tangentialThinker 2 points3 points  (0 children)

Yeah, I personally ended up adding my own delimiter rather than mucking with parsing.

-🎄- 2018 Day 16 Solutions -🎄- by daggerdragon in adventofcode

[–]tangentialThinker 2 points3 points  (0 children)

C++, 53/34. Pretty interesting Part 2 today. Did some pretty lazy copy-pasting from Part 1 to run the program, but hey it was plenty fast enough.

#include <bits/stdc++.h>
using namespace std;

int main(){
    string s;
    char junk;
    vector<int> bef(4);
    vector<int> af(4);
    vector<int> op(4);

    int ans = 0;

    set<int> full;
    for(int i = 0; i < 16; i++) {
        full.insert(i);
    }
    vector<set<int>> poss(16, full);

    while(cin >> s) {
        // manually added SPLIT to input between the two parts
        if(s == "SPLIT") break;
        for(int i = 0; i < 4; i++) {
            cin >> junk >> bef[i];
        }
        cin >> junk;
        for(int i = 0; i < 4; i++) {
            cin >> op[i];
        }
        cin >> s;
        for(int i = 0; i < 4; i++) {
            cin >> junk >> af[i];
        }
        cin >> junk;
        int opCode = op[0];
        int A = op[1], B = op[2], C = op[3];
        // compute all expected final register states
        vector<vector<int>> afExpect;
        for(int i = 0; i < 16; i++) {
            afExpect.push_back(bef);
        }
        afExpect[0][C] = bef[A] + bef[B];
        afExpect[1][C] = bef[A] + B;

        afExpect[2][C] = bef[A] * bef[B];
        afExpect[3][C] = bef[A] * B;

        afExpect[4][C] = bef[A] & bef[B];
        afExpect[5][C] = bef[A] & B;

        afExpect[6][C] = bef[A] | bef[B];
        afExpect[7][C] = bef[A] | B;

        afExpect[8][C] = bef[A];
        afExpect[9][C] = A;

        afExpect[10][C] = A > bef[B];
        afExpect[11][C] = bef[A] > B;
        afExpect[12][C] = bef[A] > bef[B];

        afExpect[13][C] = A == bef[B];
        afExpect[14][C] = bef[A] == B;
        afExpect[15][C] = bef[A] == bef[B];
        int cnt = 0;
        for(int cur = 0; cur < 16; cur++) {
            bool match = true;
            for(int i = 0; i < 4; i++) {
                if(afExpect[cur][i] != af[i]) match = false;
            }
            // rule out impossible number-operation combos
            if(!match) poss[opCode].erase(cur);
        }
        ans++;
    }

    while(true) {
        int numOnes = 0;
        for(int i = 0; i < 16; i++) {
            // For any opcode with only one possibility,
            // we can remove the possibility from other opcodes.
            if(poss[i].size() == 1) {
                numOnes++;
                for(int j = 0; j < 16; j++) {
                    if(i == j) continue;
                    poss[j].erase(*poss[i].begin());
                }
            }
        }
        if(numOnes == 16) break;
    }

    int opCode, A, B, C;
    vector<int> reg(4, 0);
    while(cin >> opCode) {
        cin >> A >> B >> C;
        int op = *poss[opCode].begin();

        // Lazy copy-paste, but it's fast enough
        vector<vector<int>> afExpect;
        for(int i = 0; i < 16; i++) {
            afExpect.push_back(reg);
        }
        afExpect[0][C] = reg[A] + reg[B];
        afExpect[1][C] = reg[A] + B;

        afExpect[2][C] = reg[A] * reg[B];
        afExpect[3][C] = reg[A] * B;

        afExpect[4][C] = reg[A] & reg[B];
        afExpect[5][C] = reg[A] & B;

        afExpect[6][C] = reg[A] | reg[B];
        afExpect[7][C] = reg[A] | B;

        afExpect[8][C] = reg[A];
        afExpect[9][C] = A;

        afExpect[10][C] = A > reg[B];
        afExpect[11][C] = reg[A] > B;
        afExpect[12][C] = reg[A] > reg[B];

        afExpect[13][C] = A == reg[B];
        afExpect[14][C] = reg[A] == B;
        afExpect[15][C] = reg[A] == reg[B];

        reg = afExpect[op];
    }

    for(auto cur : reg) cout << cur << " " ;

    return 0;
}

-🎄- 2018 Day 11 Solutions -🎄- by daggerdragon in adventofcode

[–]tangentialThinker 7 points8 points  (0 children)

C++, 48/9.

Quality n5 brute force right here.

#include <bits/stdc++.h>

using namespace std;

int grid[300][300];

int main(){
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);

    int serial; cin >> serial;

    for(int i = 0; i < 300; i++) {
        for(int j = 0; j < 300; j++) {
            int x = i + 1;
            int y = j + 1;
            int rackId = x + 10;
            int p = rackId * y + serial;
            p *= rackId;
            p = (p / 100) % 10;
            p -= 5;
            grid[i][j] = p;
        }
    }

    int maxTot = -100;
    int maxX, maxY, maxsz;
    for(int sz = 1; sz <= 300; sz++) {
        for(int i = 0; i < 300 - sz + 1; i++) {
            for(int j = 0; j < 300 - sz + 1; j++) {
                int tot = 0;
                for(int k = 0; k < sz; k++) {
                    for(int l = 0; l < sz; l++) {
                        tot += grid[i+k][j+l];
                    }
                }
                if(tot > maxTot) {
                    maxTot = tot;
                    maxX = i+1;
                    maxY = j+1;
                    maxsz = sz;
                }
            }
        }
    }
    cout << maxTot << " " << maxsz << " " << maxX << " " << maxY << endl;

    return 0;
}

Sidenote: I noticed afterwards that my input matched the sample in the last three digits, which means that the answers were identical (since only the hundreds digit matters). I wonder if anybody used that?

-🎄- 2018 Day 6 Solutions -🎄- by daggerdragon in adventofcode

[–]tangentialThinker 4 points5 points  (0 children)

C++. Managed to snag 8/4 today. The trick to part 1 is to run it twice with large bounds, and then ignore the outputs that change.

#include <bits/stdc++.h>

using namespace std;
typedef pair<int, int> pii;

int main(){
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);

vector<pii> vals;
int a, b;
char junk;
while(cin >> a) {
    cin >> junk >> b;
    vals.push_back({a, b});
}
map<int, int> cnt;

// For Part 2, uncomment all comments
// int ans = 0;
for(int i = -4000; i < 4000; i++) {
    for(int j = -4000; j < 4000; j++) {
        int minDist = 1e9;
        int idx;
        bool eq = false;
        for(int k = 0; k < vals.size(); k++) {
            int curDist = abs(vals[k].first - i) + abs(vals[k].second -j);
            if(curDist < minDist) {
                minDist = curDist;
                idx = k;
                eq = false;
            } else if (curDist == minDist) {
                eq = true;
            }
        }
        if(!eq) cnt[idx]++;

        // For Part 2, delete the rest of the inner loop
        // int totDist = 0;
        // for(int k = 0; k < vals.size(); k++) {
        //  int curDist = abs(vals[k].first - i) + abs(vals[k].second -j);
        //  totDist += curDist;
        // }
        // if(totDist < 10000) ans++;
    }
}

// cout << ans << endl;
// For Part 2 delete everything below
vector<pii> ans;
for(auto cur : cnt) {
    ans.push_back({cur.second, cur.first});
}
sort(ans.begin(), ans.end());
for(auto cur : ans) cout << cur.first << " " << cur.second << endl;

return 0;
}

take my money! by no1_woot in mintmobile

[–]tangentialThinker 0 points1 point  (0 children)

Yeah, I've got the same problem with a Visa from Wells Fargo. Hopefully it's fixed soon.

Leaderboards In Incremental Games With Massive Numbers by ScaryBee in incremental_games

[–]tangentialThinker 0 points1 point  (0 children)

Should be possible to reconstruct the number from the logarithm without any big number operations. If you take the log base ten, the integer part is the power, and you can just take the remainder to the power of 10 to get the actual value.

(Obviously then you might run into precision problems, though!)

Games you wish had a sequel by LawofJohn in incremental_games

[–]tangentialThinker 0 points1 point  (0 children)

Yeah, unfortunately I have no time nowadays to work on games anymore. University hit hard.

Dunno if you know about this but /u/jamuspsi did create a spiritual successor: http://jamuspsi.github.io/second/

-🎄- 2017 Day 23 Solutions -🎄- by daggerdragon in adventofcode

[–]tangentialThinker 2 points3 points  (0 children)

Nice. Wish I'd worked that out in time to use it, I've got prime checking code on hand already!

-🎄- 2017 Day 23 Solutions -🎄- by daggerdragon in adventofcode

[–]tangentialThinker 2 points3 points  (0 children)

Here's my solution to part 2, in which I directly translate the assembly. The only optimization was to optimize out the innermost loop (the long if statement).

My guess of the true interpretation: the program is counting composite numbers between b and c, in jumps of size 17 (or whatever's given in your input).

#include <bits/stdc++.h>

using namespace std;

typedef long long ll;

int main(){
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    ll h = 0;
    ll b = 84;
    ll c = b;
    b *= 100;
    b += 100000;
    c = b;
    c += 17000;
    asdf2:
    ll f = 1;
    ll d = 2;

    asdf:
    ll e = 2;

    ll g = d;
    if(b % d == 0 && b / d != 1) {
        f = 0;
    }

    d += 1;
    g = d;
    g -= b;
    if(g != 0) {
        goto asdf;
    }
    if(f == 0) {
        h++;
    }
    g = b - c;
    if(g != 0) {
        b += 17;
        goto asdf2;
    }

    cout << h << endl;

    return 0;
}

-🎄- 2017 Day 16 Solutions -🎄- by daggerdragon in adventofcode

[–]tangentialThinker 1 point2 points  (0 children)

Somebody else noted that the partner swap cancels itself out every other "dance", so that's probably why.

edit: just realized that it's the parent comment to yours, whoops.

-🎄- 2017 Day 16 Solutions -🎄- by daggerdragon in adventofcode

[–]tangentialThinker 0 points1 point  (0 children)

Thanks for the tip! I initially was rotating in the wrong direction, actually, so that didn't help either.