/home/wpollock1/public_html/restricted/Java2/EveryNth.java
import java.text.Normalizer;
import java.util.stream.*;
/*
Fizz-Buzz problem from codingbat.com (http://codingbat.com/prob/p196441):
Given a non-empty string and an int N, return the string made starting with
char 0, and then every Nth char of the string. So if N is 3, use char 0, 3,
6, ... and so on. N is 1 or more.
Examples:
everyNth("Miracle", 2) → "Mrce"
everyNth("abcdefg", 2) → "aceg"
everyNth("abcdefg", 3) → "adg"
Your code should validate the command line arguments, normalize and process
arbitrary Unicode.
Solution written 4/2015 by Wayne Pollock, Tampa Florida USA.
*/
class EveryNth {
public static void main ( String [] args ) {
// Validate arguments:
int n = 0;
if ( args.length != 2 ) {
System.err.println( "Usage: java EveryNth <string> <step>\n"
+ "Display every <step>-th character from <string>." );
System.exit( -1 );
}
try {
n = Integer.parseUnsignedInt( args[1] );
} catch (NumberFormatException nfe) {
System.err.println( "Error: second argument must be a positive int." );
System.exit( -1 );
}
if ( n == 0 ) {
System.err.println(
"Error: second argument must be greater than zero." );
System.exit( -1 );
}
System.out.println( everyNth( args[0], n ));
}
/** Return a String made from every nth character from a given string.
* Pre-Condition str is made of characters from the BMP (so one char =
* one character).
* @param str The given String
* @param n The skip value through str.
* @return a String composed of every n-th character of str
*/
// There are several ways to iterate over code points in modern Java. In
// this code, I use the String.codePoints method to produce a "stream" of
// code points (ints), "reduced" to an array.
// I also normalize the String, but there's no need to validate it.
// (The NFC form is best for text compatibility, when there are no
// security concerns, in which case, use "NFKC" normal form instead.)
public static String everyNth ( String raw, int n ) {
String str = Normalizer.normalize( raw, Normalizer.Form.NFC );
StringBuilder sb = new StringBuilder( raw.length() );
int i = 0;
for( int cp : str.codePoints().toArray() ) {
if ( i % n == 0 ) {
sb.appendCodePoint( cp );
}
++i;
}
return sb.toString();
}
}