반응형
Assembler로 들어온 문자열을 해석하여 실행하여 unordered_map<string, int>로 구성된 저장된 값들을 반환하는 문제이다!
MAIN
#include <string>
#include <unordered_map>
Describe(SolutionTest)
{
It(Simple1)
{
std::vector<std::string> program{ "mov a 5", "inc a", "dec a", "dec a",
"jnz a -1", "inc a" };
std::unordered_map<std::string, int> out{ { "a", 1 } };
Assert::That(assembler(program), Equals(out));
}
};
ANSWER
#include <string>
#include <unordered_map>
#include <cctype>
std::vector<std::string> split(const std::string line)
{
std::vector<std::string> splitedLine;
std::string temp;
for(int i=0; i< (int)line.size(); i++)
{
if(line[i] == ' ')
{
splitedLine.push_back(temp);
temp.clear();
} else {
temp += line[i];
}
}
splitedLine.push_back(temp);
return splitedLine;
}
bool isDigit(std::string c)
{
if(c[0] == '-') return true;
int digit = c[0] - '0';
if(digit == 0 || digit == 1 || digit == 2 || digit == 3 || digit == 4 || digit == 5 || digit == 6 || digit ==7 || digit == 8 || digit == 9)
{
return true;
}
return false;
}
std::unordered_map<std::string, int> assembler(const std::vector<std::string>& program)
{
std::unordered_map<std::string, int> maps;
for (int i=0; i<(int)program.size(); i++)
{
std::cout << program[i] << std::endl;
}
for(int i=0; i<(int)program.size(); i++)
{
std::string line = program[i];
std::vector<std::string> splitedLine = split(line);
if (splitedLine[0] == "mov") {
if(isDigit(splitedLine[2]))
{
maps[splitedLine[1]] = std::stoi(splitedLine[2]);
}
else {
maps[splitedLine[1]] = maps[splitedLine[2]];
}
}
else if (splitedLine[0] == "inc")
{
maps[splitedLine[1]]++;
}
else if (splitedLine[0] == "dec")
{
maps[splitedLine[1]]--;
}
else if (splitedLine[0] == "jnz")
{
//jump to splitedLine[2]
if (isDigit(splitedLine[1]))
{
if(std::stoi(splitedLine[1]) != 0)
{
//check y is digit
if (isDigit(splitedLine[2]))
i = i + std::stoi(splitedLine[2]) - 1;
else
i = i + maps[splitedLine[2]] - 1;
}
}
else
{
if (maps[splitedLine[1]] != 0) {
//check y is digit
if (isDigit(splitedLine[2]))
i = i + std::stoi(splitedLine[2]) - 1;
else
i = i + maps[splitedLine[2]] - 1;
}
}
}
}
return maps;
}
코드가 지저분한데 string을 line 단위로 잘 뽑아서 공백이 나오는 부분을 가지고 splitedLine을 구하고
그 첫번 째 값이 명령어가 될 것이기 때문에 그 명령어에 해당하는 연산을 수행하면된다.
여기서 까다로웠던 부분은 jnz 부분인데 우리는 line의 size를 알고 있기 때문에 그 size만큼 for문을 돌면서 i를 수정하여 그 line으로 가서 그 명령어를 다시 수행하는 방식으로 구현을 하면 된다.
이게 숫자가 올수도 있고 변수가 올 수도 있어서 이 것을 다루는 부분이 좀 까다롭다.
코드를 정리를 따로 안하고 올려서 지저분한데 막히는 분들에게 도움이 되었으면 한다.
질문이 있으면 댓글을 달아주시면 답변 드립니다!
300x250
'알고리즘 > Codewars' 카테고리의 다른 글
Codewars - [7 kyu] Reverse words (0) | 2022.05.03 |
---|---|
Codewars - [6 kyu] Sum consecutives (0) | 2022.01.17 |
댓글