Skip to content

Commit 9bd6c00

Browse files
committed
feat(day 189): compute skeleton track difficulty based on curve scoring rules
1 parent 530e805 commit 9bd6c00

1 file changed

Lines changed: 211 additions & 0 deletions

File tree

Lines changed: 211 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,211 @@
1+
"""
2+
3+
2026 Winter Games Day 9: Skeleton
4+
Given a string representing the curves on a skeleton track, determine the difficulty of the track.
5+
6+
The given string will only consist of the letters:
7+
8+
"L" for a left turn
9+
"R" for a right turn
10+
"S" for a straight segment
11+
Each direction change adds 15 points (an "L" followed by an "R" or vice versa).
12+
13+
All other curves add 5 points each (all other "L" or "R" characters).
14+
15+
Straight segments add 0 points.
16+
17+
The difficulty of the track is based on the total score. Return:
18+
19+
"Easy" if the total is 0 - 100
20+
"Medium" if the total is 101-200
21+
"Hard" if the total is over 200
22+
"""
23+
24+
25+
import unittest
26+
27+
class SkeletonTest(unittest.TestCase):
28+
29+
def test1(self):
30+
self.assertEqual(get_difficulty("SLSLLSRRLSRLRL"), "Easy")
31+
32+
def test2(self):
33+
self.assertEqual(get_difficulty("LLRSLRLRSLLRLRSLRRLRSRLLS"), "Hard")
34+
35+
def test3(self):
36+
self.assertEqual(get_difficulty("SRRRRLSLLRLRSSRLSRL"), "Medium")
37+
38+
def test4(self):
39+
self.assertEqual(get_difficulty("LSRLRLSRLRLSLRSLRLLRLSRLRLRSL"), "Hard")
40+
41+
def test5(self):
42+
self.assertEqual(get_difficulty("SLLSSLRLSLSLRSLSSLRL"), "Medium")
43+
44+
def test6(self):
45+
self.assertEqual(get_difficulty("SRSLSRSLSRRSLSRSRSLSRLSRSR"), "Easy")
46+
47+
48+
49+
50+
def get_difficulty_one(track):
51+
52+
difficulty = 0
53+
i = 0
54+
55+
while i < len(track)-1:
56+
if track[i] == "L" and track[i+1] == "R":
57+
difficulty += 15
58+
elif track[i] == "R" and track[i+1] == "L":
59+
difficulty += 15
60+
elif track[i] == "L" or track[i] == "R":
61+
difficulty += 5
62+
else:
63+
difficulty += 0
64+
i += 1
65+
66+
67+
if 0 <= difficulty <= 100:
68+
return "Easy"
69+
elif 101 <= difficulty <= 200:
70+
return "Medium"
71+
else:
72+
return "Hard"
73+
74+
"""
75+
The above code has some issues
76+
1. you stop at len(track) -1
77+
-> that means the last character in the track string is never processed.
78+
-> Example: "LRLSRRL" -> Your loop ends before checking the final "L".
79+
80+
2. You only check pairs (track[i] and track[i+1])
81+
-> This works for direction changes, but it misses scoring for the last curve if it's not part of a pair.
82+
-> For instance, a trailing "L" or "R" should add 5 points, but your loop skips it.
83+
84+
3. Straight segments(S)
85+
=> This handle them correctly (add 0), but because of the loop cutoff, a trailing "S" is also ignored.
86+
87+
88+
How scoring is supposed to work
89+
The rule say:
90+
-> Every "L" or "R" adds 5 points.
91+
-> If it's a direction change (L after R or R after L), it adds 15 points, instead of 5.
92+
-> "S" adds 0 points.
93+
94+
every character needs to be checked here
95+
96+
the above solution fails in some cases
97+
98+
1. Trailing curver skipped
99+
100+
print(get_difficulty("L"))
101+
102+
Expected: 5 => "Easy"
103+
The above code: 0 -> "Easy" (but wrong score)
104+
105+
2> Trailing curve after straight:
106+
107+
print(get_difficulty("SL"))
108+
109+
#Expected : 5 -> "Easy"
110+
# The above code 0 -> "Easy" (skipped last L)
111+
112+
3. Trailing curve after another curve
113+
114+
print(get_difficulty("LRL"))
115+
116+
# Expected: L=5, R after L= 15, L after R = 15, -> total = 35 -> "Easy"
117+
# The above code : only scores first two, skips last L => total=20 -> "Easy" but wrong score
118+
"""
119+
# This is the refined version of the above solution
120+
121+
def get_difficulty(track):
122+
difficulty = 0
123+
i = 0
124+
while i < len(track):
125+
if track[i] == "L" and i > 0 and track[i-1] == "R":
126+
difficulty += 15
127+
elif track[i] == "R" and i > 0 and track[i - 1] == "L":
128+
difficulty += 15
129+
elif track[i] in ("L", "R"):
130+
difficulty += 5
131+
132+
i += 1
133+
134+
if 0 <= difficulty <= 100:
135+
return "Easy"
136+
elif 101 <= difficulty <= 200:
137+
return "Medium"
138+
else:
139+
return "Hard"
140+
141+
"""
142+
143+
=> This loop now runs through all characters( i < len(track)),
144+
so that last item is included.
145+
=> Instead of looking ahead (track[i+1]), it looks backward (track[i-1]) to detect
146+
direction changes. That way, every character is scored, including the last one.
147+
=> Everything else (your scoring ranges and structure) stays the same.
148+
"""
149+
150+
151+
def get_difficulty(track):
152+
153+
total = 0
154+
for i, curve in enumerate(track):
155+
if curve == "S":
156+
continue
157+
if i > 0 and (curve == "L" and track[i - 1] == "R" or curve == "R" and track[i - 1] == "L"):
158+
total += 15
159+
else:
160+
total += 5
161+
162+
if total <= 100:
163+
return "Easy"
164+
elif total <= 200:
165+
return "Medium"
166+
else:
167+
return "Hard"
168+
"""
169+
print(get_difficulty("LRLSRRL"))
170+
171+
172+
- L → +5
173+
- R after L → +15
174+
- L after R → +15
175+
- S → +0
176+
- R after S → +5
177+
- R after R → +5
178+
- L after R → +15
179+
Total = 60 → "Easy"
180+
181+
182+
So the main problem was skipping the last character and only scoring pairs. With the correted loop,
183+
you'll get consistent results across all track strings.
184+
"""
185+
186+
187+
def get_difficulty(track):
188+
189+
difficulty = 0
190+
i = 0
191+
while i < len(track):
192+
if track[i] == "S":
193+
pass
194+
elif i > 0 and ((track[i] == "L" and track[i-1] == "R") or (track[i] == "R" and track[i-1]=="L")):
195+
difficulty += 15
196+
else:
197+
difficulty += 5
198+
199+
i += 1
200+
201+
if difficulty <= 100:
202+
return "Easy"
203+
elif difficulty <= 200:
204+
return "Medium"
205+
else:
206+
return "Hard"
207+
208+
209+
if __name__ == "__main__":
210+
print(get_difficulty_one("SL"))
211+
unittest.main()

0 commit comments

Comments
 (0)