문제 출처 : 프로그래머스

문제는 여기에


문제

  • 숫자로 이루어진 문자열 t와 p가 주어진다. (문자열 길이 t > p)
  • t의 문자열을 p의 길이만큼 부분 문자열으로 나눈다.
  • 나눈 부분 문자열이 나타내는 수가 p보다 작거나 같은 것이 나오는 횟수를 return 하는 함수 solution을 완성해라

 

제한사항

  • 1 <= p의 길이 <= 18
  • p의 길이 <= t의 길이 <= 10,000
  • t와 p는 숫자로만 이루어진 문자열이며, 0으로 시작하지 않습니다.

입출력 예

 

접근

  1. p의 길이만큼 부분 문자열을 만들어야하니 슬라이싱을 이용해야지 (인덱스의 차이는 p의 길이만큼)
  2. for 문을 돌면서 시작하는 인덱스를 1씩 증가시켜야겠다.
  3. 만들어진 부분 문자열을 곧바로 정수형의 p와 비교해서 조건에 맞으면 카운트를 해야겠다.

풀이

def solution(t, p):
    answer = 0
    a = int(t)
    b = int(p)
    c = a - b
    for i in range(c+1):    # range(c)만큼 반복하면 t 문자열의 마지막 문자까지 도달 X
        if int(t[i:i+b]) <= int(p):
            answer += 1
    return answer

고찰

c를 정의하지 않고 바로 사용해도 될 것 같다.

한 줄 짜리 코드를 발견해서 공부할 겸 아래에다가 적겠다.

 

다른 풀이

def solution(t, p):
    return len([t[i: i+len(p)] for i in range(len(t)-len(p)+1) if int(t[i: i+len(p)]) <= int(p)])

위 코드를 이해하기 위해서는 for 문과 if 문을 한 번에 사용하는 법을 알아야한다.

 

 

깨알지식

  1. if condition에 해당하는 값만 출력하기
for i in range(10,20):
    if i == 12:
        print(i)

-> 12

 

 

위의 코드를 한 번에 적어보면

[i for i in range(10,20) if i == 12]

-> [12]

 

로 표현이 된다.

 

출력을 보면 알 수 있듯이!  첫 번째 코드는 정수형을 출력하고, 두 번째 코드는 리스트를 출력한다.

 

 

   2. for문에 해당하는 각각의 원소가 if condition에 해당하는지, 아닌지

for i in range(10,20):
    if i == 12:
        print(i)
    else:
        print("No")

-> No No 12 No No No No No No No (줄바꿈 생략)

 

 

[i if i == 12 else "No" for i in range(10,20)]

-> ['No', 'No', 12, 'No', 'No', 'No', 'No', 'No', 'No', 'No']

 

 

제대로 공부 안 하고 봤을 때는 왜 이렇게 어렵게 쓰나 싶었는데, 10분 정도만 공부해도 한 줄 표현이 더 좋을 것 같다는

생각이 든다. 적응하고 자주 쓸 수 있게 기회가 있다면 한 줄 쓰기로 도전 해야겠다.

 

 

한 줄 쓰기 출처 : https://leedakyeong.tistory.com/entry/python-for%EB%AC%B8-if%EB%AC%B8-%ED%95%9C-%EC%A4%84%EB%A1%9C-%EC%BD%94%EB%94%A9%ED%95%98%EA%B8%B0

문제 출처 : 프로그래머스

문제는 여기에


문제

  • 자연수 n이 매개변수로 주어진다.
  • n을 x로 나눈 나머지가 1이 되도록 하는 가장 작은 자연수 x를 return하는 solution 함수를 완성해라

 

입출력 예

 

접근

1. for문을 돌리면서 나머지가 1인 것들을 찾아야겠다.

 

나의 코드

def solution(n):
    result = []
    for i in range(2,n):
        if n % i == 1:
            result.append(i)
    answer = min(result)
    return answer

 

고찰

나는 별 생각없이 n을 x로 나눈 나머지가 1인 것들을 모두 찾아 리스트에 추가하였고

그 리스트들 중에서 가장 작은 수를 return 하는 방법을 했는데

생각해보니 n-1까지 for문을 돌면서 나머지가 1인 것들을 모두 찾는 것은 비효율적이라는 것이다.

나머지가 1이 되는 것을 찾으면 반복을 빠져나오자

수정한 코드

def solution(n):
    for i in range(2,n):
        if n % i == 1:
            break
    answer = i
    return answer

61~64번에서 별을 열심히 찍었었다. 이제 별 찍기 예제의 마지막 X 모양 별 찍기를 해보려고 한다.

2023.08.18 - [BOOK/파이썬 문제풀이 100] - 62. 대각선 별 찍기

 

62. 대각선 별 찍기

별 찍기의 응용은 참 많은 것 같다. 61번에서 기초적인 별 찍기를 했으니 살짝 응용한 대각선 별 찍기도 해보자. 2023.08.18 - [BOOK/파이썬 문제풀이 100] - 61. 삼각형 별 찍기 I 61. 삼각형 별 찍기 I 이

jijibae.tistory.com


문제

다음과 같이 *를 출력하는 코드를 for 반복문을 사용해 작성하세요.

 

접근

총 행의 수는 10이므로 바깥 for문의 반복 횟수는 10번이다.

열에서 처음부터 별까지의 빈칸의 수는 1행 => 0 , 2행 => 1, ... ,5행 => 4, 6행 =>4, 7행 => 3, ... , 10행 =>0이므로

+1씩 등차수열을 띄고, 7행부터 -1씩 등차수열을 띄니 조건문을 달아야 한다고 생각했다.

대칭이 많이 보이므로, 한쪽만 잘 구현해놓으면 반대쪽은 쉽게 할 수 있을 것이다.

j = 1
for i in range(10):
    if i == 5 : i = 4
    if i > 5: 
        i = i - (2*j+1)
        j += 1
    print(' ' * i, end="")
    print('*' * 1 , end="")
    print(' ' * (8-2*i), end="")
    print('*' * 1, end="")
    print(' ' * i,)

위 풀이는 이중 for문을 사용하지 않고.. 꾸역꾸역 어떻게든 해보겠다는 나의 의지가 잘 담겨 있다..

결과는 동일하게 나오지만 배울만한 내용은 없어 더 고민해보았다.

 

별이 언제 찍힐까?

62번의 대각선 별 찍기를 기억해보면 행과 열의 인덱스가 같은 경우 별이 찍힌다.

이 예제의 X 문자중 \ 부분은 행,열의 인덱스가 같은 부분이다.

 

그럼 / 부분은 어떻게 찍을 수 있을까??

바로 인덱스의 합이다. 행과 열의 인덱스의 합이 9일 때 별이 찍힌다고 생각할 수 있다.

X 문자에서 \부분
X 문자에서 / 부분

i + j 의 값이 9일 때 별이 찍힌다는 규칙을 알면 이 문제를 쉽게 풀 수 있다.

for i in range(10):
    for j in range(10):
        if i == j or i + j == 9:
            print('*', end="")
        else:
            print(' ', end="")
    print()

결과

인덱스의 합도 고려할 수 있는 좋은 문제였다고 생각한다.

63번에서 삼각형 별 찍기II를 맛 보고 왔었다. 이번 별 찍기 문제는 신기한 규칙이 있는 것 처럼 보인다.

2023.08.21 - [BOOK/파이썬 문제풀이 100] - 63. 삼각형 별 찍기 II

 

63. 삼각형 별 찍기 II

61번에서 삼각형 별 찍기 I를 했었다. 이번에는 61번의 결과를 거꾸로 출력해보겠다. 2023.08.18 - [BOOK/파이썬 문제풀이 100] - 61. 삼각형 별 찍기 I 61. 삼각형 별 찍기 I 이 예제는 백준, 프로그래머스

jijibae.tistory.com


문제

다음과 같이 *를 출력하는 코드를 for 반복문을 사용해 작성하세요.

 

접근

총 행의 수는 3이므로 for 문의 반복 횟수는 3이다.

열에 찍히는 *의 수는 1행 => 1, 2행 => 3, 3행 => 5 의 등차수열을 띄므로 변수라는 것을 알 수 있다.

별을 찍는 것만 고려하면 안되고 빈칸까지 고려해야한다.

for i in range(1,4):
    print('' * (3-i), end="")
    print('*' * (2*i-1), end="")
    print('' * (3-i))

결과

이중 for문을 사용할 수 있나? 생각해보았는데 한 줄에 출력해야할 것이 빈칸(' ')과 별(*)의 2종류이고,

별이 중간부터 나오므로 어렵게 이중 for문으로 푸는 것보다 한 번의 반복 동안 처리하는 것이 더 쉬워 보였다.