[백준] 17225번 세훈이의 선물가게

[백준] 17225번 세훈이의 선물가게

출처: [백준] 17225번 세훈이의 선물가게


시간 제한 메모리 제한 제출 정답 맞은 사람 정답 비율
1 초 512 MB 1120 261 197 29.315%

문제

세훈이는 선물가게를 운영한다. 세훈이의 선물가게는 특이하게도 손님이 어떤 선물을 구매할지 선택할 수가 없다. 대신 세훈이의 취향으로 랜덤하게 준비된 선물 중 몇 개를 구매할 것인지, 파란색과 빨간색 중 어떤 색으로 포장 받을 것인지만 결정해 주문할 수 있다.

상민이와 지수는 세훈이의 가게에서 선물 포장을 맡은 아르바이트생이다. 손님들은 파란색 포장지를 원하면 상민이에게, 빨간색 포장지를 원하면 지수에게 주문을 한다. 두 사람은 각자 주문을 받으면 그때부터 포장을 시작하는데, 현재 남아있는 선물 중 가장 앞에 있는 선물을 가져와 포장하고 주문을 받은 개수만큼 이를 반복하는 형태다. 이때 선물 하나를 포장하는 데 상민이는 A초, 지수는 B초가 걸린다. 두 사람 모두 받거나 밀린 주문이 없는데 미리 선물을 가져오거나 포장하는 일은 없으며, 두 사람이 동시에 선물을 가져올 때는 알바짬이 조금 더 있는 상민이가 먼저 가져오고, 지수가 그 뒤의 선물을 가져온다.

세훈이는 어제 구매한 선물이 망가져 있다는 항의 전화를 받았다. 자신이 준비한 선물에는 문제가 없었기에 손님에게 포장지의 색을 물었지만, 손님은 자신이 받은 선물이 무엇인지만 말하며 화를 낼 뿐이었다. 어쩔 수 없이 세훈이는 어제 가게를 방문한 손님들의 주문 내역을 보고 그 선물을 누가 포장했는지 파악하려 한다.

방문한 손님의 수와 각 손님이 주문한 시각, 선택한 포장지, 포장 받을 선물의 개수가 주어졌을 때 상민이와 지수가 각자 어떤 선물들을 포장했는지 알아내는 프로그램을 작성해보자.


입력

첫 줄에 상민이가 선물 하나를 포장하는 데 걸리는 시간 A, 지수가 선물 하나를 포장하는 데 걸리는 시간 B, 어제 세훈이 가게의 손님 수 N(1 ≤ N ≤ 1,000)이 주어진다.

이후 N개의 줄에 걸쳐 1번부터 N번 손님의 주문 시각 ti(1 ≤ ti ≤ 86,400), 선택한 포장지의 색깔 ci(ci = “B”|”R”), 주문한 선물의 개수 mi(1 ≤ mi ≤ 100)가 주어진다.

ti는 가게가 오픈한 지 ti초 후에 손님이 주문했음을 뜻하며 ci는 포장지의 색깔을 의미하는 알파벳으로 “B”는 파란색을, “R”은 빨간색을 의미한다. 주어지는 입력은 시간의 흐름에 맞게 ti의 오름차순으로 주어지며, 서로 같은 시간에 주문한 손님은 없다.


출력

첫 번째 줄에 상민이가 포장한 선물의 개수를 출력한다. 이후 두 번째 줄에 상민이가 포장한 선물들의 번호를 오름차순으로 공백으로 구분하여 출력한다.

세 번째 줄에 지수가 포장한 선물의 개수를 출력한다. 이후 네 번째 줄에 지수가 포장한 선물들의 번호를 오름차순으로 공백으로 구분하여 출력한다.


서브태스크 1 (100점)

  • A = B = 0

A, B가 0이라는 것은 해당 아르바이트생의 포장 속도가 너무 빨라서, 주문과 동시에 해당 주문의 모든 선물 포장이 끝난다는 의미이다.

서브태스크 2 (40점)

  • 0 ≤ A, B ≤ 300

예제 입력 1

1
2
3
4
0 0 3
1 B 3
4 R 2
7 R 2

예제 출력 1

1
2
3
4
3
1 2 3
4
4 5 6 7

<그림1> 예제1 시간에 따른 상민이와 지수의 행동

예제 입력 2

1
2
3
4
5
2 3 4
1 B 3
4 R 2
6 B 2
12 R 1

예제 출력 2

1
2
3
4
5
1 2 4 5 7
3
3 6 8

<그림2> 예제2 시간에 따른 상민이와 지수의 행동


출처


알고리즘 분류


소스코드 (Heap 이용)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
import sys
import heapq

input = sys.stdin.readline

s_time, j_time, customer_count = map(int, input().split()) # 상민 포장시간, 지수 포장시간, 손님수
pacakage_list = [] # 포장시작 시간 리스트
s_end, j_end = 0, 0 # 상민, 지수 포장 끝난 시간

for _ in range(customer_count):
start_time, color, present_count = input().rstrip().split() # 주문시각, 색깔, 개수
start_time = int(start_time)

if color == 'B': # 상민

# 상민 포장 주문시각이 포장끝난 시각보다 먼저일 경우
# 주문시각(포장시작시각)을 포장끝난 시점으로 변경해준다.
start_time = max(start_time, s_end)

for i in range(int(present_count)): # 주문 개수만큼 반복
heapq.heappush(pacakage_list, [start_time, 'B']) # 상민 포장시작 시간 리스트에 저장
start_time += s_time # 기존 포장시작시간에 포장에 걸리는 시간 더하기
s_end = start_time # 포장끝난 시간은 포장시작시간+포장에 걸리는 시간

elif color == 'R': # 지수
start_time = max(start_time, j_end)

for i in range(int(present_count)):
heapq.heappush(pacakage_list, [start_time, 'R'])
start_time += j_time
j_end = start_time

s_present, j_present = [], [] # 상민, 지수가 포장한 선물리스트

for i in range(1, len(pacakage_list) + 1):
present = heapq.heappop(pacakage_list)
if present[1] == 'B':
s_present.append(i)
else:
j_present.append(i)

print(len(s_present))
print(*s_present)
print(len(j_present))
print(*j_present)

소스코드 (Queue 이용)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
import sys
from collections import deque

input = sys.stdin.readline

s_time, j_time, customer_count = map(int, input().split()) # 상민 포장시간, 지수 포장시간, 손님수
sangmin = deque() # 상민 포장시작 시간 리스트
jisu = deque() # 지수 포장시작 시간 시간 리스트
s_end, j_end = 0, 0 # 상민, 지수 포장 끝난 시간

for _ in range(customer_count):
start_time, color, present_count = input().rstrip().split() # 주문시각, 색깔, 개수
start_time = int(start_time)

if color == 'B': # 상민
start_time = max(start_time, s_end)
# if start_time < s_end: # 상민 포장 주문시각이 포장끝난 시각보다 먼저일 경우
# start_time = s_end # 주문시각(포장시작시각)을 포장끝난 시점으로 변경해준다.

for i in range(int(present_count)): # 주문 개수만큼 반복
sangmin.append([start_time, 'B']) # 상민 포장시작 시간 리스트에 저장
start_time += s_time # 기존 포장시작시간에 포장에 걸리는 시간 더하기
s_end = start_time # 포장끝난 시간은 포장시작시간+포장에 걸리는 시간

elif color == 'R': # 지수
start_time = max(start_time, j_end)
# if start_time < j_end:
# start_time = j_end

for i in range(int(present_count)):
jisu.append([start_time, 'R'])
start_time += j_time
j_end = start_time

total_list = sangmin + jisu
total_list = sorted(total_list, key=lambda x: [x[0], x[1]])

s_present, j_present = [], [] # 상민, 지수가 포장한 선물리스트

for idx, present in enumerate(total_list):
if present[1] == 'B':
s_present.append(idx + 1)
else:
j_present.append(idx + 1)

print(len(s_present))
print(*s_present)
print(len(j_present))
print(*j_present)

[백준] 14713번 앵무새

[백준] 14713번 앵무새

출처: [백준] 14713번 앵무새


시간 제한 메모리 제한 제출 정답 맞은 사람 정답 비율
1 초 512 MB 807 173 141 26.454%

문제

자가용 비행기를 타고 세계 일주를 하던 pps789와 cseteram은 어느 날 엔진 고장으로 인해 이름 모를 섬에 불시착하게 된다. 그들은 이 섬을 탐험하는 도중 아주 신기한 사실을 알게 되었는데, 바로 이 섬에 사는 앵무새들은 놀라울 정도로 인간의 말을 흉내 내는 데 뛰어나다는 것이다. 그들은 서로 떨어져 섬을 탐험하기로 하였으며, 필요하다면 앵무새를 이용해 서로에게 연락하기로 약속하였다.

1개월 후, pps789는 섬의 비밀을 밝힐 결정적인 증거를 찾게 된다. 그는 이 세기의 대발견을 cseteram에게 공유하고자 하였으나, 그의 발견은 방대하여 앵무새 한 마리가 기억하기에는 너무 많은 양이었다. 그렇기 에 pps789는 앵무새 한 마리 대신 앵무새 N마리를 이용하여 자신의 발견을 기록하였으며, 이 앵무새들을 cseteram을 향해 날렸다.

한편 섬의 반대편에서 탐험을 계속하던 cseteram은 앵무새 N마리가 자신에게 날아와 각자 할 말을 하는 것을 보고 당황하였다. pps789가 긴 글을 전달하고 싶었던 것은 알아차렸지만, 각각의 앵무새들이 말하는 것을 차례대로 기록하다 보니 원문이 무엇인지 알 수 없을 정도로 단어의 순서가 엉켜버린 것이다. 대신 그는 관찰을 통해 몇 가지 규칙을 발견할 수 있었다.

  1. 한 앵무새는 한 문장을 기억하고 있다. 문장은 여러 단어로 이루어져 있는데, 앵무새는 이 단어들을 순서대로 말한다.
  2. 한 앵무새가 단어를 말하고 그다음 단어를 말하기 전에는 약간의 간격이 있는데, 이때 다른 앵무새가 말을 가로채고 자신의 문장을 말할 수 있다.
  3. 한 앵무새가 단어를 말하는 도중에는, 다른 앵무새가 말을 가로채지 않는다.
  4. 어떤 단어도 앵무새가 말하는 모든 문장을 통틀어 2번 이상 등장하지 않는다.

앵무새는 자신이 기억하고 있는 문장을 끝까지 말한 다음 pps789에게 돌아가며, cseteram은 모든 앵무새가 돌아갈 때 까지 단어를 받아적는다. pps789가 각각의 앵무새들에게 전달한 문장 Si와, cseteram이 받아 적은 문장 L이 주어진다. 이때 문장 L이 위 규칙들을 이용하여 나올 수 있는 문장인지 판별하시오.


입력

첫 번째 줄에 앵무새의 수 N (1 ≤ N ≤ 100) 이 주어진다.

두 번째 줄부터 N개의 줄에 걸쳐 각 앵무새가 말한 문장 Si (1 ≤ i ≤ N) 가 주어지는데, 각 문장을 이루는 단어는 스페이스 한 칸을 구분으로 하여 주어진다. 문장 Si를 이루는 단어의 수는 1개 이상 100개 이하이며, 각 단어는 1개 이상 32개 이하의 영문 소문자로 구성되어있다.

N + 2 번째 줄에는 cseteram이 받아 적은 문장 L이 주어진다. 문장 L을 이루는 단어의 수는 1개 이상 10000개 이하이며, 각 단어는 1개 이상 32개 이하의 영문 소문자로 구성된다.


출력

문장 L이 가능한 문장이라면 Possible을, 불가능한 문장이라면 Impossible을 출력한다.


예제 입력 1

1
2
3
4
5
3
i want to see you
next week
good luck
i want next good luck week to see you

예제 출력 1

1
Possible

예제 입력 2

1
2
3
4
2
i found
an interesting cave
i found an cave interesting

예제 출력 2

1
Impossible

예제 입력 3

1
2
3
4
2
please
be careful
pen pineapple apple pen

예제 출력 3

1
Impossible

출처


알고리즘 분류


소스코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
import sys
from collections import deque

input = sys.stdin.readline

N = int(input())
parrot = [deque(input().rstrip().split()) for _ in range(N)]

L = input().rstrip().split()
Removed = []
for word in L:
for i in range(N):
if parrot[i] and word == parrot[i][0]:
parrot[i].popleft()
Removed.append(word)
break

for i in range(N):
if parrot[i]:
print("Impossible")
exit()
if L != Removed:
print("Impossible")
else:
print("Possible")

[백준] 2161번 카드1

[백준] 2161번 카드1

출처: [백준] 2161번 카드1


시간 제한 메모리 제한 제출 정답 맞은 사람 정답 비율
2 초 128 MB 5741 3921 3505 70.651%

문제

N장의 카드가 있다. 각각의 카드는 차례로 1부터 N까지의 번호가 붙어 있으며, 1번 카드가 제일 위에, N번 카드가 제일 아래인 상태로 순서대로 카드가 놓여 있다.

이제 다음과 같은 동작을 카드가 한 장 남을 때까지 반복하게 된다. 우선, 제일 위에 있는 카드를 바닥에 버린다. 그 다음, 제일 위에 있는 카드를 제일 아래에 있는 카드 밑으로 옮긴다.

예를 들어 N=4인 경우를 생각해 보자. 카드는 제일 위에서부터 1234 의 순서로 놓여있다. 1을 버리면 234가 남는다. 여기서 2를 제일 아래로 옮기면 342가 된다. 3을 버리면 42가 되고, 4를 밑으로 옮기면 24가 된다. 마지막으로 2를 버리고 나면, 버린 카드들은 순서대로 1 3 2가 되고, 남는 카드는 4가 된다.

N이 주어졌을 때, 버린 카드들을 순서대로 출력하고, 마지막에 남게 되는 카드를 출력하는 프로그램을 작성하시오.


입력

첫째 줄에 정수 N(1 ≤ N ≤ 1,000)이 주어진다.


출력

첫째 줄에 버리는 카드들을 순서대로 출력한다. 제일 마지막에는 남게 되는 카드의 번호를 출력한다.


예제 입력 1

1
7

예제 출력 1

1
1 3 5 7 4 2 6

출처

-


알고리즘 분류


소스코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import sys
from collections import deque

input = sys.stdin.readline

N = int(input())

card_deque = deque([i for i in range(1, N + 1)])
removed_card = []

while len(card_deque) > 0:
removed_card.append(card_deque.popleft())
card_deque.rotate(-1)

print(*removed_card)

2021년 07월 19일 월요일 IT뉴스

1. 턱밑까지 추격한 샤오미… 폴더블폰이 삼성 구할까

턱밑까지 추격한 샤오미… 폴더블폰이 삼성 구할까

중국 샤오미가 올 2분기 전 세계 스마트폰 시장 2위에 오르며 삼성전자의 턱밑까지 치고 올라온 가운데, 애플이 9월 출시할 아이폰 차기작이 아이폰 역사상 최고 히트작이 될 것이라는 전망이 나오고 있어서 삼성전자가 중저가 시장에서는 샤오미에 밀리고, 수익성에서는 애플과 격차가 더 커지는 샌드위치 신세가 될 가능성이 높다는 것이다.

삼성전자는 특히 갤럭시Z폴드3와 갤럭시Z플립3의 가격을 각각 전작보다 40만원가량 낮춘 199만원과 128만원으로 책정하는 방안도 고민 중으로 폴더블폰 가격을 아이폰이나 갤럭시S 시리즈 수준까지 낮춰 새로운 수요를 개척하겠다는 것이며 하반기 전략 스마트폰인 갤럭시노트를 올해 출시하지 않는 승부수까지 던지면서 사실상 ‘폴더블 올인’ 전략을 구사하는 것이다.


2. 크래프톤, 인도 웹소설 플랫폼 ‘프라틸리피’에 515억 원 투자… 올해 인도 IT기업에 802억 투자 집행

크래프톤, 인도 웹소설 플랫폼 ‘프라틸리피’에 515억 원 투자… 올해 인도 IT기업에 802억 투자 집행

크래프톤이 인도 최대 웹소설 플랫폼 ‘프라틸리피(Pratilipi)’에 총 4,500만 달러(한화 약 515억 원)의 투자를 진행했다.

크래프톤 손현일 투자본부장은 “프라틸리피의 서적, 코믹스, 오디오 플랫폼를 통해 인도 현지 IP의 성장을 지켜보면서 인도 현지 IP가 인도 뿐 아니라 전 세계적으로 성공할 수 있다는 장기적인 잠재력을 믿게 됐다”며, “프라틸리피는 이미 웹소설 분야의 다국어 플랫폼을 보유하고 있기 때문에 향후 시장에서 크게 성장할 기업이라고 보고 있다”고 말했다.

  • 프라틸리피는 3,000만 명의 월간 활성 이용자(MAU)와 37만 명의 작가를 확보하고 있는 인도 최대 웹소설 플랫폼이다. 12개의 인도 언어로 서비스를 제공하고 있으며, 최근에는 웹소설 뿐만 아니라 일반서적, 애니메이션, TV시리즈 등 다양한 형태의 콘텐츠 제공을 위해 관련 기업들과의 협업을 가속화하고 있다. 또, 프라틸리피 FM, 프라틸리피 코믹스 등을 출시하며 서비스 범위도 확장 중이다.

3. 의약품 주문통합 플랫폼 ‘바로팜’, 팁스 프로그램 선정

의약품 주문통합 플랫폼 ‘바로팜’, 팁스 프로그램 선정

의약품 주문통합 플랫폼인 ‘바로팜’이 중소벤처기업부가 주관하는 민간투자주도형 기술창업지원(TIPS) 프로그램에 선정됐다.

현재 200여개 약국이 바로팜 서비스를 이용하고 있고 이번 투자를 통해 수도권 위주의 서비스에서 전국적인 서비스로 확대해 나갈 예정이며 올 하반기 1000개 약국에 바로팜 서비스를 제공하는 것을 목표로 하고 있다.

현직 약사이자 바로팜 김슬기 대표는 “바로팜은 의약품 주문통합 플랫폼으로서 업무에 지친 약사님들에게 간편한 주문 시스템을 제공하고 지속적으로 약국 주문 관련 불편한 부분을 약사님들과 함께 고민해 나갈 예정이다. 이를 통해 약국경영에 도움을 주는 다양한 서비스들을 선보일 것”이라고 말했다

  • 팁스: 팁스는 우수 기술을 보유한 유망 스타트업을 발굴해 정부가 2년 간 최대 7억 원을 지원 및 투자하는 대표적인 민간 투자 주도형 기술 창업 지원 프로그램이다.

  • 바로팜: 바로팜은 의약품을 주문하는 도매사이트들을 한 곳에서 관리하는 ‘의약품 주문 통합 솔루션’을 제공하는 플랫폼이다. 현재 의약품 통합 주문, 주문 알림톡 발송, 약국 관련 주문사이트 바로가기 통합 제공, 의약품 정보 식별 및 약물 상호작용 검색 기능 제공 등 다양한 서비스를 약국에 제공하고 있다.


[Spring Boot] JAVA 오버로딩과 오버라이딩

[Spring Boot] JAVA 오버로딩과 오버라이딩

자바의 Overloading & Overriding

자바에서 다형성을 지원하는 방법으로 메서드를 오버로딩, 오버라이딩을 할 수 있다.

  • 오버로딩(Overloading): 같은 이름의 메서드 여러개를 가지면서 매개변수의 유형과 개수가 다르도록 하는 것을 의미한다.
    • 리턴값만을 다르게 갖게 작성할 수 없다.

=> 오버로딩은 기존에 없던 새로운 메서드를 정의하는 것

  • 오버라이딩(Overriding): 상위 클래스가 가지고 있는 메서드를 하위 클래스가 재정의해서 사용 하는 것을 의미한다.
    • 상위클래스의 메서드를 하위 클래스에서 재정의하는 것이다.
    • 메서드의 이름, 파라미터의 갯수, 타입이 동일해야 하며, 주로 상위 클래스의 동작을 상속받은 하위 클래스에서 변경하기 위해 사용된다.

=> 오버라이딩은 상속 받은 메서드의 내용만 변경하는 것

[Spring Boot] 데이터베이스 Update 하는 법

[Spring Boot] 데이터베이스 Update 하는 법

데이터베이스 Update하기

웹 브라우저에서 회원 수정을 하는 경우를 생각하며,

@PutMapping을 이용해서 주소를 만들어줬다. 이때 적은 주소는 @GetMapping의 주소와 동일한데, 스프링부트에서는 알아서 Get, Put을 구별해준다.

첫 번째 방법 (Save함수 사용)

주소에서 id를 받아온다. 이 id는 데이터베이스에 저장 된 id값을 불러오기 위함이다.

그리고 @ReqeustBody를 이용하여 Json 데이터를 요청하여, 이를 JavaObject로 변환한다.

SpringBoot에서는 MessageConverter가 Jackson 라이브러리를 사용하여 자동적으로 변환해준다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// email, password
@PutMapping("/dummy/user/{id}")
public User upadteUser(@PathVariable int id, @RequestBody User requestUser) { // Json 데이터를 요청 => Java Object(MessageConverter의 Jackson라이브러리로 변환해서 받음

User user = userRepository.findById(id).orElseThrow(() -> {
return new IllegalArgumentException("수정에 실패하였습니다.");
});
user.setPassword(requestUser.getPassword());
user.setEmail(requestUser.getEmail());
// save함수는 id를 전달하지 않으면 insert를 해주고,
// save함수는 id를 전달하면 해당 id에 대한 데이터가 있으면 update를 해주고
// save함수는 id를 전달하면 해당 id에 대한 데이터가 없으면 insert를 한다.

userRepository.save(user);
return null;
}

Select 때와 마찬가지로, 잘못 된 (없는) id값을 받았을 때를 방지하기 위해 IllegalArgumentException을 throw 할 수 있도록 한다.

정상적인 user객체에 수정하고자 했던 데이터(password와 email)을 set으로 수정해준다.

그리고 save함수를 이용하여 update해준다.


Save 함수, save 함수를 사용할 때

id를 전달하지 않으면 insert를 해주고,

id를 전달하고, 해당 id에 대한 데이터가 있으면 update를 해준다.

id를 전달하지만, 해당 id에 대한 데이터가 없으면 insert를 해준다.


두 번째 방법

@Transactional라는 annotaion을 사용해보자.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// email, password
@Transactional
@PutMapping("/dummy/user/{id}")
public User upadteUser(@PathVariable int id, @RequestBody User requestUser) { // Json 데이터를 요청 => Java Object(MessageConverter의 Jackson라이브러리로) 변환해서 받음

User user = userRepository.findById(id).orElseThrow(() -> {
return new IllegalArgumentException("수정에 실패하였습니다.");
});
user.setPassword(requestUser.getPassword());
user.setEmail(requestUser.getEmail());

// 더티체킹
return user;
}

첫 번째 방법과 크게 다른 것은 없지만, @Transactional을 이용하면, Save함수를 사용하지 않아도 된다.

이를 Dirty Checking (더티체킹) 이라고 한다.

updateUser라는 함수가 실행될 때, Transaction이 실행되고, return이 될때 Transaction이 자동으로 종료되며, 자동 commit이 된다.


영속성 컨텍스트와 더티체킹에 대해서 공부해보자!

영속성 컨텍스트

[Spring Boot] 데이터베이스 Select 하는 법과 에러체크

[Spring Boot] 데이터베이스 Select 하는 법과 에러체크

데이터베이스의 데이터를 Select할 때 잘못 된 인수가 들어가면 어떻게 해야할까


데이터베이스 Select하기

User table을 select하기에 앞서,

UserRepository라는 인터페이스 파일을 새로 만들고, 그 UserRepository는 JpaRepository를 상속하고 있다.

1
2
3
// 자동으로 bean등록이 된다. --> @Repository 생략가능
public interface UserRepository extends JpaRepository<User, Integer> {
}

그리고 select 기능을 넣어줄 클래스파일에 DI를 해주고,

User의 객체를 return 받을 수 있게, 메소드를 받들어주고, 주소를 넣어준다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
@RestController
public class DummyControllerTest {

@Autowired // 의존성주입(DI)
private UserRepository userRepository;

// {id} 주소로 파라미터를 전달 받을 수 있음.
// http://localhost:8000/blog/dummy/user/3
@GetMapping("/dummy/user/{id}")
public User detail(@PathVariable int id) {
User user = userRepository.findById(id)
...
return user;
}

이 때, 만약 id부분에 DB에 없는 값이 들어가면 어떻게 해야할까… 라는 생각이 들 수 있다.

이 경우, user가 null이 되고, 결국 null값을 반환해주므로 프로그램에 문제가 생길 수 있다.

그래서 findById() 는 Optional로 User객체를 감싸서 반환해준다. 이후 우리가 null인지 아닌지 판단해서 사용하면 된다.

findById().orElseGet()

id값이 유효하면 그대로 user를 반환해주면 되지만, 유효하지 않을 경우 orElseGet을 타서 user에 User()빈 객체를 넣어줄 것이다. 이건 그냥 null과 다르다

orElseGet()에 넣을 수 있는 파라미터는 Supplier의 타입(인터페이스)이고, 이 타입의 Generic부분에 ?가 되어있는데 익명 객체를 넣어준다. 그리고 함수 get을 Override 해준다.

(인터페이스는 new할 수 없기 때문에, 익명 클래스를 만들어줘야한다. )

1
2
3
4
5
6
7
User user = userRepository.findById(id).orElseGet(new Supplier<User>() {
// 데이터베이스에 값이 없는 경우 orElseGet을 타서 user에서 User()...빈 객체를 넣어줌,null이 아님
@Override
public User get() {
return new User();
}
});

findById().orElseThrow()

하지만 findByID()에서 만약 id가 null일 경우 IllegalArgumentException 를 throw하라고 적혀있다.

1
2
3
4
5
6
User user = userRepository.findById(id).orElseThrow(new Supplier<IllegalArgumentException>() {
@Override
public IllegalArgumentException get() {
return new IllegalArgumentException("해당 유저는 없습니다. id: " + id);
}
});

or 람다식을 이용해서…

1
2
3
User user = userRepository.findById(id).orElseThrow(()->{
return new IllegalArgumentException("해당 유저는 없습니다. id: " + id);
});

결과

Spring에는 AOP라는 기능이 있다.

만약 Illegal이 있을경우, 에러를 가로채서 에러페이지로 넘어갈 수 있게 만들 수 있을 것이다.

추가

요청: 웹브라우저

user 객체: 자바 오브젝트

@RestController: html파일이 아닌 data를 리턴해주는 controller

이 경우 웹브라우저가 이해할 수 있는 데이터 (Json)으로 변환해줘야하는데, SpringBoot는 MessageConter가 자바 오브젝트가 리턴될 시 자동으로 Jackson라이브러리를 호출해서 user 오브젝트를 Json으로 변환해서 브라우저에게 전달한다.


[프로그래머스] Lv2.주식가격

[프로그래머스] Lv2.주식가격

출처: [코딩테스트 연습 완주하지 못한 선수]


문제

초 단위로 기록된 주식가격이 담긴 배열 prices가 매개변수로 주어질 때, 가격이 떨어지지 않은 기간은 몇 초인지를 return 하도록 solution 함수를 완성하세요.


제한

  • prices의 각 가격은 1 이상 10,000 이하인 자연수입니다.
  • prices의 길이는 2 이상 100,000 이하입니다.

입출력

prices return
[1, 2, 3, 2, 3] [4, 3, 1, 1, 0]

입출력 예 1

  • 1초 시점의 ₩1은 끝까지 가격이 떨어지지 않았습니다.
  • 2초 시점의 ₩2은 끝까지 가격이 떨어지지 않았습니다.
  • 3초 시점의 ₩3은 1초뒤에 가격이 떨어집니다. 따라서 1초간 가격이 떨어지지 않은 것으로 봅니다.
  • 4초 시점의 ₩2은 1초간 가격이 떨어지지 않았습니다.
  • 5초 시점의 ₩3은 0초간 가격이 떨어지지 않았습니다.

소스코드

1
2
3
4
5
6
7
8
9
10
11
12
def solution(prices):
answer = []

for i in range(len(prices)):
count = 0
for j in range(i + 1, len(prices)):
count += 1
if prices[i] > prices[j]:
break
answer.append(count)

return answer
[백준] 2503번 숫자 야구

[백준] 2503번 숫자 야구

출처: [백준] 2503번 숫자 야구


시간 제한 메모리 제한 제출 정답 맞은 사람 정답 비율
1 초 128 MB 9137 4152 3430 45.923%

문제

정보문화진흥원 정보 영재 동아리에서 동아리 활동을 하던 영수와 민혁이는 쉬는 시간을 틈타 숫자야구 게임을 하기로 했다.

  • 영수는 1에서 9까지의 서로 다른 숫자 세 개로 구성된 세 자리 수를 마음속으로 생각한다. (예: 324)
  • 민혁이는 1에서 9까지의 서로 다른 숫자 세 개로 구성된 세 자리 수를 영수에게 묻는다. (예: 123)
  • 민혁이가 말한 세 자리 수에 있는 숫자들 중 하나가 영수의 세 자리 수의 동일한 자리에 위치하면 스트라이크 한 번으로 센다. 숫자가 영수의 세 자리 수에 있긴 하나 다른 자리에 위치하면 볼 한 번으로 센다.

예) 영수가 324를 갖고 있으면

  • 429는 1 스트라이크 1 볼이다.
  • 241은 0 스트라이크 2 볼이다.
  • 924는 2 스트라이크 0 볼이다.
  • 영수는 민혁이가 말한 수가 몇 스트라이크 몇 볼인지를 답해준다.
  • 민혁이가 영수의 세 자리 수를 정확하게 맞추어 3 스트라이크가 되면 게임이 끝난다. 아니라면 민혁이는 새로운 수를 생각해 다시 영수에게 묻는다.

현재 민혁이와 영수는 게임을 하고 있는 도중에 있다. 민혁이가 영수에게 어떤 수들을 물어보았는지, 그리고 각각의 물음에 영수가 어떤 대답을 했는지가 입력으로 주어진다. 이 입력을 바탕으로 여러분은 영수가 생각하고 있을 가능성이 있는 수가 총 몇 개인지를 알아맞혀야 한다.

아래와 같은 경우를 생각해보자.

  • 민혁: 123
  • 영수: 1 스트라이크 1 볼.
  • 민혁: 356
  • 영수: 1 스트라이크 0 볼.
  • 민혁: 327
  • 영수: 2 스트라이크 0 볼.
  • 민혁: 489
  • 영수: 0 스트라이크 1 볼.

이때 가능한 답은 324와 328, 이렇게 두 가지이다.

영수는 동아리의 규율을 잘 따르는 착한 아이라 민혁이의 물음에 곧이곧대로 정직하게 답한다. 그러므로 영수의 답들에는 모순이 없다.

민혁이의 물음들과 각각의 물음에 대한 영수의 답이 입력으로 주어질 때 영수가 생각하고 있을 가능성이 있는 답의 총 개수를 출력하는 프로그램을 작성하시오.


입력

첫째 줄에는 민혁이가 영수에게 몇 번이나 질문을 했는지를 나타내는 1 이상 100 이하의 자연수 N이 주어진다. 이어지는 N개의 줄에는 각 줄마다 민혁이가 질문한 세 자리 수와 영수가 답한 스트라이크 개수를 나타내는 정수와 볼의 개수를 나타내는 정수, 이렇게 총 세 개의 정수가 빈칸을 사이에 두고 주어진다.


출력

첫 줄에 영수가 생각하고 있을 가능성이 있는 답의 총 개수를 출력한다.


예제 입력 1

1
2
3
4
5
4
123 1 1
356 1 0
327 2 0
489 0 1

예제 출력 1

1
2

출처


알고리즘 분류


소스코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
import sys
from itertools import permutations

input = sys.stdin.readline

num = [1, 2, 3, 4, 5, 6, 7, 8, 9]
cases = list(permutations(num, 3))

N = int(input())
for _ in range(N):
ques, s_c, b_c = map(int, input().split())
ques = list(str(ques))

temp_cases = []
for i in range(len(cases)):
strike, ball = 0, 0
for j in range(3):
if cases[i][j] == int(ques[j]):
strike += 1
elif int(ques[j]) in cases[i]:
ball += 1
if s_c == strike and b_c == ball:
temp_cases.append(cases[i])

# 한 줄 끝나고, 맞은 케이스만 사용할 수 있도록
cases = temp_cases

print(len(cases))

[프로그래머스] [2021 카카오 채용연계형 인턴십] 숫자 문자열과 영단어

[프로그래머스] [2021 카카오 채용연계형 인턴십] 숫자 문자열과 영단어

출처: [2021 카카오 채용연계형 인턴십] 숫자 문자열과 영단어


문제

네오와 프로도가 숫자놀이를 하고 있습니다. 네오가 프로도에게 숫자를 건넬 때 일부 자릿수를 영단어로 바꾼 카드를 건네주면 프로도는 원래 숫자를 찾는 게임입니다.

다음은 숫자의 일부 자릿수를 영단어로 바꾸는 예시입니다.

  • 1478 → “one4seveneight”
  • 234567 → “23four5six7”
  • 10203 → “1zerotwozero3”

이렇게 숫자의 일부 자릿수가 영단어로 바뀌어졌거나, 혹은 바뀌지 않고 그대로인 문자열 s가 매개변수로 주어집니다. s가 의미하는 원래 숫자를 return 하도록 solution 함수를 완성해주세요.

참고로 각 숫자에 대응되는 영단어는 다음 표와 같습니다.

숫자 영단어
0 zero
1 one
2 two
3 three
4 four
5 five
6 six
7 seven
8 eight
9 nine

제한

  • 1 ≤ s의 길이 ≤ 50
  • s가 “zero” 또는 “0”으로 시작하는 경우는 주어지지 않습니다.
  • return 값이 1 이상 2,000,000,000 이하의 정수가 되는 올바른 입력만 s로 주어집니다.

입출력

s result
"one4seveneight" 1478
"23four5six7" 234567
"2three45sixseven" 234567
"123" 123

입출력 예 1

  • 문제 예시와 같습니다.

입출력 예 2

  • 문제 예시와 같습니다.

입출력 예 3

  • “three”는 3, “six”는 6, “seven”은 7에 대응되기 때문에 정답은 입출력 예 #2와 같은 234567이 됩니다.
  • 입출력 예 #2와 #3과 같이 같은 정답을 가리키는 문자열이 여러 가지가 나올 수 있습니다.

입출력 예 4

  • s에는 영단어로 바뀐 부분이 없습니다.

제한시간 안내

  • 정확성 테스트 : 10초

풀이

-


소스코드

1
2
3
4
5
6
7
8
9
def solution(s):
convert_table = {'zero': 0, 'one': 1, 'two': 2, 'three': 3, 'four': 4, 'five': 5, 'six': 6, 'seven': 7, 'eight': 8,
'nine': 9}

answer = s
for word, num in convert_table.items():
answer = answer.replace(word, str(num))

return int(answer)