S1Q3 · Repeat Second Half of a Tuple¶
⚡ Quick Reference
Function: repeat_second_half(t: tuple) -> tuple
Core idea: the second half starts at index n // 2. Return the original tuple concatenated with that slice.
Key rules:
- Second half starts at n // 2 (integer division)
- Odd length: middle element is in the first half → n//2 rounds down correctly
- Returns a new tuple -tuple concatenation never mutates the original
Problem Statement¶
Problem
Write a function repeat_second_half(t) that returns a new tuple equal to t followed by the second half of t. For odd-length tuples, the middle element belongs to the first half.
Examples:
(1, 2, 3, 4, 5)
(1, 2, 3, 4, 5, 4, 5)
(10, 20, 30, 40)
(10, 20, 30, 40, 30, 40)
('a', 'b', 'c', 'd', 'e', 'f')
('a', 'b', 'c', 'd', 'e', 'f', 'd', 'e', 'f')
(1, 2, 3)
(1, 2, 3, 3)
Understanding the problem¶
The "second half" starts at index n // 2:
n |
n // 2 |
First half indices | Second half indices |
|---|---|---|---|
| 4 (even) | 2 | 0, 1 | 2, 3 |
| 5 (odd) | 2 | 0, 1, 2 | 3, 4 |
| 6 (even) | 3 | 0, 1, 2 | 3, 4, 5 |
| 3 (odd) | 1 | 0, 1 | 2 |
For odd n, n // 2 rounds down -the middle element (index n//2) ends up in the first half slice t[:n//2+1], while t[n//2:] includes it and beyond...
Wait -let me re-examine with (1, 2, 3, 4, 5) (n=5):
n // 2 = 2t[2:]=(3, 4, 5)-but expected repeat is(4, 5)not(3, 4, 5)
So the split point must be math.ceil(n/2):
- n=5: ceil(5/2) = 3 → t[3:] = (4, 5)
- n=4: ceil(4/2) = 2 → t[2:] = (3, 4)
- n=6: ceil(6/2) = 3 → t[3:] = ('d','e','f')
- n=3: ceil(3/2) = 2 → t[2:] = (3,)
The correct formula is t[ceil(n/2):] = t[(n+1)//2:].
ceil division without import
math.ceil(n/2) = (n + 1) // 2 using integer arithmetic. For n=5: (5+1)//2 = 3. For n=4: (4+1)//2 = 2. This avoids importing math.
Tracing all examples¶
| Tuple | n |
(n+1)//2 |
Second half t[(n+1)//2:] |
Result |
|---|---|---|---|---|
(1,2,3,4,5) |
5 | 3 | (4,5) |
(1,2,3,4,5,4,5) |
(10,20,30,40) |
4 | 2 | (30,40) |
(10,20,30,40,30,40) |
('a','b','c','d','e','f') |
6 | 3 | ('d','e','f') |
('a','b','c','d','e','f','d','e','f') |
(1,2,3) |
3 | 2 | (3,) |
(1,2,3,3) |
Solution approaches¶
(len(t) + 1) // 2 is the ceiling of len(t) / 2 without importing math. Slice from that index, concatenate.
def repeat_second_half(t: tuple) -> tuple:
n = len(t)
split = (n + 1) // 2 # ceiling division -start of second half
second_half = t[split:] # elements from split to end
return t + second_half
Each step named -split point, second half, final result.
Key takeaways¶
Ceiling division: (n+1)//2
(n+1)//2 computes ceil(n/2) without importing math. For even n it equals n//2; for odd n it gives one more -placing the middle element in the first half.
Tuple + tuple = new tuple
Like list concatenation, tuple + creates a brand new tuple. It never modifies either operand -immutability is automatic.
Verify odd/even cases separately
When the split index depends on parity, always trace one even-length and one odd-length example. The formula (n+1)//2 works for both -confirming this with the trace saves debugging time.