Tam Sayıları Özgünlüğe Göre Gruplama


12

Giriş:

Kıvrımlı bulmacalar topluyorum. Bükülen bulmacaların çoğu Çinli şirketler tarafından üretilir ve satılır. En tanınmış şirketler tasarımlarını üretmek ve pazardaki bir ürün üzerinde birlikte çalışmak için bulmaca tasarımcılarından izin ister. Bu durumda, bulmaca tasarımcıları elbette bulmacalarından birinin pazara girmesinden çok mutlu ve gururlu.

Bununla birlikte, nakavt bulmacaları yapan Çinli şirketler de var. Bu vuruntular ya orijinal içerik oluşturucunun izni olmadan kullanılan tasarımlardır ya da mevcut bulmacaların düpedüz, daha düşük kaliteli kopyalarıdır.

Meydan okuma:

Belirli bir düzende (soldan sağa ) serbest bırakılan sayıların özgünlüğünü belirleyeceğiz .
Tamsayıların bir listesi verildiğinde, özgünlüklerine göre gruplandırın ve çıktı alın.

Sayıların özgünlüğü nasıl belirlenir?

  • Sayı, önceki sayının tam bir kopyası mı? Grup X+1 (en az orijinal), burada X+1 grubu diğer gruplardan sonra devam eder.
  • Bir sayı önceki bir sayının kopyası mı, bunun yerine negatif mi (yani orijinal sayı n , ama şimdi n ; ya da tam tersi)? Grup X .
  • Sayının mutlak değeri, bir veya daha fazla önceki mutlak sayıyı birleştirerek oluşturulabilir mi ve daha önce bahsedilen X+1 veya X gruplarının bir parçası değil mi? Grup XN- , burada N- , birleştirme işleminde kullanılan ayrı sayıların miktarıdır (ve N-1 ).
  • Sayı yukarıdaki grupların hiçbirine uymuyor mu, şimdiye kadar tamamen benzersiz mi? Grup 1 (en orijinal), diğer gruplardan önce lider.

Bu oldukça belirsiz gelebilir, bu yüzden burada adım adım bir örnek :

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

  • 34her zaman orijinal olan ve grup 1 ilk sayıdır . Çıktı şimdiye kadar:[[34]]
  • 9 ayrıca orijinal: [[34,9]]
  • 4 ayrıca orijinal: [[34,9,4]]
  • -34önceki sayının negatifidir 34, bu nedenle X grubundadır :[[34,9,4],[-34]]
  • 19 orijinal: [[34,9,4,19],[-34]]
  • -199önceki iki sayıdan oluşabilir 19ve 9bu X-2 grubundadır :[[34,9,4,19],[-199],[-34]]
  • 34önceki bir sayının tam kopyasıdır, bu nedenle X+1 grubundadır :[[34,9,4,19],[-199],[-34],[34]]
  • -213 orijinal: [[34,9,4,19,-213],[-199],[-34],[34]]
  • 94önceki iki sayıdan oluşabilir 9ve 4bu X-2 grubundadır :[[34,9,4,19,-213],[-199,94],[-34],[34]]
  • 1934499Dört önceki sayılarla oluşturulabilir 19, 34, 4ve iki kere 9, bu gruptaki yüzden X-4 :[[34,9,4,19,-213],[19499],[-199,94],[-34],[34]]
  • 213önceki sayının negatifidir -213, bu nedenle X grubundadır :[[34,9,4,19,-213],[1934499],[-199,94],[-34,213],[34]]
  • 3 orijinal: [[34,9,4,19,-213,3],[1934499],[-199,94],[-34,213],[34]]
  • 21 orijinal: [[34,9,4,19,-213,3,21],[1934499],[-199,94],[-34,213],[34]]
  • -2134daha önceki iki sayılarla oluşturulabilir 213ve 4(veya üç önceki sayılar 21, 3ve 4, fakat her zaman özgünlük belirlemek için numaralar birleştirerek en az miktarda kullanın) o grupta yüzden, X-2 :[[34,9,4,19,-213,3,21],[1934499],[-199,94,-2134],[-34,213],[34]]
  • 44449önceki iki sayıyla dört kez oluşturulabilir 4ve 9bu nedenle X-2 grubundadır :[[34,9,4,19,-213,3,21],[1934499],[-199,94,-2134,44449],[-34,213],[34]]
  • 444iki kez tekrarlanan daha önceki tek bir sayıdan oluşabilir , bu nedenle X-1 grubunda : [[34,9,4,19,-213,3,21],[1934499],[-199,94,-2134,44449],[44],[-34,213],[34]]

Yani giriş [34,9,4,-34,19,-199,34,-213,94,1934499,213,3,21,-2134,44449,44]için çıkış olur [[34,9,4,19,-213,3,21],[1934499],[-199,94,-2134,44449],[44],[-34,213],[34]].

Zorluk kuralları:

  • G / Ç esnektir. Tamsayıların veya dizelerin bir listesi / dizisi / akışı olarak girebilir, bunları STDIN, vb. Aracılığıyla tek tek girebilirsiniz. Çıktı, anahtar olarak gruplar, örnek olarak iç içe bir liste ve bu meydan okumadaki test senaryoları, basılı olabilir yeni satır ayrılmış, vb.
  • Giriş listesini ters sırayla almanıza izin verilir (belki de yığın tabanlı diller için yararlıdır). Bu durumda, bahsedilen soldan sağa elbette sağdan sola olur.
  • Eğer tamsayı için örneğe görebileceğiniz gibi -2134, her zaman grubunun birkaç mümkün olduğunca diğer sayıların bir birleşimidir numarası (oluşturduğu 213ve 4- iki sayıdan ve vermeyerek 21, 3ve 4- üç sayı).
  • Tamsayı örneğinde görebileceğiniz gibi, 1934499önceki bir sayıyı ( 9bu durumda) birden çok kez kullanabilirsiniz ( 44449dört 4s ve a9 örnekte ). Ancak grubu belirlemek için sadece bir kez sayılırlar.
  • Boş gruplar için çıktıda boş iç listeler bulunmasına izin verilmez. Test durumda Böylece [1,58,85,-8,5,8585,5885,518]neden olmayabilir [[1,58,85,8,5],[518],[5885],[8585],[],[]], bunun yerine boş gruplardır X ve X-1 ve sonuçlanmaz yukarıda örnek [[34,9,4,19,-213,3,21],[1934499],[],[-199,94,-2134,44449],[44],[-34,213],[34]]boş gruptur, bunun yerine X-3 .
  • Grupların sırası katıdır (bir harita kullanmazsanız, gruplar daha sonra anahtarlardan çıkarılabilir), ancak bir grup içindeki sayıların sırası herhangi bir sırada olabilir. Dolayısıyla yukarıdaki örnekte yer alan [34,9,4,19,-213,3,21]grup 1 için de [21,3,-213,19,4,9,34]veya olabilir [-213,4,34,19,9,21,3].
  • Daha önce dokuzdan fazla sayıdan oluşabilecek hiçbir sayı olmayacağı garanti edilir. Hiç var asla Yani X-10 : grupları ve olası grupların büyük miktarda 12'dir [1,X-9,X-8,...,X-2,X-1,X,X+1]
  • Tamsayıların maksimum 32 bit olacağını, yani aralık içinde olduğunu varsayabilirsiniz [−2147483648,2147483647].

Genel kurallar:

  • Bu , bayt en kısa cevap kazanır.
    Kod golf dillerinin, kod yazmayan dillerle yanıt göndermenizi engellemesine izin vermeyin. 'Herhangi bir' programlama dili için mümkün olduğunca kısa bir cevap bulmaya çalışın.
  • Varsayılan I / O kuralları ile cevabınız için standart kurallar geçerlidir , bu nedenle STDIN / STDOUT, fonksiyonlar / yöntem uygun parametreler ve dönüş tipi, tam programlar ile kullanılabilir. Çağrınız.
  • Varsayılan Loopholes yasaktır.
  • Mümkünse, lütfen kodunuz için bir test içeren bir bağlantı ekleyin (örn. TIO ).
  • Ayrıca, cevabınız için bir açıklama eklemeniz şiddetle tavsiye edilir.

Test senaryoları:

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

Yani X + 1tam kopyalar için özel bir gruptur ve Xbu tür onun yadsınması olarak tek bir numara kopyalarından oluşturulabilir diğer numaralar için bir gruptur?
Neil

1
[-2147483648,2147483647][1, 1111111111]

1
Kendim bir koleksiyoncu olmak: Buraya geldiğin çok güzel bir koleksiyon, Kevin. Gerçekten çok iyi.
J. Sallé

1
Magic: The Gathering kartlarını ve setlerini topladım ve bu kartlar oldukça küçük olmalarına rağmen şaşırtıcı derecede büyük yer kaplıyorlar.
J. Sallé

1
@ J.Sallé Oh, duyguyu biliyorum. Ayrıca Pokémon TCG kartları da topladım (ve aslında 1200'den fazla benzersiz Pikachu kartıyla dünyanın en büyük ikinci Pikachu TCG koleksiyonuna sahibim) .. 9.000'den fazla kartınız olduğunda gerçekten biraz yer kaplıyor. Yine de bulmaca kadar değil. 10 yerine sadece 1.5 raf; p
Kevin Cruijssen

Yanıtlar:



9

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

Kaba kuvvet uygulaması itertools; tüm test senaryoları TIO'daki 60 saniyelik sınır içinde çalışmaz.

Çevrimiçi deneyin!

Sayesinde ARBO 101 bayt, golf için Galen Ivanov 19 bayt, golf için ElPedro için, 5 bayt golf için movatica 17 bayt, golf için Siyah baykuş Kai için, 2 bayt golf için kalamar 2 bayt golf için ve Kevin Cruijssen için golf 1 bayt.

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

Açıklama:

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

Piton 2 , 406 379 374 373 372 368 355 bayt

Aynı yaklaşım, ancak bazı golf hileleri nedeniyle daha kısa Python 3 artık desteklemiyor. Sayesinde ARBO backport için ve 28 bayt, golf için ElPedro için, 5 bayt golf için movatica 17 bayt golf için, ve kalamar 1 byte daha golf için.

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)

Çevrimiçi deneyin!


2
Yorumlar uzun tartışmalar için değildir; bu görüşme sohbete taşındı .
James

str(abs(x))İşlev çağrısına hareket ettirerek (veya Python 2'deki ters çentiklerle abs (x)) 5 işlevini kaydedebilir ve işlev tanımındaki x'i y = str (abs (x)) 'yi kaldırarak değiştirebilirsiniz. Üzgünüz, şu anda TIO'yu çalıştıramadım.
ElPedro

lenBaşka bir baytı tıraş etmek için filtreleyebilirsiniz , değil mi?
kalamar

any()Aramalar içindeki liste sözdizimini kaldırabilirsiniz , böylece normal bir jeneratör yapar, bu da iyi çalışır ve size 4 bayt daha tasarruf sağlar :)
movatica

... ve hatta daha kısa: (x in sum(l,[]))yerine any(x in s for s in l)her ikisi için xve -x13 daha bayt kazandırır!
movatica

7

Piton 2 , 235 234 232 246 245 244 241 240 238 237 236 bayt

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)

Çevrimiçi deneyin!

Squid'in diğer Python cevabı hakkındaki yorumu sayesinde -1 byte

Bu cevabın en önemsiz test senaryolarını çözme umudu yok . TIO bağlantısında, s*11almıştır s*2hızlı için bazı durumlarda doğruluğu feda er yürütme zamanı, ama bildiğim kadarıyla gördüğünüz gibi, bu yazı sürüm her zaman teoride, doğru cevabı verir.

açıklama

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
Kendi Python cevabınızı oluşturduğunuzu görmekten memnunum :-) Ve bu da daha kısa!
OOBalance

@OOBalance Şimdi, hayatım boyunca sona erecek olsaydı ...
ArBo

1
Oh, bunun Windows sürümü ile nasıl aptalca bir şey olduğunu unuttum ( int64 bit sürümde bile sadece 32 bit kullanıyor ).
feersum

7

05AB1E , 43 41 38 35 27 bayt

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

Çevrimiçi deneyin!

Açıklama:

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

Grup numaraları çıktının bir parçası olmadığından, sipariş doğru olduğu sürece istediğimiz sayıları kullanmakta özgürüz. Bu orijinal numaralar için 0, XN grubu için 2 ^ -N, X grubu için 1, X + 1 grubu için 2 kullanır.


3
05AB1E'yi okuyamadığım için bunun nasıl çalıştığına dair bir açıklama görmek isterim.
OOBalance

@OOBalance Bir açıklama ekledim, umarım yeterince açıktır.
Grimmy

Teşekkürler, bu güzel açıklıyor. İyi yaklaşım, benim oyumu var :)
OOBalance

2

Python 2, 195 bayt

En yavaş test durumu TIO'da tamamlanamaz , ancak makinemde sadece 10 saniye sürer.

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)

LP64 Python değiştirerek kurar üzerinde 2 adet byte kısaltılabilir '%s-%%s'%a%nile `a`+'-'+`n`.


1

JavaScript (Node.js) , 211 205 bayt

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)

Çevrimiçi deneyin!

En fazla 12 grup olduğu varsayılarak.

JavaScript (node.js) , 267 226 221 218 211 bayt

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)

Çevrimiçi deneyin!

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

... veya sözlük döndürme uygunsa 193 bayt:

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

Çevrimiçi deneyin!

Bu durumda, anahtar -InfinityGrup 1 ve diğer anahtarlar Grup anlamına gelir X+key.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.