99클럽 코테 스터디 1일차 TIL [03/31]
[시작]
코테 공부는 해야 하는데 같이 문제를 풀고 공유하는 그런 커뮤니티가 있었으면 좋겠다고 생각을 했다.
심지어 내가 잘하는 편도 아니고 했다가 안 했다가 반복한 잡초? 같은 실력...
알아보던 중 항해 99라는 곳에서 코딩테스트 스터디를 실력별로 운영하길래 내돈내산으로 참여했다.
참여 기간 : 2025/03/31 ~ 2025/04/28
참여 난이도 : 파이썬 / 비기너
⏳ 코테 스터디 진행도 🧱 : [▰░ ] 1/29일 (3%)
본 글에서 다룬 문제 : 백준 1032, 백준 10988
[오늘의 문제]
매일 1문제씩 푸는 미션이 주어지는데
오늘의 문제는 https://www.acmicpc.net/problem/1032 이것
예제 입력과 예제 출력의 예시를 더 보고 싶으면 해당 링크로 들어가서 보면 된다.
[문제 분석]
문제를 읽고 예제 입출력을 보니까 문자열을 리스트에 저장해서 해결해야겠다는 생각이 들었다.
의사코드를 작성하기 전에 머리로 시뮬레이션을 돌려봤는데
문자열을 N개 입력받아서 리스트에 저장한다 → 가능가능
입력받은 문자열의 문자를 하나하나 비교한다 → 어떻게 할까..?
반복문과 조건문을 이용하면 어떻게 풀어낼 수 있겠다 생각은 들었다.
[의사 코드]
- 사용자로부터 파일 개수 N을 입력
- N개의 파일 이름을 입력받아 리스트에 저장
- 결과를 저장할 빈 문자열을 준비
- 각 글자 위치에 대해 다음을 반복
- 첫 번째 문자열의 해당 위치 글자를 기준으로 정함
- 나머지 모든 문자열의 해당 위치 글자를 차례대로 비교
- 하나라도 다르면, 해당 위치는 '?'로 정함
- 모두 같으면, 해당 문자를 결과에 추가
- 만들어진 결과 문자열을 출력
[의사 코드를 실제 코드로 구현]
N = int(input())
files = [input() for _ in range(N)]
result = ''
for i in range(len(files[0])):
current = files[0][i]
all_same = True
for j in range(1, N):
if files[j][i] != current:
all_same = False
break
result += current if all_same else '?'
print(result)
★ 코드 설명 ★
사실 더 간단하게 숏코드로 작성하고 싶었으나
어쩔 수 없이 중첩 반복문을 사용했다.
[제출 결과]
처음 제출은 로컬에서 예제코드 일부만 돌리고 되겠다 싶어서 제출했는데
옳지 않은 부분이 있어서 수정 후 제출했다.
[여러 접근 방법]
수학 문제를 풀 때 같은 문제를 여러 방법으로 푸는 공부법이 좋다고 들었다.
코테 문제에 이런 방법을 적용시키면 어떨까? 하는 생각이 들었고
바로 실행에 옮겨봤다.
위에서 내가 사용한 방식은 문자열을 세로로 비교하는 방식이다.
세로 방향으로 각 위치(i)를 기준으로 글자들을 비교하는 방식을 사용했다.
사용한 이유 : 행렬 느낌으로 직관적으로 생각이 나서
장점 : 직관적이고 문제 내용을 그대로 따라감
단점 : 중첩 반복문 사용으로 코드가 짧지 않음
백준에서 다른 분들이 제출한 코드를 참고했는데 대부분 나와 같은 방식으로 코드를 작성했다. (중첩반복문 사용)
비슷한 방법이긴 한데 조금 다른 방향으로 푼 코드
N = int(input())
files = [input() for _ in range(N)]
pattern = list(files[0])
for i in range(1, N):
for j in range(len(pattern)):
if pattern[j] != files[i][j]:
pattern[j] = '?'
print(''.join(pattern))
★ 코드 설명 ★
첫 번째 문자열을 기준으로 잡고
다른 문자열들과 각 글자 위치에서 다른 게 있으면 '?'로 변경했다.
첫 번째 문자열이 수정되어서 최종 출력된다고 보면 된다. (원본 변경)
GPT한테 또 다른 풀이 방법이 있냐고 물어봤는데
코드들을 보니까 내가 적용하지 못하는 범주여서 아직... pass
[보너스 문제]
https://www.acmicpc.net/problem/10988
[문제 풀이]
디스코드에서 파이썬/비기너 대상으로 30분 제한시간으로 주어진 문제였다.
어떤 분이 거의 2분? 3분 만에 풀길래 나도 호다닥 풀었다.
제출까지 포함해서 5분 정도 걸린 듯
'''
접근 방법
1. 알파벳 소문자로만 이루어진 단어가 주어짐
2. 이 단어가 팰린드롬인지 아닌지 확인해야함
3. 팰린드롬 : 앞으로 읽을때와 거꾸로 읽을 때 똑같은 단어를 말함
4. level, noon은 팰린드롬이고 online 이런건 팰린드롬이 아니다.
'''
word = input()
if word == word[::-1]:
print(1)
else:
print(0)
★ 코드 설명 ★
주석으로 접근 방법을 먼저 작성했다.
의사코드를 작성하려 했으나 사실 접근 방법에서 해답이 나왔으므로
의사코드는 생략하고 코드를 구현했다.
(틀리면 그때 의사코드를 작성해 보자는 마인드. 원래 이러면 안 된다)
- 단어를 입력받아 word에 저장
- 슬라이싱 문법을 사용해서 문자열을 역순으로 만들기
- 슬라이싱 문법은 아래에 따로 정리할 테니 참고
- 원래 문자열과 뒤집은 문자열이 같은지 비교
- 같으면 팰린드롬
- 다르면 아님
- 비교 결과에 따른 결과 출력
[슬라이싱 기본 문법]
사용한 김에 문법을 가져왔다.
시퀀스[시작:끝:간격]
text = "abcdef"
[다른 방법으로 코드 작성]
word = input()
if list(word) == list(reversed(word)):
print(1)
else:
print(0)
★ 코드 설명 ★
슬라이싱 방법이 아니라 reversed() 함수를 사용했다.
list(word) : 문자열을 하나하나 쪼개서 리스트로 변환함
# 예시
word = "noon"
list(word) → ['n', 'o', 'o', 'n']
list(reversed(word)) : reversed()의 결과를 다시 list()로 감싸서 뒤집힌 문자 리스트를 생성
list(reversed("noon")) → ['n', 'o', 'o', 'n']
list(reversed("apple")) → ['e', 'l', 'p', 'p', 'a']
원래 문자 리스트와 뒤집힌 문자 리스트를 비교해서 팰린드롬 여부 확인하였음
[온 김에 이것도 잡숴봐]
reserved(list)와 list.reverse()의 차이를 말해보시오
- reversed(list)
- 거꾸로 순회 가능한 객체 생성
- 반환값은 list가 아니라 reversed 객체이므로 필요시 위에처럼 list()로 감싸줘야 함
- 원본 변경 x
lst = [1, 2, 3, 4]
r = reversed(lst)
print(list(r)) # [4, 3, 2, 1]
- list.reverse()
- 리스트를 제자리에서(in-place) 거꾸로 바꿔버림
- 원본 리스트 자체가 바뀌어 버림(원본 변경 o)
- 반환값은 None
lst = [1, 2, 3]
lst.reverse()
print(lst) # [3, 2, 1]
▶ 결론은 reversed(list) 쓰는 게 안전하다. 원본 변경 안 하므로!
[디코에서 본 다른 분의 코드]
def solution(word):
l = len(word)
flag = 1
for i in range(l//2):
if word[i] != word[l-i-1]:
flag = 0
break
return flag
word = input()
print(solution(word))
★ 코드 설명 ★
문자열 길이의 절반까지만 비교하면 충분하므로
for i in range(l // 2): # 앞쪽 절반만 검사
if word[i] != word[l - i - 1]: # 뒤쪽에서 대응하는 문자와 비교
flag = 0
break
이렇게 하신 거라 생각된다.
[마무리]
보너스 문제까지 해서 2문제 밖에 없어서 글 작성에 시간이 적게 걸릴 것이라 생각했는데
생각보다 오래 걸렸다.
디코에서 다른 분들 풀이 코드를 볼 수 있는 기회가 있어서 좋았고
해설과 팁들을 공유받아서 유익한 시간이었다! (크롬 백준 허브 등)