스파르타 코딩클럽/99클럽 코딩테스트 스터디 6기

99클럽 코테 스터디 1일차 TIL [03/31]

김뚱입니다 2025. 3. 31. 18:35

[시작]

코테 공부는 해야 하는데 같이 문제를 풀고 공유하는 그런 커뮤니티가 있었으면 좋겠다고 생각을 했다.

심지어 내가 잘하는 편도 아니고 했다가 안 했다가 반복한 잡초? 같은 실력...

알아보던 중 항해 99라는 곳에서 코딩테스트 스터디를 실력별로 운영하길래 내돈내산으로 참여했다.

참여 기간 : 2025/03/31 ~ 2025/04/28

참여 난이도 : 파이썬 / 비기너

⏳ 코테 스터디 진행도 🧱 : [▰░                                                  ] 1/29일 (3%)

본 글에서 다룬 문제 : 백준 1032, 백준 10988

 

 

 

[오늘의 문제]

매일 1문제씩 푸는 미션이 주어지는데

오늘의 문제는 https://www.acmicpc.net/problem/1032 이것

예제 입력과 예제 출력의 예시를 더 보고 싶으면 해당 링크로 들어가서 보면 된다.

 

 

[문제 분석]

문제를 읽고 예제 입출력을 보니까 문자열을 리스트에 저장해서 해결해야겠다는 생각이 들었다.

의사코드를 작성하기 전에 머리로 시뮬레이션을 돌려봤는데

문자열을 N개 입력받아서 리스트에 저장한다 → 가능가능

입력받은 문자열의 문자를 하나하나 비교한다 → 어떻게 할까..?

반복문조건문을 이용하면 어떻게 풀어낼 수 있겠다 생각은 들었다.

 

 

[의사 코드]

  1. 사용자로부터 파일 개수 N을 입력
  2. N개의 파일 이름을 입력받아 리스트에 저장
    • 결과를 저장할 빈 문자열을 준비
  3. 각 글자 위치에 대해 다음을 반복
    • 첫 번째 문자열의 해당 위치 글자를 기준으로 정함
    • 나머지 모든 문자열의 해당 위치 글자를 차례대로 비교
    • 하나라도 다르면, 해당 위치는 '?'로 정함
    • 모두 같으면, 해당 문자를 결과에 추가
  4. 만들어진 결과 문자열을 출력

 

 

[의사 코드를 실제 코드로 구현]

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)

★ 코드 설명 ★

주석으로 접근 방법을 먼저 작성했다.

의사코드를 작성하려 했으나 사실 접근 방법에서 해답이 나왔으므로

의사코드는 생략하고 코드를 구현했다.

(틀리면 그때 의사코드를 작성해 보자는 마인드. 원래 이러면 안 된다)

  1. 단어를 입력받아 word에 저장
  2. 슬라이싱 문법을 사용해서 문자열을 역순으로 만들기
    • 슬라이싱 문법은 아래에 따로 정리할 테니 참고
  3. 원래 문자열과 뒤집은 문자열이 같은지 비교
    1. 같으면 팰린드롬
    2. 다르면 아님
  4. 비교 결과에 따른 결과 출력

 

 

 


[슬라이싱 기본 문법]

사용한 김에 문법을 가져왔다.

시퀀스[시작:끝:간격]

 

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문제 밖에 없어서 글 작성에 시간이 적게 걸릴 것이라 생각했는데

생각보다 오래 걸렸다.

디코에서 다른 분들 풀이 코드를 볼 수 있는 기회가 있어서 좋았고

해설과 팁들을 공유받아서 유익한  시간이었다! (크롬 백준 허브 등)