逾越节

2010年3月30日

犹太逾越节是为了庆祝《圣经》中的事件,在犹太人在埃及被俘期间,上帝杀死了埃及所有人和牲畜的第一个孩子,除了那些在门柱上标记着春天羔羊的血的房屋外,这些房屋都是经过的;结果,犹太人得以逃脱埃及的奴役。

逾越节是在春分后的第一个满月的日子庆祝的,但要做一些调整。英国数学家约翰·霍顿·康韦给出了计算逾越节日期的算法:

首先,计算犹太新年Rosh Hashanah的日期。在格里高利年普通时代的罗斯·哈萨纳于9月n个,其中:

g=余数(y/19)+1

n+分数=
(楼层(y/100)-楼层(y/400)-2)
+765433/492480×剩余量(12g/19)
+余数(y/4)/4
-(313y+89081)/98496

计算n个须遵守以下延期规则:

  1. 如果上面计算的日期是星期日、星期三或星期五,则Rosh Hashanah将出现在第二天(即分别为星期一、星期四或星期六)。
  2. 如果上面计算的日期是星期一,并且分数大于或等于23269/25920,并且如果剩余物(12g/19)大于11,Rosh Hashanah在第二天,即星期二跌倒。
  3. 如果上面计算的日期是星期二,并且分数大于或等于1367/2160,并且如果剩余物(12g/19)大于11,Rosh Hashanah于两天后,即周四坠落。

给定Rosh Hashanah的日期,同一日历年的逾越节日期计算如下3月21日之后的第天,其中如果Rosh Hashanah在9月,则为Rosh Hazanah所在的9月日;如果Rosh Hashanah位于10月,则30加上Rosh Hasanah所在的10月日。

根据犹太习俗,这个节日实际上是在上面计算的前一天日落时开始的。

您的任务是编写函数,计算任何给定日历年的Rosh Hashanah和Passover日期。完成后,欢迎您阅读运行建议的解决方案,或在下面的评论中发布自己的解决方案或讨论练习。

页:1 2

下一个素数

2010年3月26日

两人一组以前的 练习,我们必须迭代素数。在一种情况下,我们使用Eratosthenes筛生成了大量素数,但事先不知道筛需要多大,而在另一种情况中,我们迭代奇数整数,检查每一个的素数。这两种解决方案都没有吸引力。考虑到旧规则,如果你做某事两次,你应该把它构建成一个抽象,我们今天将编写一个函数,给定一个正整数n个,返回大于的最小素数n个

我们的方法是预先计算大量素数并将其存储在磁盘上。如果n个在预先计算的列表的范围内,很容易找到下一个素数。但如果n个太大了,我们会重新检查各个候选人的首要性。在我们的示例中,我们将预先计算素数到100万,但根据您的期望和内存预算,您可以根据需要调整该数字。

为了节省内存空间,我们将把预先计算好的素数存储在压缩数据结构中。每个质数都可以表示为30k个±1, 30k个±7, 30k个±11或30k个部分为±13k个这意味着我们可以用每30个数字中的8位来存储所有素数;一百万素数可以被压缩到33334字节,再加上一个小程序可以从磁盘加载压缩的素数并操作压缩的数据结构。

您的任务是编写一个函数来构建上述压缩数据结构,第二个函数将其从磁盘加载到内存,第三个函数使用压缩数据结构计算下一个素数。完成后,欢迎您阅读运行建议的解决方案,或在下面的评论中发布自己的解决方案或讨论练习。

页:1 2

德克萨斯州Hold’Em

2010年3月23日

德克萨斯扑克是扑克的一种变体。下注后,每名玩家将面对面下发两张牌,随后进行一轮下注。然后是三张社区卡(猛然躺下)任何玩家都可以使用,然后进行另一轮下注。然后是一张社区卡()被发牌,然后是一轮博彩,然后是最后一张社区卡()与它的一轮赌博。总的来说,每个玩家都有两张隐藏卡和五张社区卡,在可获得的七张卡中,拥有最好的五张牌的玩家是赢家,赢得了奖杯。扑克手牌根据以下规则从最高到最低排列:

  1. 同花顺:五张牌按顺序排列,都是同一套牌。王牌可以高或低。在两次连胜中,排名最高的牌获胜;两次顺序相同的直冲。
  2. 四张:四张等级相同的牌,外加一张不匹配的牌。排名靠前的四人组击败排名靠后的四人队;如果两者相同,则排名最高的踢球者获胜,否则平局。
  3. 满座:三张同等级的牌,两张同等级牌。排名最高的三胞胎获胜;如果两者相同,排名最高的那一对获胜,否则就平局。
  4. 同花顺:五张同花色的牌。两次刷牌是根据牌的等级进行比较的;最高级别的卡获胜,如果平局,第二级别的卡赢,以此类推,直到发现差异为止。如果两张牌都有相同等级的牌,他们就平手。
  5. 直:按顺序排列五张牌。ace可以使用高或低。两条直线是根据他们的最高牌排名的;如果他们的最高牌数相等,他们就平手。
  6. 一类三张:三张相同等级的牌,加上两张不匹配的牌。排名最高的三胞胎获胜;如果他们是相同的,踢者被比作打破平局。
  7. 两对:两张等级匹配的牌,再加上两张等级相同的牌,加上一张不匹配的牌。两对手分别排在最高一对,最低一对,最后是踢球手。
  8. 一对:两张级别匹配的牌,再加上三张不匹配的牌。排名最高的一对获胜,用三个踢球者打破平局。
  9. 高位牌:五张不匹配的牌。手牌排名在最高的牌上,其次是第二高的牌,依此类推。

你的任务是编写一个程序,从七张牌的列表中选择最好的五张牌。完成后,欢迎您阅读运行建议的解决方案,或在下面的评论中发布自己的解决方案或讨论练习。

页:1 2

我们研究了约翰·波拉德的第页-1以前的分解算法运动。您可能还记得,该算法查找数字的因子n个通过计算整数的最小公倍数达到某个界限B类,称之为k个,然后计算2的最大公约数k个-1和n个; 如果最大公约数在1和之间n个,这是一个因素n个

从数学上讲,我们正在试图找到一个因子第页|n个(这是“第页划分n个“,意思是第页是的一个因素n个,对于那些不熟悉数学符号的人),我们知道其因子分解第页-1.考虑数字15770708441=135979×115979。如果我们采用波拉德的第页-边界为150的1算法,未发现因子,但如果我们应用Pollard的第页-找到了一个边界为180的算法135979因子,因为135979–1=2×3×131×173;增加边界以包括因子173使波拉德第页-1算法有效。首先找到135979因子,因为115979–1=2×103×563,563为越界。

增加界限的另一种方法是调用第二个阶段,该阶段寻找第页-1除一个因子在第一阶段界限和第二阶段界限之间外,所有因子均小于第一阶段界限。也就是说,我们不是计算lcm(1..180),而是计算lcm(1..150)×j个,其中j个范围从151到180。对于150和180这样的小数字,差异并不重要,但对于更大的数字,例如B类1= 106B类2= 109计算成本的差异是显而易见的。

你的任务是编写波拉德的两阶段版本第页-1算法。完成后,欢迎您阅读运行建议的解决方案,或在下面的评论中发布自己的解决方案或讨论练习。

页:1 2

我们在前面看到过运动为旅行推销员问题找到一个精确的解决方案非常耗时O(运行)(n个!)。另一种选择是一种启发式方法,可以快速提供相当好的解决方案。其中一个启发式方法是“最近邻居”:选择一个起点,然后在每个步骤中选择最近的未访问点,将其添加到当前巡更并标记为已访问,重复操作直到没有未访问点为止。

您的任务是编写一个程序,使用最近邻启发法解决旅行推销员问题。完成后,欢迎您阅读运行建议的解决方案,或在下面的评论中发布自己的解决方案或讨论练习。

页:1 2

旅行推销员:蛮力

2010年3月12日

旅行推销员的问题很经典:在地图上找到每座城市只访问一次的最短行程,然后返回原点。这是实践中的一个重要问题;例如,考虑到城市是一块大电路板上的焊接点,每个焊接点都必须由焊接机器人访问。这也是数学中的一个重要问题,众所周知是NP问题,这意味着非平凡问题的最优解是不可能的。尽管如此,还是有一些启发式算法能够很好地最小化巡游长度。

我们将在一个偶然的系列练习中检查旅行推销员问题,从今天的练习开始,看看检查所有可能的旅行的暴力解决方案。算法很简单:首先,随机选择一个巡更,然后确定巡更的所有可能排列。其次,确定每次巡演的长度。第三,报告具有最小长度的游览作为解决方案。

您的任务是编写一个程序,使用brute-force算法解决旅行推销员问题。完成后,欢迎您阅读运行建议的解决方案,或在下面的评论中发布自己的解决方案或讨论练习。

页:1 2

词汇排列

2010年3月9日

Edsger Dijkstra,在他的书中程序设计学科描述了一个函数,该函数在给定元素列表和返回这些元素的总排序的函数的情况下,生成列表的下一个字典排列;例如,列表(1 2 3 4)按字典顺序的排列是(1 2 34)(2 1 3 4)(1 3 2 4)(3 1 2 4)2 3 1)(3 4 2 1)(4 3 2 1)。如果列表中最不重要的项目位于最前面,那么比(1 2 3 4)大的下一个元素是(2 1 3 4),因为列表中最重要的尾部没有改变,并且下一个较大的排列在最不重要元素中有所不同。为了进行更大的排列,列表中的某些元素必须被其左侧的较大元素替换;为了进行下一个置换,置换必须发生在尽可能靠左的最低有效位置,并且置换元素必须尽可能小。

您的任务是编写返回下一个词典排列和列表中所有排列的列表的函数。完成后,欢迎您阅读运行建议的解决方案,或在下面的评论中发布自己的解决方案或讨论练习。

页:1 2

二进制搜索树

2010年3月5日

二进制搜索树是一种简单且常用的数据结构。二进制搜索树是一种分层数据结构,其中每个节点存储一个键、一个值和指向两个子节点的指针。每个节点都有一个父节点,但树的根节点除外,该节点没有父节点。在每个节点上,键大于或等于其左子节点中所有节点的键,小于或等于其右子节点中的所有节点的密钥。任何节点都可以为空;空节点没有键、值和子节点。右侧显示了一个示例二进制搜索树。

横穿这棵树相当简单。从根开始,将当前节点上的密钥与要查找的密钥进行比较。如果目标关键字小于当前关键字,则在左侧子关键字处重复搜索;同样,如果目标键大于当前键,则在右子级重复搜索。如果目标键和当前键相同,则已找到所需的节点;如果到达空节点,则目标键不在树中。插入和删除操作在每个节点上维护有序属性。

您的任务是编写操作二进制搜索树的函数;您应该在库中包含查找、插入、删除和登记功能。完成后,欢迎您阅读运行建议的解决方案,或在下面的评论中发布自己的解决方案或讨论练习。

页:1 2

哥德巴赫猜想

2010年3月2日

克里斯蒂安·哥德巴赫(1690-1764)是普鲁士数学家,与欧拉同时代。数论中最著名的未经证实的猜想之一是哥德巴赫猜想,它指出每一个大于2的偶数都是两个素数之和;例如,28=5+23。

你的任务是编写一个函数,找出两个素数与大于2的给定偶数相加。完成后,欢迎您阅读运行建议的解决方案,或在下面的评论中发布自己的解决方案或讨论练习。

页:1 2