Loading the catalog…
Loading the catalog…
📌 문제 설명 문자열 s가 주어진다. 문자열은 여러 개의 집합을 표현하고 있고, 각 집합에는 숫자들이 들어 있다. 예를 들어 "{{2},{2,1},{2,1,3},{2,1,3,4}}" 라면 {2} {2,1} {2,1,3} {2,1,3,4} 가 들어 있는 것이다. 이 집합들을 이용해서 [2,1,3,4] 라는 튜플을 찾아야 한다. 중요한 조건은 집합의 원소 순서는 중요하지 않다. 각 집합은 튜플의 앞부분을 포함한다. 원소가 적은 집합부터 확인하면 새로운 숫자를 하나씪 찾을 수있다. 💡 처음 문제를 보고 든 생각 처음에는 문자열 안에 {{2},{2,1},{2,1,3},{2,1,3,4}} 처럼 여러 데이터가 들어 있어서 이걸 어떻게 분리해야 하는지부터 어려웠다. 특히 처음에는 for i in s: 처럼 문자열 자체를 반복하면 각 집합이 하나씩 나올 것이라고 생각했다. 하지만 문자열을 for문으로 돌리면 문자 하나씩 꺼내진다. 예를 들어 s = "{{2},{2,1}}" for i in s: 이면 { { 2 } , { 2 , 1 } } 처럼 문자 하나씩 나온다. 따라서 먼저 문자열을 집합 단위 로 분리해야 한다. 🔥 전체 풀이 흐름 이 문제는 크게 다음 순서로 해결한다. 문자열 정리 ↓ 집합별로 분리 ↓ 각 숫자를 문자열 → 정수로 변환 ↓ 2차원 리스트 groups 생성 ↓ 원소 개수가 적은 순서로 정렬 ↓ 작은 집합부터 숫자를 하나씩 확인 ↓ answer에 없는 숫자 발견 ↓ answer에 추가 ↓ 현재 group 탐색 종료 🔍 전체 코드 def solution(s): answer = [] s = s[2:-2] sets = s.split("},{") groups = [] for group in sets: numbers = list(map(int, group.split(","))) groups.append(numbers) groups.sort(key=len) for group in groups: for num in group: if num not in answer: answer.append(num) break return answer 🧠 1. answer = [] answer = [] 빈 리스트를 만든다. 최종적으로 튜플의 원소를 저장할 공간이다. 처음에는 answer = [] 이고, 숫자를 하나씩 찾으면서 [2] [2,1] [2,1,3] [2,1,3,4] 처럼 늘어난다. 🧠 2. 문자열 슬라이싱 s = s[2:-2] 이 부분이 처음에는 상당히 헷갈릴 수 있다. 원래: {{2},{2,1},{2,1,3},{2,1,3,4}} 이다. 문자열에서 s[2:-2] 를 하면 앞에서 2개 제거 뒤에서 2개 제거 앞에서 2개 제거 뒤에서 2개 제거 한다. 즉, {{2},{2,1},{2,1,3},{2,1,3,4}} ^^ ^^ 제거 제거 결과: 2},{2,1},{2,1,3},{2,1,3,4 가 된다. 📌 슬라이싱 기본 문법 문자열[시작:끝] 여기서 중요한 점: 👉 끝 인덱스는 포함하지 않는다. 그리고 음수 인덱스도 사용할 수 있다. 예: s[-1] → 마지막 문자 s[-2] → 뒤에서 두 번째 문자 따라서 s[2:-2] 는 2번째 위치부터 뒤에서 2번째 위치 직전까지 가져오는 것이다. 🧠 3. split() sets = s.split("},{") 여기서는 문자열을 "},{" 를 기준으로 잘라낸다. 예: 2},{2,1},{2,1,3},{2,1,3,4 ↓ [ "2", "2,1", "2,1,3", "2,1,3,4" ] 가 된다. 📌 split()의 의미 문자열.split(기준) 은 문자열을 특정 기준으로 잘라서 리스트로 만든다. 예: "apple,banana,melon".split(",") 결과: ["apple", "banana", "melon"] 이번 문제에서는 s.split("},{") 이므로 "},{" 를 기준으로 집합들을 분리한 것이다. 🧠 4. groups = [] groups = [] 빈 리스트를 하나 만든다. 왜 필요할까? 아직 sets 안의 숫자들은 "2" "2,1" "2,1,3" "2,1,3,4" 처럼 문자열이다. 우리가 원하는 것은 [ [2], [2,1], [2,1,3], [2,1,3,4] ] 같은 형태이다. 따라서 변환한 결과를 저장할 새로운 리스트가 필요하다. 그 역할이 groups이다. 🔥 5. for group in sets for group in sets: sets 안에서 하나씩 꺼낸다. 예를 들어: sets = [ "2", "2,1", "2,1,3", "2,1,3,4" ] 이면 반복하면서 이면 반복하면서 첫 번째 group = "2" 두 번째 group = "2,1" 세 번째 group = "2,1,3" 네 번째 group = "2,1,3,4" 가 된다. 🔥 6. group.split(",") group.split(",") 각 group 안의 숫자들을 다시 , 기준으로 분리한다. 예: group = "2,1,3" 이면 group.split(",") 결과: ["2", "1", "3"] 이다. 여기서 중요한 점: 👉 아직 문자열이다. "2" "1" "3" 🔥 7. map() map(int, group.split(",")) 여기가 이번 문제에서 새롭게 배운 중요한 문법이다. map()은 여러 개의 값에 같은 함수를 하나씩 적용하는 기능 이다. 형식: map(함수, 여러 개의 값) 이번에는 map(int, ["2", "1", "3"]) 이므로 각 원소에 int()를 적용한다. "2" → int("2") → 2 "1" → int("1") → 1 "3" → int("3") → 3 즉, map(int, ["2", "1", "3"]) 은 ["2", "1", "3"] ↓ int 적용 ↓ [2, 1, 3] 을 만드는 과정이다. 📌 map()의 핵심 map(int, data) 라고 하면 data 안에 있는 각각의 값에 int()를 적용한다. 예: map(int, ["10", "20", "30"]) ↓ 10 20 30 🧠 8. 왜 list()가 필요한가? list(map(int, group.split(","))) 여기서는 split ↓ map ↓ list 순서로 처리된다. 안쪽부터 보면: 1 split group.split(",") "2,1,3" ↓ ["2", "1", "3"] 2 map map(int, ["2", "1", "3"]) 각각 int() 적용. 3 list list(...) map으로 만들어진 값을 실제 리스트로 만든다. 결과: [2, 1, 3] ⭐ 한 줄을 분해해서 읽는 방법 numbers = list(map(int, group.split(","))) 처음부터 한 번에 읽으려고 하면 어렵다. 안쪽부터 읽으면 된다. group.split(",") ↓ 문자열을 , 기준으로 자름 map(int, ...) ↓ 각 문자열에 int 적용 list(...) ↓ 리스트로 만듦 최종: numbers = [2, 1, 3] 🔥 9. groups.append(numbers) groups.append(numbers) 변환한 numbers를 groups에 넣는다. 예를 들어 numbers = [2,1,3] 이면 groups.append(numbers) 후: groups = [ [2], [2,1], [2,1,3] ] 처럼 된다. 📌 append() 리스트.append(값) 은 리스트의 맨 뒤에 값을 하나 추가한다. 예: numbers = [] numbers.append(2) numbers.append(5) 결과: [2, 5] 🧠 여기까지 데이터가 어떻게 변했는지 이 부분은 꼭 기억해두자. 원본 문자열 "{{2},{2,1},{2,1,3}}" ↓ s[2:-2] "2},{2,1},{2,1,3" ↓ split("},{") ["2", "2,1", "2,1,3"] ↓ group 하나 꺼냄 "2,1,3" ↓ split(",") ["2", "1", "3"] ↓ map(int, ...) 2, 1, 3 ↓ list(...) [2, 1, 3] ↓ append() groups에 저장 ↓ [ [2], [2,1], [2,1,3] ] 문자열 → 문자열 리스트 → 숫자 리스트 → 2차원 리스트 이 흐름이 이번 문제에서 가장 중요하다. 🔥 10. groups.sort(key=len) 이제 groups 안에는: groups = [ [2,1,3,4] [2], [2,1,3] [2,1] ] 처럼 여러 리스트가 들어 있다. groups.sort(key=len) 을 실행하면 👉 각 리스트의 길이를 기준으로 정렬한다. 각각: [2,1,3,4] → 길이 4 [2] → 길이 1 [2,1,3] → 길이 3 [2,1] → 길이 2 따라서: [ [2], [2,1], [2,1,3], [2,1,3,4] ] 가 된다. 📌 key=의 의미 sort(key=기준) 은 무엇을 기준으로 정렬할지 지정하는 것 이다. groups.sort(key=len) 이면 각각의 원소에 len()을 적용한 결과를 기준으로 정렬 한다. ❗ key=len vs key=len() 중요하다. key=len ⭕️ key=len() ❌ key=len은 "나중에 각각의 원소에 len을 적용해." 라는 뜻이다. len()은 지금 당장 실행하려는 형태라서 key에 넣을 수 없다. 🔥 11. 중첩 for 정렬된 groups를 이제 하나씩 꺼낸다. for group in groups: 예: group = [2] group = [2,1] group = [2,1,3] group = [2,1,3,4] 그런데 각 group 안에도 숫자가 여러 개 있다. 그래서 다시: for num in group: 을 사용한다. 즉: groups ↓ group 하나 ↓ num 하나 구조다. ⭐ 12. if num not in answer if num not in answer: 이번 문제의 핵심 조건이다. 뜻: 현재 숫자 num이 아직 answer에 없다면 이다. 예: answer = [2,1] num = 2 이면 2 not in [2,1] ❌ 거짓 따라서 if 안의 코드는 실행되지 않는다. 반대로: num = 3 이면 3 not in [2,1] ✅ 참 그래서: answer.append(3) 을 실행한다. 📌 in / not in x in 리스트 👉 x가 리스트 안에 있는가? x not in 리스트 👉 x가 리스트 안에 없는가? 예: 2 in [1,2,3] → True 4 in [1,2,3] → False 4 not in [1,2,3] → True 🔥 13. break if num not in answer: answer.append(num) break 새로운 숫자를 찾으면 answer.append(num) 으로 추가한다. 그리고 바로: break 한다. break의 정확한 의미 break는 현재 실행 중인 가장 가까운 for 또는 while 반복문 하나를 즉시 종료한다. 이번 코드에서는: for group in groups: for num in group: if num not in answer: answer.append(num) break break가 종료하는 것은: for num in group 이다. 바깥쪽 for group in groups는 종료하지 않는다. 그래서 다음 group으로 넘어간다. 🔥 14. continue break와 같이 알아두면 좋다. continue 는 현재 반복만 건너뛰고 다음 반복으로 넘어간다. 예: for num in group: if num in answer: continue answer.append(num) break 여기서는 이미 answer에 있는 숫자 → continue → 다음 num 확인 이다. break와 continue 차이 문법 의미 break 반복문 자체를 종료 continue 현재 반복만 건너뜀 pass 아무것도 하지 않음 이번 문제에서는 break 가 필요하다. 왜냐하면 새로운 숫자 하나를 찾으면 👉 현재 group에서는 더 볼 필요가 없기 때문이다. 🧠 break 흐름 다시 보기 for group in groups: for num in group: if num not in answer: answer.append(num) break 예를 들어: group = [2,1,3] answer = [2,1] 이면 num = 2 → 이미 있음 → 다음 num = 1 → 이미 있음 → 다음 num = 3 → 없음 → answer에 추가 → break 현재 group 종료 ↓ 다음 group 이다. 🎯 전체 알고리즘 정리 1 문자열 양끝의 {{ }} 제거 ↓ 2 },{ 기준으로 집합 분리 ↓ 3 각 숫자를 , 기준으로 분리 ↓ 4 문자열 숫자를 int로 변환 ↓ 5 groups에 2차원 리스트로 저장 ↓ 6 리스트 길이순으로 정렬 ↓ 7 작은 group부터 확인 ↓ 8 숫자를 하나씩 확인 ↓ 9 answer에 없는 숫자 발견 ↓ 10 answer에 추가 ↓ 11 break ↓ 12 다음 group 🧠 이번 문제에서 새로 배운 Python 문법 1 문자열 슬라이싱 s[2:-2] 앞 2개와 뒤 2개를 제외하고 가져온다. 2 split() s.split(",") 특정 문자를 기준으로 문자열을 나눠 리스트로 만든다. 3 map() map(int, data) data의 각 원소에 int()를 적용한다. 4 list() list(map(...)) 반복 가능한 값을 리스트로 만든다. 5 append() groups.append(numbers) 리스트 뒤에 하나의 값을 추가한다. 6 sort(key=...) groups.sort(key=len) 각 원소에 len()을 적용한 결과를 기준으로 정렬한다. 7 in num in answer num이 answer 안에 있는지 확인한다. 8 not in num not in answer num이 answer 안에 없는지 확인한다. 9 break break 가장 가까운 반복문 하나를 종료한다. 10 continue continue 현재 반복만 건너뛰고 다음 반복으로 넘어간다. ❗ 이번 문제에서 특히 기억할 것 map()은 map(함수, 여러 값) 👉 여러 값에 같은 함수를 각각 적용 sort(key=...)는 sort(key=기준) 👉 그 기준을 이용해서 정렬 break는 반복문 하나 종료 continue는 현재 반복만 패스 ↓ 다음 반복 not in은 아직 없는가? 라고 읽으면 편하다. 그래서 if num not in answer: 는 "이 숫자 아직 정답에 없나?" 라고 읽으면 된다. 💭 이번 문제에서 가장 중요한 사고방식 처음에는 문자열 하나가 너무 복잡해 보였다. 하지만 하나씩 뜯어보면: 문자열 ↓ 집합 문자열 ↓ 숫자 문자열 ↓ 정수 ↓ 리스트 ↓ 2차원 리스트 로 변환해 나간 것이다. 그리고 마지막에는 groups ↓ group ↓ num 순서로 다시 하나씩 꺼내면서 if num not in answer: 로 필요한 숫자만 골랐다. 즉 이번 문제는 단순히 튜플 문제를 푼 것이 아니라, 문자열로 들어온 복잡한 데이터를 원하는 자료구조로 변환하고, 중첩 반복문으로 단계적으로 탐색하는 방법 을 연습한 문제라고 볼 수 있다. 🔥 한 줄 정리 👉 문자열을 split()과 map()으로 숫자 리스트로 변환하고, sort(key=len)으로 작은 집합부터 정렬한 뒤, not in으로 새로운 원소만 찾아 break하는 문제
What RADAR observed and classified to build this opportunity. It is what the source published, not a verification that the offer is still active.
📌 프로그래머스 - 튜플 (64065). 📌 문제 설명 문자열 s가 주어진다. 문자열은 여러 개의 집합을 표현하고 있고, 각 집합에는 숫자들이 들어 있다. 예를 들어 "{{2},{2,1},{2,1,3},{2,1,3,4}}" 라면 {2} {2,1} {2,1,3} {2,1,3,4} 가 들어 있는 것이다. 이 집합들을 이용해서 [2,1,3,4] 라는 튜플을 찾아야 한다. 중요한 조건은 집합의 원소 순서는 중요하지 않다. 각 집합은 튜플의 앞부분을 포함한다. 원소가 적은 집합부터 확인하면 새로운 숫자를 하나씪 찾을 수있다. 💡 처음 문제를 보고 든 생각 처음에는 문자열 안에 {{2},{2,1},{2,1,3},{2,1,3,4}} 처럼 여러 데이터가 들어 있어서 이걸 어떻게 분리해야 하는지부터 어려웠다. 특히…
Open source