Your order, please, CodeWars Kata

오랜만에 코딩 테스트를 진행해 봤습니다. 예전에는 주로 프로그래머스를 이용했었는데요. 다시 들어가 보니 코딩 테스트 사이트라기보다는 채용 연계 사이트로 변신한 것 같은 느낌이네요. 그래서 사이트를 찾다 보니 코드워즈(CodeWars)라는 외국 사이트가 눈에 띄었습니다.

 

CodeWars?

코드워즈 로고

코드워즈(CodeWars)는 유저들이 협력해서 코딩 테스트를 만들고 평가하는 공간입니다. 프로그래머스에도 비슷한 서비스가 있지만 회사에서 준비한 코딩 테스트 위주라면, 코드워즈는 유저가 직접 코딩 테스트 문제를 만들고 평가하는 것이 주력입니다.

유저들을 위한 재미 요소도 많아 괜찮은 사이트인 것 같습니다. 보통 연습하기, 훈련하기 등으로 명명하는 코딩 테스트 훈련을 이곳에서는 'Kata'라고 부릅니다. 유도에서 따온 이 단어는 무언가를 갈고닦는 것을 의미합니다.

레벨링 시스템도 존재합니다. 'kyu'라고 부르는 이 레벨 시스템은 마스터 레벨과의 거리를 의미합니다. 그래서 처음 8 kyu에서 시작해서 레벨이 올라갈 때마다 7 kyu, 6 kyu 순으로 숫자가 내려갑니다. 마스터 레벨에 도달하면 거꾸로 숫자가 올라가는 시스템이라고 합니다. 태권도나 유도에서의 단수와 비슷하다고 보면 될 것 같습니다. 어릴 적 기억을 더듬어보면 검은 띠를 따기 전에 흰 띠에서 시작해서 노랑 띠 빨강 띠 이렇게 올라가다가 검은 띠를 따고 나면 1단, 2단 올라가는 것과 비슷한 시스템이라고 볼 수 있습니다.

상당히 많은 수의 문제를 제공하고 있고, 다양한 언어를 지원합니다. 대부분 사이트에서 단순히 테스트 데이터만 제공되는 것에 반해 코드워즈에서는 Junit 테스트 클래스를 기본으로 제공합니다. 그래서 Junit을 이용한 TDD를 연습하기에도 적합한 사이트가 되겠습니다.

저는 현재 이 곳에서 12문제를 풀었고 현재 6 kyu가 되었습니다. 국내 개발자뿐 아니라 세계 곳곳의 개발자들이 작성한 Best Practice를 볼 수 있다는 것이 굉장히 매력적이고, 그래서 문제 하나하나를 빨리 풀고 싶어 지는 장점이 있네요. 앞으로 이 곳에서 풀은 문제들을 하나하나 리뷰하는 콘텐츠를 진행해볼까 합니다.

 

Your order, please

사진: CodeWars

www.codewars.com/kata/55c45be3b2079eccff00010f

Details

Your task is to sort a given string. Each word in the string will contain a single number. This number is the position the word should have in the result.

Note: Numbers can be from 1 to 9. So 1 will be the first word (not 0).

If the input string is empty, return an empty string. The words in the input String will only contain valid consecutive numbers.

 

Examples

"is2 Thi1s T4est 3a"  -->  "Thi1s is2 3a T4est"
"4of Fo1r pe6ople g3ood th5e the2"  -->  "Fo1r the2 g3ood 4of th5e pe6ople"
""  -->  ""

 

입력 데이터로 단어들이 주어 집니다. 매 단어는 숫자를 포함하고 있습니다. 숫자는 1에서 9까지이고 우리는 입력단 단어들을 이 숫자를 이용해서 오름차순으로 정렬하여 출력해야 합니다.

 

My Solution

코드가 엄청 길어졌습니다. Java 8 이상 API에 익숙하지가 않아서.. (경력 얼마나 됐다고 벌써 Old 한 개발자가 된 기분) 예전 API 위주로 사용하니 코드가 엄청 기네요.

가장 심플하게 생각해서 단어에 포함된 숫자를 추출해서 단어와 함께 VO를 구성하고 이 VO를 정렬하여 출력했습니다.

  1. WordVO 작성: 단어와 단어에 포함된 숫자를 쌍으로 묶어주기 위해서 클래스를 작성해줬습니다.
  2. 기존 단어를 VO 배열로 변환하기
  3. VO배열 정렬하기: Arrays.sort()와 Comparator를 이용해서 정렬
  4. 배열 출력하기: WordVO 클래스에서 toString() 메서드를 재정의해서 출력

Stream을 이용한 배열 정렬이라든가, String.join()을 이용한 스트링 배열의 출력과 같은 부분을 놓쳐서 아쉬웠고, 이런 API들을 이용한다면 더 효율적인 코드를 만들 수 있을 것 같습니다.

package com.codewars;

import java.util.Arrays;
import java.util.Comparator;
import java.util.Optional;
import java.util.stream.Stream;

public class Order {

    public static String order(String words) {
        // ...
        String[] wordList = words.split(" ");
        WordVO[] wordVos = new WordVO[wordList.length];
        int arrayIndex = 0;
        for (String word : wordList) {

            for (int i = 0; i < word.length(); i++) {
                int order = 0;
                try {
                    order = Integer.parseInt(String.valueOf(word.charAt(i)));
                    wordVos[arrayIndex] = new WordVO(word, order);
                    arrayIndex++;
                    break;
                } catch (NumberFormatException e) {

                }

            }
        }

        Arrays.sort(wordVos, new Comparator<WordVO>() {
            @Override
            public int compare(WordVO o1, WordVO o2) {
                return (o1.number > o2.number ? 1 : -1);
            }
        });

        Stream<WordVO> result = Arrays.stream(wordVos);
        StringBuffer sb = new StringBuffer();
        result.forEach(item -> sb.append(Optional.ofNullable(item).orElse(new WordVO("", 0)).toString()));

        return sb.toString().strip();
    }

}

class WordVO {
    public String word;
    public int number;

    public WordVO(String word, int number) {
        this.word = word;
        this.number = number;
    }

    @Override
    public String toString() {
        return word + " ";
    }
}

github.com/finewink/CodeWars-Maven/blob/30a6b12c922128bf1e85e58f184a910631e720a3/codewars/src/main/java/com/codewars/Order.java

Best Practices

문제를 풀고 나면 다른 사람들의 BP를 볼 수 있다는 점이 좋습니다.

import java.util.Arrays;
import java.util.Comparator;

public class Order {
  public static String order(String words) {
    return Arrays.stream(words.split(" "))
      .sorted(Comparator.comparing(s -> Integer.valueOf(s.replaceAll("\\D", ""))))
      .reduce((a, b) -> a + " " + b).get();
  }
}

저 긴 소스가 한 줄로 만들어질 수 있다는 게 충격적이면서도 매력적이죠. stream()을 이용해서 배열에 접근하면서 sorted()reduce()를 이용해서 결과까지 한방에 만들어냈습니다. 이 소스를 보니 Java 8 문법을 얼른 익혀야겠다는 생각이 마구 들지 않나요.

 

 

728x90
  • 네이버 블러그 공유하기
  • 네이버 밴드에 공유하기
  • 페이스북 공유하기
  • 카카오스토리 공유하기