Skip to content

S2Q2 · Snakes and Ladders - Next Position

⚡ Quick Reference

Type: Full I/O problem

Core idea: move forward by dice, stay if over 100, then apply one snake/ladder lookup.

pos, dice, n = map(int, input().split())
board = {}
for _ in range(n):
    parts = input().split()
    kind, a, b = parts[0], int(parts[1]), int(parts[2])
    if kind == 'L':
        board[a] = b   # bottom → top
    else:
        board[a] = b   # head → tail

new_pos = pos + dice
if new_pos > 100:
    new_pos = pos
print(board.get(new_pos, new_pos))

Key rules: - New position = pos + dice; if > 100 → stay at pos - L bottom topboard[bottom] = top - S head tailboard[head] = tail - Look up board.get(new_pos, new_pos) - returns new_pos if no snake/ladder - Only one move applied - no chaining


Problem Statement

Problem (I/O type)

Given current position, dice value, and snake/ladder positions, compute the next board position following the game rules.

Example:

Input
5 3 3
L 8 15
S 17 4
L 20 25
Output
15

Understanding the rules

Current pos = 5,  dice = 3
New pos = 5 + 3 = 8

board = {8: 15,   ← ladder (bottom 8 → top 15)
         17: 4,   ← snake  (head 17 → tail 4)
         20: 25}  ← ladder (bottom 20 → top 25)

board.get(8, 8) = 15  →  print 15 ✓

Edge case - exceeds 100:

pos = 98,  dice = 5
new_pos = 103  →  > 100  →  stay at 98
print 98

Edge case - no snake or ladder:

pos = 10,  dice = 3
new_pos = 13  →  not in board  →  board.get(13, 13) = 13
print 13

Snakes and ladders use the same dict

Both snakes (S head tail) and ladders (L bottom top) map a trigger position to a destination. They can live in the same board dict - the lookup logic is identical regardless of type.


Tracing the example

Step Value
Parse first line pos=5, dice=3, n=3
Read L 8 15 board[8] = 15
Read S 17 4 board[17] = 4
Read L 20 25 board[20] = 25
new_pos = 5 + 3 8
8 > 100? No
board.get(8, 8) 15
Output 15

Solution approaches

pos, dice, n = map(int, input().split())
board = {}
for _ in range(n):
    kind, a, b = input().split()
    board[int(a)] = int(b)   # works for both L and S

new_pos = pos + dice
if new_pos > 100:
    new_pos = pos
print(board.get(new_pos, new_pos))

Since both snakes and ladders map trigger → destination, we don't even need to check kind - just store a → b for both.

pos, dice, n = map(int, input().split())
ladders = {}
snakes  = {}

for _ in range(n):
    parts = input().split()
    kind, a, b = parts[0], int(parts[1]), int(parts[2])
    if kind == 'L':
        ladders[a] = b
    else:
        snakes[a] = b

new_pos = pos + dice

if new_pos > 100:
    print(pos)
elif new_pos in ladders:
    print(ladders[new_pos])
elif new_pos in snakes:
    print(snakes[new_pos])
else:
    print(new_pos)

Keeps snakes and ladders in separate dicts - more explicit, easier to extend.

first = input().split()
pos, dice, n = int(first[0]), int(first[1]), int(first[2])

parse = lambda line: (int(line[1]), int(line[2]))
board = dict(parse(input().split()) for _ in range(n))

new_pos = pos + dice
print(board.get(new_pos if new_pos <= 100 else pos,
                new_pos if new_pos <= 100 else pos))

Lambda parses each line; the ternary handles the >100 case inline in the get call.


Key takeaways

01

dict.get(pos, pos) for no-move default

board.get(new_pos, new_pos) returns the mapped destination if the position is a trigger, or the position itself if not. One call handles both cases - no separate if pos in board check needed.

02

Snakes and ladders share the same mapping

Both map a trigger position to a destination. The kind field (`L` or `S`) only tells you whether it moves you up or down - but the lookup logic is identical. One dict handles both.

03

Check > 100 before the board lookup

If the dice roll would take you past 100, stay at the current position - don't check the board at all. The order matters: exceeding 100 is checked first, board lookup second.