18회차 코딩테스트

2026-09-23 · Java 2문제 · SQL 2문제 · 2 PASS / 2 FAIL

오답노트의 Java 제출 칸은 비어 있다. FAIL 기록은 유지하고 정답 풀이를 실행 가능한 파일로 정리했다. SQL 두 문제는 제출문을 그대로 보존했다. 아래 로컬 검증은 프로그래머스 재채점 결과가 아니다.

18회차

정수 내림차순으로 배치하기

2026-09-23

한 줄 요약자릿수를 오름차순으로 정렬한 뒤 거꾸로 읽으면 큰 숫자부터 배치된다.

쉽게 말하면118372를 한 자리씩 나눠 1·1·2·3·7·8로 정렬하고 뒤에서 읽어 873211을 만든다.
FAIL · 원문 기록2026.09.23 · 18회차

문제 원문 · 18회차 전체 기록

제출 코드: 원문에 없음. FAIL 결과와 정답 풀이만 남아 있다. 아래 코드는 복습용 정답 풀이이며, 실제 제출본의 오류 원인을 재현한 것은 아니다.

JAVA오답노트의 정답 풀이 · 문자열 방식
import java.util.Arrays;

// 오답노트의 정답 풀이를 실행 가능한 클래스로 정리. 제출 코드는 원문에 없음.
public class DescendingDigitsString {
    public long solution(long n) {
        String[] arr = String.valueOf(n).split("");
        Arrays.sort(arr);
        StringBuilder sb = new StringBuilder();
        for (int i = arr.length - 1; i >= 0; i--) {
            sb.append(arr[i]);
        }
        return Long.parseLong(sb.toString());
    }
}

또 다른 풀이는 % 10으로 맨 끝 자리를 꺼내고 / 10으로 버린 다음 정렬한다. 수학적 분리 방식을 함께 보자.

숫자 자체에는 길이 속성이 없고, 배열은 arr.length, 문자열은 str.length()다. 입력이 최대 80억이므로 반환형과 파싱은 long 및 Long.parseLong을 사용한다. 반복해서 문자열을 조립할 때는 StringBuilder로 누적할 수 있다.

스스로 확인
7999999999를 정렬하면 입력 상한인 80억보다 커져도 괜찮을까?
결과는 9999999997이다. 입력의 상한이 결과의 상한인 것은 아니다. long 범위에는 들어가며, int로 바꾸면 범위를 벗어난다.
핵심 정리
  • Java 두 풀이 모두 20,008개 입력 통과: 1~10,000 전수·무작위 10,000·경계 8개.
  • 기댓값은 정렬 대신 숫자 빈도표로 만들었다.
  • 제출 당시 FAIL과 로컬 정답 풀이 PASS는 서로 다른 기록이다.
18회차

폰켓몬

2026-09-23

한 줄 요약정답은 종류 수와 선택 가능한 마릿수 N/2 중 작은 값이다.

쉽게 말하면종류가 많아도 두 마리만 고를 수 있으면 두 종류가 한계다. 세 마리를 골라도 종류가 두 개뿐이면 두 종류가 한계다.
FAIL · 원문 기록2026.09.23 · 18회차

문제 원문 · 18회차 전체 기록

제출 코드: 원문에 없음. FAIL 결과와 정답 풀이만 남아 있다. 아래 코드는 복습용 정답 풀이이며, 실제 제출본의 오류 원인을 재현한 것은 아니다.

JAVA오답노트의 정답 풀이
import java.util.HashSet;

// 오답노트의 정답 풀이. FAIL 제출본을 복원한 코드가 아님.
public class PokemonKinds {
    public int solution(int[] nums) {
        int maxPick = nums.length / 2;
        HashSet<Integer> pocket = new HashSet<>();
        for (int num : nums) {
            pocket.add(num);
        }
        int kindCount = pocket.size();
        if (kindCount > maxPick) {
            return maxPick;
        } else {
            return kindCount;
        }
    }
}

HashSet에 번호를 모두 넣으면 중복이 사라지고 size()가 종류 수가 된다. 저장 순서와 인덱스는 제공하지 않지만 이 문제는 개수만 필요하다. 마지막 if문은 Math.min(pocket.size(), nums.length / 2)와 같은 뜻이다.

왜 두 값 중 작은 값으로 충분한가? 종류 수와 N/2를 넘을 수 없고, 그 작은 값만큼 서로 다른 종류를 하나씩 고르면 그 상한에 도달한다. 종류가 부족하면 남는 자리는 이미 고른 종류로 채울 수 있다.

스스로 확인
[3,3,3,2,2,2]에서 세 마리를 고르는데 정답이 왜 2인가?
마릿수는 3이지만 종류 번호는 3과 2뿐이다. 이 문제의 반환값은 선택한 마릿수가 아니라 종류 수다.
핵심 정리
  • 배열 길이와 고유 종류 수를 구분한다.
  • 공식 예제 3건·작은 배열 전수 7,380건·길이 10,000 경계 2건 통과.
  • 작은 배열의 기댓값은 N/2개를 고르는 모든 조합을 실제 열거해 계산했다.
18회차

이름이 있는 동물의 아이디

2026-09-23

한 줄 요약NULL이 아닌 이름을 가진 행을 고르고 ID 오름차순으로 조회한다.

쉽게 말하면지난 회차의 이름 없는 동물이 IS NULL이었다면 이번에는 조건을 IS NOT NULL로 뒤집는다.
PASS · 원문 기록2026.09.23 · 18회차

문제 원문 · 18회차 전체 기록

SQL제출 코드 · 오답노트 원문
SELECT ANIMAL_ID
FROM ANIMAL_INS
WHERE NAME IS NOT NULL
ORDER BY ANIMAL_ID ASC;

NAME != NULL이나 NAME <> NULL은 NULL 여부를 검사하지 못한다. SQL 비교 결과가 UNKNOWN이 되어 WHERE를 통과하지 못하기 때문이다. 또한 MariaDB의 기본 문자열 처리에서 ''는 NULL이 아니므로 이 쿼리는 빈 문자열 행도 포함한다.

TEXTMariaDB 12.3.3 실제 검증
픽스처: A100(NULL), A200(체리), A300(NULL), A400(빈 문자열), A500(보리)
실제 결과: A200, A400, A500
NAME <> NULL 결과: 0건
스스로 확인
이름이 빈 문자열인 A400을 무조건 빼야 할까?
아니다. 문제의 NULL 조건을 먼저 따른다. 빈 문자열까지 제외하라는 별도 요구가 있을 때만 조건을 추가한다.
핵심 정리
  • NULL 검사는 IS NULL / IS NOT NULL.
  • 필터링 조건과 결과 정렬은 별개의 역할이다.
  • SQL 제출문은 원문 그대로 파일로 보존했다.
18회차

헤비 유저가 소유한 장소

2026-09-23

한 줄 요약호스트별 개수는 서브쿼리에서 세고, 그 호스트의 모든 장소는 바깥 쿼리에서 가져온다.

쉽게 말하면먼저 장소를 둘 이상 가진 사람의 명단을 만든 뒤, 그 명단에 든 사람의 장소를 하나도 빠뜨리지 않고 꺼낸다.
PASS · 원문 기록2026.09.23 · 18회차

문제 원문 · 18회차 전체 기록

SQL제출 코드 · 오답노트 원문
SELECT ID, NAME, HOST_ID
FROM PLACES
WHERE HOST_ID IN (
    SELECT HOST_ID
    FROM PLACES
    GROUP BY HOST_ID
    HAVING COUNT(*) >= 2
)
ORDER BY ID ASC;

GROUP BY HOST_ID로 사람별로 묶고 HAVING COUNT(*) >= 2로 그룹을 고른다. 바깥의 WHERE HOST_ID IN (...)은 장소 행을 걸러낸다. 최종 정렬 기준은 호스트 번호가 아니라 ID다.

바깥 쿼리 자체를 HOST_ID로 묶으면 장소별 행을 유지하지 못한다. 그룹 기준을 판단하는 단계와 원래 행을 반환하는 단계를 분리하는 이유다.

TEXTMariaDB 임시 테이블 검증
호스트 10: 장소 2개 / 20: 1개 / 30: 3개
반환 ID: 10, 40, 60, 70, 90 (공간 ID 순서)
각 호스트가 1개씩만 남은 경우: 0건
빈 테이블: 0건
스스로 확인
COUNT(*) >= 2를 WHERE에 바로 적으면 될까?
같은 쿼리 단계의 WHERE는 개별 행을 거르고, HAVING은 그룹의 집계 결과를 거른다. 이 풀이에서는 HAVING에 써야 한다.
핵심 정리
  • >= 2이므로 정확히 2개인 호스트도 포함한다.
  • 결과가 여러 호스트일 수 있어 = 대신 IN으로 비교한다.
  • 두 SQL 합계 8개 검증 통과. 실제 수업 테이블은 변경하지 않았다.