Lesson 4
Center-Out List Traversal in Kotlin
Introduction

Greetings! Welcome to our lesson today, where we'll unravel a fascinating aspect of list manipulation. Here's the question: How would you traverse a list not from the beginning to the end, or vice versa, but from the center outward in either direction? Today's lesson is all about exploring this concept with Kotlin. Brace yourself for a captivating learning journey.

Task Statement

Our task is to produce a new list, given a list of integers, that starts from the center of the original list and alternates direction towards both ends. That is, the first element of our new list will be the middle element of the original one.

After defining the starting point, we will alternate between elements to the left and to the right of this center until all elements have been included. If the length of the initial list is even, we first take the element to the left of the center, then the one to the right of the center, and then do the alternation as described above.

For example, for numbers = listOf(1, 2, 3, 4, 5), the output would be [3, 2, 4, 1, 5].

We will break down this seemingly complex task into manageable pieces to progressively build our Kotlin solution. Keep in mind an additional condition: the length of the list — represented as n — can range from 1 to 100,000, inclusive.

Solution Building: Step 1

First, let's establish the midpoint of our list. Our task requires us to expand our list from the center to the ends, so we divide its length by 2 using integer division in Kotlin. If we find that the list's length is odd, we include the middle element in the newOrder list, given it has no counterpart. If the list's length is even, newOrder initially remains empty.

Here is how it looks in Kotlin:

Kotlin
1fun iterateMiddleToEnd(numbers: List<Int>): MutableList<Int> { 2 val mid = numbers.size / 2 // index of the left middle element 3 val newOrder = mutableListOf<Int>() // MutableList to store new order 4 5 if (numbers.size % 2 == 1) { 6 newOrder.add(numbers[mid]) // Adding the middle element to the resulting MutableList if length is odd 7 } 8 // newOrder remains empty for now if length is even 9 10 return newOrder 11}
Solution Building: Step 2

Successfully solving our task requires two pointers: left and right. These pointers are initialized to point to the elements immediately to the left and right of the middle element, respectively.

Here is the Kotlin method with the added initialization of these pointers:

Kotlin
1fun iterateMiddleToEnd(numbers: List<Int>): MutableList<Int> { 2 val mid = numbers.size / 2 // index of the left middle element 3 var left: Int 4 var right: Int 5 val newOrder = mutableListOf<Int>() // MutableList to store new order 6 7 if (numbers.size % 2 == 1) { 8 left = mid - 1 // Pointing to the left of the middle element 9 right = mid + 1 // Pointing to the right of the middle element 10 newOrder.add(numbers[mid]) // Adding the middle element to the resulting MutableList 11 } else { 12 left = mid - 1 // Pointing to the left of the middle element 13 right = mid // Pointing to the middle element 14 } 15 16 return newOrder 17}
Solution Building: Step 3

With our pointers initialized, it's time to navigate the list and form our new order. In Kotlin, while loops provide the necessary control structure to iterate from the center of the list to both ends. In each iteration, we push the elements at indices left and right to the newOrder list, decrement left by one, and increment right by one.

Here's how it looks when we put together the full Kotlin method:

Kotlin
1fun iterateMiddleToEnd(numbers: List<Int>): MutableList<Int> { 2 val mid = numbers.size / 2 // index of the left middle element 3 var left: Int 4 var right: Int 5 val newOrder = mutableListOf<Int>() // MutableList to store new order 6 7 if (numbers.size % 2 == 1) { 8 left = mid - 1 // Pointing to the left of the middle element 9 right = mid + 1 // Pointing to the right of the middle element 10 newOrder.add(numbers[mid]) // Adding the middle element to the resulting MutableList 11 } else { 12 left = mid - 1 // Pointing to the left of the middle element 13 right = mid // Pointing to the middle element 14 } 15 16 while (left >= 0 || right < numbers.size) { 17 if (left >= 0) newOrder.add(numbers[left--]) 18 if (right < numbers.size) newOrder.add(numbers[right++]) 19 } 20 21 return newOrder 22} 23 24fun main() { 25 val numbers = listOf(1, 2, 3, 4, 5) 26 27 val result = iterateMiddleToEnd(numbers) 28 println(result) // Output should be [3, 2, 4, 1, 5] 29}

By implementing this approach, we have successfully created a new list, starting from the middle and alternating to the left and right ends of the original list, effectively fulfilling the requirements of our task!

Lesson Summary

Well done on reaching the end of this lesson! You've uncovered a riveting method of traversing and manipulating lists! Take a moment to pat yourself on the back for understanding and implementing this concept. As the proverb goes, practice makes perfect. Hence, I encourage you to employ this concept in similar problems. Your exceptional journey in mastering algorithms with Kotlin has just begun. Embrace the challenge and happy coding!

Enjoy this lesson? Now it's time to practice with Cosmo!
Practice is how you turn knowledge into actual skills.