Problem 225900 · easy · Level 02 Linear Data Structures

A Test Set That Stays Put

train/test split · deterministic rules · hashing · modular arithmetic

A clinic adds new patient records to its dataset every week. If the data were reshuffled and split again each week, records that were test examples last week could become training examples this week, and the test set would slowly leak into training. Instead every record decides its side by its own id, a whole number:

  • compute bucket = (id * 2654435761) % 2**32 % 100, a number from 0 to 99 that looks random but is always the same for the same id;
  • the record goes to the test set if bucket < test_pct, otherwise to the training set.

Write stable_split(ids, test_pct) that returns a tuple (train_ids, test_ids), two lists that keep the order of ids. An id can appear more than once (several visits of one patient); every copy follows the same rule, so they all land on the same side.

Examples

Input:  ids = [1, 2, 3, 4, 5, 6, 7, 8], test_pct = 30
Output: ([1, 3, 4, 6, 7], [2, 5, 8])
Explanation: the buckets are 61, 26, 87, 52, 17, 78, 43 and 4; ids 2, 5 and 8 have buckets below 30.
Adding ids 9 and 10 next week (buckets 69 and 34) sends both to training
and moves nobody else.

Input:  ids = [104, 7, 104, 12], test_pct = 50
Output: ([12], [104, 7, 104])

Constraints

  • 0 <= len(ids) <= 10**5, 0 <= id <= 10**12
  • 0 <= test_pct <= 100

Goals

  • Split a dataset into training and test examples with a fixed rule
  • Make every example's side depend only on its own id
  • See why such a split keeps old test examples in the test set when new data arrives
Starting Python…