Back to Freecodecamp

Challenge 195: 2026 Winter Games Day 16: Curling

curriculum/challenges/english/blocks/daily-coding-challenges-python/697a49e9860d24853adef680.md

latest4.9 KB
Original Source

--description--

Given a 5x5 matrix representing the "house" at the end of a curling round, determine which team scores and how many points they score.

The layout:

  • The center cell (index [2, 2]) is the "button".
  • The 8 cells directly surrounding the button represent ring 1.
  • And the 16 cells on the outer edge of the house represent ring 2.

In the given matrix:

  • "." represents an empty space.
  • "R" represents a space with a red stone.
  • "Y" represents a space with a yellow stone.

Scoring rules:

  • Only one team can score per round.
  • The team with the stone closest to the button scores.
  • The scoring team earns 1 point for each of their stones that is closer to the button than the opponent's closest stone.
  • The lower the ring number, the closer to the center the stone is.
  • If both teams' closest stone is the same distance from the center, no team scores.

Return:

  • A string in the format "team: number_of_points". e.g: "R: 2".
  • or "No points awarded" if neither team scored any points.

For example, given:

js
[
  [".", ".", "R", ".", "."],
  [".", "R", ".", ".", "."],
  ["Y", ".", ".", ".", "."],
  [".", "R", ".", ".", "."],
  [".", ".", ".", ".", "."]
]

Return "R: 2". The two red stones in ring 1 are tied for the closest and are the only two stones closer than yellows closest.

--hints--

score_curling([[".", ".", "R", ".", "."], [".", "R", ".", ".", "."], ["Y", ".", ".", ".", "."], [".", "R", ".", ".", "."], [".", ".", ".", ".", "."]]) should return "R:2".

js
({test: () => { runPython(`
from unittest import TestCase
TestCase().assertEqual(score_curling([[".", ".", "R", ".", "."], [".", "R", ".", ".", "."], ["Y", ".", ".", ".", "."], [".", "R", ".", ".", "."], [".", ".", ".", ".", "."]]), "R: 2")`)
}})

score_curling([[".", ".", "R", ".", "."], [".", ".", ".", ".", "."], [".", ".", "Y", ".", "R"], [".", ".", "Y", "Y", "."], [".", "Y", "R", "R", "."]]) should return "Y: 3".

js
({test: () => { runPython(`
from unittest import TestCase
TestCase().assertEqual(score_curling([[".", ".", "R", ".", "."], [".", ".", ".", ".", "."], [".", ".", "Y", ".", "R"], [".", ".", "Y", "Y", "."], [".", "Y", "R", "R", "."]]), "Y: 3")`)
}})

score_curling([[".", "R", "Y", ".", "."], ["Y", ".", ".", ".", "."], [".", ".", ".", ".", "."], [".", "Y", "R", "Y", "."], [".", ".", "R", "R", "."]]) should return "No points awarded".

js
({test: () => { runPython(`
from unittest import TestCase
TestCase().assertEqual(score_curling([[".", "R", "Y", ".", "."], ["Y", ".", ".", ".", "."], [".", ".", ".", ".", "."], [".", "Y", "R", "Y", "."], [".", ".", "R", "R", "."]]), "No points awarded")`)
}})

score_curling([[".", "Y", "Y", ".", "."], ["Y", ".", ".", "R", "."], [".", ".", "R", ".", "."], [".", ".", "R", "R", "."], [".", "Y", "R", "Y", "."]]) should return "R: 4".

js
({test: () => { runPython(`
from unittest import TestCase
TestCase().assertEqual(score_curling([[".", "Y", "Y", ".", "."], ["Y", ".", ".", "R", "."], [".", ".", "R", ".", "."], [".", ".", "R", "R", "."], [".", "Y", "R", "Y", "."]]), "R: 4")`)
}})

score_curling([["Y", "Y", "Y", "Y", "Y"], ["Y", "R", "R", "R", "Y"], ["Y", "R", "Y", "R", "Y"], ["Y", "R", "R", "R", "Y"], ["Y", "Y", "Y", "Y", "Y"]]) should return "Y: 1".

js
({test: () => { runPython(`
from unittest import TestCase
TestCase().assertEqual(score_curling([["Y", "Y", "Y", "Y", "Y"], ["Y", "R", "R", "R", "Y"], ["Y", "R", "Y", "R", "Y"], ["Y", "R", "R", "R", "Y"], ["Y", "Y", "Y", "Y", "Y"]]), "Y: 1")`)
}})

score_curling([["Y", "R", "Y", "R", "Y"], ["R", ".", ".", ".", "R"], ["Y", ".", ".", ".", "Y"], ["R", ".", ".", ".", "R"], ["Y", ".", ".", "R", "Y"]]) should return "No points awarded".

js
({test: () => { runPython(`
from unittest import TestCase
TestCase().assertEqual(score_curling([["Y", "R", "Y", "R", "Y"], ["R", ".", ".", ".", "R"], ["Y", ".", ".", ".", "Y"], ["R", ".", ".", ".", "R"], ["Y", ".", ".", "R", "Y"]]), "No points awarded")`)
}})

--seed--

--seed-contents--

py
def score_curling(house):

    return house

--solutions--

py
def score_curling(house):
  stones = {'R': [], 'Y': []}
  
  for i in range(5):
    for j in range(5):
      cell = house[i][j]
      if cell == 'R' or cell == 'Y':
        distance = max(abs(i - 2), abs(j - 2))
        stones[cell].append(distance)
  
  red_closest = min(stones['R']) if stones['R'] else float('inf')
  yellow_closest = min(stones['Y']) if stones['Y'] else float('inf')
  
  if red_closest == float('inf') and yellow_closest == float('inf'):
    return "No points awarded"
  
  if red_closest == yellow_closest:
    return "No points awarded"
  
  if red_closest < yellow_closest:
    winner = 'R'
    opponent_closest = yellow_closest
    winning_stones = stones['R']
  else:
    winner = 'Y'
    opponent_closest = red_closest
    winning_stones = stones['Y']
  
  points = sum(1 for d in winning_stones if d < opponent_closest)
  
  return "No points awarded" if points == 0 else f"{winner}: {points}"