문제해결능력의 부족함을 느껴 코드워즈 문제풀이를 시작했습니다. 제 정답과 베스트 솔루션을 비교해보니 코드양이 너무 비교되더라구요. 다음과 같은 조건에 부합하는 코드를 작성해야 합니다.

우선 Javascript로 먼저 작성해본 다음 Python과 Java로도 작성합니다.


조건

  • x와 o가 둘 다 적어도 1개 이상 포함되어야 하고 갯수가 같아야한다.
  • 메서드는 불리언을 리턴해야만 한다.

테스트 케이스

Test.assertEquals(XO('xo'), true);
Test.assertEquals(XO('XO'), true);
Test.assertEquals(XO('xo0'), true);
Test.assertEquals(XO('xxxoo'), false);
Test.assertEquals(XO('xxOo'), true);
Test.assertEquals(
  XO(''),
  true,
  'Empty string contains equal amount of x and o'
);
Test.assertEquals(XO('xxxxxoooxooo'), true);
Test.assertEquals(XO('xxxm'), false);
Test.assertEquals(XO('ooom'), false);
Test.assertEquals(XO('Oo'), false);
Test.assertEquals(
  XO('abcdefghijklmnopqrstuvwxyz'),
  true,
  'Alphabet contains equal amount of x and o'
);

Javascript

제가 작성한 코드는 아래와 같습니다.

function XO(str) {
  let arr = str.toLowerCase(); // 문자열에 있는 대문자를 소문자로 바꾼다.
  let count = 0;

  for (let i = 0; i < str.length; i++) {
    // x와 o의 개수가 같으면 count가 0이 되도록 만든다.
    if (arr[i] === 'o') {
      count += 1;
    } else if (arr[i] === 'x') {
      count -= 1;
    }
  }

  if (count == 0) {
    // count가 0이면 true를 아니면 false를 반환한다.
    return true;
  } else {
    return false;
  }
}

문제를 풀고나니 솔루션을 볼 수 있었습니다. 두가지 솔루션이 가장 맘에 들더군요.

  1. 정규식을 이용했다. 정규식에 관해 정리해놓은 내용은 여기로 들어가서 확인합니다.
function XO(str) {
  return (str.match(/x/gi) || []).length === (str.match(/o/gi) || []).length; // 대소문자 구별없이 반환된 x의 개수와 o의 개수를 비교한다.
}
  1. ES6 배열 메서드를 이용했다. 배열 메서드에 관해 정리해놓은 내용은 여기로 들어가서 확인합니다.
function XO(str) {
  let arr = str.toLowerCase().split(''); // 문자열에 있는 대문자를 소문자로 만들고 한글자씩 분리한다.
  return (
    arr.filter(o => o === 'o').length === arr.filter(x => x === 'x').length // 필터한 배열의 요소가 x, o와 정확히 일치하는 것의 개수를 비교한다.
  );
}

Python

제가 작성한 코드는 다음과 같습니다. 자바스크립트와 같은 방식으로 풀었습니다.

def xo(s):
    count = 0
    for i in s.lower(): # 문자열에 있는 대문자를 소문자로 바꾼뒤 반복문으로 x와 o의 갯수가 같으면 count가 0이 되도록 만든다.
        if i == 'x':
            count += 1
        elif i == 'o':
            count -= 1

    if count == 0: # count가 0이면 True를 아니면 False를 반환한다.
        return True
    else:
        return False

역시 문제를 풀고나니 솔루션을 볼 수 있었습니다. 다음은 베스트 솔루션입니다.

def xo(s):
    return s.lower().count('x') == s.lower().count('o') # 카운트한 배열의 요소가 x, o와 정확히 일치하는 것의 개수를 비교한다.

Java

제가 작성한 코드는 다음과 같습니다. 자바스크립트와 같은 방식으로 풀었습니다.

public class XO {

  public static boolean getXO (String str) {
    str = str.toLowerCase(); // 문자열에 있는 대문자를 소문자로 바꾼다.
    int count = 0;

    for (int i = 0; i < str.length(); i++) {
    // x와 o의 개수가 같으면 count가 0이 되도록 만든다.
      if (str.charAt(i) == 'x') {
        count += 1;
      } else if (str.charAt(i) == 'o') {
        count -= 1;
      }
    }

    if (count == 0) { // count가 0이면 True를 아니면 False를 반환한다.
      return true;
    } else {
      return false;
    }
  }
}

역시 문제를 풀고나니 솔루션을 볼 수 있었습니다. 다음은 베스트 솔루션입니다.

public class XO {

  public static boolean getXO (String str) {
    str = str.toLowerCase(); // 문자열에 있는 대문자를 소문자로 바꾼다.
    return str.replace("o","").length() == str.replace("x","").length(); // 리플레이스한 배열의 요소 x와 o의 길이가 서로 정확히 일치하는 것의 개수를 비교한다.
  }
}

정리

이 문제를 해결한 사람들은 전부 44,425명입니다. 44,425명 중

자바 4,731명 (10.6%) 파이썬 13,554명 (30.5%) 자바스크립트 17,345명 (39.0%)

으로 자바스크립트로 문제를 해결한 사람이 가장 많았습니다. 아직까지는 3언어 모두 이렇다 할만한 코드양의 차이는 없습니다. 난이도 높은 문제를 풀다보면 차이가 보이겠죠.