Katkat

Solve three algorithmic OA problems

DRWSoftware Engineer · Online Assessment

Last updated

This set evaluates algorithmic problem-solving skills including array manipulation and simulation for knockout tournament dynamics, graph traversal and constructive movement-sequence design on grids, and broader competencies in handling permutations, connectivity, and constraint-driven constructions.

This is an online assessment (Codility-style, 150 minutes) consisting of three independent coding problems. Solve each one separately; they do not share input or state.


Part 1 — Knockout Tournament Match Counts

There are $n$ players standing in a line, indexed $1$ to $n$. Player $i$ has a distinct skill value $a[i]$, and the values $a[1..n]$ form a permutation of the integers $1$ to $n$ (so all skills are distinct).

A series of knockout rounds is played:

  1. In each round, the surviving players are paired from left to right: positions $1$ vs $2$, $3$ vs $4$, and so on.
  2. In each pair, the player with the higher skill value wins and advances; the other is eliminated and leaves the tournament.
  3. After a round, the winners keep their relative left-to-right order and form the player sequence for the next round.
  4. Rounds continue until exactly one player (the overall champion) remains.

Define $b[1..n]$ where $b[i]$ is the total number of matches the original player $i$ participates in (until they are eliminated, or until they win the tournament).

Task: Given $n$ and the skill array $a[1..n]$, return the array $b[1..n]$.

What This Part Should Cover

  • Recognizing that match count equals the number of rounds the player remains alive (one match per round per alive player).
  • A correct round-by-round simulation (or equivalent divide-and-conquer / segment recursion) that preserves left-to-right winner ordering.
  • Complexity argument: total work across all rounds is $\sum_k n/2^k = O(n)$ comparisons plus $O(n \log n)$ for the increments — comfortably within $n \le 200{,}000$.
  • Correct handling of the champion (they play $k = \log_2 n$ matches, the maximum).

Part 2 — Robot Path Planning with Movement Instructions

You are given an $R \times C$ grid ($3 \le R, C \le 50$). Each cell is one of:

  • # — wall (cannot be entered),
  • . — empty floor (can be entered),
  • * — the robot's starting cell (also a traversable floor cell).

Guarantees: the outer border (first/last row, first/last column) is entirely walls; all floor cells form a single connected component; the robot starts on a floor cell.

You control the robot with characters ^ (up), v (down), < (left), > (right). Every move must keep the robot inside the grid and on a floor cell (. or *). You do not need to return to the start.

Construct an instruction string for each of the five variants below. For every variant the output length must be at most $100{,}000$. Any valid sequence is accepted — shortest-path optimality is not required. Assume each described shape admits such a sequence within the bound.

The variants:

  1. Subtask 1 — Rectangular border walk. All floor cells form a solid axis-aligned rectangle. The start is at the rectangle's top-left corner. Visit exactly the border (perimeter) cells, all of them, and never step on an interior floor cell.

  2. Subtask 2 — Full rectangular coverage. Floor cells form a solid rectangle; start anywhere inside; visit every floor cell at least once.

  3. Subtask 3 — Dumbbell. Two disjoint rectangles connected by a single floor cell (a 1-cell corridor); start anywhere; visit every floor cell.

  4. Subtask 4 — Simple path. The floor cells form a simple path in the orthogonal-adjacency graph (no branches, no cycles); start anywhere on it; visit every cell.

  5. Subtask 5 — Arbitrary connected shape. Any connected floor region (per the global guarantees); start anywhere; visit every floor cell.

Task (all subtasks): Output one valid instruction string of ^v<> that keeps the robot on floor cells and meets the variant's visitation requirement, with length $\le 100{,}000$. You may treat each subtask as its own test case with its own grid.

What This Part Should Cover

  • A single coverage routine (DFS Euler tour with inverse-move backtracking) handling subtasks 2–5 uniformly, plus the realization that subtask 1 needs its own perimeter walk because interior cells are forbidden.
  • A correct, explicit length argument tying $2(V-1)$ to the $100{,}000$ bound.
  • Move/inverse-move bookkeeping and a visited set so the robot never re-enters as a "new" cell and never steps onto a wall or out of bounds.
  • Handling degenerate shapes (single floor cell ⇒ empty string; a 1-wide rectangle in subtask 1 where the "perimeter" is the whole region).

Part 3 — Maximum Sum of Two Numbers Without Shared Digits

You are given an array of $n$ integers $a[1..n]$ ($1 \le n \le 200{,}000$). Assume each $a[i]$ is a non-negative integer (state a reasonable upper bound, e.g. up to $10^9$, if your method needs one).

Two numbers have no common digit if, written in base-10 without leading zeros, their digit sets are disjoint. For example $12$ and $340$ are allowed; $15$ and $51$ are not (they share 1 and 5).

Task: Choose two distinct indices $i\ne j$ such that $a[i]$ and $a[j]$ share no digit and $a[i] + a[j]$ is maximized. Output that maximum sum. If no valid pair exists, return a sentinel value (e.g. $-1$) and document it.

What This Part Should Cover

  • The 10-bit digit-mask reduction and keeping only the max value per mask ($\le 1024$ survivors) — turning a quadratic-in-$n$ search into one over a constant 1024-mask space.
  • A correct disjointness test (mask1 & mask2 == 0) and a correct argument that the distinct-index constraint is satisfied automatically.
  • Either the $O(1024^2)$ mask-pair scan or the $O(10 \cdot 2^{10})$ SOS/complement approach, with overall complexity $O(n \log(\max a) + 2^{10} \cdot 10)$.
  • Defined, documented behavior when no compatible pair exists.

Hints

Hint 1

Reframe the structure: Because $n = 2^k$, the bracket is a perfect binary tree of depth $k$. A player who survives to round $r$ (1-indexed) has played exactly $r$ matches; they get one more match each round until they lose.

Hint 2

A clean way to count: You do not need to know *who* wins each round to count matches — every still-alive player plays exactly one match per round. So $b[i] = (\text{number of rounds player } i \text{ survives into})$. Simulate round by round: increment $b$ for every alive player, then keep the per-pair winner. This is $O(n \log n)$ total work, since the alive set halves each round.

Hint 3

One algorithm covers most of it: Variants 2–5 all ask for *full coverage* of an arbitrary (or special-case) connected region. A single technique solves all of them: a DFS over the floor cells, emitting the move character when you step into a new cell and the inverse move (`^`↔`v`, `<`↔`>`) when you backtrack. This produces an Euler tour of a spanning tree.

Hint 4

Why the length bound is safe: A DFS-backtracking walk traverses each spanning-tree edge exactly twice, so its length is $2 \cdot (V-1)$ where $V$ is the number of floor cells. With border walls, $V \le 48 \times 48 = 2304$, giving at most $\approx 4606$ moves — far under $100{,}000$. Subtask 1 (border-only walk) is the one case the generic DFS does *not* solve, since it forbids interior cells; handle it separately by walking the rectangle's perimeter explicitly.

Hint 5

Compress each number to a 10-bit signature: Each number's relevant information is just *which of the digits 0–9 it contains* — a 10-bit mask. There are only $2^{10} = 1024$ possible masks. Reduce the array to: for each mask, the **maximum** value having exactly that digit set.

Hint 6

Pair masks by disjointness: Two numbers are compatible iff their masks AND to $0$. Naively pair all surviving masks ($\le 1024^2 \approx 10^6$ pairs) and take the best disjoint pair — or, faster, use a Sum-Over-Subsets (SOS) DP so that for each mask $m$ you instantly look up the best value whose mask is a subset of the complement $\lnot m$. Note no number has an empty mask (even `0` contains digit `0`), so a number is never disjoint with itself — the $i \ne j$ requirement is automatic across distinct masks.

Follow-up questions

  • **Part 1:** Instead of $b[i]$, return for each player the skill value of the opponent who eliminated them (and a sentinel for the champion). How does your simulation change?
  • **Part 2:** For subtask 5, can you guarantee a covering walk of length **strictly less** than $2(V-1)$ in general, or is that bound tight? What grid shape forces it to be tight?
  • **Part 3:** Generalize to selecting $k$ numbers (not just two) that are pairwise digit-disjoint with maximum total sum. How does the mask-DP change, and what is the complexity?
  • **Part 3:** If the "no common digit" rule were replaced by "share at most one common digit," how would you adapt the mask approach?