Skip to content

Fix #208: seed problem 59 interactor from a per-test secret - #209

Closed
Kingpython123 wants to merge 1 commit into
FrontierCS:mainfrom
Kingpython123:fix-208-problem59-seed
Closed

Kingpython123 wants to merge 1 commit into
FrontierCS:mainfrom
Kingpython123:fix-208-problem59-seed

Conversation

@Kingpython123

Copy link
Copy Markdown

algorithmic/problems/59/interactor.cpp is non-adaptive but built its hidden array with testlib's rnd at the fixed default seed (3905348978240129619) and never reseeded it (registerInteraction does not seed rnd). The .ans files were empty and unused, so the array was a deterministic function of n, identical across every test with the same n. A submission that replays the same rnd stream reconstructs the array and answers with zero comparison queries, scoring 100 on every test (same class as #202–#205).

Fix

Read a per-test secret seed from the hidden answer file and rnd.setSeed() before generating the array:

int n = inf.readInt(1, 30000, "n");
rnd.setSeed(ans.readLong());   // per-test secret; the contestant only ever receives n
cout << n << endl;

This follows the repo's other non-adaptive interactors, which take their hidden data from the answer file (for example problems 2, 89, 124, 135). The contestant still receives only n, so the array is no longer predictable from a fixed seed. Each public testdata/*.ans now holds a distinct seed.

Note for maintainers: the private test set for this problem needs the same one-integer seed added to each of its answer files, since the interactor now reads it.

Reproduction

A standalone program (no testlib) that replays the default stream and makes no query:

#include <bits/stdc++.h>
using namespace std;
struct Rnd {
    unsigned long long seed = 3905348978240129619ULL;
    static const unsigned long long MUL=0x5DEECE66DULL, ADD=0xBULL, MASK=(1ULL<<48)-1;
    static const long long LLMAX=9223372036854775807LL;
    long long nextBits(int bits){
        if(bits<=48){ seed=(seed*MUL+ADD)&MASK; return (long long)(seed>>(48-bits)); }
        return (nextBits(31)<<32) ^ nextBits(32);   // version=-1 -> lowerBitCount=32
    }
    long long next(long long n){ long long lim=LLMAX/n*n,b; do{b=nextBits(63);}while(b>=lim); return b%n; }
    int next(int from,int to){ return (int)(next((long long)to-from+1)+from); }
} rnd;
int main(){ int n; if(!(cin>>n))return 0; vector<int> a(n); iota(a.begin(),a.end(),1);
    for(int i=0;i<n;i++){ int j=rnd.next(i,min(n-1,i+2)); swap(a[i],a[j]); }
    cout<<"!"; for(int v:a) cout<<' '<<v; cout<<endl; }

Piping it through the interactor (g++ 11.4, -O2 -std=gnu++17):

before fix: every test -> "Correct! Queries = 0 ... Ratio: 1.000000000000"  (full score, no queries)
after  fix: the same zero-query replay -> "wrong answer Wrong final array"  on every test with n >= 2

Tests

algorithmic/tests/test_problem59.py reconstructs the array the interactor will use from each committed secret seed and feeds it back with no queries. The array from the committed seed is accepted (Ratio: 1.0); the array from the old default seed is rejected on every test with n >= 2. All 19 checks pass with this change (one n = 1 case is skipped, since a length-1 array is unique); on main the accept checks fail because the interactor ignores the seed.

Fixes #208.

The problem 59 interactor is non-adaptive but built its hidden array with
testlib's rng at the fixed default seed and never reseeded, so the array was a
deterministic function of n. A program replaying that stream reconstructed the
array and answered with zero comparison queries, scoring 100 on every test.

Read a per-test secret seed from the hidden answer file and setSeed() the rng
before generating the array, as the other non-adaptive interactors in this repo
take their hidden data from the answer file. The contestant still receives only
n, so the array is no longer predictable. Each public testdata answer file gets
a distinct seed; private test answer files need one integer seed added too.

Add algorithmic/tests/test_problem59.py as a regression test.
@Kingpython123

Copy link
Copy Markdown
Author

Thanks for the quick fix! This is superseded by #211, which landed the fix for #208, so I'm closing this PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Problem 59 interactor is non-adaptive with a fixed RNG seed, so a zero-query program scores 100

1 participant