반응형
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 |
댓글