문제 링크입니다: https://www.codewars.com/kata/statistics-for-an-athletic-association/train/cpp
문제 해석하는데 걸린 시간 정말 오래 걸렸습니다.
처음에 hh|mm|ss가 팀 당 3명씩 출전시켜서 hh, mm, ss 그룹끼리 평균을 내는 문제인 줄 알았다가 한참 지나고 나서야 시간/분/초 기록인 것을 깨달았습니다.
또한 hh/mm/ss 중 하나라도 00이라면 NULL 포인터가 들어간다고 문제에 적혀있어서 예외처리하느라 코드가 상당히 지저분해졌습니다.
개인적으로 마음에 드는 코드는 아니지만(이쁘지 않고 상당히 지저분합니다 ㅠ) 그래도 풀었다는 것에 의의를 두고 나중에 수정해보겠습니다!
/*
당신은 지역 스포츠팀의 "컴퓨터 전문가"이다.
많은 팀의 육상선수들이 경쟁하려고 한 곳에 모였다.
각 팀마다의 기록이 시|분|초 단위로 저장된다.
예를 들어 5개의 팀이 있다면 아래와 같이 저장된다.
"01|15|59, 1|47|6, 01|17|20, 1|32|34, 2|3|17"
각 회차마다 팀들의 기록 범위, 평균, 그리고 중간값을 구하는 함수를 정의하고
문자열을 반환하는데 "Range: hh|mm|ss Average: hh|mm|ss Median: hh|mm|ss"와 같은 형태로 반환하시오
*/
#include <iostream>
#include <vector>
#include <algorithm>
#include <string>
using namespace std;
class Stat
{
public:
static std::string stat(const std::string &strg);
};
//범위
std::string getRange(vector<int> &v)
{
std::string range;
int max, min;
max = min = v[0];
for (int i = 1; i < v.size(); i++)
{
if (max < v[i])
max = v[i];
if (min > v[i])
min = v[i];
}
int result = max - min;
if ((result / 3600) < 10)
range += '0';
range += to_string(result / 3600);
range += '|';
if ((result / 60) % 60 < 10)
range += '0';
range += to_string((result / 60) % 60);
range += '|';
if (result % 60 < 10)
range += '0';
range += to_string(result % 60);
return range;
}
//평균
string getAverage(vector<int> &v)
{
std::string avg;
int sum = 0;
for (int i = 0; i < v.size(); i++)
sum += v[i];
int average = sum / v.size();
if (average / 3600 < 10)
avg += '0';
avg += to_string(average / 3600);
avg += '|';
if ((average / 60) % 60 < 10)
avg += '0';
avg += to_string((average / 60) % 60);
avg += '|';
if (average % 60 < 10)
avg += '0';
avg += to_string(average % 60);
return avg;
}
//중간값
string getMedian(vector<int> &v)
{
std::string med;
int length = v.size();
int median;
sort(v.begin(), v.end()); //정렬을 시킨다
if (length % 2)
median = v[length / 2];
else
median = (v[length / 2] + v[length / 2 - 1]) / 2;
if (median / 3600 < 10)
med += '0';
med += to_string(median / 3600);
med += '|';
if ((median / 60) % 60 < 10)
med += '0';
med += to_string((median / 60) % 60);
med += '|';
if (median % 60 < 10)
med += '0';
med += to_string(median % 60);
return med;
}
std::string Stat::stat(const std::string &strg)
{
if (strg.empty())
return "";
vector<int> record;
string result;
int idx = 0;
while (1)
{
int sum = 0, cnt = 0;
int digit[2];
for (;strg[idx] != '|';idx++)
if(strg[idx]!=NULL)
digit[cnt++] = strg[idx]-'0';
//시간
if (cnt == 1)
{
sum += digit[0] * 3600; //한자리 숫자일 경우
}
else if (cnt == 2)
{
sum += (digit[0] * 10 + digit[1]) * 3600; //두자리 숫자일 경우
}
//분
cnt = 0, idx++;
for (;strg[idx] != '|'; idx++)
if(strg[idx]!=NULL)
digit[cnt++] = strg[idx]-'0';
if (cnt == 1)
{
sum += digit[0] * 60;
}
else if (cnt == 2)
{
sum += (digit[0] * 10 + digit[1]) * 60;
}
//초
cnt=0, idx++;
if (strg[idx] != NULL)
digit[cnt++] = strg[idx++] - '0';
if (strg[idx] == ',')
{
sum += digit[0];
idx += 2;
}
else
{
if (idx == strg.length())
{
record.push_back(sum);
break;
}
else
{
digit[cnt++] = strg[idx++] - '0';
sum += (digit[0] * 10 + digit[1]);
}
}
record.push_back(sum);
if (idx == strg.length())
break;
if (strg[idx] == ',')
idx += 2;
}
result += "Range: ";
result += getRange(record);
result += " Average: ";
result += getAverage(record);
result += " Median: ";
result += getMedian(record);
return result;
}
int main(void)
{
std::string l = "01|15|59, 1|47|16, 01|17|20, 1|32|34, 2|17|17";
cout << Stat::stat(l) << endl;
l = "02|15|59, 2|47|16, 02|17|20, 2|32|34, 2|17|17, 2|22|00, 2|31|41";
cout << Stat::stat(l) << endl;
return 0;
}
개발환경:Visual Studio 2017
지적, 조언, 질문 환영입니다! 댓글 남겨주세요~
'알고리즘 > codewars' 카테고리의 다른 글
codewars: Playing on a chessboard (0) | 2018.02.01 |
---|---|
codewars: Tank Truck (0) | 2018.01.30 |
codewars: Simple Encryption #1 - Alternating Split (0) | 2018.01.30 |
codewars: Build a pile of Cubes (0) | 2018.01.29 |
codewars: Fibonacci, Tribonacci and friends (0) | 2018.01.29 |