Codewars 문제풀기 (04/09)
Printer Errors
- String을 인수로 받는다.
- String은 a~z문자만 있다고 가정한다.
- 입력 String에서 m-z 문자를 error문자로 보고 error 문자를 counting한다
- “(error문자수)/전체문자개수” 형태의 String을 리턴한다.
1. Test와 리팩토링
-
우선 출력 포맷은 “숫자/숫자”의 형태의 String을 리턴해야한다.
-
테스트 코드
@Test public void testShouldReturnFormattedString() { // Given: Set string will not print error String given = "abcdefghijklm"; // When: Call printerError method String actual = Printer.printerError(given); // Then: Should Return "error/total" string format assertEquals("0/13", actual); }
-
실제 코드
public class Printer { public static String printerError(String s) { return String.format("%d/%d", 0, 13); } }
- 출력 포맷을 “%d/%d”형태로 하기위해 String.format()을 사용했다.
-
-
입력 String이 a~m중의 문자로만 구성되어있는 경우 즉, error 문자가 없을 경우 0/총문자개수 형태로 출력한다.
-
테스트 코드
@Test public void testShouldReturnNoErrorCountWhenStringContainsAtoM() { // Given: Set string contains a~m character String given = "ababcdhefefghhijkkllmmaa"; // When: Call printerError method String actual = Printer.printerError(given); // Then: Should Return "error/total" string format assertEquals("0/24", actual); }
-
실제 코드
public class Printer { public static String printerError(String s) { return String.format("%d/%d", 0, s.length()); } }
- error문자 개수가 없다고 가정한 테스트이기 때문에 두번째 인수를 0으로 했다.
-
-
입력 String이 n~z이 포함되어 있는 경우 “error문자 개수/총문자개수” 형태로 출력한다.
-
테스트 코드
@Test public void testShouldReturnMoreThan1ErrorCountWhenStringContainsNtoZ() { // Given: Set string contains a~m character String given = "aaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbmmmmmmmmmmmmmmmmmmmxyz"; // When: Call printerError method String actual = Printer.printerError(given); // Then: Should Return "error/total" string format assertEquals("3/56", actual); }
-
실제코드
public class Printer { public static String printerError(String s) { int count = 0; for (int i = 0; i < s.length(); i++) { if (s.charAt(i) > 'm') { count++; } } return String.format("%d/%d", count, s.length()); } }
- for문을 이용해서 문자열에서 ‘m’보다 큰 문자를 counting했다.
-
-
리팩토링
-
for문 없이 stream의 filter() 메서드를 사용하면 count할 수 있을것 같다.
public class Printer { public static String printerError(String s) { long count = s.chars().filter(c -> c > 'm').count(); return String.format("%d/%d", count, s.length()); } }
- format메서드 내에서 바로 호출할 수도 있지만 지역변수로 선언하는게 더 깔끔해보인다.
-
매직넘버를 상수로 추출했다.
public class Printer { public static final char ERROR_CHAR_INDEX = 'm'; public static String printerError(String s) { long count = s.chars().filter(c -> c > ERROR_CHAR_INDEX).count(); return String.format("%d/%d", count, s.length()); } }
-
굳이 써야하나? 라는 생각도 드는데, 배운거 써먹는거라 생각하고 리팩토링했다.
-
리팩토링 요소가 더 없다고 판단해서 제출했다(리팩토링 제외 약 10분 소요)
-
-
2. 답 비교, 느낀점
Best Practice 가장 많이 받은 코드
public class Printer {
public static String printerError(String s) {
return s.replaceAll("[a-m]", "").length() + "/" + s.length();
}
}
- a~m까지의 모든 문자들을 삭제하고 남은 문자열의 길이가 결국 error 문자 count가 된다.
댓글남기기