알고리즘/codewars

codewars: Statistics for an Athletic Association

꾸준함. 2018. 1. 30. 18:04

문제 링크입니다: 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


지적, 조언, 질문 환영입니다! 댓글 남겨주세요~

반응형