Build a Resource Transition Probability Graph from Unsorted Access Logs

Read the full interview experience this question came from →

Quick Overview

Build a probability-weighted transition graph from unsorted access logs, preserving per-user chronology, repeated visits, and START and END states.

Build a Resource Transition Probability Graph from Unsorted Access Logs

Company: Duolingo

Role: Software Engineer

Category: Coding & Algorithms

Difficulty: medium

Interview Round: Technical Screen

Given an unsorted list of web-resource access logs, build a directed transition graph and return the outgoing transition probabilities for each source state. Each log is a three-element record `[time, user_id, resource_id]`. Time is a string containing the number of seconds since midnight; all logs are from the same day. Put each user's visits in chronological order and treat that user's observed visits as one path from `START` through the resources to `END`. Implement `transition_graph(logs)` to return an adjacency mapping: each source state maps to its possible next states and their numeric transition probabilities. Include `START` and each visited resource as source states; `END` is terminal and must not be a source state. ### Transition Rules - Each user contributes one transition from `START` to their first resource. - Each pair of consecutive visits by the same user contributes one resource-to-resource transition. Consecutive visits to the same resource count as a self-transition; do not collapse them. - Each user contributes one transition from their last resource to `END`, including users with only one visit. - For a source state, an outgoing edge's probability is its transition count divided by the total number of transitions leaving that state across all users. - Count transition occurrences, not just distinct users or distinct edges. A user who visits a resource several times may contribute several outgoing transitions from it. ### Input and Output - Resource and user identifiers are strings. Compare timestamps numerically, not lexicographically. Return count ratios without rounding; decimal values shown in examples are approximate. Mapping order does not matter. - For this practice version, times are valid integer seconds from 0 through 86,399; resource IDs do not equal the reserved labels `START` or `END`; and visits by the same user at an equal timestamp retain their input order. These conventions settle details the source report did not specify. - For empty input, return `{"START": {}}`. Each log record represents a visit, including a record that repeats another record. ### Example 1 — Interleaved Users and Repeated Visits ```text logs = [ ["200", "user_1", "resource_5"], ["3", "user_1", "resource_1"], ["620", "user_1", "resource_1"], ["620", "user_3", "resource_1"], ["34", "user_6", "resource_2"], ["95", "user_9", "resource_1"], ["416", "user_6", "resource_1"], ["58523", "user_3", "resource_1"], ["53760", "user_3", "resource_3"], ["58522", "user_22", "resource_1"], ["100", "user_3", "resource_6"], ["400", "user_6", "resource_2"] ] ``` The result is shown with exact fractions where a decimal representation would repeat: | Source | Outgoing probabilities | |---|---| | `START` | `resource_1`: 3/5; `resource_2`: 1/5; `resource_6`: 1/5 | | `resource_1` | `END`: 5/7; `resource_3`: 1/7; `resource_5`: 1/7 | | `resource_2` | `resource_1`: 1/2; `resource_2`: 1/2 | | `resource_3` | `resource_1`: 1 | | `resource_5` | `resource_1`: 1 | | `resource_6` | `resource_1`: 1 | ### Example 2 — Single-Visit Users and a Self-Transition ```text logs = [ ["1", "user_96", "resource_5"], ["1", "user_10", "resource_5"], ["301", "user_11", "resource_5"], ["301", "user_12", "resource_5"], ["603", "user_12", "resource_5"], ["1603", "user_12", "resource_7"] ] result = { "START": {"resource_5": 1.0}, "resource_5": {"END": 0.6, "resource_5": 0.2, "resource_7": 0.2}, "resource_7": {"END": 1.0} } ``` Let `n` be the number of log entries when describing time and auxiliary-space complexity.

Overview: Build a probability-weighted transition graph from unsorted access logs, preserving per-user chronology, repeated visits, and START and END states.

Read the full Duolingo Software Engineer interview experience this question came from

|Home/Coding & Algorithms/Duolingo
Duolingo logo
Duolingo
Jul 20, 2026
mediumSoftware EngineerTechnical ScreenCoding & Algorithms
0
0

Given an unsorted list of web-resource access logs, build a directed transition graph and return the outgoing transition probabilities for each source state.

Each log is a three-element record [time, user_id, resource_id]. Time is a string containing the number of seconds since midnight; all logs are from the same day. Put each user's visits in chronological order and treat that user's observed visits as one path from START through the resources to END.

Implement transition_graph(logs) to return an adjacency mapping: each source state maps to its possible next states and their numeric transition probabilities. Include START and each visited resource as source states; END is terminal and must not be a source state.

Transition Rules

  • Each user contributes one transition from START to their first resource.
  • Each pair of consecutive visits by the same user contributes one resource-to-resource transition. Consecutive visits to the same resource count as a self-transition; do not collapse them.
  • Each user contributes one transition from their last resource to END , including users with only one visit.
  • For a source state, an outgoing edge's probability is its transition count divided by the total number of transitions leaving that state across all users.
  • Count transition occurrences, not just distinct users or distinct edges. A user who visits a resource several times may contribute several outgoing transitions from it.

Input and Output

  • Resource and user identifiers are strings. Compare timestamps numerically, not lexicographically. Return count ratios without rounding; decimal values shown in examples are approximate. Mapping order does not matter.
  • For this practice version, times are valid integer seconds from 0 through 86,399; resource IDs do not equal the reserved labels START or END ; and visits by the same user at an equal timestamp retain their input order. These conventions settle details the source report did not specify.
  • For empty input, return {"START": {}} . Each log record represents a visit, including a record that repeats another record.

Example 1 — Interleaved Users and Repeated Visits

logs = [
  ["200",   "user_1",  "resource_5"],
  ["3",     "user_1",  "resource_1"],
  ["620",   "user_1",  "resource_1"],
  ["620",   "user_3",  "resource_1"],
  ["34",    "user_6",  "resource_2"],
  ["95",    "user_9",  "resource_1"],
  ["416",   "user_6",  "resource_1"],
  ["58523", "user_3",  "resource_1"],
  ["53760", "user_3",  "resource_3"],
  ["58522", "user_22", "resource_1"],
  ["100",   "user_3",  "resource_6"],
  ["400",   "user_6",  "resource_2"]
]

The result is shown with exact fractions where a decimal representation would repeat:

SourceOutgoing probabilities
STARTresource_1: 3/5; resource_2: 1/5; resource_6: 1/5
resource_1END: 5/7; resource_3: 1/7; resource_5: 1/7
resource_2resource_1: 1/2; resource_2: 1/2
resource_3resource_1: 1
resource_5resource_1: 1
resource_6resource_1: 1

Example 2 — Single-Visit Users and a Self-Transition

logs = [
  ["1",    "user_96", "resource_5"],
  ["1",    "user_10", "resource_5"],
  ["301",  "user_11", "resource_5"],
  ["301",  "user_12", "resource_5"],
  ["603",  "user_12", "resource_5"],
  ["1603", "user_12", "resource_7"]
]

result = {
  "START":      {"resource_5": 1.0},
  "resource_5": {"END": 0.6, "resource_5": 0.2, "resource_7": 0.2},
  "resource_7": {"END": 1.0}
}

Let n be the number of log entries when describing time and auxiliary-space complexity.

Submit Your Answer to Earn 20XP

Sign in to leave a comment

Loading comments...