PS/알고리즘 문제풀이

[프로그래머스] [3차] 방금그곡(java)

2023. 8. 6. 13:51
목차
  1. 핵심
  2. 정답 코드
  3. 해설
  4. 배운 점

https://school.programmers.co.kr/learn/courses/30/lessons/17683

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

옛날에 풀려다가 문제를 이해를 못 해서 넘겼었던 문제이다.

오랜만에 다시 천천히 읽어보니 단순 구현문제였다.

 

핵심

요즘 문제를 풀 때 주석을 달고 분석을 시작하고 한다. 일단 내가 적은 주석이다.

// 우선 문자를 구분해줘야함 C, C# 등등 -> 중요포인트라고 생각되는건
// C, C#, D, D#, E, F, F#, G, G#, A, A#, B 12개가 있음 #은 다른 문자로 대체하느게 좋아보임
// A B  C D E F G H   I   J  K   L
// A B  C D E F G A#  C# D#  F#  G#  이렇게 매칭하기
// 문자를 반복해서 길게 이어줘야함 ex) 14분동안 진행이면 7분짜리 노래 x 2
// contains로 찾으면 됨
// (추가) 플레이 타임인 긴 순서, 같다면 먼저 찾은 노래로

개인적으로 핵심은 #부분을 다른 문자로 대체하는 것이다.

 

정답 코드

import java.util.Comparator;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Optional;

class Solution {
    static HashMap<Integer, String> matchingTimeAndTitle = new HashMap<>();

    public String solution(String m, String[] musicInfos) {
        for (String musicInfo : musicInfos) {
            findMatchMusic(m, musicInfo);
        }

        Optional<Entry<Integer, String>> max = matchingTimeAndTitle
                .entrySet()
                .stream()
                .max(Comparator.comparingInt(Entry::getKey));

        return max.map(Map.Entry::getValue)
                .orElse("(None)");
    }

    private void findMatchMusic(String m, String music) {
        String[] musicInfo = music.split(",");

        m = changeMusic(m);
        String target = changeMusic(musicInfo[3]);

        int runtime = findRuntime(musicInfo[0], musicInfo[1]);

        StringBuilder totalMusic = new StringBuilder();
        for (int i = 0; i < runtime; i++) {
            totalMusic.append(target.charAt(i % target.length()));
        }

        if (isCorrectMatchingMusic(totalMusic, m, runtime)) {
            matchingTimeAndTitle.put(runtime, musicInfo[2]);
        }
    }

    private String changeMusic(String music) {
        return music.replace("A#", "H")
                .replace("C#", "I")
                .replace("D#", "J")
                .replace("F#", "K")
                .replace("G#", "L");
    }

    private int findRuntime(String startTime, String endTime) {
        String[] endTimeSplit = endTime.split(":");
        String[] startTimeSplit = startTime.split(":");

        int endHour = Integer.parseInt(endTimeSplit[0]);
        int endMinute = Integer.parseInt(endTimeSplit[1]);
        int startHour = Integer.parseInt(startTimeSplit[0]);
        int startMinute = Integer.parseInt(startTimeSplit[1]);

        int end = endHour * 60 + endMinute;
        int start = startHour * 60 + startMinute;

        return end - start;
    }

    private boolean isCorrectMatchingMusic(StringBuilder totalMusic, String m, int runtime) {
        return totalMusic.toString().contains(m) && !matchingTimeAndTitle.containsKey(runtime);
    }
}

해설

생각보다 단순한 구현문제였다.

우선 각 음악의 정보와 내가 들은 음악정보를 반복문을 통해 각각 비교를 한다.

findMatchMusic으로 들어가면 아까 말했듯이 #을 다른 문자로 대체하여 쉽게 풀 수 있도록 만들어준다.

이후 반복된 시간을 찾은 다음 그 음악을 런타임 시간 동안 반복하여 전부 송출된 음악을 찾는다.

만약 내가 들은 음악과 전체 음악이 같다면 matchingTimeAndTitle에 넣어준다.

여기서 중요한 점은 길이 같은 경우에는 이미 들어온 값을 사용해야 하기 때문에 업데이트하지 않는다. 

전부 반복문을 통해 찾았다면 키값(런타임)이 가장 큰 값을 반환한다. 만약 없다면 -> 매칭이 없었음 

요구대로 (None)을 반환한다.

 

 

배운 점

최근에 리트코드만 풀다가 오랜만에 프로그래머스가 풀고 싶어 져서 복귀했다.

요즘은 그냥 재미있어서 계속 푸는 느낌이 강하다.

주석에서 (추가)라고 쓴 부분이 있는데, 이 부분을 놓치고 풀어서 처음에 삽질을 좀 하였다.

자세히 읽으려 했음에도 잘 안 읽히는 부분이 있는 것 같다. 

그래도 나름대로 빠르게 찾아서 해결할 수 있었다.

예전에도 이 문제를 풀려했었는데, 문제자체가 이해가 안 돼서 포기했었다.

그동안의 성장? 덕분인지 문제 해석도 잘되고 생각보다 쉽게 풀 수 있었다.

현재 300등을 돌파하였다.

알고리즘이 재미있어서 꾸준히 풀다 보니 순위가 높아지는 것 같다.

덕분에 논리적 사고력도 전에 비해 많이 늘었다는 생각도 든다.

순위가 높아지다 보니 랭킹을 높이는 재미도 생겼다.

그래서 현재 목표는 100등을 향해 달리는 것이다.

저작자표시

'PS > 알고리즘 문제풀이' 카테고리의 다른 글

[백준] 9328번 열쇠(java)  (0) 2023.08.09
[백준] 13460번 구슬 탈출2(java)  (0) 2023.08.08
[LeetCode] 688 - Knight Probability in Chessboard(java)  (0) 2023.07.22
[LeetCode] 2024 - Maximize the Confusion of an Exam(java)  (0) 2023.07.07
[LeetCode] 209 - Minimum Size Subarray Sum(java)  (0) 2023.07.06
  1. 핵심
  2. 정답 코드
  3. 해설
  4. 배운 점
'PS/알고리즘 문제풀이' 카테고리의 다른 글
  • [백준] 9328번 열쇠(java)
  • [백준] 13460번 구슬 탈출2(java)
  • [LeetCode] 688 - Knight Probability in Chessboard(java)
  • [LeetCode] 2024 - Maximize the Confusion of an Exam(java)
javajoha
javajoha
깃허브 https://github.com/kimtaesoo99 알고리즘 전용 블로그 https://javajoha.tistory.com/
javajoha
기록하는 개발자가 되자
javajoha
전체
오늘
어제
  • 분류 전체보기 (270)
    • 개발일기 (14)
    • Spring (15)
    • JPA (9)
    • JAVA (18)
    • 좋은 개발자가 되기 (11)
    • PS (133)
      • 알고리즘 (17)
      • 알고리즘 문제풀이 (116)
    • CS (22)
    • Git (1)
    • Docker (1)
    • AWS (4)
    • 프로젝트 (18)
      • 커뮤니티 (10)
      • ChatUniv (6)
      • HOTSOS (1)
      • Travelink (1)
    • 활동 (24)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

  • 알고리즘 문제풀이를 다른 블로그에서 진행합니다.

인기 글

태그

  • 백트래킹
  • 완전탐색
  • 객체지향의 사실과 오해
  • Java
  • 개발일기
  • 알고리즘
  • 백준
  • 자바
  • spring
  • 백준알고리즘
  • 프로그래머스
  • JPA
  • 동적계획법
  • DP
  • 커뮤니티
  • dfs
  • 프로젝트
  • 데이터베이스
  • 부스트캠프
  • BFS

최근 댓글

최근 글

hELLO · Designed By 정상우.
javajoha
[프로그래머스] [3차] 방금그곡(java)
상단으로

티스토리툴바

단축키

내 블로그

내 블로그 - 관리자 홈 전환
Q
Q
새 글 쓰기
W
W

블로그 게시글

글 수정 (권한 있는 경우)
E
E
댓글 영역으로 이동
C
C

모든 영역

이 페이지의 URL 복사
S
S
맨 위로 이동
T
T
티스토리 홈 이동
H
H
단축키 안내
Shift + /
⇧ + /

* 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.