Integer Grup berdasarkan Orisinalitas

12

Pengantar:

Saya mengumpulkan teka-teki berliku. Sebagian besar teka-teki berliku diproduksi dan dijual oleh perusahaan Cina. Sebagian besar perusahaan terkenal meminta izin dari perancang puzzle untuk menghasilkan desain mereka dan bekerja bersama menuju suatu produk di pasar. Dalam hal ini, perancang puzzle tentu saja sangat senang dan bangga bahwa salah satu teka-teki mereka menghantam pasar.

Namun ada juga perusahaan China yang membuat puzzle knock-off. Tiruan-tiruan ini adalah desain yang digunakan tanpa izin dari pencipta asli, atau merupakan salinan dengan kualitas lebih rendah dan lebih murah dari teka-teki yang sudah ada.

Tantangan:

Kita akan menentukan orisinalitas angka yang 'dirilis' dalam urutan tertentu (dari kiri ke kanan ).
Diberikan daftar bilangan bulat, kelompokkan dan hasilkan menurut orisinalitasnya.

Bagaimana keaslian angka ditentukan?

  • Apakah angka merupakan duplikat tepat dari angka sebelumnya? Grup (paling tidak orisinal), di mana grup tertinggal, setelah semua grup lainnya.X+1X+1
  • Apakah angka merupakan duplikat dari angka sebelumnya, tetapi sebaliknya negatif (yaitu angka asli adalah n , tetapi sekarang n ; atau sebaliknya)? Kelompok X .
  • Bisakah nilai absolut dari angka tersebut dibentuk dengan menggabungkan satu atau lebih angka absolut sebelumnya, dan bukankah itu bagian dari kelompok yang disebutkan sebelumnya atau ? Grup , di mana adalah jumlah angka berbeda yang digunakan dalam rangkaian (dan ).X+1XXNNN1
  • Apakah jumlahnya tidak cocok dengan salah satu grup di atas, sehingga sejauh ini benar-benar unik? Grup (paling orisinal), yang memimpin sebelum semua grup lain.1

Ini mungkin terdengar agak kabur, jadi di sini contoh langkah demi langkah :

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

  • 34adalah angka pertama, yang selalu asli dan di grup . Output sejauh ini:1[[34]]
  • 9 juga asli: [[34,9]]
  • 4 juga asli: [[34,9,4]]
  • -34adalah negatif dari angka sebelumnya 34, jadi itu dalam grup :X[[34,9,4],[-34]]
  • 19 asli: [[34,9,4,19],[-34]]
  • -199dapat dibentuk oleh dua angka sebelumnya 19dan 9, jadi itu dalam grup :X2[[34,9,4,19],[-199],[-34]]
  • 34adalah salinan persis dari nomor sebelumnya, jadi itu dalam grup :X+1[[34,9,4,19],[-199],[-34],[34]]
  • -213 asli: [[34,9,4,19,-213],[-199],[-34],[34]]
  • 94dapat dibentuk oleh dua angka sebelumnya 9dan 4, jadi itu dalam grup :X2[[34,9,4,19,-213],[-199,94],[-34],[34]]
  • 1934499dapat dibentuk oleh empat angka sebelumnya 19, 34, 4, dan dua kali 9, sehingga dalam kelompok :X4[[34,9,4,19,-213],[19499],[-199,94],[-34],[34]]
  • 213adalah negatif dari angka sebelumnya -213, jadi itu dalam grup :X[[34,9,4,19,-213],[1934499],[-199,94],[-34,213],[34]]
  • 3 asli: [[34,9,4,19,-213,3],[1934499],[-199,94],[-34,213],[34]]
  • 21 asli: [[34,9,4,19,-213,3,21],[1934499],[-199,94],[-34,213],[34]]
  • -2134dapat dibentuk oleh dua angka sebelumnya 213dan 4(atau tiga nomor sebelumnya 21, 3dan 4, tetapi kita selalu menggunakan paling sedikit concatenating nomor untuk menentukan orisinalitas), sehingga dalam kelompok :X2[[34,9,4,19,-213,3,21],[1934499],[-199,94,-2134],[-34,213],[34]]
  • 44449dapat dibentuk oleh dua angka sebelumnya empat kali 4dan 9, jadi itu dalam grup :X2[[34,9,4,19,-213,3,21],[1934499],[-199,94,-2134,44449],[-34,213],[34]]
  • 44dapat dibentuk oleh satu angka sebelumnya 4, diulang dua kali, jadi dalam grup : X1[[34,9,4,19,-213,3,21],[1934499],[-199,94,-2134,44449],[44],[-34,213],[34]]

Jadi untuk input [34,9,4,-34,19,-199,34,-213,94,1934499,213,3,21,-2134,44449,44]outputnya [[34,9,4,19,-213,3,21],[1934499],[-199,94,-2134,44449],[44],[-34,213],[34]].

Aturan tantangan:

  • I / O fleksibel. Anda dapat memasukkan sebagai daftar / larik / aliran bilangan bulat atau string, masukan satu per satu melalui STDIN, dll. Keluaran dapat berupa peta dengan grup sebagai kunci, daftar bersarang sebagai contoh dan uji kasus dalam tantangan ini, dicetak baris baru dipisahkan, dll.
  • Anda diizinkan untuk mengambil daftar input dalam urutan terbalik (mungkin berguna untuk bahasa berbasis stack). Dalam hal ini dari kiri ke kanan tentu saja dari kanan ke kiri.
  • Seperti yang anda lihat di contoh untuk integer -2134, kami selalu kelompok angka yang merupakan gabungan dari nomor lain dengan sesedikit mungkin (yang dibentuk oleh 213dan 4- dua nomor, dan bukan dengan 21, 3, dan 4- tiga angka).
  • Seperti yang Anda lihat pada contoh untuk bilangan bulat 1934499, Anda dapat menggunakan angka sebelumnya ( 9dalam kasus ini) beberapa kali (mirip dengan 44449menggunakan empat 4dan 9dalam contoh). Namun mereka hanya dihitung satu kali untuk menentukan grup.
  • Anda tidak diizinkan memiliki daftar dalam kosong di output untuk grup kosong. Jadi, test case [1,58,85,-8,5,8585,5885,518]mungkin tidak menghasilkan [[1,58,85,8,5],[518],[5885],[8585],[],[]]sebaliknya, di mana grup kosong adalah dan , dan contoh di atas mungkin tidak menghasilkan sebaliknya, di mana grup kosong adalah .XX1X - 3[[34,9,4,19,-213,3,21],[1934499],[],[-199,94,-2134,44449],[44],[-34,213],[34]]X3
  • Urutan grup ketat (kecuali Anda menggunakan peta, karena grup kemudian dapat dikurangkan dari tombol), tetapi urutan angka dalam grup dapat dalam urutan apa pun. Jadi [34,9,4,19,-213,3,21]untuk grup pada contoh di atas juga bisa atau .1[21,3,-213,19,4,9,34][-213,4,34,19,9,21,3]
  • Anda dijamin bahwa tidak akan pernah ada angka yang dapat dibentuk oleh lebih dari sembilan angka sebelumnya. Jadi, Anda tidak akan pernah memiliki grup , dan jumlah grup terbesar yang mungkin adalah 12:X10[1,X9,X8,...,X2,X1,X,X+1]
  • Anda dapat mengasumsikan bilangan bulat akan maksimal 32 bit, jadi dalam jangkauan [−2147483648,2147483647].

Aturan umum:

  • Ini adalah , jadi jawaban tersingkat dalam byte menang.
    Jangan biarkan bahasa kode-golf mencegah Anda memposting jawaban dengan bahasa non-codegolf. Cobalah untuk memberikan jawaban sesingkat mungkin untuk bahasa pemrograman 'apa pun'.
  • Aturan standar berlaku untuk jawaban Anda dengan aturan I / O default , sehingga Anda diizinkan untuk menggunakan STDIN / STDOUT, fungsi / metode dengan parameter yang tepat dan tipe pengembalian, program penuh. Panggilanmu.
  • Celah default tidak diperbolehkan.
  • Jika memungkinkan, silakan tambahkan tautan dengan tes untuk kode Anda (yaitu TIO ).
  • Juga, menambahkan penjelasan untuk jawaban Anda sangat dianjurkan.

Kasus uji:

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
sumber
Jadi, X + 1apakah grup khusus untuk salinan yang tepat, dan Xapakah grup untuk nomor lain yang dapat dibentuk dari salinan nomor tunggal, seperti negasinya?
Neil
1
[2147483648,2147483647][1, 1111111111]
1
Menjadi seorang kolektor sendiri: itu koleksi bagus yang Anda dapatkan di sana, Kevin. Memang sangat bagus.
J. Sallé
1
Saya mengumpulkan Magic: The Gathering cards and set, yang masih menempati jumlah ruang yang sangat besar walaupun ukurannya cukup kecil.
J. Sallé
1
@ J.Sallé Oh, saya tahu perasaan itu. Saya juga mengumpulkan kartu TCG Pokémon (dan sebenarnya memiliki koleksi TCG Pikachu terbesar kedua di dunia dengan lebih dari 1200 kartu Pikachu unik). Ketika Anda memiliki lebih dari 9.000 kartu, itu memang memakan banyak ruang. Tapi tidak sebanyak teka-teki. Hanya 1,5 rak alih-alih 10.; p
Kevin Cruijssen

Jawaban:

1

Jelly , 36 33 byte

ADṪŒṖfƑƇƊQ€Ẉ.*;,AṪe$€SƲṀµƤż⁸ṢZ¹ƙ/

Cobalah online!

Saya yakin ini bisa bermain golf lebih banyak. Beberapa inspirasi diambil dari jawaban 05AB1E Grimy , jadi pastikan untuk mengungguli yang juga!

Nick Kennedy
sumber
9

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

Implementasi brute-force menggunakan itertools; tidak semua uji berjalan dalam batas 60 detik pada TIO.

Cobalah online!

Terima kasih kepada ArBo untuk golf 101 byte, ke Galen Ivanov untuk golf 19 byte, ke ElPedro untuk golf 5 byte, untuk movatica untuk golf 17 byte, ke Black Owl Kai untuk golf 2 byte, untuk squid untuk golf 2 byte dan untuk Kevin Cruijssen untuk bermain golf 1 byte.

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

Penjelasan:

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 byte

Pendekatan yang sama, tetapi lebih pendek karena beberapa trik golf, Python 3 tidak mendukung lagi. Terima kasih kepada ArBo untuk backport dan untuk golf 28 byte, untuk ElPedro untuk golf 5 byte, untuk movatica untuk golf 17 byte, dan untuk squid untuk golf 1 byte lebih.

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)

Cobalah online!

Ketidakseimbangan
sumber
2
Komentar bukan untuk diskusi panjang; percakapan ini telah dipindahkan ke obrolan .
James
Anda dapat menyimpan 5 di keduanya dengan memindahkan str(abs(x))(atau abs (x) dengan backticks di Python 2) ke pemanggilan fungsi dan mengubah x dalam definisi fungsi menjadi y menghapus y = str (abs (x)). Maaf, saat ini TIO tidak bisa berfungsi.
ElPedro
Anda dapat memfilter dengan lenmencukur byte lain, bukan?
cumi
Anda dapat menghapus sintaksis daftar any()panggilan di dalam , sehingga membuatnya menjadi generator normal, yang berfungsi dengan baik dan menghemat 4 byte lagi :)
movatica
... dan bahkan lebih pendek: (x in sum(l,[]))alih-alih any(x in s for s in l)untuk keduanya xdan -xmenyimpan 13 byte lebih banyak!
movatica
7

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

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)

Cobalah online!

-1 byte berkat komentar Squid pada jawaban Python lainnya

Jawaban ini tidak memiliki harapan untuk menyelesaikan apa pun kecuali yang paling sepele dari kasus uji. Dalam link TIO, s*11telah digantikan oleh s*2, mengorbankan kebenaran dalam beberapa kasus untuk cepat er waktu eksekusi, tetapi sejauh yang saya bisa melihat, versi dalam posting ini selalu menghasilkan jawaban yang benar, dalam teori.

Penjelasan

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
sumber
2
Saya senang melihat Anda telah membuat jawaban Python Anda sendiri :-) Dan itu juga lebih pendek!
OOBalance
@OOBalance Sekarang, kalau saja itu akan berakhir dalam hidupku ...
ArBo
1
Oh, saya lupa tentang bagaimana itu hal yang konyol dengan versi Windows (hanya menggunakan 32 bit untuk intbahkan dalam versi 64-bit).
feersum
7

05AB1E , 43 41 38 35 27 byte

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

Cobalah online!

Penjelasan:

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

Karena nomor grup bukan bagian dari output, kami bebas menggunakan nomor apa pun yang kami inginkan, selama urutannya benar. Ini menggunakan 0 untuk angka asli, 2 ^ -N untuk grup XN, 1 untuk grup X, 2 untuk grup X + 1.

Grimmy
sumber
3
Saya ingin melihat penjelasan bagaimana ini bekerja karena saya tidak bisa membaca 05AB1E.
OOBalance
@OOBalance Saya menambahkan penjelasan, semoga cukup jelas.
Grimmy
Terima kasih, itu menjelaskannya dengan baik. Pendekatan yang baik, dapatkan
jawaban
2

Python 2, 195 byte

Kasing uji paling lambat tidak bisa selesai di TIO , tetapi hanya butuh sekitar 10 detik di mesin saya.

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)

Ini dapat disingkat 2 byte pada LP64 Python builds dengan mengganti '%s-%%s'%a%ndengan `a`+'-'+`n`.

feersum
sumber
1

JavaScript (Node.js) , 211 205 byte

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)

Cobalah online!

Menggunakan asumsi bahwa paling banyak ada 12 kelompok.

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

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)

Cobalah online!

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

... atau 193 byte jika mengembalikan kamus tidak masalah:

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

Cobalah online!

Dalam hal ini, kunci -Infinityberarti Grup 1 dan kunci lainnya berarti Grup X+key.

Shieru Asakoto
sumber