Prize Draw

13 篇文章 0 订阅
6 篇文章 0 订阅

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表达式和列表递推式熟练的很啊。

 

 

 

 

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,让我来回答你的问题。 根据概率、剩余奖品数量动态抽奖算法实现,概率总和可以不为100%。这种算法通常被称为概率加权抽样(Probability Weighted Sampling)。 下面是一个简单的Java实现示例: ```java import java.util.*; public class ProbabilityWeightedSampling { public static void main(String[] args) { // 奖品列表,每项奖品包括名称、概率、数量 List<Prize> prizes = new ArrayList<>(); prizes.add(new Prize("奖品A", 0.5, 10)); prizes.add(new Prize("奖品B", 0.3, 5)); prizes.add(new Prize("奖品C", 0.2, 3)); // 抽奖 Prize prize = draw(prizes); System.out.println("恭喜您获得了" + prize.name); } // 抽奖方法 public static Prize draw(List<Prize> prizes) { double totalProbability = 0; for (Prize prize : prizes) { totalProbability += prize.probability * prize.quantity; } double random = Math.random() * totalProbability; double currentProbability = 0; for (Prize prize : prizes) { currentProbability += prize.probability * prize.quantity; if (random < currentProbability) { prize.quantity--; return prize; } } return null; } // 奖品类 static class Prize { String name; // 奖品名称 double probability; // 中奖概率 int quantity; // 剩余数量 public Prize(String name, double probability, int quantity) { this.name = name; this.probability = probability; this.quantity = quantity; } } } ``` 在这个示例中,我们定义了一个奖品列表,每项奖品包括名称、概率、数量。抽奖时,我们遍历奖品列表,计算出每项奖品的加权概率,然后根据随机数在加权概率上进行抽奖。抽中奖品后,我们将该奖品的数量减1,防止重复中奖。 需要注意的是,由于概率总和不一定为100%,因此我们需要将概率乘以奖品数量,得到每项奖品的加权概率。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值