RailsOnTiles.java
import static org.junit.Assert.assertEquals;
import org.junit.Test;
/**
* 3x3マスの各位置のタイル。東西南北に位置するタイルのindexを持つ
*/
class Tile {
int northernIndex;
int easternIndex;
int sourthernIndex;
int westernIndex;
char name;
Tile(int n, int e, int s, int w, char nm) {
northernIndex = n;
easternIndex = e;
sourthernIndex = s;
westernIndex = w;
name = nm;
}
/**
* 東西南北のindexを返す。9の場合はタイルの外
*/
int get(char bearing) {
if (bearing == 'N') {
return northernIndex;
}
if (bearing == 'E') {
return easternIndex;
}
if (bearing == 'S') {
return sourthernIndex;
}
return westernIndex;
}
@Override
public String toString() {
return String.valueOf(name);
}
}
/**
* 既定の3つのレール。各方角から入ったときの出口の方角を持つ
*/
class Rail {
char northernExit;
char easternExit;
char sourthernExit;
char westernExit;
Rail(char n, char e, char s, char w) {
northernExit = n;
easternExit = e;
sourthernExit = s;
westernExit = w;
}
/**
* enter方角から入ってきた場合のexit方角を返す
*/
char getExit(char enter) {
if (enter == 'N') {
return northernExit;
}
if (enter == 'E') {
return easternExit;
}
if (enter == 'S') {
return sourthernExit;
}
return westernExit;
}
}
/**
* 問題: http://nabetani.sakura.ne.jp/hena/ord5railsontiles/
*/
public class RailsOnTiles {
protected String solve(String input) {
Rail[] rails = createRails();
Tile[] tiles = createTiles();
String result = "";
result = loop(tiles, rails, 'S', 1, input, result);
return result;
}
protected String loop(Tile[] tiles, Rail[] rails, char bearing, int index,
String input, String result) {
if (isOut(index)) {
return result;
}
result += tiles[index].toString();
int railId = Integer.valueOf(String.valueOf(input.charAt(index)));
Rail rail = rails[railId];
char exitBearing = rail.getExit(invert(bearing)); // 前回の出口の方角を反転して、入口として与え、次の出口の方角を得る
int nextIndex = tiles[index].get(exitBearing); // 出て行く方角のindexを得る
return loop(tiles, rails, exitBearing, nextIndex, input, result);
}
protected char invert(char c) {
if (c == 'N') {
return 'S';
}
if (c == 'E') {
return 'W';
}
if (c == 'S') {
return 'N';
}
return 'E';
}
protected boolean isOut(int i) {
return 8 < i ? true : false;
}
protected Rail[] createRails() {
Rail[] result = new Rail[3];
result[0] = new Rail('S', 'W', 'N', 'E');
result[1] = new Rail('E', 'N', 'W', 'S');
result[2] = new Rail('W', 'S', 'E', 'N');
return result;
}
protected Tile[] createTiles() {
Tile[] result = new Tile[9];
result[0] = new Tile(9, 1, 3, 9, 'A');
result[1] = new Tile(9, 2, 4, 0, 'B');
result[2] = new Tile(9, 9, 5, 1, 'C');
result[3] = new Tile(0, 4, 6, 9, 'D');
result[4] = new Tile(1, 5, 7, 3, 'E');
result[5] = new Tile(2, 9, 8, 4, 'F');
result[6] = new Tile(3, 7, 9, 9, 'G');
result[7] = new Tile(4, 8, 9, 6, 'H');
result[8] = new Tile(5, 9, 9, 7, 'I');
return result;
}
public static void main(String[] args) {
RailsOnTiles rot = new RailsOnTiles();
System.out.println(rot.solve("101221102"));
}
protected void test(String input, String expected) {
RailsOnTiles rot = new RailsOnTiles();
assertEquals(expected, rot.solve(input));
}
@Test
public void testRailsOnTiles() throws Exception {
/* #0 */test("101221102", "BEDGHIFEH");
/* #1 */test("000000000", "BEH");
/* #2 */test("111111111", "BCF");
/* #3 */test("222222222", "BAD");
/* #4 */test("000211112", "BEFIHEDGH");
/* #5 */test("221011102", "BADGHIFEBCF");
/* #6 */test("201100112", "BEHIFCBADEF");
/* #7 */test("000111222", "BEFIH");
/* #8 */test("012012012", "BC");
/* #9 */test("201120111", "BEDABCFI");
/* #10 */test("220111122", "BADEHGD");
/* #11 */test("221011022", "BADG");
/* #12 */test("111000112", "BCFIHEBA");
/* #13 */test("001211001", "BEFI");
/* #14 */test("111222012", "BCFEHIF");
/* #15 */test("220111211", "BADEHI");
/* #16 */test("211212212", "BCFEBAD");
/* #17 */test("002112210", "BEFC");
/* #18 */test("001010221", "BEF");
/* #19 */test("100211002", "BEFIHG");
/* #20 */test("201212121", "BEFCBAD");
}
}