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
anda
have rank1
,B
andb
rank2
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 eachn
is multiplied by its corresponding weight to get what they call awinning 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 is2
so Paul's winning number is54 * 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 rankreturn: 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 这个名字,P
AUL -> 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表达式和列表递推式熟练的很啊。