PracHub
QuestionsCoachesLearningGuidesInterview Prep

Quick Overview

This question evaluates a candidate's ability to implement filesystem-style path resolution, including handling relative and absolute paths, dot components, and symbolic link indirection. It tests string parsing, iterative state tracking, and cycle detection logic, commonly used in coding interviews to assess correctness on edge cases and simulation-style problems.

  • medium
  • Anthropic
  • Coding & Algorithms
  • Software Engineer

Path Resolution with Symbolic Links

Company: Anthropic

Role: Software Engineer

Category: Coding & Algorithms

Difficulty: medium

Interview Round: Onsite

# Path Resolution with Symbolic Links Implement the path-resolution logic of a Unix-style `cd` command, including following symbolic links and detecting link cycles. You are given: - `cwd`: an absolute, already-canonical current working directory (a string beginning with `/`, e.g. `/home/user`; the root is `/`). - `path`: the target argument passed to `cd`. It may be absolute (begins with `/`) or relative to `cwd`, and may contain the special components `.` (current directory) and `..` (parent directory). - `links`: a list of `[link_path, target]` pairs describing symbolic links. `link_path` is an absolute canonical path; `target` is the path the link points to (it may itself be absolute or relative, and may contain `.`/`..`). Resolve `path` and return the final canonical absolute directory, applying these rules: 1. Split `path` into components on `/`. If `path` is absolute, start from `/`; otherwise start from `cwd`. 2. Process components left to right. `.` is ignored. `..` moves to the parent (at `/`, `..` stays at `/`). A normal component is appended to the accumulated path. 3. **After appending a normal component**, check whether the resulting accumulated absolute path exactly matches a `link_path`. If it does, the link is followed: resolve its `target` (relative targets resolve against the directory that contains the link) and continue resolving any remaining components from there. 4. **Cycle detection:** if following links causes the resolution to enter the *same* `link_path` a second time within this single `cd` call, stop and return the string `"CYCLE"`. Return the final canonical absolute path as a string (no trailing slash except for the root `/`), or `"CYCLE"` if a symbolic-link cycle is detected. ## Constraints - All paths use `/` as the separator and contain no empty components other than those implied by a leading `/`. - `1 <= number of links <= 10^4`; total input size fits comfortably in memory. - You may assume every `..` is valid to apply (never escapes above `/`). ## Examples Example 1 — plain navigation: ``` cwd = "/home/user" path = "../user/docs/./projects" links = [] => "/home/user/docs/projects" ``` Example 2 — following a symlink: ``` cwd = "/" path = "/var/log/today/error" links = [["/var/log/today", "/var/log/2026-06-30"]] => "/var/log/2026-06-30/error" ``` Example 3 — symlink cycle: ``` cwd = "/" path = "/a/b" links = [["/a", "/a/b/c"], ["/a/b/c", "/a"]] => "CYCLE" ```

Quick Answer: This question evaluates a candidate's ability to implement filesystem-style path resolution, including handling relative and absolute paths, dot components, and symbolic link indirection. It tests string parsing, iterative state tracking, and cycle detection logic, commonly used in coding interviews to assess correctness on edge cases and simulation-style problems.

Implement the path-resolution logic of a Unix-style `cd` command, including following symbolic links and detecting link cycles. You are given: - `cwd`: an absolute, already-canonical current working directory (a string beginning with `/`, e.g. `/home/user`; the root is `/`). - `path`: the target argument passed to `cd`. It may be absolute (begins with `/`) or relative to `cwd`, and may contain the special components `.` (current directory) and `..` (parent directory). - `links`: a list of `[link_path, target]` pairs describing symbolic links. `link_path` is an absolute canonical path; `target` is the path the link points to (it may itself be absolute or relative, and may contain `.`/`..`). Resolve `path` and return the final canonical absolute directory, applying these rules: 1. Split `path` into components on `/`. If `path` is absolute, start from `/`; otherwise start from `cwd`. 2. Process components left to right. `.` is ignored. `..` moves to the parent (at `/`, `..` stays at `/`). A normal component is appended to the accumulated path. 3. **After appending a normal component**, check whether the resulting accumulated absolute path exactly matches a `link_path`. If it does, the link is followed: resolve its `target` (relative targets resolve against the directory that contains the link) and continue resolving any remaining components from there. 4. **Cycle detection:** if following links causes the resolution to enter the *same* `link_path` a second time within this single `cd` call, stop and return the string `"CYCLE"`. Return the final canonical absolute path as a string (no trailing slash except for the root `/`), or `"CYCLE"` if a symbolic-link cycle is detected. Example 1 (plain navigation): `cwd="/home/user"`, `path="../user/docs/./projects"`, `links=[]` => `"/home/user/docs/projects"`. Example 2 (following a symlink): `cwd="/"`, `path="/var/log/today/error"`, `links=[["/var/log/today", "/var/log/2026-06-30"]]` => `"/var/log/2026-06-30/error"`. Example 3 (symlink cycle): `cwd="/"`, `path="/a/b"`, `links=[["/a", "/a/b/c"], ["/a/b/c", "/a"]]` => `"CYCLE"`.

Constraints

  • All paths use '/' as the separator and contain no empty components other than those implied by a leading '/'.
  • 1 <= number of links <= 10^4; total input size fits comfortably in memory.
  • Every '..' is valid to apply (never escapes above '/').
  • cwd is absolute and already canonical; link_path values are absolute and canonical.
  • A link's target may be absolute or relative and may itself contain '.' and '..'.

Examples

Input: ('/home/user', '../user/docs/./projects', [])

Expected Output: '/home/user/docs/projects'

Explanation: No links. Starting from /home/user: '..' -> /home, 'user' -> /home/user, 'docs' -> /home/user/docs, '.' ignored, 'projects' -> /home/user/docs/projects.

Input: ('/', '/var/log/today/error', [['/var/log/today', '/var/log/2026-06-30']])

Expected Output: '/var/log/2026-06-30/error'

Explanation: Absolute path. After appending 'today' the accumulated path /var/log/today matches a link, so it is replaced by its absolute target /var/log/2026-06-30; the remaining component 'error' is appended to give /var/log/2026-06-30/error.

Input: ('/', '/a/b', [['/a', '/a/b/c'], ['/a/b/c', '/a']])

Expected Output: 'CYCLE'

Explanation: Appending 'a' matches link /a -> /a/b/c; resolving that re-appends 'a', which matches /a again (already followed) -> CYCLE.

Input: ('/home/user', '/', [])

Expected Output: '/'

Explanation: Absolute path with no components resolves to the root.

Input: ('/', '/x/y', [['/x/y', '../z']])

Expected Output: '/z'

Explanation: /x/y is a symlink to the relative target ../z, resolved against its containing directory /x, giving /z.

Input: ('/', '../../..', [])

Expected Output: '/'

Explanation: '..' at the root stays at the root, so repeated '..' clamps to /.

Input: ('/', '/a', [['/a', '/b'], ['/b', '/c/d']])

Expected Output: '/c/d'

Explanation: Chained links: /a -> /b, then /b -> /c/d; each is followed once, ending at /c/d.

Input: ('/home', 'docs', [['/home/docs', '/mnt/docs']])

Expected Output: '/mnt/docs'

Explanation: Relative path 'docs' from /home hits link /home/docs -> absolute target /mnt/docs.

Input: ('/', '/self', [['/self', '/self']])

Expected Output: 'CYCLE'

Explanation: A self-referential link: following /self resolves to /self again, which is already in the visited set -> CYCLE.

Hints

  1. Model the current location as a stack of path components; the root '/' is the empty stack, and the accumulated absolute path is '/' + '/'.join(stack).
  2. Keep the yet-to-process components in a queue. When you follow a link, resolve its target into components and push them to the FRONT of the queue so any remaining original components are processed afterward.
  3. Only check for a link match right after appending a *normal* component (not after '.' or '..'). Relative targets resolve against the link's containing directory, so pop the link's own name off the stack before applying the target; for an absolute target, reset the stack to the root first.
  4. For cycle detection, record every link_path you follow in a visited set for this single call; if you are about to follow a link_path already in the set, return "CYCLE".
Last updated: Jul 1, 2026

Loading coding console...

PracHub

Master your tech interviews with 8,000+ real questions from top companies.

Product

  • Questions
  • Learning Tracks
  • Interview Guides
  • Resources
  • Premium
  • For Universities
  • Student Access

Browse

  • By Company
  • By Role
  • By Category
  • Topic Hubs
  • SQL Questions
  • AI Coding Questions
  • Compare Platforms
  • Discord Community

Support

  • support@prachub.com
  • (916) 541-4762

Legal

  • Privacy Policy
  • Terms of Service
  • About Us

© 2026 PracHub. All rights reserved.

Related Coding Questions

  • Banking System Simulation - Anthropic (medium)
  • LRU Cache - Anthropic (medium)
  • Account Balance with Expiring Grants - Anthropic (medium)
  • In-Memory Key-Value Database with Nested Transactions - Anthropic (medium)
  • Time-Based Key-Value Store - Anthropic (medium)