CodeKata/Codewars

[CK] Decode the Morse code

anothel 2021. 10. 27.

In this kata you have to write a simple Morse code decoder. While the Morse code is now mostly superseded by voice and digital data communication channels, it still has its use in some applications around the world.

The Morse code encodes every character as a sequence of "dots" and "dashes". For example, the letter A is coded as ·−, letter Q is coded as −−·−, and digit 1 is coded as ·−−−−. The Morse code is case-insensitive, traditionally capital letters are used. When the message is written in Morse code, a single space is used to separate the character codes and 3 spaces are used to separate words. For example, the message HEY JUDE in Morse code is ···· · −·−−   ·−−− ··− −·· ·.

NOTE: Extra spaces before or after the code have no meaning and should be ignored.

In addition to letters, digits and some punctuation, there are some special service codes, the most notorious of those is the international distress signal SOS (that was first issued by Titanic), that is coded as ···−−−···. These special codes are treated as single special characters, and usually are transmitted as separate words.

Your task is to implement a function that would take the morse code as input and return a decoded human-readable string.

For example:

decodeMorse('.... . -.--   .--- ..- -.. .')
//should return "HEY JUDE"

 

Solution

std::string decodeMorse(std::string morseCode) {
  std::string decoded;
  int spaceCount = 0;
  std::string morseWord;
  bool isStart = false;

  for( auto p : morseCode ) {
    if( p == ' ' ) {
      if(3 == ++spaceCount && isStart == true) {
        decoded += " ";        
      } else {
        decoded += MORSE_CODE[morseWord];        
        morseWord.clear();
      }      
      continue;
    } else {
      isStart = true;
      spaceCount = 0;
      morseWord += p;
    }
  }
  decoded += MORSE_CODE[morseWord];
  if(decoded.at(decoded.length()-1) == ' ') {
    decoded.erase(decoded.length()-1, decoded.length());
  }
  return decoded;
}

 

Shirohana의 코드

#include <regex>

const std::regex morse("([^\\s]+|\\s{3})");

std::string decodeMorse(std::string morseCode) {
  std::string decoded;
  
  auto begin = morseCode.begin() + morseCode.find_first_not_of(' ');
  auto end = morseCode.begin() + morseCode.find_last_not_of(' ') + 1;
  
  for (auto it = std::sregex_iterator(begin, end, morse); it != std::sregex_iterator(); ++it) {
    std::string str = it->str();
    decoded += str == "   " ? " " : MORSE_CODE[str];
  }
  
  return decoded;
}

 

dascandy의 코드

std::string decodeMorse(std::string morseCode) {
  std::string decoded;
  const char* current = morseCode.data(), *end = current + morseCode.size();
  
  // Strip off all leading and trailing space first
  while (*current == ' ') current++;
  while (end[-1] == ' ') end--;
  
  while (current < end) {
    if (*current == ' ') {
      decoded += ' ';
      current += 2;
    } else {
      const char* start = current;
      while (current < end && *current == '.' || *current == '-') ++current;
      decoded += MORSE_CODE[std::string(start, current)];
      current++;
    }
  }
  return decoded;
}

 

후기

모스부호를 받아서 읽을 수 있는 문장으로 변환하는 문제였다. 처음 문제를 보고 놀라고, 이걸 기어코 풀어내는 나에게 놀라고, 이 문제를 이렇게 풀어낼 수도 있구나 하며 남의 코드를 보고 총 3번 나를 놀라게 한 문제였다.

어떻게 해서든 모스부호끼리 엮는 건 됐는데 공백을 찾아내는 게 힘들었고, 마지막엔 필요 없는 시작할 때 나오는 공백과 마지막에 나오는 필요 없는 공백들을 제거하는 것이 어려웠다. 이걸 코드로 하나하나 제거해줬는데, 남의 코드를 보니 대부분 STL 정규표현식을 사용했다.

두 번째 남의 코드에서는 내가 까다롭게 생각한 부분을 제거하고 시작했다. 이 부분을 제거하면 그나마 문제를 풀어나가기가 수월하긴 하겠지..

참 어렵고 난해했던 코드였다.

 

(url: https://www.codewars.com/kata/54b724efac3d5402db00065e)

 

'CodeKata > Codewars' 카테고리의 다른 글

[CK] Product of consecutive Fib numbers  (0) 2021.10.28
[CK] Greed is Good  (0) 2021.10.27
[CK] Decode the Morse code  (0) 2021.10.27
[CK] Mexican Wave  (0) 2021.10.25
[CK] Rectangle into Squares  (0) 2021.10.25
[CK] Playing with digits  (0) 2021.10.21

댓글0