拉伸数组


13

之前我定义了粉碎数组的过程

迷恋我们从左到右读取数组。如果在某一点上我们连续遇到两个相同的元素,则将第一个删除,将第二个加倍。

例如,这是粉碎以下数组的过程

[5,2,2,4]
 ^
[5,2,2,4]
   ^
[5,2,2,4]
     ^
[5,4,4]
   ^
[5,4,4]
     ^
[5,8]
   ^

请注意,同一元素可以折叠多次。在该示例中,2,2,4一次折叠就崩溃了8

现在,粉碎阵列很容易,但要取消粉碎却很困难。您的任务是将一个正整数数组作为输入,并输出在重复压碎后可以形成输入的最大数组。例如,阵列[4]通过压碎形成,而压碎[2,2]又通过压碎形成[1,1,1,1]。由于我们不能有非整数值,[1,1,1,1]因此无法进一步展开,这就是我们的答案。

您将永远不会0在输入数组中收到a ,因为此类数组可以无限扩展。您也永远不会收到两个奇数彼此相邻的案件,这些案件不可能是压碎的结果。

这是因此答案将以其来源的大小(以字节为单位)进行评分,而字节越少越好。

在开始回答之前,我只想说这个挑战比看起来要困难得多。在进行过程中检查您的直觉,并确保您的答案通过了所有测试用例。

测试用例

[] -> []
[5] -> [5]
[6] -> [3,3]
[8] -> [1,1,1,1,1,1,1,1]
[4,8] -> [1,1,1,1,1,1,1,1,1,1,2]
[2,8] -> [1, 1, 1, 1, 2, 1, 1, 1, 1]
[4,4] -> [1,1,1,1,1,1,1,1]

1
对不起,但我仍然不明白规则。为什么[1,1,1,1,1,1,1,1,1,1,2]生产[4, 8]而不是[8, 4]?这应该是[1,>1,1,1,1,1,1,1,1,1,2][2,1,>1,1,1,1,1,1,1,2][2,>2,1,1,1,1,1,1,2][4,1,>1,1,1,1,1,2][4,2,1,>1,1,1,2][4,2,>2,1,1,2][4,>4,1,1,2][8,1,>1,2][8,2,>2][8,4]
tsh

2
@tsh我认为您对粉碎的工作方式存在误解。下面是它需要第一遍的路径:[1,>1,1,1,1,1,1,1,1,1,2][2,>1,1,1,1,1,1,1,1,2][2,1,>1,1,1,1,1,1,1,2][2,2,>1,1,1,1,1,1,2][2,2,1,>1,1,1,1,1,2][2,2,2,>1,1,1,1,2][2,2,2,1,>1,1,1,2][2,2,2,2,>1,1,2][2,2,2,2,1,>1,2][2,2,2,2,2,>2][2,2,2,2,4>],第二遍:[2,>2,2,2,4][4,>2,2,4][4,2,>2,4][4,4,>4][4,8>]。希望这可以清除它。如果您想看一些代码,可以参考前面的问题,该问题的答案实现了粉碎功能。
Ad Hoc Garf Hunter

如果我输出数字,可以用换行符隔开,可以吗?
scottinet

@scottinet这是一种输出列表的合理方法。前进。
Ad Hoc Garf Hunter

[4, 4]应该删除测试用例,因为我们在拉伸=>压碎序列之后永远无法获得该数组,因为这将以[8]
scottinet 17/08/29

Answers:


2

的JavaScript(Node.js的)237个 221 213 186字节

f=a=>a.map(b=>{for(i=1;~b%2;b/=2)i*=2;return Array(i).fill(b)}).reduce((t,c,i,s)=>{b=c.slice();if(i)r=2*s[--i].length,b.length>=r&&b[0]==s[i][0]?b[r-2]+=b.pop():b;return t.concat(b)},[])

在线尝试!

该算法通过将每个数字拉伸到最大值来计算最佳拉伸数组,然后在必要时将正确的一对数字粉碎回去,从而有效地创建“粉碎阻止程序”,从而中断先前编号的粉碎顺序。

例如:

[1, 1, 1, 1, 1, 1][4,2]一次粉碎,但[1, 1, 1, 1, 2]结果[2, 4]

面临的挑战是确定应该在哪里确切地放置粉碎阻止器,以便粉碎结果数组可以得到正确的结果:

  • 仅当先前的扩展编号等于当前扩展编号并且当前的扩展序列大于先前的扩展编号时,才需要放置粉碎阻止程序。举例来说,[2, 4]需要一个美眉阻滞剂(拉伸次数1,重复,并且[1, 1]比短[1,1,1,1]),但[4, 2][2, 6]没有要求一个
  • 如果我们调用n先前的扩展序列,并且如果上述条件得到验证,那么当前序列就是该n序列的重复。要中断前一个数字的挤压序列,我们需要将挤压阻止器放置n在当前数字的第二个序列的末尾以进行拉伸。例如:[2, 8] => [(1, 1)=n, (1, 1) + (2) + (1, 1) + ...][4, 8] => [(1, 1, 1, 1)=n, (1, 1, 1, 1) + (1, 1, 2) + ...]


1

Python 2中230个 228 226字节

通过迭代与输入总和相同的所有可能列表进行工作。删除那些在压缩状态下不等于输入数组的数组,选择最长的数组。

编辑:通过删除ifmain函数中的-2个字节

编辑: -2字节,通过删除两个不必要的方括号

lambda x:max((c(z[:],x),len(z),z)for z in b(sum(x)))[2]
def c(x,y):
 i=e=1
 while x[i:]:
	if x[~-i]==x[i]:del x[i];i-=1;x[i]*=2;e=2
	i+=1
 return x==y or~-e and c(x,y)
b=lambda s:[z+[-~i]for i in range(s)for z in b(s+~i)]+[[]]

在线尝试!

说明

主要功能,负责查找所有可能的解决方案并选择最长的解决方案

lambda x:max((c(z[:],x),len(z),z)for z in b(sum(x)))[2]

挤压功能,用于检查y是否等于挤压之一。

def c(x,y):
 i=e=1
 while x[i:]:
	if x[~-i]==x[i]:del x[i];i-=1;x[i]*=2;e=2
	i+=1
 return x==y or~-e and c(x,y)

用给定的总和生成所有可能的排列

b=lambda s:[z+[-~i]for i in range(s)for z in b(s+~i)]+[[]]

0

05AB1E41 37字节

vy[DÉ#2÷]DYQX©NoDU‹&sDV¸X∍sić·®·Íǝ}»,

在线尝试!

我的Javascript解决方案的端口。

说明:

vy                   for each member of the list
[DÉ#2÷]              divide by 2 until odd: stack = stretched value, N = iterations
DYQ                  stetched value equal to the previous one?
X©NoDU‹              previous size < current one? (+store the new size in X)
&                    AND on the 2 previous tests
sDV¸X∍s              build a list of the new stretched value repeated X times
                      (+store the new stetched value in Y)
ić·®·Íǝ}             if the previous tests are true:
                       reduce the result list size by 1
                       multiply by 2 the number at the crush block position
»,                   join by newline + print the list
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.