{"id":"sorting-searching-smallest","slug":"smallest-value","title":"Algorithms and the smallest value","text":"An **algorithm** is a precise, step-by-step way to solve a problem: precise enough that a computer can follow it without guessing, and correct for every input of the right kind, not only for the example you tried first. You've written many algorithms already: adding up the numbers of a list, finding the largest value of an array (module 15), counting the words on a line.\n\nThis module is about two problems that come up in almost every kind of program. **Sorting** puts values in order: a contact list by name, prices from the cheapest up. **Searching** finds where a value is. Both have several algorithms, and some do far less work than others, so the module also counts how much work each one does.\n\nIt starts with a small algorithm that sorting builds on.\n\n### The smallest value, and where it is\n\nHere are a runner's lap times, in seconds. Which lap was the fastest?\n\n```java\npublic class Main {\n    public static void main(String[] args) {\n        int[] laps = {74, 71, 69, 73, 70};\n        int best = fastestLap(laps);\n        System.out.println(\"Fastest lap: \" + laps[best] + \" seconds, lap \" + (best + 1));\n    }\n\n    public static int fastestLap(int[] laps) {\n        int fastest = 0;\n        for (int i = 1; i < laps.length; i++) {\n            if (laps[i] < laps[fastest]) {\n                fastest = i;\n            }\n        }\n        return fastest;\n    }\n}\n```\n\n```output\nFastest lap: 69 seconds, lap 3\n```\n\n- `fastest` is the index of the smallest value found so far. It starts at 0, the first element, and the loop compares every later element with `laps[fastest]`.\n- Module 15 kept the value and its index in two variables. One is enough: the index gives the value too, as `laps[fastest]`.\n- The method returns the index, not the value. With the index, the caller can get the value (`laps[best]`), but with only the value, it couldn't tell where it was.\n- With `<`, a later lap that's only as fast doesn't take the place of the earlier one, so on a tie the first one wins.\n\n### From a given index on\n\nSometimes only part of the array counts. Say the first three laps were a warm-up: which lap was the fastest from index 3 on? The method takes the index to start from, and both the fastest so far and the loop start there:\n\n```java\npublic class Main {\n    public static void main(String[] args) {\n        int[] laps = {74, 71, 69, 73, 70};\n        System.out.println(fastestFrom(laps, 0));\n        System.out.println(fastestFrom(laps, 3));\n        System.out.println(fastestFrom(laps, 4));\n    }\n\n    public static int fastestFrom(int[] laps, int start) {\n        int fastest = start;\n        for (int i = start + 1; i < laps.length; i++) {\n            if (laps[i] < laps[fastest]) {\n                fastest = i;\n            }\n        }\n        return fastest;\n    }\n}\n```\n\n```output\n2\n4\n4\n```\n\n- From index 3 on, the laps are 73 and 70. The smaller one is at index 4, and that's what the method returns: the index still counts from the start of the array, not from `start`.\n- From index 4, the last one, only one lap is left, so it's the fastest. The loop doesn't run at all.\n- `fastestFrom(laps, 0)` does the same work as `fastestLap(laps)`.\n\nKeep this method in mind: in step 3, a sorting algorithm calls it once for each index of the array.\n","task":"A greenhouse logs its lowest temperature every night. Fill in the blanks of `coldestFrom(int[] temps, int start)`, which returns the index of the lowest temperature from index `start` on. The check runs:\n\n```java\nint[] temps = {3, -2, 5, -4, 1};\nSystem.out.println(coldestFrom(temps, 0));\nSystem.out.println(coldestFrom(temps, 4));\n```\n\nand expects:\n\n```\n3\n4\n```\n","kind":"fill","seed":"public class Main {\n    public static void main(String[] args) {\n        int[] temps = {3, -2, 5, -4, 1};\n        System.out.println(coldestFrom(temps, 0));\n        System.out.println(coldestFrom(temps, 4));\n    }\n\n    public static int coldestFrom(int[] temps, int start) {\n        int coldest = [[start]];\n        for (int i = [[start + 1‖start]]; i < temps.length; i++) {\n            if (temps[i] < temps[[[coldest]]]) {\n                coldest = i;\n            }\n        }\n        return coldest;\n    }\n}\n","solution":"public class Main {\n    public static void main(String[] args) {\n        int[] temps = {3, -2, 5, -4, 1};\n        System.out.println(coldestFrom(temps, 0));\n        System.out.println(coldestFrom(temps, 4));\n    }\n\n    public static int coldestFrom(int[] temps, int start) {\n        int coldest = start;\n        for (int i = start + 1; i < temps.length; i++) {\n            if (temps[i] < temps[coldest]) {\n                coldest = i;\n            }\n        }\n        return coldest;\n    }\n}\n","hints":["It works like `fastestFrom` above. The coldest so far starts at the index where the search starts, not at 0.","The loop starts right after `start`, at `start + 1`, and each temperature is compared with the coldest one so far, `temps[coldest]`."],"tests":[{"name":"Test 1","stdin":"","call":"int[] temps = {3, -2, 5, -4, 1};\nSystem.out.println(coldestFrom(temps, 0));\nSystem.out.println(coldestFrom(temps, 4));\n","expect":"3\n4","hidden":false},{"name":"Test 2","stdin":"","call":"int[] temps = {-8, 2, 0, 4, 1};\nSystem.out.println(coldestFrom(temps, 1));\nSystem.out.println(coldestFrom(temps, 3));\nSystem.out.println(coldestFrom(temps, 2));\n","expect":"2\n4\n2","hidden":true},{"name":"Test 3","stdin":"","call":"int[] temps = {6, 6, 6};\nSystem.out.println(coldestFrom(temps, 0));\nSystem.out.println(coldestFrom(temps, 1));\nint[] one = {12};\nSystem.out.println(coldestFrom(one, 0));\n","expect":"0\n1\n0","hidden":true}],"require":[],"forbid":[],"more":[{"task":"What does this program print? Two of the prices are equal, and the last line prints a price, not an index.\n","kind":"predict","seed":"public class Main {\n    public static void main(String[] args) {\n        int[] prices = {8, 3, 9, 3, 5};\n        System.out.println(cheapestFrom(prices, 0));\n        System.out.println(cheapestFrom(prices, 2));\n        System.out.println(prices[cheapestFrom(prices, 4)]);\n    }\n\n    public static int cheapestFrom(int[] prices, int start) {\n        int cheapest = start;\n        for (int i = start + 1; i < prices.length; i++) {\n            if (prices[i] < prices[cheapest]) {\n                cheapest = i;\n            }\n        }\n        return cheapest;\n    }\n}\n","solution":"public class Main {\n    public static void main(String[] args) {\n        int[] prices = {8, 3, 9, 3, 5};\n        System.out.println(cheapestFrom(prices, 0));\n        System.out.println(cheapestFrom(prices, 2));\n        System.out.println(prices[cheapestFrom(prices, 4)]);\n    }\n\n    public static int cheapestFrom(int[] prices, int start) {\n        int cheapest = start;\n        for (int i = start + 1; i < prices.length; i++) {\n            if (prices[i] < prices[cheapest]) {\n                cheapest = i;\n            }\n        }\n        return cheapest;\n    }\n}\n","hints":["From index 0, the lowest price is 3. It's at index 1 and again at index 3, and with `<` the second 3 doesn't replace the first.","From index 2 on, the prices are 9, 3 and 5, and the 3 is at index 3 of the whole array. From index 4, only one price is left, and the last line prints the price at that index."],"tests":[{"name":"Output","stdin":"","expect":"1\n3\n5","hidden":false}],"require":[],"forbid":[],"lines":["1","3","5"]},{"task":"A board-game club keeps the winning score of each game night in an array. Write the method `highestFrom(int[] scores, int start)`. It returns the index of the highest score from index `start` on. When two scores are equally high, it returns the index of the first one. The check runs:\n\n```java\nint[] scores = {42, 57, 38, 57, 49};\nSystem.out.println(highestFrom(scores, 0));\nSystem.out.println(highestFrom(scores, 2));\n```\n\nand expects:\n\n```\n1\n3\n```\n","kind":"code","seed":"public class Main {\n    public static void main(String[] args) {\n        int[] scores = {42, 57, 38, 57, 49};\n        System.out.println(highestFrom(scores, 0));\n        System.out.println(highestFrom(scores, 2));\n    }\n\n    // Write the method highestFrom here.\n}\n","solution":"public class Main {\n    public static void main(String[] args) {\n        int[] scores = {42, 57, 38, 57, 49};\n        System.out.println(highestFrom(scores, 0));\n        System.out.println(highestFrom(scores, 2));\n    }\n\n    public static int highestFrom(int[] scores, int start) {\n        int highest = start;\n        for (int i = start + 1; i < scores.length; i++) {\n            if (scores[i] > scores[highest]) {\n                highest = i;\n            }\n        }\n        return highest;\n    }\n}\n","hints":["The method starts `public static int highestFrom(int[] scores, int start) {`. Keep the index of the highest score so far, starting from `start`.","Compare with `>`, not `>=`: then a later score that only ties doesn't take the place of the first one."],"tests":[{"name":"Test 1","stdin":"","call":"int[] scores = {42, 57, 38, 57, 49};\nSystem.out.println(highestFrom(scores, 0));\nSystem.out.println(highestFrom(scores, 2));\n","expect":"1\n3","hidden":false},{"name":"Test 2","stdin":"","call":"int[] scores = {90, 10, 20, 15};\nSystem.out.println(highestFrom(scores, 1));\nSystem.out.println(highestFrom(scores, 3));\nSystem.out.println(highestFrom(scores, 0));\n","expect":"2\n3\n0","hidden":true},{"name":"Test 3","stdin":"","call":"int[] scores = {-5, -2, -9, -2};\nSystem.out.println(highestFrom(scores, 0));\nSystem.out.println(highestFrom(scores, 2));\nint[] one = {7};\nSystem.out.println(highestFrom(one, 0));\n","expect":"1\n3\n0","hidden":true}],"require":[{"pattern":"\\bpublic\\s+static\\s+int\\s+highestFrom\\s*\\(\\s*int\\s*\\[\\s*\\]\\s*\\w+\\s*,\\s*int\\s+\\w+\\s*\\)","message":"Write the method as `public static int highestFrom(int[] scores, int start)`."}],"forbid":[]}]}