Codewars 문제풀기 (03/22)
Take a Ten Minute Walk
- char 배열을 인자로 받는다.
- ‘e’, ‘w’, ‘s’, ‘n’에 따라 동 서 남 북으로 움직인다.
- 10번 움직였을 때 위치가 제자리라면 true를 리턴한다.
- TenMinWalk.isValid(new char[] {‘n’,’s’,’n’,’s’,’n’,’s’,’n’,’s’,’n’,’s’})) –> 제자리로 왔으므로 true
- TenMinWalk.isValid(new char[] {‘w’,’e’,’w’,’e’,’w’,’e’,’w’,’e’,’w’,’e’,’w’,’e’})); –>10번 넘게 움직였으므로 false
- TenMinWalk.isValid(new char[] {‘n’,’n’,’n’,’s’,’n’,’s’,’n’,’s’,’n’,’s’})); –> 10번 움직였으나 제자리가 아니므로 false
1. Test를 만들었다
- 
    배열 길이가 10이 아닐 때 false를 리턴해야한다. - 테스트 코드 (assertFasle(),assertTrue를 쓸 수 있지만 문제들 통일성을 위해assertEquals()사용)
 @Test public void testShouldReturnFalseWhenInputLengthIsNotTen() { //Given : Set walking count less then 10 char[] given = new char[5]; //When : Call isValid method boolean actual = TenMinWalk.isValid(given); //Then : Should return false assertEquals(false, actual); }- 실제 코드
 public class TenMinWalk { public static boolean isValid(char[] walk) { return walk.length == 10; } }
- 테스트 코드 (
- 
    배열 길이가 10이지만, 다 움직이고 제자리에 오지 않을경우 false를 리턴해야한다. - 테스트 코드
 @Test public void testShouldReturnFalseWhenWalkerNotComeStartingPoint() { //Given : Set walking count 10, not coming to starting point char[] given = {'w', 's', 'e', 'n', 'w', 'w', 'e', 'n', 'w','w'}; //When : Call isValid method boolean actual = TenMinWalk.isValid(given); //Then : Should return false assertEquals(false, actual); }- 실제 코드
 public class TenMinWalk { public static boolean isValid(char[] walk) { if (walk.length != 10) { return false; } int wCount = 0; int nCount = 0; int sCount = 0; int eCount = 0; int invalidCount = 0; for (int i = 0; i < walk.length; i++) { switch (walk[i]) { case 'w': wCount++; break; case 'n': nCount++; break; case 'e': eCount++; break; case 's': sCount++; break; default: invalidCount++; break; } } if (wCount == eCount && nCount == sCount) { return true; } return false; } }- 위, 아래 / 좌, 우 쌍으로 이동 횟수가 같아야 결국 제자리로 돌아오기 때문에 각 count를 세고 같은지 판단하여 true, false를 리턴하도록 풀었다.
 
- 
    배열의 길이가 10이고, 다 움직이고 제자리로 돌아온 경우에 true를 리턴해야한다. - 테스트 코드
 @Test public void testShouldReturnTrueWhenWalkerComeStartingPoint() { //Given : Set walking count less then 10 char[] given = {'w', 's', 'e', 'n', 'w', 's', 'e', 'n', 'w','e'}; //When : Call isValid method boolean actual = TenMinWalk.isValid(given); //Then : Should return true assertEquals(true, actual);- 
        실제 코드 그대로 - Success(약 20분)
 
 
2. 리팩토링
stream.filter()를 사용하면 switch문이 필요없지 않을까 해서 사용해봤다.
public class TenMinWalk {
  public static boolean isValid(char[] walk) {
    if (walk.length != 10) {
      return false;
    }
    long nCount = String.valueOf(walk).chars().filter(character -> character == 'n').count();
    long sCount = String.valueOf(walk).chars().filter(character -> character == 's').count();
    long wCount = String.valueOf(walk).chars().filter(character -> character == 'w').count();
    long eCount = String.valueOf(walk).chars().filter(character -> character == 'e').count();
    return wCount == eCount && nCount == sCount;
  }
}
- 변수 선언 없이 그냥 return에 적어주려 햇는데 너무 길어지고 지저분해 보여서 변수 할당해주었다.
3. 답 비교, 느낀점
Best Practice 가장 많이 받은 코드
public class TenMinWalk {
  public static boolean isValid(char[] walk) {
    if (walk.length != 10) {
      return false;
    }
    int x = 0, y = 0;
    for (int i = 0; i < 10; i++) {
      switch (walk[i]) {
        case 'n':
          y++;
          break;
        case 'e':
          x++;
          break;
        case 's':
          y--;
          break;
        case 'w':
          x--;
          break;
      }
    }
    return x == 0 && y == 0;
  }
}
- switch/case문을 사용하는것보다 Stream을 사용하는것이 더 깔끔해보여서 사용했는데 Best Practice는 오히려 이 방법이 더 많이 받았다. 그리고 나는 w, e, s, n count를 모두 세었는데 여기서는 x, y좌표로 ++, – 해주었다. 변수 선언을 덜 해서 좋은것 같다.
- 문제가 좀 길어서 잘못 이해했다. 처음에 그냥 10번 count에 맞게 이동만 하면 true를 return한다고 생각해서 그렇게 풀다가 마지막 테스트를 보고 제자리로 돌아와야한다는 것을 알았다. 다시 한번 테스트 코드의 중요성을 알게되었다..
 
      
     
      
댓글남기기