Prize Draw

https://www.codewars.com/kata/5616868c81a0f281e500005c

To participate in a prize draw each one gives his/her firstname.

Each letter of a firstname has a value which is its rank in the English alphabet. A and a have rank 1B and b rank 2 and so on.

The length of the firstname is added to the sum of these ranks hence a number n. An array of random weights is linked to the firstnames and each n is multiplied by its corresponding weight to get what they call a winning number.

Example: names: COLIN,AMANDBA,AMANDAB,CAROL,PauL,JOSEPH weights: [1, 4, 4, 5, 2, 1]

PAUL -> n = length of firstname + 16 + 1 + 21 + 12 = 4 + 50 -> 54 The weight associated with PAUL is 2 so Paul's winning number is 54 * 2 = 108.

Now one can sort the firstnames in decreasing order of the winning numbers. When two people have the same winning number sort them alphabetically by their firstnames.

#Task:

parameters: st a string of firstnames, we an array of weights, n a rank

return: the firstname of the participant whose rank is n (ranks are numbered from 1)

#Example: names: COLIN,AMANDBA,AMANDAB,CAROL,PauL,JOSEPH weights: [1, 4, 4, 5, 2, 1] n: 4

The function should return: PauL

Note:

  • If st is empty return "No participants".

  • If n is greater than the number of participants then return "Not enough participants".

  • See Examples Test Cases for more examples.

 题目:

每个人名字根据所在字母的位置(都按照小写位置计算)求和 再加上本身名字的长度计算出一个值n,同时会给你一个对应名字的权重w,最后用 n*w 获得这个人最终的winner_num,

如:

names: 'COLIN,AMANDBA,AMANDAB,CAROL,PauL,JOSEPH'

 weights: [1, 4, 4, 5, 2, 1] 

针对 PauL 这个名字,PAUL -> n = length of firstname + 16 + 1 + 21 + 12 = 4 + 50 -> 54  

winner_num = n * wight = 54 * 2 = 108,

每个名字都计算出一个winner_num值,针对值进行降序排列,如果winner_num相同,再根据name排序最终我们将获取到一个排序好的列表,最后说出一个值返回对应列表中的名称:

#Example: names: COLIN,AMANDBA,AMANDAB,CAROL,PauL,JOSEPH weights: [1, 4, 4, 5, 2, 1] n: 4

The function should return: PauL

我的算法:

def rank(st, we, n):
    import string    
    alph = string.ascii_lowercase
    win_num = []
    names = st.split(',')
    if not st:
        return 'No participants'
    if n>len(names):
        return 'Not enough participants'
    for index,name in enumerate(names):
        length = len(name)
        count = sum([alph.index(i)+1 for i in name.lower()])
        win_num.append((length+count)*we[index])    
    result = [(rank,name) for rank,name in zip(win_num,names)]    
    result = sorted(result,key=lambda x:(-x[0],x[1]))

    return result[n-1][1]
        

 

大神的算法:

def rank(st, we, n):
    if not st:
        return "No participants"
    
    if n>len(we):
        return "Not enough participants"

    name_score = lambda name,w: w*(len(name)+sum([ord(c.lower())-96for c in name]))
    
    scores= [name_score(s,we[i]) for i,s in enumerate(st.split(','))]
    
    scores = list(zip(st.split(','),scores))    
    
    scores.sort(key=lambda x: (-x[1],x[0]))
    
    return scores[n-1][0]

大神的lambda表达式和列表递推式熟练的很啊。

 

 

 

 

你可能感兴趣的:(python,菜鸟练习,kata)