Purpose
A garland word is a word
formed by chopping off the last few letters and “wrapping around” to the start.
For example: You can chop off the the trailing “on” from “onion” and still form the word by wrapping around to the starting “on”. In other words, you can write the letters “o”, “n”, “i” in a circle, in that order, and form the word “onion”.
I say that a garland word is of degree n if you can do the above with the last n letters of the word.
Build an implementation that returns the garland degree of a String
. (Note, this was a dailyprogrammer
subreddit question)
Strategy
- Check if
String
is size 0 (return garland degree of 0) or size 1 (return garland degree of 1). - Start with the first character in the
String
. Iterate through the characters in theString
from the second character onwards. Do we see a matching character? If not, return size 0. - Move on to the first + second characters in the
String
. Iterate through the characters in theString
from the 3rd character onwards for a matching substring - if we can't see one, return size 1. - Repeat.
- Note that the upper limit of the garland degree should be the the
floor
of thelength
of theString
divided by 2. (Right? Or am I missing something?)
Implementation
public class GarlandDegreeIdentifierImpl implements GarlandDegreeIdentifier {
@Override
public int identifyGarlandDegree(final String candidate) {
switch (candidate.length()) {
case 0: {
return 0;
}
case 1: {
return 1;
}
default: {
final char[] chars = candidate.toCharArray();
for (int subStringIndex = 1; subStringIndex <= chars.length - subStringIndex; subStringIndex++) {
final char[] startingChars = Arrays.copyOfRange(chars, 0, subStringIndex);
final char[] remainingChars = Arrays.copyOfRange(chars, subStringIndex, chars.length);
if (subsetIndexIdentifier(remainingChars, startingChars) == -1) {
return subStringIndex - 1;
}
}
return Math.floorDiv(chars.length, 2);
}
}
}
@Override
public int subsetIndexIdentifier(final char[] chars, final char[] candidateChars) {
for (int index = 0; index <= chars.length - candidateChars.length; index++) {
int counter = 0;
for (int candidateCharIndex = 0; candidateCharIndex < candidateChars.length; candidateCharIndex++) {
if (chars[index + candidateCharIndex] != candidateChars[candidateCharIndex]) {
counter++;
}
}
if (0 == counter) {
return index;
}
}
return -1;
}
}