CodeWars 13 : Help the bookseller !

김기욱·2021년 6월 25일
0

코딩테스트

목록 보기
52/68
post-custom-banner

문제설명

A bookseller has lots of books classified in 26 categories labeled A, B, ... Z. Each book has a code c of 3, 4, 5 or more characters. The 1st character of a code is a capital letter which defines the book category.

In the bookseller's stocklist each code c is followed by a space and by a positive integer n (int n >= 0) which indicates the quantity of books of this code in stock.

For example an extract of a stocklist could be:

L = {"ABART 20", "CDXEF 50", "BKWRK 25", "BTSQZ 89", "DRTYM 60"}.
or
L = ["ABART 20", "CDXEF 50", "BKWRK 25", "BTSQZ 89", "DRTYM 60"] or ....

You will be given a stocklist (e.g. : L) and a list of categories in capital letters e.g :

M = {"A", "B", "C", "W"} 
or
M = ["A", "B", "C", "W"] or ...

and your task is to find all the books of L with codes belonging to each category of M and to sum their quantity according to each category.

For the lists L and M of example you have to return the string (in Haskell/Clojure/Racket a list of pairs):

(A : 20) - (B : 114) - (C : 50) - (W : 0)

where A, B, C, W are the categories, 20 is the sum of the unique book of category A, 114 the sum corresponding to "BKWRK" and "BTSQZ", 50 corresponding to "CDXEF" and 0 to category 'W' since there are no code beginning with W.

요약 : 리스트 M(알파벳묶음)에 들어있는 알파벳을 기준으로 리스트 L(책이름 묶음)의 첫글자가 M에있는 알파벳과 일치하는 모든 책들이 가진 숫자를 더해서 (알파벳 : 숫자의합) - (알파벳 : 숫자의합) 과 같은 문자열을 만들어 리턴하시오.

제한사항

If L or M are empty return string is ""

Note:
In the result codes and their values are in the same order as in M.

파라미터 중 하나라도 비어있으면, ''(공백)을 리턴한다.
또한, 리턴값은 파라미터 M과 똑같은 순서로 나열되어 있어야 한다.

입출력 예시

L = ["ABART 20", "CDXEF 50", "BKWRK 25", "BTSQZ 89", "DRTYM 60"]
M = ["A", "B", "C", "W"]

결과값 : (A : 20) - (B : 114) - (C : 50) - (W : 0)

풀이

import re
def stock_list(listOfArt, listOfCat):
    result = ''
    for v in listOfCat:
        words = f' - ({v} : {v.lower()})' if len(result) > 0 else f'({v} : {v.lower()})'
        number = sum(map(int, re.findall('\d+', ' '.join(filter(lambda x : x[0]==v, listOfArt)))))
        result += words.replace(v.lower(), str(number))
    return result if listOfArt and listOfCat else ''
  1. 제 풀이는 다음과 같은 플로우로 진행됩니다.
  2. 우선 listOfCat(알파벳묶음)을 for loop로 돌리며, 'A: a - B: b'와 같이 알파벳대문자와 소문자로 이뤄진 문자열을 만듭니다.
  3. 또한 필터 & 정규표현식 & map & sum을 사용해서 알파벳과 일치하는 모든 책들의 숫자를 추출하고, 그 합계를 구합니다.(일치하는 문자열 찾음 -> 문자열을 숫자만 빼내서 리스트를 만듬 -> int로 바꿔줌 -> 모두 더함)
  4. 만들어진 문자열의 소문자를 합계로 치환(replace)해줍니다.
  5. 삼항연산자로 파라미터가 안 들어 올 때 공백('')을 리턴시켜줍니다.

다른풀이

def stock_list(listOfArt, listOfCat):
    if listOfArt and listOfCat:
        return " - ".join(['(%s : %d)' % (c, sum([int(i.split(" ")[1]) for i in listOfArt if c==i[0]])) for c in listOfCat])
    else:
        return ""
profile
어려운 것은 없다, 다만 아직 익숙치않을뿐이다.
post-custom-banner

0개의 댓글