Challenge #2

Hanpang

Time limit per turn
5,000 ms
Memory limit
512 MB
Submissions
72
Participants
11

The English statement is unavailable. The Korean statement is shown instead.

Problem

15×815 \times 8 크기의 보드에서 같은 색 타일을 제거하여 가능한 한 높은 점수를 얻는 게임을 진행합니다.

보드는 1×11 \times 1 크기의 칸이 151588열로 배열된 형태입니다. 행 번호는 위에서 아래로 11행부터 1515행, 열 번호는 왼쪽에서 오른쪽으로 11열부터 88열까지이며, rrcc열의 칸을 (r,c)(r,c)로 표기합니다.

각 칸은 빈칸이거나 세 가지 색 중 하나의 타일을 가집니다. 새 행의 각 칸 색은 세 가지 색 중 하나를 서로 독립적으로 같은 확률로 선택하여 생성합니다. 게임을 시작할 때 보드의 맨 아래에 이렇게 생성한 타일 88개로 이루어진 행 하나가 추가됩니다.

한 턴에는 비어 있지 않은 칸 (r,c)(r,c) 하나를 선택합니다. 선택한 타일과 상하좌우로 연결된 같은 색 타일을 모두 제거합니다. 대각선으로 맞닿은 타일은 연결되지 않습니다. 연결된 타일이 하나뿐인 경우에도 선택할 수 있습니다.

한 번에 kk개의 타일을 제거했다면 k2k^2점을 얻습니다. 제거한 뒤에는 각 열의 남은 타일이 빈칸 없이 아래로 떨어집니다. 이후 새로운 타일 88개로 이루어진 행이 보드 아래에 추가되고, 기존 보드는 한 행 위로 이동합니다.

새 행을 추가할 때 보드의 맨 위에 남아 있던 타일이 보드 밖으로 밀려나면 게임이 종료됩니다. 종료를 일으킨 마지막 행동에서 제거한 타일의 점수도 최종 점수에 포함됩니다.

각 실행은 다음 조건 중 하나가 먼저 만족되면 종료됩니다.

  • 새 행 추가로 타일이 보드 위쪽을 벗어난 경우
  • 정상적인 행동을 200200번 수행한 경우
  • 준비 응답과 모든 행동 응답의 누적 시간 5,000ms5{,}000\text{ms}를 모두 사용한 경우
  • 출력 형식에 맞지 않는 문자열, 범위를 벗어난 좌표, 빈칸 좌표를 출력한 경우
  • 프로그램 실행 중 오류가 발생한 경우

잘못된 행동, 시간 초과, 실행 오류가 발생해도 그 전에 얻은 점수는 유지됩니다. 잘못된 행동은 보드와 점수에 반영되지 않습니다.

행 생성에 사용하는 실제 난수 초기값은 공개되지 않습니다. 하나의 평가 정책 버전에는 서로 다른 비공개 초기값 30개로 이루어진 평가 집합이 하나만 고정되며, 모든 제출은 이 집합으로 평가됩니다. 내부 평가 기록의 seedId 11부터 3030까지는 이 30개 초기값을 나타내는 불투명한 식별자이며, 같은 평가 정책 버전에서는 모든 제출에서 각 seedId가 동일한 실제 초기값에 대응합니다. 활성 평가 정책 버전 동안 제출 상세에는 전체 평가 상태, 완료 횟수, 점수 합과 평균만 표시하며, seedId별 상태·점수·종료 사유·매치 식별자와 리플레이는 실제 초기값을 역추정할 수 있으므로 제공하지 않습니다. 해당 버전이 종료된 뒤에만 seedId별 결과와 제출자 본인의 seedId=1 정제 리플레이를 공개 가능한 정보로 전환할 수 있습니다. 이 리플레이는 다른 사용자에게 공개하지 않으며, seedId=2부터 3030까지의 리플레이도 제공하지 않습니다.

30회 실행의 점수 합(scoreSum)이 높은 제출이 더 높은 순위를 얻습니다. scoreSum이 같다면 제출 시각이 빠른 제출이 앞서고, 제출 시각도 같다면 제출 ID가 작은 제출이 앞섭니다. 사용자별로 이 순서가 가장 높은 제출 하나만 리더보드에 표시됩니다.

보드의 상태를 정확히 관리하고, 앞으로 추가될 행으로 인해 게임이 종료되기 전에 큰 연결 요소를 만들어 높은 점수를 얻는 Agent를 작성해주세요!

Input

Hanpang Agent 프로토콜

보드는 151588열입니다. Agent 프로토콜의 행은 위에서 아래로 1부터 15, 열은 왼쪽에서 오른쪽으로 1부터 8까지 사용합니다. SDK 내부에서 빈칸은 0, 타일 색은 1, 2, 3입니다.

C++20과 Python3 Starter는 한 파일 상단에 공식 SDK를 포함합니다. SDK는 새 행 삽입, 연결요소 제거, 중력, 프로토콜 처리를 담당합니다. 사용자 코드는 mutable boardcalculateMove() 또는 calculate_move()만 수정합니다. board 배열 인덱스는 각 언어 관례대로 0부터 시작하지만, 함수가 반환하는 Actionrow, col은 Agent 프로토콜과 같은 1-based 좌표입니다.

채점기→플레이어 입력 플레이어→채점기 출력 제한 설명
START READY 남은 총 시간 Agent 준비 handshake. 응답 시간도 같은 총 시간에서 차감됩니다.
TURN remaining_ms new_row PANG row col remaining_ms 새 행을 반영한 뒤 제거할 타일 선택
  • Agent는 START를 읽기 전에 READY를 자발적으로 출력하면 안 됩니다.
  • READYPANG row col 뒤에는 줄바꿈을 출력하고 즉시 flush합니다.
  • 한 참가자는 START의 READY와 모든 TURN 응답을 합쳐 총 5,000ms5{,}000\text{ms}를 가집니다. 명령별 고정 시간 제한은 없습니다.
  • remaining_ms는 READY와 successful TURN response의 Broker RESULT elapsed_ms를 누적 차감한 남은 총 시간입니다. OS CPU 시간이 아닙니다.
  • 응답의 elapsed_ms >= remaining_ms이면 PANG을 parse/apply하지 않고 TIME_LIMIT으로 종료하며 이전 점수를 보존합니다.
  • new_row는 길이 88의 문자열이며 각 문자는 1, 2, 3입니다. 첫 TURN은 초기 바닥 행입니다.
  • 다음 행은 행동 전에 공개되지 않습니다.
  • row, col은 각각 1row151 \le row \le 15, 1col81 \le col \le 8인 정수입니다. 단일 타일도 선택할 수 있습니다.
  • 출력 형식 오류, 범위 밖·빈칸 좌표, invalid UTF-8/control byte/oversized output은 해당 행동을 적용하지 않고 마지막 확정 점수를 보존합니다.
  • Agent protocol에는 terminal FINISH 입력이 없습니다. Judger가 terminal LOG와 control FINISH를 만든 뒤 Broker가 participant process를 종료합니다.

SDK는 new_row를 반영한 뒤 사용자 전략을 호출합니다. 사용자가 선택한 행동을 출력하기 전에 SDK는 같은 색 상하좌우 연결요소를 로컬 보드에서 제거하고 각 열에 중력을 적용합니다. 다음 TURN의 새 행을 추가하면 로컬 보드가 채점기 보드와 다시 같은 상태가 됩니다.

Example

채점기→플레이어 입력 플레이어→채점기 출력
START READY
TURN 5000 32131311 PANG 15 7
TURN 4999 11223312 PANG 15 7
\vdots \vdots

remaining_ms 값은 설명을 위한 예시입니다. 실제 값은 READY 응답과 각 successful TURN 응답의 Broker elapsed를 같은 5,000ms bank에서 누적 차감한 결과에 따라 달라집니다. Agent가 받는 terminal FINISH 명령은 없습니다.

Sample Code