본문 바로가기

개발일지/TIL

TIL 23-04-20 페어 프로그래밍 - 직사각형 넓이 구하기

1. 페어 프로그래밍 - 직사각형 넓이 구하기 

 문제점

2차원 좌표 평면에 변이 축과 평행한 직사각형이 있습니다. 
직사각형 네 꼭짓점의 좌표 [[x1, y1], [x2, y2], [x3, y3], [x4, y4]]가 
담겨있는 배열 dots가 매개변수로 주어질 때,
직사각형의 넓이를 return 하도록 solution 함수를 완성해보세요

문제를 이해하는 것부터 상당히 어렵다.

if dots = [[-1, -1], [1, 1], [1, -1], [-1, 1]]

코드로 작성하기 전 문제부터 이해를 해야해서 직접 그려봤다.

# dots = [[x1, y1], [x2, y2], [x3, y3], [x4, y4]]

# return 은 직사각형의 넓이

# for, sort, max, min

 시도해 본 것들

하드 코딩 2중 for문과 양수, 음수에 따른 조건문으로 x, y의 길이가 최댓값이 되는 조합 찾기 <- 반례가 1개 생겼는데 찾을 방법을 몰라서 포기

dots에서 x와 y를 분리해서 따로 만들기 <- x와 y를 분리해서 보면 2개씩 같은 값이 나오고 최댓값과 최솟값의 차이를 구하면 된다는 것을 알게 됨 

sort(reverse=True)를 사용해서 크기순으로 정렬하기 <- [0]이 max, [3]이 min이 된다.

max, min 함수 사용하기 

 해결 방법

def solution(dots):
	# List comprehension
	x = [dots[x][0] for x in range(len(dots))]
	y = [dots[y][1] for y in range(len(dots))]
	
	x.sort(reverse=True)
	y.sort(reverse=True)
	
	width = x[0] - x[3]
	height = y[0] - y[3]
	
	answer = width * height
  return answer

코드의 흐름을 따라갈 수 있어서 이해할 수 있는 방법이었다.

def solution(dots):
return (max(dots)[0] -min(dots)[0]) * (max(dots)[1] - min(dots)[1])

max, min의 사용법을 알고 난 뒤 리팩토링

바로 이렇게 작성하려면 아직 갈길이 멀다

 알게 된 점

문제를 이해하는 게 어려웠지만 요구하는 조건 자체는 0번째 리스트의 (최댓값 - 최솟값) * 1번째 리스트의 (최댓값 - 최솟값)을 return 하면 되는 문제였다.

1번처럼 풀고 나서 2번으로 리팩토링 하는 것은 가능했지만, 바로 2번처럼 풀기가 어렵다.

 

1. 백준 알고리즘 문제 - 평균은 넘겠지

 문제점

첫째 줄에는 테스트 케이스의 개수 C가 주어진다.
둘째 줄부터 각 테스트 케이스마다 학생의 수 N(1 ≤ N ≤ 1000, N은 정수)이 첫 수로 주어지고,
이어서 N명의 점수가 주어진다. 점수는 0보다 크거나 같고, 100보다 작거나 같은 정수이다.

출력
각 케이스마다 한 줄씩 평균을 넘는 학생들의 비율을 반올림하여 소수점 셋째 자리까지 출력한다.

# 첫줄 케이스 개수 for문 길이 
# 학생수, 학생수 * 점수
# 평균을 넘는 학생 수를 소수점 셋째 자리까지 출력
# 반올림 format(, ". 3f") %로 출력

 시도해 본 것들

  1. 첫 줄에서 입력받은 값으로 for문 진행
  2. 두번째 줄 부터 scores =  map(int,input().split())으로 값 받기 <- 리스트 형태로 안들어감 
    좀 더 찾아보니 list(map(int,input().split()))으로 감싸면 내가 원하는 것 처럼 변수에 입력됨
  3. pop(0)으로 list의 첫 번째 인덱스에서 학생 수 빼내기 
  4. 합산 점수를 구하기 위해 sum(*scores)시도 <- sum이 받는 인자가 2개까지 가능함 [23.04.21 추가] sum 사용 가능
    오늘 배운 언패킹을 바로 참고하며 add함수 작성 후 add를 이용해서 합산 점수 구하기
  5. 합산 점수 // 학생수로 평균 점수 구하기
  6. 평균을 넘긴 학생의 비율을 구하기 위해서 len사용 
    분모는 len(scores)로 쉽게 작성가능했는데 분자에서 List Comprehension을 좀 더 자세하게 써보기로 하고 for 문과 if문을 추가해서 평균 점수보다 높은 값만 빼도록 시도 했다.
    print([i for i in scores if i > average_score])
  7. len으로 감싸고 출력 했을 때 소수점 단위로 바로 나오므로 * 100을 추가하고 round로 감쌌지만, 빈 소숫점을 출력하지 못함
    round말고 다른 함수가 있었던걸 떠올리고 바로 검색 foramt(, '.소숫점 자릿수f')를 찾음

 해결 방법

def add(*args):
    total_score = 0
    for i in args:
        total_score += i
    return total_score


a = int(input())
for _ in range(a):
    scores = list(map(int, (input().split())))
    students = scores.pop(0)
    total_score = add(*scores)
    average_score = total_score // students
    over_score_raito = format(
        len([i for i in scores if i > average_score]) / len(scores) * 100, ".3f")
    print(f'{over_score_raito}%')

23-04-21 수정:

a = int(input())
for _ in range(a):
    scores = list(map(int, (input().split())))
    students = scores.pop(0)
    total_score = sum(scores)
    average_score = total_score // students
    over_score_raito = format(
        len([i for i in scores if i > average_score]) / len(scores) * 100, ".3f")
    print(f'{over_score_raito}%')

sum의 인자가 더해줄 숫자들, 시작 값으로 구성되어 있어서 *scores로 풀어 넣는 게 불가능 했다. 

# ex) scores를 더하는데 , 기본값을 100으로 가진다.
total_score = sum(scores, 100)

sum에 언패킹해서 집어넣을 게 아니라 리스트를 집어넣으면 sum에서 알아서 언패킹해 더해주는 것 같다.

 알게 된 점

배웠던 것을 활용하면 풀 수 있을 것 같아서 이렇게 풀었는데 난이도 대비 복잡해진 것 같다. 

언패킹을 잘 이해한줄 알았는데 1시간도 안돼서 써보려고 했을 때 시행착오를 겪는 것을 보면 역시 스스로 써봐야 제대로 깨닫게 된다.

 

 

'개발일지 > TIL' 카테고리의 다른 글

TIL 23-04-22 백준 알고리즘 - 벌집  (0) 2023.04.22
TIL 23-04-21 페어 프로그래밍 - 연속된 수의 합  (0) 2023.04.21
TIL 23-04-19  (2) 2023.04.19
TIL 23-04-18  (1) 2023.04.18
TIL 23-04-17  (0) 2023.04.17