Целочисленные группы по оригинальности


12

Вступление:

Я собираю извилистые головоломки. Большинство извилистых головоломок производятся и продаются китайскими компаниями. Большинство известных компаний запрашивают разрешение у разработчиков пазлов на разработку своих проектов и совместную работу над созданием продукта на рынке. В этом случае дизайнеры головоломок, конечно же, очень счастливы и горды тем, что одна из их головоломок появилась на рынке.

Есть, однако, и китайские компании, которые выпускают загадочные пазлы. Эти подделки являются либо дизайнами, использованными без разрешения оригинального создателя, либо просто более дешевыми копиями уже низкого качества уже существующих головоломок.

Вызов:

Мы собираемся определить оригинальность чисел, которые «выпущены» в определенном порядке (слева направо ).
Дайте список целых чисел, сгруппируйте и выведите их по оригинальности.

Как определяется оригинальность номеров?

  • Является ли число точной копией более раннего числа? Группа Икс+1 (наименее оригинальная), где группа Икс+1 идет за всеми остальными группами.
  • Является ли число дубликатом более раннего числа, но вместо этого оно отрицательное (т. Е. Исходное число было N , а теперь -N или наоборот)? Группа Икс .
  • Можно ли сформировать абсолютное значение числа путем объединения одного или нескольких более ранних абсолютных чисел, и не является ли оно частью ранее упомянутых групп Икс+1 или Икс ? Группа Икс-N , где N - количество различных чисел, используемых в конкатенации (и N1 ).
  • Разве число не подходит ни к одной из вышеперечисленных групп, поэтому пока оно полностью уникально? Группа 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, так что это в группе Икс :[[34,9,4],[-34]]
  • 19 оригинально: [[34,9,4,19],[-34]]
  • -199может быть образован двумя предыдущими числами 19и 9, таким образом, это в группе Икс-2 :[[34,9,4,19],[-199],[-34]]
  • 34является точной копией более раннего числа, поэтому оно находится в группе Икс+1 :[[34,9,4,19],[-199],[-34],[34]]
  • -213 оригинально: [[34,9,4,19,-213],[-199],[-34],[34]]
  • 94может быть образован двумя предыдущими числами 9и 4, таким образом, это в группе Икс-2 :[[34,9,4,19,-213],[-199,94],[-34],[34]]
  • 1934499может быть образован из четырех предыдущих чисел 19, 34, 4и в два раза 9, так что в группе Икс-4 :[[34,9,4,19,-213],[19499],[-199,94],[-34],[34]]
  • 213является отрицательным от предыдущего числа -213, так что это в группе Икс :[[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может быть образован двумя более ранними числами 213и 4(или тремя более ранними числами 21, 3и 4, но мы всегда используем наименьшее количество соединяющих чисел для определения оригинальности), так что это в группе Икс-2 :[[34,9,4,19,-213,3,21],[1934499],[-199,94,-2134],[-34,213],[34]]
  • 44449может быть образован двумя предыдущими числами четыре раза 4и 9, таким образом, это в группе Икс-2 :[[34,9,4,19,-213,3,21],[1934499],[-199,94,-2134,44449],[-34,213],[34]]
  • 44может быть образован одним более ранним числом 4, повторенным два раза, так что это в группе Икс-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]].

Правила вызова:

  • Ввод / вывод является гибким. Вы можете вводить в виде списка / массива / потока целых чисел или строк, вводить их одну за другой через STDIN и т. Д. Выходными данными могут быть карта с группами в качестве ключа, вложенный список в качестве примера и тестовые примеры в этой задаче, напечатанные перевод строки и т. д.
  • Вам разрешено принимать входной список в обратном порядке (возможно, это полезно для стековых языков). В таком случае упомянутое слева направо, конечно, справа налево.
  • Как вы можете видеть на примере для целого числа -2134, мы всегда группа число , которое является объединением других чисел как можно (образуемым 213и 4- два числа, а не 21, 3и 4- три числа).
  • Как вы можете видеть в примере для целого числа 1934499, вы можете использовать более раннее число ( 9в данном случае) несколько раз (аналогично 44449использованию четырех 4s и a 9в примере). Однако они подсчитываются только один раз для определения группы.
  • Вы не можете иметь пустые внутренние списки в выходных данных для пустых групп. Таким образом, тестовый случай [1,58,85,-8,5,8585,5885,518]может не привести к тому [[1,58,85,8,5],[518],[5885],[8585],[],[]], что пустыми группами являются Икс и Икс-1 , а приведенный выше пример может не привести к тому [[34,9,4,19,-213,3,21],[1934499],[],[-199,94,-2134,44449],[44],[-34,213],[34]], что пустой группой является Икс-3 .
  • Порядок групп строгий (если только вы не используете карту, поскольку группы затем могут быть вычтены из ключей), но порядок чисел в группе может быть в любом порядке. Таким образом, [34,9,4,19,-213,3,21]для группы 1 в приведенном выше примере также может быть [21,3,-213,19,4,9,34]или [-213,4,34,19,9,21,3].
  • Вам гарантировано, что никогда не будет никаких чисел, которые могут быть сформированы более чем девятью предыдущими числами. Таким образом, у вас никогда не будет никаких групп Икс-10 , а наибольшее количество групп - 12:[1,Икс-9,Икс-8,,,,,Икс-2,Икс-1,Икс,Икс+1]
  • Можно предположить, что целые числа будут максимум 32 бита, поэтому в пределах диапазона [−2147483648,2147483647].

Основные правила:

  • Это , поэтому выигрывает самый короткий ответ в байтах.
    Не позволяйте языкам кода-гольфа отговаривать вас от публикации ответов на языках, не относящихся к кодексу. Попробуйте найти как можно более короткий ответ для «любого» языка программирования.
  • Стандартные правила применяются к вашему ответу с правилами ввода / вывода по умолчанию , поэтому вы можете использовать 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
@ArBo Давайте предположим, что целые числа максимум 32 бита, поэтому в диапазоне [-2147483648,2147483647] . Таким образом, ваш пример не является допустимым, но [1, 1111111111]возможен.
Кевин Круйссен

1
Быть коллекционером: это чертовски хорошая коллекция, Кевин. Очень мило на самом деле.
Ж. Салле

1
Я собираю карты и наборы Magic: The Gathering, которые по-прежнему занимают удивительно большое пространство, хотя они довольно маленькие.
Ж. Салле

1
@ J.Sallé О, я знаю это чувство. Я также собираю карты Pokémon TCG (и фактически у меня есть вторая по величине коллекция Pikachu TCG в мире с более чем 1200 уникальными картами Pikachu). Когда у вас более 9000 карт, это действительно занимает довольно мало места. Не так много, как головоломки. Всего 1,5 полки вместо 10.; p
Кевин Круйссен

Ответы:



9

Python 3 , 565 564 524 523 500 437 399 394 393 389 385 372 байт

Использование грубой силы itertools; не все тестовые случаи выполняются в течение 60 секунд на TIO.

Попробуйте онлайн!

Спасибо ArBo за игру в гольф 101 байт, Галену Иванову за игру в гольф 19 байтов, ElPedro за игру в гольф 5 байтов, movatica для игры в гольф 17 байтов, Black Owl Kai за игру в гольф 2 байта, кальмару за игру в гольф 2 байта и Кевину Круйссену за игра в гольф 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
Комментарии не для расширенного обсуждения; этот разговор был перенесен в чат .
Джеймс

Вы можете сохранить 5 в обоих, переместившись str(abs(x))(или abs (x) с обратными галочками в Python 2) к вызову функции и изменив x в определении функции на y, удалив y = str (abs (x)). Извините, не могу заставить 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 (она использует только 32 бита intдаже в 64-битной версии).
feersum

7

05AB1E , 43 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 для исходных чисел, 2 ^ -N для группы XN, 1 для группы X, 2 для группы X + 1.


3
Я хотел бы увидеть объяснение того, как это работает, так как я не могу читать 05AB1E.
OOBalance

@OOBalance Я добавил объяснение, надеюсь, оно достаточно понятно.
Grimmy

Спасибо, это хорошо объясняет. Хороший подход, мой голос :)
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) , 211 205 байт

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, а другие ключи означает Группу X+key.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.