Challenge 3: A Custom Range-Clamping Delegate — Solution import kotlin.reflect.KProperty class RangeClamped(private var value: Int, private val range: IntRange) { operator fun getValue(thisRef: Any?, property: KProperty<*>): Int { return value } operator fun setValue(thisRef: Any?, property: KProperty<*>, newValue: Int) { value = newValue.coerceIn(range) } } class Display { var brightness: Int by RangeClamped(50, 0..100) } fun main() { val display = Display() println(display.brightness) display.brightness = 150 println(display.brightness) display.brightness = -20 println(display.brightness) } /* Output: 50 100 0 Notes: - setValue uses the standard library's coerceIn(range) to clamp any assigned value into the allowed range before storing it — assigning 150 to a 0..100 range stores 100, and assigning -20 stores 0. - getValue simply returns the already-clamped stored value, so reads never need to reapply the clamp. - Because RangeClamped implements getValue/setValue as operator functions, it works with the "by" keyword exactly like the built-in delegates (lazy, observable) covered earlier in the chapter. */