可爱的递归功能
#python #perl #theweeklychallenge

每周挑战191

abaoqian1,My solutions

任务1:两次

任务

您获得了整数列表,@list

编写一个脚本以找出列表中最大的项目是否至少是其他项目的两倍。

我的解决方案

有两种观察值可用于此任务。

  • 可能的结果为1(如果为true),而-1如果不是真的。
  • 在负面整数方面,“最大”一词似乎是模棱两可的。 -14大于-1吗?出于此任务的目的,我认为更大的手段在数值上更大。
  • 给定上述负数列表,所有负数始终将返回true。最大的(最接近零)将始终大于所有其他值加倍。这可能不是故意的,但是示例并没有给出应该发生的事情的方向。在现实世界中,我会要求澄清代码应该做什么。 MSA不是我的老板:)

随之而来的是,它是数值对列表进行排序(perl中的数组)的问题,并检查最后一个数字是否大于或等于第二个最后一个数字的两倍。打印1如果是,则-1如果不是。

在Python和Perl(以及大多数语言)中,我们可以将最后一个值作为array[-1],第二个值为array[-2]

例子

$ ./ch-1.py 1 2 3 4
-1

$ ./ch-1.py 1 2 0 5
1

$ ./ch-1.py 2 6 3 1
1

$ ./ch-1.py 4 5 2 3
-1

任务2:可爱清单

任务

您有一个整数,0 < $n <= 15

编写一个脚本以查找形成可爱列表的数字订单数。

使用输入@list =(1、2、3,.. $ n)用于正整数$ n,如果每个条目都以1个索引,则@list的订购是可爱的>

  1. $ list [$ i]均匀地被$ i或
  2. 分开
  3. $ i均匀排除在$ list [$ i]

我的解决方案

解决每周任务的一部分是确定最佳解决方案。通常,这些任务涉及相对较小的列表,数字或字符串,因此优化很少会提高性能并添加不必要的汇编,但这不是这些任务之一!

我的第一个本能是在itertools中使用组合功能,并计算可爱列表的数量。但是15! (那是1 1 14â15)超过1万亿,因此我可以将其排除为可行的解决方案。

我们可以观察到并非所有数字都可以出现在任何位置。例如,只有均匀的数字(和1)才能处于第二个位置,而只能在第三位置排名3(和1)。

i创建一个名为possibles的列表(perl中的数组)列表。这个基于0的数组计算每个位置的所有可能值。

在上周的博客中,我说在做这些挑战时我已经过度使用了递归功能,今天也不例外。我有一个称为find_solutions的函数,它可以行走不同的路径,以查看我们是否可以找到不超过一次数字的路径。我们已经知道,每个值都处于正确的位置以提供可爱的列表。它返回找到的火柴数,然后打印数字。

递归函数采用两个值frontback。正面表示我们已经处理的值,而返回是我们尚未处理的列表。对于每次迭代,我从背面列表中获取第一个列表。如果我们尚未使用该号码,请再次调用front的函数,并添加新值,然后从后面列表中取出第一个值。如果我们已经看到了这个数字,我们什么也不做,因为我们知道我们不能列出有效的列表。

我相信可以进一步优化列表,包括可能以相反顺序处理列表。但是,生成15的解决方案仅需0.38秒,因此对于此任务来说足够有效。但是,它确实会很快变得更加昂贵。当$n为20时,我的计算机花了48秒才能找到解决方案。

例子

$ ./ch-2.py 2
2

$ ./ch-2.py 10
700

$ ./ch-2.py 15
24679