Групуйте цілі особи за оригінальністю


12

Вступ:

Я збираю закручені пазли. Більшість крутих пазлів виробляють і продають китайські компанії. Більшість відомих компаній просять дозволу у дизайнерів головоломки на виготовлення своїх конструкцій та спільної роботи над продуктом на ринку. У цьому випадку дизайнери головоломок, звичайно, дуже раді і пишаються тим, що одна з їх головоломок потрапила на ринок.

Однак є і китайські компанії, які складають головоломки. Ці нокаути - або конструкції, що використовуються без дозволу оригінального творця, або прямо дешевіші копії меншої якості вже існуючих пазлів.

Виклик:

Ми будемо визначати оригінальність чисел, які вивільняються в певному порядку (зліва направо ).
Дано список цілих чисел, згрупуйте та виведіть їх за їх оригінальністю.

Як визначається оригінальність чисел?

  • Чи число є точним дублікатом більш раннього числа? Група Х+1 (найменш оригінальна), де група Х+1 є кінцевою, після всіх інших груп.
  • Чи є число дублікатом більш раннього числа, але замість нього від'ємним (тобто початкове число було н , а тепер -н ; або навпаки)? Х група .
  • Чи може бути утворене абсолютне значення числа шляхом об'єднання одного або декількох більш ранніх абсолютних чисел, і чи не воно є частиною раніше згаданих груп Х+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
[-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; не всі тестові випадки працюють у межах TIO, що перевищує 60 секунд.

Спробуйте в Інтернеті!

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

Ви можете зберегти 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

Пітон 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 байт завдяки коментарю Кальмарів щодо іншої відповіді 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 Я додав пояснення, сподіваюся, це досить зрозуміло.
Гріммі

Дякую, що це добре пояснює. Хороший підхід, підкажіть :)
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 байти на збірках LP64 Python, замінивши '%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.