Path Finder #4: where are you?, CodeWars Kata
Path Finder #4: where are you?
Hey, Path Finder, where are you?
My Solution
Path Finder 시리즈의 자바 버전은 #4가 마지막입니다. 문제를 보고 굉장히 황당했습니다. 디렉션이 전혀 없기 때문입니다. 힌트는 오로지 테스트 코드였습니다. Point
클래스는 문제에서 주어집니다.
@Parameters
public static Collection<Object[]> prepTests() {
return Arrays.asList(new Object[] { "", new Point(0, 0) }, new Object[] { "RLrl", new Point(0, 0) },
new Object[] { "r5L2l4", new Point(4, 3) }, new Object[] { "r5L2l4", new Point(0, 0) },
new Object[] { "10r5r0", new Point(-10, 5) }, new Object[] { "10r5r0", new Point(0, 0) });
}
테스트 코드를 보면 동일한 입력값에 대해 다른 결과가 나오는 것을 알 수 있습니다. 이것을 보고 이 문제를 풀기 위해서는 멤버 변수를 static
변수를 통해 상태값을 유지할 필요가 있다는 것을 알 수 있습니다.
다음으로 풀어야 할 것은 r, l, R, L
문자의 쓰임새입니다. 옆에 숫자가 나오는 경우도 있기 때문에 방향을 바꾸는 지시어라는 것을 알 수 있습니다. 결국 (x, y)
로 이뤄진 2차원의 좌표상에서 방향을 움직여가며 이동하게 되는 것이기 때문에 `r, l, R, L
이 각각 어떤 방향으로 이동하는지만 알면 되는 문제였습니다. 결과적으로 r
은 오른쪽으로 방향 전환, l
은 왼쪽으로 방향 전환, R
과 L
은 반대방향으로 전환이었습니다. 이것을 코드로 옮기기 시작했습니다.
#3의 BP를 보고 객체지향적인 설계를 좀 더 신경쓰기로 마음 먹었습니다. enum Direction
을 생성하고 void move(Point now, int move)
를 통해 현재 포인트에서 이동하는 것을 구현했고요, void changeDirection(char flag)
로 방향 전환을 구현했습니다.
여기까지만 하면 나머지는 쉽습니다. 입력값을 한 글자씩 읽어가면서 `r, l, R, L
이 나오면 방향을 전환하고 숫자가 나오면 그만큼 움직여줍니다. 황당하면서도 재밌는 유형이긴 했는데 문제 해석이 너무 시간을 많이 쏟아 이런 문제는 추천드리고 싶진 않네요.
import java.awt.Point;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.regex.Pattern;
// Do your magic...!
public class PathFinder {
enum Direction {
LEFT, UP, RIGHT, DOWN;
static LinkedList<Direction> directions = new LinkedList<Direction>();
static {
directions.addAll(Arrays.asList(Direction.values()));
}
public static void move(Point now, int move) {
Direction peek = directions.peek();
if (peek == UP) {
now.setLocation(now.getX(), now.getY() + move);
} else if (peek == RIGHT) {
now.setLocation(now.getX() + move, now.getY());
} else if (peek == DOWN) {
now.setLocation(now.getX(), now.getY() - move);
} else if (peek == LEFT) {
now.setLocation(now.getX() - move, now.getY());
}
}
public static void changeDirection(char flag) {
if (flag == 'r') {
directions.addLast(directions.removeFirst());
} else if (flag == 'R') {
directions.addLast(directions.removeFirst());
directions.addLast(directions.removeFirst());
} else if (flag == 'L') {
directions.addLast(directions.removeFirst());
directions.addLast(directions.removeFirst());
} else {
directions.addFirst(directions.removeLast());
}
}
}
static Point now = new Point(0, 0);
public static Point iAmHere(String path) {
StringBuffer sb = new StringBuffer();
for (int i = 0; i < path.length(); i++) {
if (Pattern.matches("r|l|R|L", path.charAt(i) + "")) {
if (sb.length() > 0) {
int move = Integer.parseInt(sb.toString());
sb.setLength(0);
Direction.move(now, move);
}
Direction.changeDirection(path.charAt(i));
} else {
sb.append(path.charAt(i));
}
}
if (sb.length() > 0) {
int move = Integer.parseInt(sb.toString());
sb.setLength(0);
Direction.move(now, move);
}
return now;
}
}
Best Practice
BP는 주어진 Point
클래스를 상속한 Me
라는 클래스를 활용했습니다. 이 클래스를 static으로 선언하여 상태를 유지했고, move
, back
, turn
메소드를 통해 방향전환과 이동을 처리했네요. 이 BP 역시 객체지향 설계가 돋보이는 코드입니다.
import java.util.regex.*;
import java.awt.Point;
public class PathFinder {
private static final Pattern P_PATH = Pattern.compile("\\d+|.");
private static final Me ME = new Me(0,0);
private static class Me extends Point {
private int dx=-1, dy=0;
private Me(int x, int y) { super(x,y); }
private Point here() { return new Point(this); }
private void move(int n) { x += n*dx; y += n*dy; }
private void back() { dx*=-1; dy*=-1; }
private void turn(char c) { int oldX = dx;
dx = dy==0 ? 0 : dy * (c=='l'?-1:1);
dy = oldX==0 ? 0 : oldX * (c=='r'?-1:1); }
@Override public String toString() { return String.format("x,y=%d,%d (dx,dy=%d,%d)", x,y,dx,dy); }
}
public static Point iAmHere(String path) {
Matcher m = P_PATH.matcher(path);
while (m.find()) {
String v = m.group();
if ("RL".contains(v)) ME.back();
else if ("rl".contains(v)) ME.turn(v.charAt(0));
else ME.move(Integer.parseInt(v));
}
return ME.here();
}
}
'IT Contents > 프로그래밍 팁' 카테고리의 다른 글
Path Finder #3: the Alpinist, CodeWars Kata 자바 솔루션 (0) | 2021.04.23 |
---|---|
Path Finder #2: shortest path, CodeWars Kata 자바 솔루션 (0) | 2021.04.22 |
Path Finder #1: can you reach the exit?, CodeWars Kata 자바 솔루션 (0) | 2021.04.21 |
Breadcrumb Generator, CodeWars Kata 자바 솔루션 (0) | 2021.04.20 |
Befunge Interpreter, CodeWars Kata 자바 솔루션 (0) | 2021.04.19 |
최근댓글