Checklist IOAI Indonesia 2026 National Training Camp 1 – Simulation 2 · 2.3 task
Missing Token
Indonesian title: Missing 👽 Token
Predict the original position of a known missing token in sequences of an invented alien language.
The task
A fictional transmission uses an 'alphabet' of 30 phonetic symbols (for example zyr, plorg, vexn); messages have 7–20 tokens and follow an unknown ordering rule. In every damaged message exactly one token is missing; its identity is known but its position is not.
The training set has 1,500 rows (the true position label, the missing token and the incomplete sequence x0…x19 padded with <PAD>); the test set has 500 rows. The baseline predicts the middle position. Statement by Rifki Afina Putri.
Abridged and translated by SOTA from the official Indonesian materials. The official statement has the exact rules, and it wins wherever this summary differs.
In English
This task was published in Indonesian. SOTA translated its 3 files into English on 17 September 2026. Only the words changed in the notebooks: markdown, code comments, messages and printed output. The code, file names and paths are the original's, so a translated notebook runs with the original data.
- Task notebook Indonesian original of Task notebook
- Competition overview Indonesian original of Competition overview
- Data description Indonesian original of Data description
Read the task notebook in English
Missing 👽 Token
By: Rifki Afina Putri
🕵️♂️ Predict Where The Lost Token Belongs
The Arecibo-II Observatory in lunar orbit has just received a repeated transmission from a civilisation in the Kepler-442 star system, about 1,200 light years from Earth. After analysis, the research team managed to establish that the transmission is made up of 30 unique phonetic symbols, an alien "alphabet" with tokens such as zyr, plorg, vexn, kri and groxx.
Each message from Kepler-442 is a sequence of symbols 7–20 tokens long. The research team is confident that the order of these tokens is not random: there is some rule that governs how the symbols are arranged, similar to a grammar or to the ordinal rules of numbers.
The problem is that the transceiver on Arecibo-II has broken down:
- In each message, exactly one token is missing
- The identity of the missing token is still known
- But its position in the original sequence is not known
The research team has already rescued 1,500 complete messages from an old archive (from before the transceiver broke down), which you can use to learn the patterns of the alien language. Then there are 500 new, damaged messages waiting to be reconstructed. For each of these damaged messages, you know:
- The remaining sequence of symbols (the incomplete sequence, with one token already removed)
- The identity of the missing token
Your task: build a system that predicts the original position of the missing token in each damaged message.
🗂️ Data Format
train.csv — 1,500 rows
label: the original position of the missing token (0 toL, whereL= the length of the incomplete sequence)missing_unit: string, the missing alien tokenx0, x1, …, x19: the incomplete sequence, padded with the string<PAD>

(Labels in the figure: baris = row; posisi token = token position.)
test.csv — 500 rows (without the label column)
- The same columns, except that
labelis absent.
sample_submission.csv
id,label
0,0
1,0
…
📤 Submission Format
A file named submission.csv containing 500 rows:
id,label
0,3
1,0
2,7
…
id matches the row order in test.csv (0-indexed).
📊 Metric
Mean Absolute Error (MAE) on the test set.
1
Setup & Load Data
!pip install gdown
import os, sys, numpy as np, pandas as pd, random
import gdown
from pathlib import Path
np.random.seed(42)
random.seed(42)
train_filename = "train.csv"
test_filename = "test.csv"
sample_filename = "sample_submission.csv"
gdown.download(f"https://drive.google.com/uc?id=1mUXixgltNumMyiATk1unV6yTUJetk2NA", train_filename, quiet=False)
gdown.download(f"https://drive.google.com/uc?id=1KkKisDZKBA2aQXffopzprAqWaCyrqjAo", test_filename, quiet=False)
gdown.download(f"https://drive.google.com/uc?id=1PIBWDOUFE3NtVMyViclj93-8_ChJIrqE", sample_filename, quiet=False)
# alternative links
# gdown.download(f"https://drive.google.com/uc?id=1GMEqfXZL1jSBv7xjFW0ZjsYCrv2rsGEl", train_filename, quiet=False)
# gdown.download(f"https://drive.google.com/uc?id=1NQbEVCEXVk4bDRhU-j9Errhv2ZWA3FBs", test_filename, quiet=False)
# gdown.download(f"https://drive.google.com/uc?id=1ig5p_Dxn7g6sn1elW1WPuYFJOmhM2LMA", sample_filename, quiet=False)
train_df = pd.read_csv(train_filename)
test_df = pd.read_csv(test_filename)
sample = pd.read_csv(sample_filename)
print("\ntrain:", train_df.shape, "| test:", test_df.shape)
train_df.head()
Data Exploration
You may edit this if there are other aspects of the data you want to analyse.
PAD = "<PAD>"
SEQ_COLS = [f"x{i}" for i in range(20)]
def clean_seq(row):
return [row[c] for c in SEQ_COLS if row[c] != PAD]
# Basic stats
lengths = train_df.apply(lambda r: len(clean_seq(r)), axis=1)
print("Sequence length (incomplete) — min:", lengths.min(),
"max:", lengths.max(), "mean:", round(lengths.mean(), 1))
Baseline: Predict the Middle
The most naive way to guess the position of the missing token: assume that every missing token's position is in the middle.
def predict_middle(row):
L = len(clean_seq(row))
return L // 2
from sklearn.model_selection import train_test_split
from sklearn.metrics import mean_absolute_error # <-- Changed to MAE
# Split train -> train_local / val_local
train_local, val_local = train_test_split(
train_df, test_size=0.2, random_state=42, shuffle=True
)
train_local = train_local.reset_index(drop=True)
val_local = val_local.reset_index(drop=True)
print(f"train_local: {len(train_local)} rows | val_local: {len(val_local)} rows")
def evaluate(predict_fn, df=None):
"""
Run predict_fn on val_local (or on the df you pass in) and print the MAE.
predict_fn : callable(row) -> int
A function that takes one DataFrame row and returns the predicted position.
df : DataFrame, optional
Default: val_local. Must have a `label` column.
"""
if df is None:
df = val_local
preds = df.apply(predict_fn, axis=1).values
y = df["label"].values
mae = mean_absolute_error(y, preds)
print(f"MAE: {mae:.4f} on {len(df)} samples")
return mae
# Quick sanity check: middle baseline on val_local
print("\n--- Sanity check: middle baseline ---")
_ = evaluate(predict_middle)
# Generate predictions for test set
test_preds = test_df.apply(predict_middle, axis=1)
# Create submission DataFrame
submission = pd.DataFrame({
"id": np.arange(len(test_df)),
"label": test_preds
})
# Save to CSV
submission.to_csv("baseline_submission.csv", index=False)
print("Saved baseline_submission.csv")
print(submission.head())
Solution
Implement your solution here.
Translated by SOTA. The Indonesian original is the official version and wins wherever the two differ. The example figure in the notebook keeps its Indonesian labels (baris = row, posisi token = token position); a caption glosses them. If you organise this olympiad and would like the translation removed, email [email protected] and we will take it down.
At a glance
- You get
train.csv(label,missing_unit, x0–x19),test.csv,sample_submission.csv(Google Drive).- You submit
submission.csvwith 500 rows: id, label.- Scoring
- Mean Absolute Error between predicted and true positions.
- Rules
- Individual participation.
- Format
- Pelatnas 1 IOAI 2026 (first national training-and-selection camp), Simulation 2 on Kaggle; competition window 17 April 2026 15:35 UTC – 18 April 2026 07:30 UTC; individual; up to 50 submissions per day.