房间内有 100 人,每人有 100 块,有钱的人每分钟随机给另一个人 1 块,最后这个房间内的财富分布怎样?...

在知乎看到一个有意思的问题:房间内有 100 人,每人有 100 块,有钱的人每分钟随机给另一个人 1 块,最后这个房间内的财富分布怎样?

最近在研究 java8 的新特性,就用相关代码写了一个demo。使用lambda表达式和函数式风格编程,代码简洁,看起来跟Scala非常相似!

使用Stream操作对象,只需要几行代码就能解决复杂的循环问题。

import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class Main {
    //解决问题:房间内有 100 人,每人有 100 块,有钱的人每分钟随机给另一个人 1 块,最后这个房间内的财富分布怎样?
    public static void main(String[] args) {
        //基于java8,stream特性,创建对象,100长度list,每个元素为100,即100个人,每人100元钱
        List<Integer> money= Stream.iterate(100 , n -> 100).limit(100).collect(Collectors.toList());
        //循环给钱,注意给钱是每分钟一次批量给,有钱的人才给
        for(int i=0;i<200000;i++){
            //被给钱的对象,临时记录(有钱的人减一元)
            List<Integer> moneyTemp=money.stream().map(n -> {return n>0?n-1:0;}).collect(Collectors.toList());
            //同一时间,钱大于0的人,给一元到随机的一个人
            money.stream().filter(n -> n>0).forEach(n -> {int a=(int)(Math.random()*100);moneyTemp.set(a,moneyTemp.get(a)+1);});
            //赋值给money
            money=moneyTemp;
            //排序之后再打印结果
            System.out.println("打印结果,list="+money.toString());
            System.out.println("打印排序后的结果,list="+money.stream().sorted().collect(Collectors.toList()).toString());
        }
    }
}


代码输出结果(最后一次的结果,排序是为了方便观察规律):

打印结果,list=[61, 62, 53, 4, 34, 206, 29, 21, 156, 0, 115, 117, 138, 411, 1, 16, 302, 253, 163, 227, 140, 23, 92, 41, 89, 16, 142, 9, 171, 150, 116, 39, 68, 178, 621, 291, 53, 13, 79, 58, 8, 155, 92, 110, 3, 28, 79, 152, 68, 61, 5, 24, 67, 1, 71, 119, 182, 214, 84, 31, 106, 177, 208, 169, 33, 32, 8, 90, 99, 20, 20, 49, 377, 78, 60, 155, 50, 163, 71, 99, 12, 96, 163, 57, 201, 64, 124, 20, 121, 28, 259, 88, 27, 8, 21, 233, 68, 0, 13, 21]

打印排序后的结果,list=[0, 0, 1, 1, 3, 4, 5, 8, 8, 8, 9, 12, 13, 13, 16, 16, 20, 20, 20, 21, 21, 21, 23, 24, 27, 28, 28, 29, 31, 32, 33, 34, 39, 41, 49, 50, 53, 53, 57, 58, 60, 61, 61, 62, 64, 67, 68, 68, 68, 71, 71, 78, 79, 79, 84, 88, 89, 90, 92, 92, 96, 99, 99, 106, 110, 115, 116, 117, 119, 121, 124, 138, 140, 142, 150, 152, 155, 155, 156, 163, 163, 163, 169, 171, 177, 178, 182, 201, 206, 208, 214, 227, 233, 253, 259, 291, 302, 377, 411, 621]

问题的答案挺有意思的,结果金钱并不会平均分布,最大的能到600多元,最少的0元,会有很大的差别。

我已开始也以为钱会平均分布,实在理解不到原因。不过知乎上已经有相关的原理和公式推导,有兴趣的同学可以去搜索一下。其实这是一个热力学问题,一个封闭的系统中,在粒子数量足够大,系统处于平衡态时,粒子处在某一状态下的概率应呈指数形式分布。

转载于:https://my.oschina.net/u/2485991/blog/1341297

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,下面是一个简单的使用 PHP 编写的扑克牌比大小游戏,可以让两个人抽牌,每人五张。代码如下: ```php <?php // 定义扑克牌花色和点数数组 $suits = array('♠', '♥', '♦', '♣'); $ranks = array('A', 'K', 'Q', 'J', '10', '9', '8', '7', '6', '5', '4', '3', '2'); // 初始化一副牌 $deck = array(); foreach ($suits as $suit) { foreach ($ranks as $rank) { $deck[] = $suit . $rank; } } // 洗牌 shuffle($deck); // 两个人抽牌 $player1_hand = array_slice($deck, 0, 5); $player2_hand = array_slice($deck, 5, 5); // 计算每个人的牌型大小 $player1_rank = calculateRank($player1_hand); $player2_rank = calculateRank($player2_hand); // 比较牌型大小,输出胜者 if ($player1_rank > $player2_rank) { echo "Player 1 wins!\n"; } elseif ($player1_rank < $player2_rank) { echo "Player 2 wins!\n"; } else { echo "Tie!\n"; } // 计算牌型大小的函数 function calculateRank($hand) { // 定义牌型数组 $ranks = array( 'Straight flush' => 9, 'Four of a kind' => 8, 'Full house' => 7, 'Flush' => 6, 'Straight' => 5, 'Three of a kind' => 4, 'Two pairs' => 3, 'One pair' => 2, 'High card' => 1 ); // 将牌拆分成花色和点数数组 $suits = array(); $ranks = array(); foreach ($hand as $card) { $suits[] = substr($card, 0, 1); $ranks[] = substr($card, 1); } // 判断是否为同花顺 if (isStraight($ranks) && isFlush($suits)) { return $ranks['Straight flush']; } // 判断是否为四条 if (in_array(4, array_count_values($ranks))) { return $ranks['Four of a kind']; } // 判断是否为葫芦 if (in_array(3, array_count_values($ranks)) && in_array(2, array_count_values($ranks))) { return $ranks['Full house']; } // 判断是否为同花 if (isFlush($suits)) { return $ranks['Flush']; } // 判断是否为顺子 if (isStraight($ranks)) { return $ranks['Straight']; } // 判断是否为三条 if (in_array(3, array_count_values($ranks))) { return $ranks['Three of a kind']; } // 判断是否为两对 if (count(array_keys(array_count_values($ranks), 2)) == 2) { return $ranks['Two pairs']; } // 判断是否为一对 if (in_array(2, array_count_values($ranks))) { return $ranks['One pair']; } // 如果都不是以上牌型,则为高牌 return $ranks['High card']; } // 判断是否为顺子 function isStraight($ranks) { $max_rank = array_search(max($ranks), $ranks); $min_rank = array_search(min($ranks), $ranks); return (max($ranks) - min($ranks) == 4 && count(array_unique($ranks)) == 5) || ($max_rank == 12 && $min_rank <= 3 && count(array_unique($ranks)) == 5); } // 判断是否为同花 function isFlush($suits) { return count(array_unique($suits)) == 1; } ?> ``` 这个游戏主要是根据每个人抽到的牌来计算牌型大小,然后比较大小来决定胜负。在计算牌型大小时,主要是通过判断每个人手中的牌是否为同花顺、四条、葫芦、同花、顺子、三条、两对、一对或高牌等牌型来确定大小。希望这个例子能对你有所帮助。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值