Created
September 5, 2013 03:29
-
-
Save futureperfect/6445737 to your computer and use it in GitHub Desktop.
Determine whether an array is "circular".
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package io.tense.interview.arrays; | |
import static com.google.common.base.Preconditions.checkNotNull; | |
public class CircularArrays { | |
/** | |
* Tests for the the complete "circularity" of an array of integers where | |
* traversal is performed by taking array[i] and summing the index i and | |
* value stored in the array to derive a new index. | |
* | |
* Circular means that we traverse a cycle where all elements in the array | |
* are visited once and only once and the traversal returns to where it | |
* began. Hamiltonian cycle might be a good way to describe it if you squint | |
* at this problem the right way. | |
* | |
* Null arrays throw an NPE (because don't be a dick, please) | |
* Empty arrays return false | |
* | |
* @param array | |
* @return whether the list is circular | |
*/ | |
public static boolean checkIsCircular(int[] array) { | |
checkNotNull(array); | |
if (array.length == 0) { | |
return false; | |
} | |
int fencepost = 0; | |
int index = 0; | |
for (int i = 0; i < array.length - 1; i++) { | |
//behavior of modulus function here is... inconvenient. This fixes it for our purposes | |
index = (((index + array[index]) % array.length) + array.length) % array.length; | |
if (index == fencepost) { | |
return false; | |
} | |
} | |
index = (index + array[index]) % array.length; | |
return index == fencepost; | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package io.tense.interview.arrays; | |
import static io.tense.interview.arrays.CircularArrays.checkIsCircular; | |
import static org.junit.Assert.assertFalse; | |
import static org.junit.Assert.assertTrue; | |
import org.junit.Test; | |
public class CircularArraysTest { | |
@Test | |
public void testIdentityListIsCircular() { | |
assertTrue(checkIsCircular(new int[]{0})); | |
} | |
@Test | |
public void testSingleElementListIsCircular() { | |
assertTrue(checkIsCircular(new int[]{3})); | |
} | |
@Test | |
public void testTwoElementCircularListIsCircular() { | |
assertTrue(checkIsCircular(new int[]{1, 1})); | |
} | |
@Test | |
public void testLongCircularList() { | |
assertTrue(checkIsCircular(new int[]{1, 1, 1, 1, 1, 1})); | |
} | |
@Test | |
public void testNonCircularList() { | |
assertFalse(checkIsCircular(new int[]{1, 1, 0})); | |
} | |
@Test | |
public void testListThatCyclesEarly() { | |
assertFalse(checkIsCircular(new int[]{1, -1, 0, 0, 7, 1})); | |
} | |
@Test | |
public void testListThatCyclesInTheMiddle() { | |
assertFalse(checkIsCircular(new int[]{1, 1, 1, -1, 1, 1, 1})); | |
} | |
@Test | |
public void testListThatCyclesInNegativeDirection() { | |
assertTrue(checkIsCircular(new int[]{-1, -1, -1, -1})); | |
} | |
@Test(expected=NullPointerException.class) | |
public void testThrowsNPEWithNullInput() { | |
checkIsCircular(null); | |
} | |
@Test | |
public void testZeroSizedInput() { | |
assertFalse(checkIsCircular(new int[]{})); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment