일년에 한번 다른 곳으로 여행을 가는 미국 학생 모임이 있습니다.

이번에는 산호세로 여행을 가기로 했습니다.

 

여행 경비를 모두 똑같이 부담하기로 했지만, 돈을 쓸때마다 나눠서 내는건 비효율적입니다.

그래서 한명씩 식비, 숙박비, 교통비를 부담하기로 합니다.

 

여행이 끝나고 정산할 때, 지출한 내역을 조사한 다음, 1센트 단위에서 모든 학생들이 쓴 돈이 같도록 돈을 주고 받습니다.

지출 내역이 주어졌을 때, 모든 학생이 쓴 돈이 1센트 단위 내에서 똑같아지기 위해 전달되어야 하는 최소 액수를 구해봅시다.

 

입력

표준 입력을 통해서 여러 번의 여행 정보가 입력 됩니다.

각 여행은 여행에 참가한 학생 수를 나타내는 정수 n으로 구성됩니다.

이 정수 n 밑으로는 n 개의 줄이 입력이 되는데, 각 줄에는 달러와 센트 단위로 각 학생의 지출한 경비가 입력됩니다.

학생 수는 최대 1000명을 넘지 않으며, 지출한 금액도 $10,000.00 이상을 넘지 않습니다.

마지막 여행에는 0만 들어있는 줄이 입력됩니다. 

 

출력

각 여행에 대해 각 학생이 사용한 금액이 똑같아지기 위해 전달되어야 하는 금액의 총합을 출력한다.

 

예제

3 (입력 시작)

10.00

20.00

30.00

 

$10.00 (출력)

 

4 (입력 시작)

15.00

15.01

3.00

3.01

 

$11.99 (출력)

 

(종료)


해설

학생들 지출 내역을 전부 더해서, 평균 금액을 구합니다.

각자 지출한 돈에서 평균 금액만큼의 차이를 구해서, 전달되어야 하는 금액의 합을 구합니다.

 

금액 차이를 구할 경우, 평균 금액보다 높은 돈을 지출한 경우에만 계산합니다.

낮게 낸 사람은 오히려 받아야 하니까요.

 

그리고 1센트 단위에서 같아야 한다는 말의 의미를 생각해보세요.

그 이하의 금액은 절삭해서 계산해야 하니까, 이 부분 처리에 신경을 써야 합니다.

# TheTrip.py , 0003 quiz
# written by badsaram

import sys
import math

class trip(object) :
    def __init__(self) :
        self.costs = []
        self.members = 4
        
    def isNumber(self, number) :
        try :
            float(number)
            return True
        except ValueError :
            return False

    def inputCost(self) :
        str = input()
        if((str.isdigit() == False) or (str.isdecimal() == False)) :
            print("Not Digit or Not Decimal")
            return False
        
        self.members = int(str)
        if (self.members <= 0) :
            sys.exit()
        
        for i in range(0, self.members) :
            str = input()
            if (self.isNumber(str) == False) :
                print("Not Number or Not Decimal")
                return False
            
            temp = float(str)
            if ((temp < 0.0) or (temp >= 10000.00)) :
                print("0 < cost < 10000")
                
            self.costs.append(float(str))
                
        return True
    
    def calcMinDelivery(self) :
        sum = 0.0
        avg = 0.0
        MinDelivery = 0.0
        
        for cost in self.costs :
            sum += cost
            
        avg = sum / self.members 
        
        for cost in self.costs :
            if (cost > avg) :
                temp = int((cost - avg) * 100) #floor under 0.00
                MinDelivery += (temp / 100)

        return MinDelivery
    
if __name__ == '__main__' :
    obj = trip()
    
    while (True) :
        if (obj.inputCost() == True) :
            print("$%.2f" % obj.calcMinDelivery())

'코딩 테스트' 카테고리의 다른 글

문제 6 : 인터프리터(Interpreter)  (0) 2022.07.28
문제 5 : 그래픽 편집기  (0) 2022.07.27
문제 4 : LCD 디스플레이  (0) 2022.07.26
문제 2 : 지뢰 찾기  (0) 2022.07.18
문제 1 : 3n+1, 콜라츠 추측, 우박 수열  (0) 2022.07.15

"지뢰 찾기" 라는 게임을 아시나요?

마이크로소프트 윈도우즈에 기본 프로그램으로 깔려있었습니다.

MxN 크기의 지뢰 밭에서 모든 지뢰의 위치를 찾는 게임입니다.

 

지뢰 찾기 게임

이번 문제에서는 이 지뢰 찾기 게임을 간단하게 구현해 봅니다. 

각 칸에 인접한 지뢰 수를 표시해주는 것인데, 각 칸에는 최대 8개의 인접한 칸이 있을 수 있습니다.

 

아래 예제를 보겠습니다. 4x4 지뢰밭이고, 2개의 지뢰가 '*' 문자로 표시되어 있습니다.

이 경우 각 지뢰 주변에 힌트 숫자로 표시를 해서 출력을 하면 됩니다.

 

입, 출력 예제

입력

입력은 지뢰밭의 정보를 받습니다. 첫 줄은 지뢰 밭의 행과 열의 개수를 받습니다.

그 다음 줄부터는 주어진 행만큼, 각 열을 입력 받습니다. 매 줄마다 열 크기만큼의 문자열로 구성됩니다.

행과 열의 크기는 1 이상이고, 최대 100개로 제한됩니다.  (0 < 행, 열 100)

 

지뢰가 없는 칸은 '.', 지뢰는 '*'로 표시합니다. 따옴표는 생략합니다.

 

출력

각 지뢰밭에 대해서 "Field :" 메시지를 우선 출력합니다.

그 다음 줄부터는 지뢰밭의 크기에 맞춰, '.' 대신에 힌트 숫자를 출력합니다.

 

예제


해설

2차원 배열을 동적으로 할당해서 입력된 지뢰밭 정보를 넣습니다.

이 후에는 지뢰밭 배열을 탐색해서, '.'를 만나면 주변 칸의 지뢰 문자 '*' 의 개수를 파악해서 힌트 숫자를 구합니다.

# minesweeper.py , 0002 quiz
# written by badsaram

import sys
import string

class quiz_minesweeper(object) :
    def __init__(self) :
        self.check_pattern = []
        self.check_pattern.append([-1, -1])
        self.check_pattern.append([-1, 0])
        self.check_pattern.append([-1, +1])
        self.check_pattern.append([0, -1])
        self.check_pattern.append([0, +1])
        self.check_pattern.append([+1, -1])
        self.check_pattern.append([+1, 0])
        self.check_pattern.append([+1, +1])
        
        self.initBoard()
    
    def initBoard(self) :
        self.matrix = []
        self.result = []
        self.y = 0
        self.x = 0
        
        for i in range(0, 100) : 	# max height : 100
            self.matrix.append([])
            self.result.append([])
        
            for j in range(0, 100) :	# max width  : 100
                self.matrix[i].append('\0')
                self.result[i].append('\0')

    def inputBoard(self) :
        self.initBoard()
        
        #input n(y), m(x)
        str = input()
        arr = str.split(' ')
        
        #check input n(y), m(x)
        if ((len(arr) != 2) or (arr[0].isdigit() == False) or (arr[1].isdigit() == False)) :
            print("Input two decimal numbers")
            return False
        
        self.y = int(arr[0])
        self.x = int(arr[1])
        
        if ((self.y == 0) and (self.x == 0)) :
            sys.exit()
        elif((self.y <= 0) or (self.x <= 0) or (self.y > 100) or (self.x > 100)) :
            print("N, M value are out of range")
            return False
            
        for i in range(0, self.y) :
            str = input()
            
            #check line count
            if (len(str) != self.x) :
                print("Mine Board Row Input Error")
                return False
                
            #check characters in row for '*' and '.'
            #input each character to matrix[]
            for j in range(0, len(str)) :
                if((str[j] == '*') or (str[j] == '.')) :
                    self.matrix[i][j] = str[j]
                else :
                    print("only * and . character are allowed")
                    return False

        return True

    def checkBoard(self) :
        for i in range(0, self.y) :
            for j in range(0, self.x) :
                if (self.matrix[i][j] == '.') :
                    self.result[i][j] = string.digits[self.checkCell(i, j)]
                elif (self.matrix[i][j] == '*') :
                    self.result[i][j] = '*'
                                       
    def checkCell(self, y, x) :
        mine_count = 0
    
        for pattern in self.check_pattern :
            check_y = y + pattern[0]
            check_x = x + pattern[1]
        
            if ((check_y >= 0) and (check_x >= 0) and (self.matrix[check_y][check_x] == '*')) :
                mine_count += 1
        
        return mine_count
            
    def printBoard(self) :
        self.checkBoard()
        
        print("\nField : ")
    
        for i in range(0, self.y) :
            for j in range(0, self.x) :
                if (j < (self.x - 1)) :
                    print(self.result[i][j], end = ' ')
                else :
                    print(self.result[i][j])

if __name__ == '__main__' :
    obj = quiz_minesweeper()

    while (True) :
        if (obj.inputBoard() == True) :
            obj.printBoard()

무협지를 보면 많은 무공이 등장하고 그 중에서 고수들이 등장합니다.

 

고수들의 실력을 초식과 내공으로 구분하는데,

그 성취를 "삼류 - 이류 - 일류 - 절정 - 초절정 - 화경 - 현경 - 생사경" 으로 나누곤 합니다.

 

SW 개발자, 프로그래머도 이와 같은 경지가 있을까?

 

무협지의 무공에 비할 수 있는 것으로는 "C", "C++", "Python" 같은 프로그래밍 언어일 수도 있고

"임베디드", "웹", "게임", "데이터베이스", "프론트/백엔드", "보안" 같은 전문 분야로 나눌수도 있겠습니다.

 

다양한 관점이 있겠지만, 여기서는 결과물인 S/W를 어떤 수준으로 만드냐로 나눠봅니다.

수준 S/W 설명
1 버그 없는 S/W 버그 없이 동작하는 S/W. 기본 중의 기본.
2 최적화 된 S/W 메모리, 실행시간을 최적화 한 경제적인 S/W
임베디드 쪽으로 가면, 비용과 관련이 있다.
3 재사용 가능한 S/W 한번 쓰고 버리는게 아니라, 향후에도 Re-use 할 수 있는 S/W. 객체지향, 모듈화, 디자인 패턴이 이쪽과 관련이 있다.
4 신뢰성 있는 S/W 의료, 항공, 자동차 쪽 S/W는 사소한 버그가 사람의 생명을 앗아갈 수 있다. 버그가 없고, 충분히 검증 되었다는 것을 어떻게 증명하고, 어떻게 사전에 위험 요소를 예방할 것인가? 각종 S/W 개발 Process, S/W 정적/동적 테스트 기법등이 관련이 있다.
5 기능 안전, 고가용성을 만족하는 S/W
아무리 조심해도 버그나 시스템의 장애는 생길 수 있다. 이 때 S/W가 장애를 극복하고, 안전하게 동작할 수 있는가? 의료, 항공, 자동차, 금융쪽에서도 신뢰성과 더불어 중요한 부분.

대학생 수준에서는 1번 단계만 잘해서, 작성한 S/W를 데모만 잘하면 되는 수준입니다.

하지만 직장에 들어가서, "돈 받고 만드는 S/W" 는 2~4단계 수준까지도 만족해야 합니다.

점점 "S/W 개발", 프로그래밍은 업무적으로 어려워집니다.

 

여러분은 어느 경지인가요?

"우박수", "우박 수열" 대해 들어보셨나요?

 

아래 함수 T(n)을 우박 수열이라고 합니다.

"이 함수에 아무 자연수 n을 넣고, 반복하면 결국 1이 되지 않을까?" 라고 추측한 것이 "콜라츠 추측" 입니다.

 

예를 들어, n = 22일 경우 아래 같은 수열이 만들어집니다. 

 22 13 34 17 52 26 13 40 20 10 5 16 8 4 2 1

 

이 추측은 로타르 콜라츠(Lothar Collatz)가 1937년에 제기했고, 아직까지도 풀리지 않고 있다고 합니다.

 

자, 이제 이걸 한번 코딩 테스트로 풀어볼까요?

 

입력

2개의 정수를 입력으로 받습니다. 한 줄에 한 쌍의 수가 입력 됩니다. 정수의 범위는 0 ~ 1,000,000 범위로 제한합니다.

 

출력

두개의 입력된 정수에 대해, 우선 두 정수를 순서대로 출력하고 두 정수 사이의 최대 사이클 길이를 출력합니다.

 

사이클 길이는 T(n) 함수를 반복해서 수행했을 때 '1'이 되는 횟수를 의미합니다.

위에 n = 22 인 수열을 보면 사이클 길이는 16입니다.

 

예제
No 입력 출력
1 1 10 1 10 20
2 100 200 100 200 125
3 201 210 201 210 89

 


해설

T(n)을 calc3N1() 함수로 구현 후, 입력 받은 두 수 범위 내의 모든 수에 대해 사이클 길이를 구합니다.

그리고 이렇게 구한 사이클 길이 중 가장 큰 값을 출력합니다.

# 3N1.py , 0001 quiz
# written by badsaram

import sys

class quiz_3N1(object) :
	def inputNumber(self) :
		self.fromNum = 0
		self.toNum = 0

		# input string and parse 
		print("input : ")
		str = input()
		arr = str.split(' ')

		# check 'exit'
		if (arr[0] == "exit") :
			sys.exit()
		
		# error check for input string
		if (len(arr) != 2) :
			print("Error : Input 2 Numbers")
			return False
		
		for chk in arr :
			if ((chk.isdigit() == False) or (chk.isdecimal() == False)) :
				print("Error : Not digit or not decimal")
				return False

		if ((int(arr[0]) <= 0) or (int(arr[1]) <= 0) or (int(arr[0]) >= 1000000) or (int(arr[1]) >= 1000000)) :
			print("Error : Input number range (0 < x < 1000000)")
			return False

		self.fromNum = int(arr[0])
		self.toNum = int(arr[1])

		if (self.toNum < self.fromNum) :
			temp = self.toNum
			self.toNum = self.fromNum
			self.fromNum = temp
			
		return True

	def calc3N1(self, num) :
		cycle_len = 1

		if (num <= 0) :
			return 0
		elif (num == 1) :
			return 1	
		
		temp = num
		while (temp != 1) :
			cycle_len = cycle_len + 1

			if ((temp % 2) == 0) :
				temp = temp / 2
			else :
				temp = 3 * temp + 1

		return cycle_len

	def getMax_calc3N1(self) :
		max_cycle_len = self.calc3N1(self.fromNum)

		for i in range(self.fromNum, self.toNum) :
			temp = self.calc3N1(i)

			if (temp > max_cycle_len) :
				max_cycle_len = temp

		return max_cycle_len				
					

if __name__ == '__main__' :
	obj = quiz_3N1()
	
	while (True) :
		if (obj.inputNumber() != True) : 
			continue
		
		print(obj.fromNum, obj.toNum, obj.getMax_calc3N1())

'코딩 테스트' 카테고리의 다른 글

문제 6 : 인터프리터(Interpreter)  (0) 2022.07.28
문제 5 : 그래픽 편집기  (0) 2022.07.27
문제 4 : LCD 디스플레이  (0) 2022.07.26
문제 3 : 여행 경비 계산  (0) 2022.07.20
문제 2 : 지뢰 찾기  (0) 2022.07.18

+ Recent posts