diff --git a/kata/7-kyu/index.md b/kata/7-kyu/index.md index e50a6af5..705a24dc 100644 --- a/kata/7-kyu/index.md +++ b/kata/7-kyu/index.md @@ -320,6 +320,7 @@ - [London CityHacker](london-cityhacker "5bce125d3bb2adff0d000245") - [Longest vowel chain](longest-vowel-chain "59c5f4e9d751df43cf000035") - [Looking for a benefactor](looking-for-a-benefactor "569b5cec755dd3534d00000f") +- [Loop Detector](loop-detector "68851563123e161332d2a84b") - [Lost number in number sequence](lost-number-in-number-sequence "595aa94353e43a8746000120") - [Love vs friendship](love-vs-friendship "59706036f6e5d1e22d000016") - [lucky number](lucky-number "55afed09237df73343000042") diff --git a/kata/7-kyu/loop-detector/README.md b/kata/7-kyu/loop-detector/README.md new file mode 100644 index 00000000..0b5e06e4 --- /dev/null +++ b/kata/7-kyu/loop-detector/README.md @@ -0,0 +1,61 @@ +# [Loop Detector](https://www.codewars.com/kata/loop-detector "https://www.codewars.com/kata/68851563123e161332d2a84b") + +In this kata, you'll simulate traversing a one-way pointer chain, similar to a singly linked list. Each element in the input list represents +the index of the next element to move to. + +Your task is to determine whether this chain eventually enters a loop, or whether it terminates by stepping out of bounds. + +## Function Signature + +* ```arr``` is a list or array of non-negative integers. + +* Return ```True``` (or your language's equivalent) if the traversal enters a loop. + +* Return ```False``` (or your language's equivalent) if the traversal terminates. + +## How Traversal Works + +* Begin at index ```0```. + +* Read the value at the current index to get the next index. + +* Continue stepping through the array. + +* If you encounter an index you've already visited, you've found a loop — return ```True``` (or your language's equivalent). + +* If a step takes you to an index outside the array, the traversal ends — return ```False``` (or your language's equivalent). + +## Examples + +``` +Input: 1, 2, 3, 4, 2 ➞ True +Path: 0 -> 1 -> 2 -> 3 -> 4 -> 2 -> ... (loop detected) + +Input: 1, 2, 3, 4, 5 ➞ False +Path: 0 -> 1 -> 2 -> 3 -> 4 -> 5 -> (out of bounds) + +Input: 0 ➞ True +Path: 0 -> 0 -> 0 -> ... (self-loop) + +Input: 3, 2, 1, 6 ➞ False +Path: 0 -> 3 -> 6 -> (out of bounds) + +Input: 1, 0 ➞ True +Path: 0 -> 1 -> 0 -> 1 -> ... (cycle of two) +``` + +## Notes + +* The input may be empty. In that case, return ```False``` (or your language's equivalent). + +* All elements are guaranteed to be non-negative integers. + +* You must detect any kind of loop, whether it be a: + +LICENSE build.gradle.kts docs gradle gradle.properties gradlew gradlew.bat kata settings.gradle.kts Self-loop (e.g., ```[0]```) + +LICENSE build.gradle.kts docs gradle gradle.properties gradlew gradlew.bat kata settings.gradle.kts Two-node loop (e.g., ```[1, 0]```) + +LICENSE build.gradle.kts docs gradle gradle.properties gradlew gradlew.bat kata settings.gradle.kts Larger cycle (e.g., ```[1, 2, 0]```) + +* An index is considered out of bounds if it is greater than or equal to ```len(arr)```. \ No newline at end of file diff --git a/kata/7-kyu/loop-detector/main/Kata.java b/kata/7-kyu/loop-detector/main/Kata.java new file mode 100644 index 00000000..2a019b01 --- /dev/null +++ b/kata/7-kyu/loop-detector/main/Kata.java @@ -0,0 +1,7 @@ +import static java.util.stream.IntStream.iterate; + +interface Kata { + static boolean hasLoop(int[] arr) { + return iterate(0, i -> arr[i]).limit(arr.length + 1L).allMatch(i -> i < arr.length); + } +} \ No newline at end of file diff --git a/kata/7-kyu/loop-detector/test/SampleTests.java b/kata/7-kyu/loop-detector/test/SampleTests.java new file mode 100644 index 00000000..5df24c2d --- /dev/null +++ b/kata/7-kyu/loop-detector/test/SampleTests.java @@ -0,0 +1,21 @@ +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import org.junit.jupiter.api.Test; + +class SampleTests { + @Test + void cyclic() { + assertTrue(Kata.hasLoop(new int[]{0})); + assertTrue(Kata.hasLoop(new int[]{1, 0})); + assertTrue(Kata.hasLoop(new int[]{2, 0, 1, 5})); + assertTrue(Kata.hasLoop(new int[]{1, 2, 3, 4, 2})); + } + + @Test + void acyclic() { + assertFalse(Kata.hasLoop(new int[0])); + assertFalse(Kata.hasLoop(new int[]{3, 2, 1, 4})); + assertFalse(Kata.hasLoop(new int[]{1, 2, 3, 4, 5})); + } +} \ No newline at end of file