# Humanity's Heritage

*English translation by SOTA – AI Community of the Russian original. Organisers who would like this translation removed can email sota.ai.community@gmail.com.*

All-Russian School Olympiad in Informatics 2025–2026, Final Stage<br>
“Artificial Intelligence” profile, Tour 2, Moscow, 25 March 2026<br>
Task D

## Statement

The eruption of Mount Vesuvius in 79 AD buried in ash and destroyed the city of Pompeii and many other towns, including Herculaneum, where in 1750 an ancient Roman villa with a large number of ancient papyri was discovered. The scrolls kept in its library had been carbonised and turned into fragile black cylinders. Today, scientists are striving to read them using X-ray tomography, computer reconstruction and machine learning.

When Vadim learned about this, he thought that he too would like to take part in the decipherment. On learning that scientists are already working on restoring the text inside each individual papyrus, he realised that the next step is to restore the correct order of the papyri themselves, since ancient treatises usually consisted of several parts.

Since Vadim does not know Ancient Greek, he decided to consider an analogous problem in Russian first. For this, he took a collection of poems and left some of the poems unchanged (`train_D.json`). He split each of the remaining poems (`test_D.json`) into two parts and then shuffled all the left and right parts together. Now Vadim's task is to restore the original pairs and put the poems back together.

## Input format

The following files are attached to the task:

- `model_D.zip`: weights for a large language model.
- `baseline_D.ipynb`: a notebook with a baseline solution of the task and an example of using the large language model `model_D.zip` to obtain text embeddings
- `train_D.json`: additional poems in full;
- `test_D.json`: the shuffled left and right parts of the poems;
- `submission_D.csv`: an example of the solution that must be submitted to the testing system.

## Output format

For checking, you must upload the archive `solution_D.zip`.

The archive must contain:

1. The file `submission_D.csv` with two columns:
   - `left_id`: the ID of a left half from `test_D.json`;
   - `right_id`: the ID of a right half from `test_D.json`.
2. The file `solution_D.ipynb`: a Jupyter Notebook with your solution.

You may add to the archive additional files needed for your solution to work. The archive must, however, contain exactly one file with the extension `.csv` and exactly one file with the extension `.ipynb`.

## Scoring

You can get up to 60 points for this task.

The data are split into a public and a private part. When you submit `submission_D.csv`, you are shown the result on the **public** part. After the end of the stage, the result will be recomputed on the **private** part. The public and private parts do not overlap.

After the end of the stage, your metric will be converted to a 60-point scale according to the following rule:

- the result of the **baseline solution**, with a value of Accuracy $\leq X$, is scored **0 points**;
- a result with a value of Accuracy $\geq Y$ is scored **60 points**;
- if the value of Accuracy lies between $X$ and $Y$, the number of points is computed by the linear interpolation formula:

$$\text{Score} = 60 \cdot \frac{\text{Accuracy} - X}{Y - X}.$$

The metric values $X$ and $Y$ will be available in the testing system.

The final score for the task is based on the **last** submission.

## Metric for evaluating the accuracy of the answer

This task evaluates how correctly the left and right parts of the poems are matched.

Let:

- $N$ be the total number of left parts in `test.json`;
- $K$ be the number of correctly restored pairs, that is, pairs `(left_id, right_id)` that coincide with the true correspondence.

Then the metric is computed by the formula

$$\text{Accuracy} = \frac{K}{N}.$$

In other words, the metric shows the proportion of correctly restored poems.

The value of **Accuracy** lies in the range from 0 to 1. The higher the value, the better the quality of the solution.

Example of computing **Accuracy** in `Python`:

```python
import pandas as pd

merged = true_pairs.merge(pred_pairs, on="left_id", suffixes=("_true", "_pred"))
correct = (merged["right_id_true"] == merged["right_id_pred"]).sum()
accuracy = correct / len(merged)

print("Accuracy =", accuracy)
```
