{"id":"sorting-searching-swap","slug":"swapping","title":"Swapping, and sorting by hand","text":"Sorting moves values around in an array, and its basic move is the **swap**: two elements trade places. It takes a little care. This tries to swap the first two heights the obvious way:\n\n```java\nint[] heights = {152, 140, 171};\nheights[0] = heights[1];\nheights[1] = heights[0];\nSystem.out.println(Arrays.toString(heights));\n```\n\n```output\n[140, 140, 171]\n```\n\nThe first line copies 140 over 152, so 152 is gone before the second line can use it. `heights[1] = heights[0]` then copies 140 back to where it already was. It's like swapping the drinks in two full glasses: you need a third, empty glass to hold one drink while you pour the other.\n\nIn code, the third glass is a variable:\n\n```java\nint[] heights = {152, 140, 171};\nint temp = heights[0];\nheights[0] = heights[1];\nheights[1] = temp;\nSystem.out.println(Arrays.toString(heights));\n```\n\n```output\n[140, 152, 171]\n```\n\n`temp` keeps a copy of 152 while 140 moves to index 0, and then 152 goes to index 1. (`Arrays.toString` gives an array's values in square brackets, as in module 15.)\n\nAs a method, a swap takes the array and the two indexes. A method that gets an array can change the caller's array (module 15), so the swap shows in `main`:\n\n```java\nimport java.util.Arrays;\n\npublic class Main {\n    public static void main(String[] args) {\n        int[] heights = {152, 140, 171, 131};\n        switchPlaces(heights, 0, 3);\n        System.out.println(Arrays.toString(heights));\n    }\n\n    public static void switchPlaces(int[] values, int a, int b) {\n        int temp = values[a];\n        values[a] = values[b];\n        values[b] = temp;\n    }\n}\n```\n\n```output\n[131, 140, 171, 152]\n```\n\n### Sorting a line of people by hand\n\nPicture a class lining up for a photo, shortest first. One simple way to do it: find the shortest person, and have them swap places with whoever stands first. Then find the shortest of the rest, and swap them with whoever stands second. Keep going until you reach the end of the line. This is **selection sort**: each round *selects* the smallest of the values that aren't in place yet.\n\nHere it is on five heights, in centimeters. Each round finds the smallest value from the round's index on, and swaps it to that index:\n\n| Round | Smallest from the index on | Swap | The array after the round |\n| --- | --- | --- | --- |\n| start | | | `[152, 140, 171, 131, 160]` |\n| index 0 | 131, at index 3 | 0 and 3 | `[131, 140, 171, 152, 160]` |\n| index 1 | 140, at index 1 | 1 and 1 | `[131, 140, 171, 152, 160]` |\n| index 2 | 152, at index 3 | 2 and 3 | `[131, 140, 152, 171, 160]` |\n| index 3 | 160, at index 4 | 3 and 4 | `[131, 140, 152, 160, 171]` |\n\n- After each round, one more value is in its final place, and the front part of the array is sorted.\n- In the round of index 1, 140 is already where it belongs. Swapping an element with itself changes nothing, so this round needs no special case.\n- Five values take four rounds. Once all the others are in place, the last one, 171, has nowhere else to go.\n\nEach round is two things you've already seen: step 1's search for the smallest value from an index on, and a swap. The program of this task writes the rounds out by hand. Its `positionOfLowest(values, start)` is step 1's `fastestFrom` with names that fit any numbers: it returns the index of the smallest value from `start` on.\n","task":"What does this program print? Do the rounds on paper, the way the table does.\n","kind":"predict","seed":"import java.util.Arrays;\n\npublic class Main {\n    public static void main(String[] args) {\n        int[] heights = {158, 162, 149, 171, 144};\n        switchPlaces(heights, 0, positionOfLowest(heights, 0));\n        System.out.println(Arrays.toString(heights));\n        switchPlaces(heights, 1, positionOfLowest(heights, 1));\n        System.out.println(Arrays.toString(heights));\n        switchPlaces(heights, 2, positionOfLowest(heights, 2));\n        System.out.println(Arrays.toString(heights));\n    }\n\n    public static int positionOfLowest(int[] values, int start) {\n        int lowest = start;\n        for (int i = start + 1; i < values.length; i++) {\n            if (values[i] < values[lowest]) {\n                lowest = i;\n            }\n        }\n        return lowest;\n    }\n\n    public static void switchPlaces(int[] values, int a, int b) {\n        int temp = values[a];\n        values[a] = values[b];\n        values[b] = temp;\n    }\n}\n","solution":"import java.util.Arrays;\n\npublic class Main {\n    public static void main(String[] args) {\n        int[] heights = {158, 162, 149, 171, 144};\n        switchPlaces(heights, 0, positionOfLowest(heights, 0));\n        System.out.println(Arrays.toString(heights));\n        switchPlaces(heights, 1, positionOfLowest(heights, 1));\n        System.out.println(Arrays.toString(heights));\n        switchPlaces(heights, 2, positionOfLowest(heights, 2));\n        System.out.println(Arrays.toString(heights));\n    }\n\n    public static int positionOfLowest(int[] values, int start) {\n        int lowest = start;\n        for (int i = start + 1; i < values.length; i++) {\n            if (values[i] < values[lowest]) {\n                lowest = i;\n            }\n        }\n        return lowest;\n    }\n\n    public static void switchPlaces(int[] values, int a, int b) {\n        int temp = values[a];\n        values[a] = values[b];\n        values[b] = temp;\n    }\n}\n","hints":["The first round finds the smallest of all, 144 at index 4, and swaps indexes 0 and 4. The 158 that stood first moves to the end.","Each later round looks only from its own index on. From index 1 on, the smallest is 149. From index 2 on, it's the 158 that moved to the end in the first round."],"tests":[{"name":"Output","stdin":"","expect":"[144, 162, 149, 171, 158]\n[144, 149, 162, 171, 158]\n[144, 149, 158, 171, 162]","hidden":false}],"require":[],"forbid":[],"lines":["[144, 162, 149, 171, 158]","[144, 149, 162, 171, 158]","[144, 149, 158, 171, 162]"],"more":[{"task":"A relay team's running order is a list of names. Write the method `tradePlaces(ArrayList<String> order, int a, int b)`, which swaps the runners at indexes `a` and `b`. A list has no `[ ]`: read an element with `get`, and put a new one in its place with `set(index, value)` (module 14). The check runs:\n\n```java\nArrayList<String> order = new ArrayList<>();\norder.add(\"Ada\");\norder.add(\"Bo\");\norder.add(\"Cy\");\norder.add(\"Dee\");\ntradePlaces(order, 1, 2);\nSystem.out.println(order);\n```\n\nand expects:\n\n```\n[Ada, Cy, Bo, Dee]\n```\n","kind":"code","seed":"import java.util.ArrayList;\n\npublic class Main {\n    public static void main(String[] args) {\n        ArrayList<String> order = new ArrayList<>();\n        order.add(\"Ada\");\n        order.add(\"Bo\");\n        order.add(\"Cy\");\n        order.add(\"Dee\");\n        tradePlaces(order, 1, 2);\n        System.out.println(order);\n    }\n\n    // Write the method tradePlaces here.\n}\n","solution":"import java.util.ArrayList;\n\npublic class Main {\n    public static void main(String[] args) {\n        ArrayList<String> order = new ArrayList<>();\n        order.add(\"Ada\");\n        order.add(\"Bo\");\n        order.add(\"Cy\");\n        order.add(\"Dee\");\n        tradePlaces(order, 1, 2);\n        System.out.println(order);\n    }\n\n    public static void tradePlaces(ArrayList<String> order, int a, int b) {\n        String temp = order.get(a);\n        order.set(a, order.get(b));\n        order.set(b, temp);\n    }\n}\n","hints":["It's the same three moves as `switchPlaces`, with list methods. The third glass is a String: `String temp = order.get(a);`.","`order.set(a, order.get(b));` puts runner `b` at index `a`, and `order.set(b, temp);` puts the runner you kept in `temp` at index `b`."],"tests":[{"name":"Test 1","stdin":"","call":"ArrayList<String> order = new ArrayList<>();\norder.add(\"Ada\");\norder.add(\"Bo\");\norder.add(\"Cy\");\norder.add(\"Dee\");\ntradePlaces(order, 1, 2);\nSystem.out.println(order);\n","expect":"[Ada, Cy, Bo, Dee]","hidden":false},{"name":"Test 2","stdin":"","call":"ArrayList<String> order = new ArrayList<>();\norder.add(\"Kim\");\norder.add(\"Lou\");\norder.add(\"Max\");\ntradePlaces(order, 0, 2);\nSystem.out.println(order);\ntradePlaces(order, 2, 1);\nSystem.out.println(order);\ntradePlaces(order, 1, 1);\nSystem.out.println(order + \" \" + order.size());\n","expect":"[Max, Lou, Kim]\n[Max, Kim, Lou]\n[Max, Kim, Lou] 3","hidden":true},{"name":"Test 3","stdin":"","call":"ArrayList<String> order = new ArrayList<>();\norder.add(\"Nia\");\norder.add(\"Oz\");\ntradePlaces(order, 1, 0);\nSystem.out.println(order);\n","expect":"[Oz, Nia]","hidden":true}],"require":[{"pattern":"\\bpublic\\s+static\\s+void\\s+tradePlaces\\s*\\(\\s*ArrayList<String>\\s+\\w+\\s*,\\s*int\\s+\\w+\\s*,\\s*int\\s+\\w+\\s*\\)","message":"Write the method as `public static void tradePlaces(ArrayList<String> order, int a, int b)`."},{"pattern":"\\.set\\s*\\(","min":2,"message":"Put the two runners in their new places with `set`."}],"forbid":[{"pattern":"\\bCollections\\b","message":"Swap the runners yourself, with `get` and `set`."}]},{"task":"A hiking trail's checkpoints are in an array, in the order of the walk out. Write the method `reverseInPlace(String[] checkpoints)`, which turns the same array around for the walk back: the last checkpoint becomes the first, and so on. Don't make a new array. Swap elements instead: the first with the last, the second with the second to last, and so on, up to the middle. The check runs:\n\n```java\nString[] checkpoints = {\"Parking\", \"Lake\", \"Bridge\", \"Summit\"};\nreverseInPlace(checkpoints);\nSystem.out.println(Arrays.toString(checkpoints));\n```\n\nand expects:\n\n```\n[Summit, Bridge, Lake, Parking]\n```\n","kind":"code","seed":"import java.util.Arrays;\n\npublic class Main {\n    public static void main(String[] args) {\n        String[] checkpoints = {\"Parking\", \"Lake\", \"Bridge\", \"Summit\"};\n        reverseInPlace(checkpoints);\n        System.out.println(Arrays.toString(checkpoints));\n    }\n\n    // Write the method reverseInPlace here.\n}\n","solution":"import java.util.Arrays;\n\npublic class Main {\n    public static void main(String[] args) {\n        String[] checkpoints = {\"Parking\", \"Lake\", \"Bridge\", \"Summit\"};\n        reverseInPlace(checkpoints);\n        System.out.println(Arrays.toString(checkpoints));\n    }\n\n    public static void reverseInPlace(String[] checkpoints) {\n        for (int i = 0; i < checkpoints.length / 2; i++) {\n            int other = checkpoints.length - 1 - i;\n            String temp = checkpoints[i];\n            checkpoints[i] = checkpoints[other];\n            checkpoints[other] = temp;\n        }\n    }\n}\n","hints":["The element at index `i` trades places with the one at `checkpoints.length - 1 - i`. Swap them with a `temp` variable, which here is a String.","Stop in the middle: `for (int i = 0; i < checkpoints.length / 2; i++)`. A loop over the whole array would swap every pair twice, and put everything back where it was. With an odd count, the middle element stays where it is."],"tests":[{"name":"Test 1","stdin":"","call":"String[] checkpoints = {\"Parking\", \"Lake\", \"Bridge\", \"Summit\"};\nreverseInPlace(checkpoints);\nSystem.out.println(Arrays.toString(checkpoints));\n","expect":"[Summit, Bridge, Lake, Parking]","hidden":false},{"name":"Test 2","stdin":"","call":"String[] checkpoints = {\"Gate\", \"Mill\", \"Ridge\", \"Cave\", \"Peak\"};\nreverseInPlace(checkpoints);\nSystem.out.println(Arrays.toString(checkpoints));\nreverseInPlace(checkpoints);\nSystem.out.println(Arrays.toString(checkpoints));\n","expect":"[Peak, Cave, Ridge, Mill, Gate]\n[Gate, Mill, Ridge, Cave, Peak]","hidden":true},{"name":"Test 3","stdin":"","call":"String[] two = {\"Start\", \"End\"};\nreverseInPlace(two);\nSystem.out.println(Arrays.toString(two));\nString[] one = {\"Hut\"};\nreverseInPlace(one);\nSystem.out.println(Arrays.toString(one));\nString[] none = new String[0];\nreverseInPlace(none);\nSystem.out.println(Arrays.toString(none));\n","expect":"[End, Start]\n[Hut]\n[]","hidden":true}],"require":[{"pattern":"\\bpublic\\s+static\\s+void\\s+reverseInPlace\\s*\\(\\s*String\\s*\\[\\s*\\]\\s*\\w+\\s*\\)","message":"Write the method as `public static void reverseInPlace(String[] checkpoints)`."}],"forbid":[{"pattern":"\\bnew\\s+String\\s*\\[","message":"Turn the array around in place, by swapping its elements, without making a new array."},{"pattern":"\\bArrayList\\b|\\bCollections\\b","message":"Swap the elements of the array itself, without a list."}]}]}