이런저런 IT 이야기

Programming Challenges #32 본문

Algorithm

Programming Challenges #32

이런저런 IT 이야기 2023. 5. 24. 10:55
반응형

미국 사람들은 축구(football)를 soccer라고 부르긴 하지만 어쨌든 축구는 세계에서 가장 인기 있는 스포츠다. 월드컵 우승을 다섯 번이나 차지한 브라질 같은 나라에는 전국 및 지역 토너먼트가 워낙 많아서 각 토너먼트가 어떻게 돌아가는 있는지 파악하기가 힘들 정도다. 토너먼트 이름, 팀 이름, 경기 수를 받아서 지금까지의 토너먼트 순위를 출력하는 프로그램을 만들어야 한다.

두 팀 중에서 골을 더 많이 넣는 팀이 경기에 이기게 되고 적게 넣은 팀이 경기에 지게 된다. 넣은 골 수가 같으면 비기게 된다. 게임에 이기면 3점, 비기면 1점, 지면 0점의 승점을 얻는다.

팀 순위는 다음과 같은 규칙에 따라 결정된다.

 

  1. 승점 순서대로 결정
  2. 이긴 횟수가 많은 팀순으로 결정
  3. 골 득실 차(얻은 골 수 - 뺏길 골 수)를 기준으로 결정
  4. 다 득점 순으로 결정
  5. 게임 수가 적은 순서대로 결정
  6. 팀 이름에 따라 사전 순으로 결정(대소문자를 구분하지 않음)

 

입력

첫번째 줄에는 0보다 크고 1,000보다 작은 정수 N이 들어있다. 그 밑에는  N개의 토너먼트에 대한 설명이 입력되는데, 각 줄은 토너먼트 이름으로 시작된다. 이 이름은 하나의 줄에 입력되어야 하며 최대 100개 까지의 글자, 숫자, 공백 등으로 이루어진다. 그 다음 줄에는 그 토너먼트에 참가하는 팀의 갯수를 나타내는 T(1<T<=30)가 들어있다. 그 밑에는 T개의 줄이 입력되는데 각 줄마다 팀 이름이 하나씩 들어있다. 팀 이름은 최대 30문자로 구성되며 ASCII 코드로 32(스페이스) 이상인 모든 문자(‘#’, ‘@‘는 제외)가 들어갈수있다. 

팀 이름이 있는 줄다음 줄에는 그 토너먼트에서 이미 치룬 경기 횟수를 나타내는 음이 아닌 정수 G가 들어있다. G는 1,000보다 크지 않다. 그 밑으로는 G개의 줄에 걸쳐서 다음과 같은 형식으로 경기 결과가 입력된다.

 

team_name_1#goals1@goals2#team_name_2

 

예를 들어 Team A#3@1#Team B Team A Team B라는 팀간에 경기가 있었는데 Team A 3점을 Team B 1점을 냈다는걸 의미한다. 수는 20보다 작은 음이 아닌 정수로 주어진다. 게임 결과에서 언급되는 이름은 모두 이름을 열거해놓은 부분에 들어있고 어떤 팀도 자신과 경기를 같는 일은 없다.

function calculateTournamentRanking(tournamentData) {
  const tournaments = tournamentData.split("\n\n");
  const ranking = {};

  for (let i = 0; i < tournaments.length; i++) {
    const tournamentInfo = tournaments[i].split("\n");
    const tournamentName = tournamentInfo[0];
    const teamCount = parseInt(tournamentInfo[1]);
    const teams = tournamentInfo.slice(2, 2 + teamCount);
    const gameCount = parseInt(tournamentInfo[2 + teamCount]);
    const games = tournamentInfo.slice(3 + teamCount);

    const scores = {};

    for (let j = 0; j < teamCount; j++) {
      scores[teams[j]] = { points: 0, wins: 0, goalsFor: 0, goalsAgainst: 0 };
    }

    for (let j = 0; j < gameCount; j++) {
      const game = games[j].split("#");
      const team1 = game[0];
      const [goals1, goals2] = game[1].split("@");
      const team2 = game[2];

      scores[team1].goalsFor += parseInt(goals1);
      scores[team1].goalsAgainst += parseInt(goals2);
      scores[team2].goalsFor += parseInt(goals2);
      scores[team2].goalsAgainst += parseInt(goals1);

      if (goals1 > goals2) {
        scores[team1].points += 3;
        scores[team1].wins += 1;
      } else if (goals1 < goals2) {
        scores[team2].points += 3;
        scores[team2].wins += 1;
      } else {
        scores[team1].points += 1;
        scores[team2].points += 1;
      }
    }

    const sortedTeams = Object.keys(scores).sort((a, b) => {
      if (scores[a].points !== scores[b].points) {
        return scores[b].points - scores[a].points;
      }
      if (scores[a].wins !== scores[b].wins) {
        return scores[b].wins - scores[a].wins;
      }
      if ((scores[a].goalsFor - scores[a].goalsAgainst) !== (scores[b].goalsFor - scores[b].goalsAgainst)) {
        return (scores[b].goalsFor - scores[b].goalsAgainst) - (scores[a].goalsFor - scores[a].goalsAgainst);
      }
      if (scores[a].goalsFor !== scores[b].goalsFor) {
        return scores[b].goalsFor - scores[a].goalsFor;
      }
      return a.toLowerCase().localeCompare(b.toLowerCase());
    });

    ranking[tournamentName] = sortedTeams;
  }

  return ranking;
}

// Example usage
const tournamentData = `Tournament 1
4
Team A
Team B
Team C
Team D
4
Team A#3@1#Team B
Team B#2@2#Team C
Team C#1@2#Team A
Team D#0@0#Team A

Tournament 2
3
Team X
Team Y
Team Z
2
Team X#1@1#Team Y
Team Z#2@0#Team X`;

const result = calculateTournamentRanking(tournamentData);
console.log(result);

 

결과:

입력된 정보별 토너먼트를 정리하면 아래와 같이 나오며, sort함수를 통해서 정렬하면 결과 값이 나온다.

Tournament 1
{
  "Team A": {
    "points": 7,
    "wins": 2,
    "goalsFor": 5,
    "goalsAgainst": 2
  },
  "Team B": {
    "points": 1,
    "wins": 0,
    "goalsFor": 3,
    "goalsAgainst": 5
  },
  "Team C": {
    "points": 1,
    "wins": 0,
    "goalsFor": 3,
    "goalsAgainst": 4
  },
  "Team D": {
    "points": 1,
    "wins": 0,
    "goalsFor": 0,
    "goalsAgainst": 0
  }
}
Tournament 2
{
  "Team X": {
    "points": 1,
    "wins": 0,
    "goalsFor": 1,
    "goalsAgainst": 3
  },
  "Team Y": {
    "points": 1,
    "wins": 0,
    "goalsFor": 1,
    "goalsAgainst": 1
  },
  "Team Z": {
    "points": 3,
    "wins": 1,
    "goalsFor": 2,
    "goalsAgainst": 0
  }
}

 

최종결과값

{
"Tournament 1": [ "Team A", "Team D", "Team C", "Team B" ],
"Tournament 2": [ "Team Z", "Team Y", "Team X" ]
}
반응형

'Algorithm' 카테고리의 다른 글

Programming Challenges #34  (0) 2023.05.24
Programming Challenges #33  (0) 2023.05.24
Big O 표기법을 그래프로 표현  (0) 2023.05.24
알고리즘의 시간 복잡도를 나타내는 표기 방법  (0) 2023.05.24
휴리스틱 알고리즘  (0) 2023.05.23