按独创性分组整数


12

介绍:

我收集曲折的难题。大多数曲折的拼图游戏都是由中国公司生产和销售的。大多数知名公司都要求拼图游戏设计师许可,以制作他们的设计并共同开发市场上的产品。在这种情况下,拼图设计师当然为他们的拼图之一上市而感到非常高兴和自豪。

但是,也有一些中国公司制造难题。这些仿冒品是未经原始创作者许可使用的设计,或者是已经存在的拼图的价格便宜的低价副本。

挑战:

我们将确定以特定顺序(从左到右)“释放”的数字的独创性。
给定整数列表,请按其原始性进行分组和输出。

如何确定数字的独创性?

  • 一个数字是否与先前的数字完全相同?组(最不原始),在所有其他组之后是X + 1组。X+1X+1
  • 一个数字是不是一个较早数字的重复,而是一个负数(即原始数字是,但是现在是;反之亦然)?组。nnX
  • 数字的绝对值可以通过连接一个或多个更早的绝对数来形成,并且它不属于前面提到的组或吗?组X - ñ,其中Ñ是不同数字的在级联(和所使用的量Ñ 1)。X+1XXNNN1
  • 这个数字不适合上述任何一组吗?到目前为止,它是完全唯一的吗?第1组(最原始的组),在所有其他组之前领先。

这听起来似乎很模糊,所以这里有一个分步示例

输入清单: [34,9,4,-34,19,-199,34,-213,94,1934499,213,3,21,-2134,44449,44]

  • 34是第一个数字,始终是原始数字,在组1。到目前为止的输出:[[34]]
  • 9 也是原来的: [[34,9]]
  • 4 也是原来的: [[34,9,4]]
  • -34是早期数字的负数34,因此它在X组中:[[34,9,4],[-34]]
  • 19 是原始的: [[34,9,4,19],[-34]]
  • -199可以由两个较早的数字19和组成9,所以在X2组中:[[34,9,4,19],[-199],[-34]]
  • 34是较早数的精确副本,因此它在组X+1[[34,9,4,19],[-199],[-34],[34]]
  • -213 是原始的: [[34,9,4,19,-213],[-199],[-34],[34]]
  • 94可以由两个较早的数字9和组成4,所以在X-2组中:[[34,9,4,19,-213],[-199,94],[-34],[34]]
  • 1934499可以由四个较早的数字形成19344,和两次9,因此它在组X-4[[34,9,4,19,-213],[19499],[-199,94],[-34],[34]]
  • 213是早期数字的负数-213,因此它在X组中:[[34,9,4,19,-213],[1934499],[-199,94],[-34,213],[34]]
  • 3 是原始的: [[34,9,4,19,-213,3],[1934499],[-199,94],[-34,213],[34]]
  • 21 是原始的: [[34,9,4,19,-213,3,21],[1934499],[-199,94],[-34,213],[34]]
  • -2134可以由两个较早的数字2134(或三个较早的数字213和和组成)4,但是我们总是使用最少数量的串联数字来确定创意),因此它在X-2组中:[[34,9,4,19,-213,3,21],[1934499],[-199,94,-2134],[-34,213],[34]]
  • 44449可以由两个较早的数字四次形成49,所以它在组X-2[[34,9,4,19,-213,3,21],[1934499],[-199,94,-2134,44449],[-34,213],[34]]
  • 44可以由一个更早的数字形成4,重复两次,所以在X-1个组中: [[34,9,4,19,-213,3,21],[1934499],[-199,94,-2134,44449],[44],[-34,213],[34]]

因此对于输入[34,9,4,-34,19,-199,34,-213,94,1934499,213,3,21,-2134,44449,44],输出为[[34,9,4,19,-213,3,21],[1934499],[-199,94,-2134,44449],[44],[-34,213],[34]]

挑战规则:

  • I / O是灵活的。您可以输入整数或字符串的列表/数组/流,通过STDIN等一一输入。输出可以是以组为键的映射,嵌套列表为示例和此挑战中的测试用例,已打印换行符分隔等
  • 允许您以相反的顺序输入输入列表(这可能对基于堆栈的语言很有用)。在这种情况下,从左到右提到的当然是从右到左。
  • 正如你可以看到的例子为整数-2134,我们始终组数字,其他数字与尽可能少的连接(通过形成2134-两个数字;而不是2134-三个数字)。
  • 正如您在integer的示例中所看到的1934499,您可以多次使用一个更早的数字(9在这种情况下)(类似于在示例中44449使用4 4s和a 9)。但是,它们只计算一次即可确定组。
  • 不允许在输出中为空组提供空的内部列表。所以测试用例[1,58,85,-8,5,8585,5885,518]可能不会导致[[1,58,85,8,5],[518],[5885],[8585],[],[]]代替,其中,所述空的基团是XX-1个,和上述可能不会导致在示例[[34,9,4,19,-213,3,21],[1934499],[],[-199,94,-2134,44449],[44],[-34,213],[34]]代替,其中所述空的基团是X-3
  • 组的顺序是严格的(除非您使用地图,否则可以从键中扣除组),但是组内数字的顺序可以是任意顺序。因此,上面示例中的[34,9,4,19,-213,3,21]1个的也可以是[21,3,-213,19,4,9,34][-213,4,34,19,9,21,3]
  • 您可以保证不会有超过九个以前的数字构成的任何数字。所以,你将永远不会有任何X-10组,以及可能的组的最大数量为12:[1个X-9X-8X-2X-1个XX+1个]
  • 您可以假设整数最大为32位,所以在range内[−2147483648,2147483647]

一般规则:

  • 这是,因此最短答案以字节为单位。
    不要让代码高尔夫球语言阻止您使用非代码高尔夫球语言发布答案。尝试针对“任何”编程语言提出尽可能简短的答案。
  • 标准规则适用于具有默认I / O规则的答案,因此您可以使用STDIN / STDOUT,具有正确参数的函数/方法以及返回类型的完整程序。你的来电。
  • 默认漏洞是禁止的。
  • 如果可能的话,请添加一个带有测试代码的链接(即TIO)。
  • 另外,强烈建议为您的答案添加说明。

测试用例:

Input:  [34,9,4,-34,19,-199,34,-213,94,1934499,213,3,21,-2134,44449,44]
Output: [[34,9,4,19,-213,3,21],[1934499],[-199,94,-2134,44449],[44],[-34,213],[34]]

Input:  [17,21,3,-317,317,2,3,117,14,-4,-232,-43,317]
Output: [[17,21,3,2,117,14,-4],[-317,-232,-43],[317],[3,317]]

Input:  [2,4,8,10,12,-12,-102,488,10824]
Output: [[2,4,8,10,12],[10824],[-102,488],[-12]]

Input:  [0,100,-100,10000,-100,1001000]
Output: [[0,100],[10000,1001000],[-100],[-100]]

Input:  [1,58,85,-8,5,8585,5885,518]
Output: [[1,58,85,-8,5],[518],[5885],[8585]]

Input:  [4,-4,44,5,54]
Output: [[4,5],[54],[44],[-4]]

那么,X + 1是一个用于精确副本的特殊组X吗?是否是一个可以由单个数字的副本形成的其他数字的组,例如它的取反?
尼尔

1
[-21474836482147483647][1, 1111111111]

1
我自己就是一个收藏家:凯文,那是你该死的精美收藏。的确很好。
J.Sallé19年

1
我收集了《魔术:聚会》卡片和套装,尽管它们很小,但它们仍然占据着令人惊讶的巨大空间。
J.Sallé19年

1
@J.Sallé哦,我知道这种感觉。我还收集了PokémonTCG卡(实际上拥有世界上第二大的Pikachu TCG集合,其中包含1200多种独特的Pikachu卡。)当您拥有9,000多个卡时,它的确占据了相当大的空间。但是,不像难题。只有1.5个货架,而不是10个货架; p
Kevin Cruijssen

Answers:



9

Python 3中565 564 524 523 500 437 399 394 393 389 385 372字节

使用蛮力的实施itertools; 并非所有测试用例都在TIO的60秒限制内运行。

在线尝试!

由于ARBO用于高尔夫球101个字节,以盖伦诺夫为高尔夫19个字节,以ElPedro为高尔夫5个字节,以movatica为高尔夫17个字节,以黑色猫头鹰启用于高尔夫球2个字节,以鱿鱼为高尔夫2个字节,并凯文Cruijssen为打高尔夫球1个字节。

from itertools import*
w=permutations
def c(l,x):
 for i in range(9):
  for q in w(map(abs,sum(l,[]))):
   for s in w(q[:i+1]*len(x)):
    z='';s=[*s]
    while x[len(z):]:
     z+=str(s.pop(0))
     if z==x:return 9-i
 return 0
def f(a):
 l=[[]for _ in a*6]
 for x in a:l[(x in sum(l,[]))*11or(-x in sum(l,[]))*10or any(l)and c(l,str(abs(x)))]+=x,
 return[*filter(len,l)]

说明:

from itertools import *
w = permutations  # We'll be using this twice

def c  # Helper function to calculate which group a number belongs in according to the concatenation rule; returns 0 (original) if none is found
(l, x):  # First parameter is the list of groups (a list of lists of numbers), second parameter is the number to investigate
 for i in range(9):  # There won't be any concatenations of more than 9 elements
  for q in w(map(abs,sum(l,[]))):  # Flatten l to get a plain list of previous numbers, then generate permutations of their absolute values as lists; for each permutation ...
   for s in w(q[:i+1]*len(x)):  # ... use only the first i + 1 elements; inflate the list with enough copies to compose the target number and permutate; then try to compose the target number from each permutation:
    z = ''  # Start with the empty string
    s = [*s]  # Convert permutation to list
    while x[len(z):]:  # Keep going until the length of the concatenated string equals the length of the target number
     z += str(s.pop(0))  # Concatenate the first element of the current permutation list and remove it
     if z == x:  # If the target number has been synthesized successfully ...
      return 9 - i  # stop searching and return the appropriate group
 return 0  # If no concatenation has been found, consider the number original

def f(a):  # Solution function, takes a list of numbers as argument
 l = [[] for _ in a * 6]  # Populate the result list with at least 12 empty groups if there is more than one number in the input (we'll be using only the first 12 and removing empty ones later); if there is just one, we'll only need one group in the output
 for x in a:  # For each number in order:
  l[(x in sum(l, [])) * 11 or (-x in sum(l, [])) * 10 or any(l) and c(l, str(abs(x)))] += x,  # If x is not the first number, attempt concatenation (if not, c(l, str(abs(x))) would crash due to l not containing any non-empty sublists; use absolute value of the number under investigation; convert to string since we'll be needing the number of digits and comparing it to a string later); if -x has already been seen, put it in Group X; if x has already been seen, put it in Group X + 1
  return [* filter(len, l)]  # Remove empty lists and return the result

Python 2中406个 379 374 373 372 368 355字节

相同的方法,但是由于一些打高尔夫球的技巧而变得更短Python 3不再支持。感谢ArBo的后向移植和28字节的打高尔夫球,感谢ElPedro的5字节的打高尔夫球,movatica的17字节的打高尔夫球,以及鱿鱼的1字节的打高尔夫球。

from itertools import*
w=permutations
def c(l,x):
 for i in range(9):
  for q in w(map(abs,sum(l,[]))):
	for s in map(list,w(q[:i+1]*len(x))):
	 z=''
	 while x[len(z):]:
		z+=`s.pop(0)`
		if z==x:return 9-i
 return 0
def f(a):
 l=[[]for _ in a*6]
 for x in a:l[(x in sum(l,[]))*11or(-x in sum(l,[]))*10or any(l)and c(l,`abs(x)`)]+=x,
 return filter(len,l)

在线尝试!


2
评论不作进一步讨论;此对话已转移至聊天
詹姆斯

通过将str(abs(x))(或Python 2中带有反引号的abs(x))移至函数调用,并将函数定义中的x更改为y,可以删除两者,从而节省5 。抱歉,暂时无法让TIO工作。
ElPedro

您可以过滤len以删除另一个字节,对吗?
乌贼

您可以删除any()调用内的列表语法,从而使其成为普通的生成器,该生成器也可以正常工作,并为您节省了另外4个字节:)
movatica

......甚至更短:(x in sum(l,[]))不是any(x in s for s in l)两个x-x节省13多个字节!
movatica

7

Python 2中235 234 232 246 245 244个 241 240 238 237 236字节

from itertools import*
s=[];r=map(list,[s]*12)
for e in input():r[-(e in s)or max([10*(-e in s)]+[10-len(set(p[:i]))for p in permutations(`abs(x)`for x in s*11)for i in range(len(p))if''.join(p[:i])==`e`])]+=e,;s+=e,
print filter(len,r)

在线尝试!

-1字节,感谢Squid对其他Python答案的评论

这个答案除了解决最琐碎的测试用例外,别无他法。在TIO链接,s*11已被取代s*2,在某些情况下,快速牺牲正确性执行时间,但据我所看到的,在这个帖子的版本始终得到正确的答案,在理论上。

说明

from itertools import*          # So that we can abuse permutations
s=[];                           # s will hold the already classified numbers
r=map(list,[s]*12)              # r will hold these too, but in the form of
                                #  a nested list, sorted by originality
for e in input():               # Here comes the big one; iterate over the input
 r[-(e in s)or                  # If e has already passed, it is not original
   max([10*(-e in s)]+          # Else, we count 10 - the number of seen elements
                                #  needed to make this one, or 0 if it's new,
                                #  or 10 if its inverse has already passed
   [10-len(set(p[:i]))          # The number of distinct elements in...
    for p in permutations(      #  for each permutation of the seen elements,
      `abs(x)`for x in s*11)
                                #  with values occuring up to 10 times (to
                                #  account for 1111111111, for example;
                                #  we need 11 here and not 10, because
                                #  p[:i] doesn't include i)...
    for i in range(len(p))      #  each prefix...
    if''.join(p[:i])            #  only if its concatenation is equal to
      ==`e`])]                  #  the current element
 +=e,;s+=e,                     # Append the element to the relevant lists
print filter(len,r)             # And finally, print the non-empty result lists

2
我很高兴看到您创建了自己的Python答案:-)而且它也更短!
OOBalance

@OOBalance现在,如果它会在我的一生中终止...
ArBo

1
哦,我忘记了Windows版本的可笑之处(int即使在64位版本中也仅使用32位)。
feersum

7

05AB1E43 41 38 35 27字节

.¡IN£UÄ.œεgΘ>XÄyÙå;P*}àXyå+

在线尝试!

说明:

.¡                              # group by:
  IN£                           #  first N elements of the input, N being the iteration count
     U                          #  store this as X
  Ä                             #  absolute value of the current number
   .œ                           #  partitions (eg 449 => [[4, 4, 9], [44, 9], [4, 49], [449]])
     ε             }            #  map each partition to:
      gΘ>                       #   2 if length = 1, 1 otherwise
           yÙ                   #   for each unique element in the current partition:
         XÄ  å                  #    1 if it's in the absolute value of X, 0 otherwise
              ;                 #   divide all by 2
               P*               #   product of all these numbers
                  à             #  take the maximum
                   Xyå+         #  add 1 if X contains the current number

由于组号不是输出的一部分,因此只要顺序正确,我们就可以随意使用任何所需的号。这对于原始数字使用0,对于XN组使用2 ^ -N,对于X组使用1,对于X + 1使用2。


3
我很想看一下它的工作原理,因为我看不懂05AB1E。
OOBalance

@OOBalance我添加了一个解释,希望它足够清楚。
Grimmy19年

谢谢,这很好地解释了。好的方法,请我 :)
OOBalance

2

Python 2,195字节

最慢的测试用例无法在TIO上完成,但是在我的机器上仅需10秒钟。

import re
a=[()];m=a*99
for n in input():
    i=0;r='-('
    while i<10>re.search(r'(\b.+\b).+'*i+r+')+$','%s-%%s'%a%n):i+=1;r+='|\\'+`i`
    m[48*(n in a)|32*(-n in a)|14-i]+=n,;a+=n,
print filter(len,m)

它可以由2个字节上的Python LP64构建通过更换被缩短'%s-%%s'%a%n`a`+'-'+`n`


1

JavaScript(Node.js)211205字节

a=>a.map(s=>(c[q=(G=(n,r=[],A=Math.abs,N=""+A(s))=>N[L="length"]<n[L]?0:N!=n?Math.max(0,...c.flat().map(x=>G(n+A(x),[...r,x]))):1/r?s-r?11:12:12+~new Set(r).size)``]=c[q]||[]).push(s),c=[])&&c.filter(x=>x)

在线尝试!

假设最多有12个组。

的JavaScript(Node.js的)267个 226 221 218 211字节

a=>a.map(s=>(c[q=(G=(n,r=[],A=Math.abs,N=""+A(s))=>N[L]<n[L]?0:N!=n?Math.max(0,...c.flat().map(x=>G(n+A(x),[...r,x]))):1/r?l-(s!=+r):l+~new Set(r).size)``]=c[q]||[]).push(s),c=[],l=a[L="length"])&&c.filter(x=>x)

在线尝试!

a=>a.map(                       // Iterate through all items:
 s=>(c[q=(
  G=(                           //  Helper function to calculate index (=GroupNo-1):
   n,                           //   Stores different (repeatable) permutations
   r=[],                        //   Stores the elements used
   A=Math.abs,
   N=""+A(s))                   //   Stores the string version of the absolute value
  =>
  N[L="length"]<n[L]?           //   If n is longer then N:
   0                            //    0 (Group 1) - no permutation found to equal the string
  :N!=n?                        //   Else if N!=n:
   Math.max(0,...c.flat().map(  //    Return max of the results of the next recursion
    x=>G(n+A(x),[...r,x])       //    for each of the elements in c
   ))
  :1/r?                         //   Else if r has only 1 item: (=+s/-s)
   s-r?11:12                    //    Return l-1 (Group X) if r=-s, and l (Group X+1) if r=s
  :12+~new Set(r).size          //   Else: return l-r.size-1 (Group X-r.size)
 )``]=c[q]||[]).push(s),        //  Push the element into the corresponding array
 c=[]                           //  Initialize an empty array
)&&c.filter(x=>x)               // Filter out all empty groups

...或193个字节(如果可以返回字典):

a=>a.map(c=s=>(c[q=(G=(n,r=[],A=Math.abs,N=""+A(s))=>N[L="length"]<n[L]?-1/0:N!=n?Math.max(...d.map(x=>G(n+A(x),[...r,x]))):1/r?+!(s-r):-new Set(r).size)``]=c[q]||[]).push(s)&d.push(s),d=[])&&c

在线尝试!

在这种情况下,键-Infinity表示组1,其他键表示Group X+key

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.