Entiers de groupe par originalité

12

Introduction:

Je collectionne des puzzles tortueux. La plupart des puzzles tortueux sont produits et vendus par des entreprises chinoises. La plupart des entreprises bien connues demandent la permission des créateurs de puzzles pour produire leurs conceptions et travailler ensemble vers un produit sur le marché. Dans ce cas, les concepteurs de puzzles sont bien sûr très heureux et fiers qu'un de leurs puzzles arrive sur le marché.

Cependant, il existe également des entreprises chinoises qui fabriquent des puzzles de contrefaçon. Ces imitations sont soit des conceptions utilisées sans l'autorisation du créateur d'origine, soit des copies de moindre qualité de puzzles déjà existants.

Défi:

Nous allons déterminer l'originalité des numéros qui sont «publiés» dans un ordre spécifique (de gauche à droite ).
Étant donné une liste d'entiers, regroupez-les et sortez-les par leur originalité.

Comment l'originalité des nombres est-elle déterminée?

  • Un numéro est-il un double exact d'un numéro antérieur? Groupe (le moins original), où le groupe suit, après tous les autres groupes.X+1X+1
  • Un nombre est-il un double d'un nombre antérieur, mais son négatif à la place (c'est-à-dire que le nombre d'origine était , mais maintenant ; ou vice-versa)? Groupe .nnX
  • La valeur absolue du nombre peut-elle être formée en concaténant un ou plusieurs nombres absolus antérieurs, et ne fait-elle pas partie des groupes mentionnés précédemment ou ? Groupe , où est la quantité de nombres distincts utilisés dans la concaténation (et ).X+1XXNNN1
  • Le nombre ne correspond-il à aucun des groupes ci-dessus, est-il donc complètement unique jusqu'à présent? Groupe (le plus original), qui mène devant tous les autres groupes.1

Cela peut sembler assez vague, voici donc un exemple étape par étape :

Liste d'entrées: [34,9,4,-34,19,-199,34,-213,94,1934499,213,3,21,-2134,44449,44]

  • 34est le premier nombre, qui est toujours original et dans le groupe . Sortie jusqu'à présent:1[[34]]
  • 9 est aussi original: [[34,9]]
  • 4 est aussi original: [[34,9,4]]
  • -34est le négatif du nombre précédent 34, il est donc dans le groupe :X[[34,9,4],[-34]]
  • 19 est original: [[34,9,4,19],[-34]]
  • -199peut être formé par les deux nombres précédents 19et 9, donc c'est dans le groupe :X2[[34,9,4,19],[-199],[-34]]
  • 34est une copie exacte d'un nombre antérieur, il fait donc partie du groupe :X+1[[34,9,4,19],[-199],[-34],[34]]
  • -213 est original: [[34,9,4,19,-213],[-199],[-34],[34]]
  • 94peut être formé par les deux nombres précédents 9et 4, donc c'est dans le groupe :X2[[34,9,4,19,-213],[-199,94],[-34],[34]]
  • 1934499peut être formé par les quatre numéros antérieurs 19, 34, 4, et deux fois 9, il est donc dans le groupe :X4[[34,9,4,19,-213],[19499],[-199,94],[-34],[34]]
  • 213est le négatif du nombre précédent -213, il est donc dans le groupe :X[[34,9,4,19,-213],[1934499],[-199,94],[-34,213],[34]]
  • 3 est original: [[34,9,4,19,-213,3],[1934499],[-199,94],[-34,213],[34]]
  • 21 est original: [[34,9,4,19,-213,3,21],[1934499],[-199,94],[-34,213],[34]]
  • -2134peut être formé par les deux numéros précédents 213et 4(ou les trois numéros précédents 21, 3et 4, mais nous utilisons toujours le moins de chiffres concaténer pour déterminer l' originalité), il est donc dans le groupe :X2[[34,9,4,19,-213,3,21],[1934499],[-199,94,-2134],[-34,213],[34]]
  • 44449peut être formé par les deux nombres précédents quatre fois 4et 9, donc c'est dans le groupe :X2[[34,9,4,19,-213,3,21],[1934499],[-199,94,-2134,44449],[-34,213],[34]]
  • 44peut être formé par un seul nombre antérieur 4, répété deux fois, il fait donc partie du groupe : X1[[34,9,4,19,-213,3,21],[1934499],[-199,94,-2134,44449],[44],[-34,213],[34]]

Donc, pour l'entrée, [34,9,4,-34,19,-199,34,-213,94,1934499,213,3,21,-2134,44449,44]la sortie est [[34,9,4,19,-213,3,21],[1934499],[-199,94,-2134,44449],[44],[-34,213],[34]].

Règles du défi:

  • Les E / S sont flexibles. Vous pouvez saisir une liste / un tableau / un flux d'entiers ou de chaînes, les saisir un par un via STDIN, etc. La sortie peut être une carte avec les groupes comme clé, une liste imbriquée comme exemple et des cas de test dans ce défi, imprimés saut de ligne séparé, etc.
  • Vous êtes autorisé à prendre la liste d'entrée dans l'ordre inverse (peut-être utile pour les langues basées sur la pile). Dans ce cas, la mention de gauche à droite est bien sûr de droite à gauche.
  • Comme vous pouvez le voir à l'exemple entier -2134, nous regroupons toujours un nombre qui est une concaténation d'autres numéros avec aussi peu que possible (formé par 213et 4- deux nombres, et non par 21, 3et 4- trois numéros).
  • Comme vous pouvez le voir dans l'exemple pour entier 1934499, vous pouvez utiliser un nombre antérieur (le 9dans ce cas) plusieurs fois (similaire à l' 44449utilisation de quatre 4s et de a 9dans l'exemple). Ils ne sont cependant comptés qu'une seule fois pour déterminer le groupe.
  • Vous n'êtes pas autorisé à avoir des listes internes vides dans la sortie pour les groupes vides. Ainsi, le scénario de test [1,58,85,-8,5,8585,5885,518]peut ne pas aboutir à la [[1,58,85,8,5],[518],[5885],[8585],[],[]]place, où les groupes vides sont et , et l'exemple ci-dessus peut ne pas aboutir à la place, où le groupe vide est .XX1X - 3[[34,9,4,19,-213,3,21],[1934499],[],[-199,94,-2134,44449],[44],[-34,213],[34]]X3
  • L'ordre des groupes est strict (sauf si vous utilisez une carte, car les groupes peuvent alors être déduits des clés), mais l'ordre des numéros au sein d'un groupe peut être dans n'importe quel ordre. Ainsi, le [34,9,4,19,-213,3,21]groupe dans l'exemple ci-dessus peut également être ou .1[21,3,-213,19,4,9,34][-213,4,34,19,9,21,3]
  • Vous avez la garantie qu'il n'y aura jamais de numéros pouvant être formés par plus de neuf numéros précédents. Vous n'aurez donc jamais de groupes , et le plus grand nombre possible de groupes est 12:X10[1,X9,X8,...,X2,X1,X,X+1]
  • Vous pouvez supposer que les entiers seront de 32 bits au maximum, donc dans la plage [−2147483648,2147483647].

Règles générales:

  • C'est le , donc la réponse la plus courte en octets l'emporte.
    Ne laissez pas les langues de golf de code vous décourager de publier des réponses avec des langues non-golfeur de code. Essayez de trouver une réponse aussi courte que possible pour «n'importe quel» langage de programmation.
  • Des règles standard s'appliquent à votre réponse avec des règles d'E / S par défaut , vous êtes donc autorisé à utiliser STDIN / STDOUT, des fonctions / méthodes avec les paramètres appropriés et des programmes complets de type retour. Ton appel.
  • Les failles par défaut sont interdites.
  • Si possible, veuillez ajouter un lien avec un test pour votre code (par exemple TIO ).
  • De plus, l'ajout d'une explication à votre réponse est fortement recommandé.

Cas de test:

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]]
Kevin Cruijssen
la source
X + 1Est-ce donc un groupe spécial pour les copies exactes, et Xun groupe pour d'autres nombres qui peuvent être formés à partir de copies d'un seul numéro, comme sa négation?
Neil
1
@ArBo Supposons que les entiers soient au maximum 32 bits, donc dans la plage . Votre exemple n'est donc pas une entrée valide, mais il est possible. [2147483648,2147483647][1, 1111111111]
Kevin Cruijssen
1
Être moi-même collectionneur: c'est une sacrée belle collection que vous avez là, Kevin. Très beau effectivement.
J. Sallé
1
Je collectionne les cartes et ensembles Magic: The Gathering, qui occupent toujours une quantité étonnamment grande même s'ils sont assez petits.
J. Sallé
1
@ J.Sallé Oh, je connais le sentiment. Je collectionne également les cartes Pokémon TCG (et possède en fait la deuxième plus grande collection Pikachu TCG au monde avec plus de 1200 cartes Pikachu uniques). Lorsque vous avez plus de 9 000 cartes, cela prend en effet pas mal d'espace. Pas autant que les énigmes. Seulement 1,5 étagère au lieu de 10.; p
Kevin Cruijssen

Réponses:

9

Python 3 , 565 564 524 523 500 437 399 394 393 389 385 372 octets

Mise en œuvre de la force brute en utilisant itertools; tous les cas de test ne s'exécutent pas dans la limite de 60 secondes sur TIO.

Essayez-le en ligne!

Merci à ArBo pour le golf de 101 octets, à Galen Ivanov pour le golf de 19 octets, à ElPedro pour le golf de 5 octets, à movatica pour le golf de 17 octets, à Black Owl Kai pour le golf de 2 octets, à calmar pour le golf de 2 octets et à Kevin Cruijssen pour golf 1 octet.

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)]

Explication:

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 octets

Même approche, mais plus courte en raison de certaines astuces de golf, Python 3 ne prend plus en charge. Merci à ArBo pour le backport et au golf 28 octets, à ElPedro pour le golf 5 octets, à movatica pour le golf 17 octets et au calmar pour le golf 1 octet de plus.

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)

Essayez-le en ligne!

OOBalance
la source
2
Les commentaires ne sont pas pour une discussion approfondie; cette conversation a été déplacée vers le chat .
James
Vous pouvez enregistrer 5 dans les deux en déplaçant str(abs(x))(ou abs (x) avec des raccourcis en Python 2) vers l'appel de fonction et en changeant x dans la définition de fonction en y supprimant y = str (abs (x)). Désolé, impossible de faire fonctionner TIO pour le moment.
ElPedro
Vous pouvez filtrer par lenpour raser un autre octet, non?
squid
Vous pouvez supprimer la syntaxe de la liste dans les any()appels, ce qui en fait un générateur normal, qui fonctionne aussi bien et vous fait économiser 4 octets supplémentaires :)
movatica
... et encore plus court: (x in sum(l,[]))au lieu de any(x in s for s in l)pour les deux xet -xéconomise 13 octets de plus!
movatica
7

Python 2 , 235 234 232 246 245 244 241 240 238 237 236 octets

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)

Essayez-le en ligne!

-1 octet grâce au commentaire de Squid sur l'autre réponse Python

Cette réponse n'a aucun espoir de résoudre, sauf le plus trivial des cas de test. Dans le lien TIO, s*11a été remplacé par s*2, en sacrifiant la justesse dans certains cas , rapide er temps d'exécution, mais pour autant que je peux voir, la version dans ce post donne toujours la bonne réponse, en théorie.

Explication

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
ArBo
la source
2
Je suis heureux de voir que vous avez créé votre propre réponse Python :-) Et c'est aussi plus court!
OOBalance
@OOBalance Maintenant, si seulement cela se terminait de mon vivant ...
ArBo
1
Oh, j'ai oublié comment c'est une chose idiote avec la version Windows (elle n'utilise que 32 bits, intmême dans la version 64 bits).
feersum
7

05AB1E , 43 41 38 35 27 octets

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

Essayez-le en ligne!

Explication:

.¡                              # 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

Étant donné que les numéros de groupe ne font pas partie de la sortie, nous sommes libres d'utiliser tous les numéros que nous voulons, tant que l'ordre est correct. Cela utilise 0 pour les numéros d'origine, 2 ^ -N pour le groupe XN, 1 pour le groupe X, 2 pour le groupe X + 1.

Grimmy
la source
3
J'aimerais voir une explication de comment cela fonctionne car je ne peux pas lire 05AB1E.
OOBalance
@OOBalance J'ai ajouté une explication, j'espère que c'est assez clair.
Grimmy
Merci, ça explique bien. Bonne approche, ayez mon vote positif :)
OOBalance
2

Python 2, 195 octets

Le cas de test le plus lent ne peut pas être terminé sur TIO , mais cela ne prend que 10 secondes environ sur ma machine.

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)

Il peut être raccourci de 2 octets sur les versions LP64 Python en le remplaçant '%s-%%s'%a%npar `a`+'-'+`n`.

feersum
la source
1

JavaScript (Node.js) , 211 205 octets

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)

Essayez-le en ligne!

En utilisant l'hypothèse qu'il y a au plus 12 groupes.

JavaScript (Node.js) , 267 226 221 218 211 octets

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)

Essayez-le en ligne!

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

... ou 193 octets si le renvoi d'un dictionnaire est correct:

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

Essayez-le en ligne!

Dans ce cas, clé -Infinitysignifie Groupe 1 et autres clés signifie Groupe X+key.

Shieru Asakoto
la source