Temukan kecocokan maksimal dalam hubungan keterbagian

16

Anda diberi satu set bilangan bulat positif. Anda harus mengaturnya menjadi berpasangan sehingga:

  • Setiap pasangan berisi 2 angka, salah satunya adalah kelipatan dari yang lain. Misalnya, 8 adalah kelipatan dari 4, dan 9 adalah kelipatan dari 9.
  • Jika nomor yang sama terjadi berkali-kali pada set awal, itu dapat digunakan berkali-kali dalam pasangan; suatu nomor bahkan dapat dipasangkan dengan kejadian lain dari nomor yang sama
  • Jumlah pasangan maksimum yang mungkin diperoleh.

Output harus berupa jumlah pasangan. Kode terpendek menang.

Contoh data

2,3,4,8,9,18 -> 3

7,14,28,42,56 -> 2

7,1,9,9,4,9,9,1,3,9,8,5 -> 6

8,88,888,8888,88888,888888 -> 3

2,6,7,17,16,35,15,9,83,7 -> 2

ghosts_in_the_code
sumber
3
Adakah yang tahu apakah masalah ini NP-complete? Saya pikir set "keras" terkecil adalah 2,3,4,8,9,18. (Setiap angka dalam daftar itu adalah faktor dan / atau kelipatan dari setidaknya dua angka lain dalam daftar, tetapi hanya memiliki satu solusi.)
Neil

Jawaban:

6

Haskell, 109 107 76 70 byte

Terima kasih kepada nimi karena telah menghemat 33 byte dan mengajari saya lebih banyak Haskell. :)
Terima kasih kepada xnor karena telah menyimpan 6 byte lagi.

import Data.List
f l=maximum$0:[1+f t|a:b:t<-permutations l,a`mod`b<1]

Yay, golf Haskell pertamaku. Ini bekerja sama dengan semua jawaban sejauh ini (yah, tidak cukup: hanya menghitung panjang awalan terpanjang dari pasangan yang valid dalam setiap permutasi, tapi itu setara dan sebenarnya apa kode CJam asli saya lakukan).

Untuk golfitude ekstra, ini juga sangat tidak efisien dengan secara rekursif menghasilkan semua permutasi dari suffix setiap kali dua elemen permutasi pertama adalah pasangan yang valid.

Martin Ender
sumber
Apakah ini f=perlu?
Alex A.
@AlexA. Saya tidak yakin apa kebijakan standar pada PPCG untuk fungsi yang tidak disebutkan namanya di Haskell, tetapi saya telah memeriksa beberapa jawaban Haskell lainnya dan mereka menggunakan fungsi bernama. Selain itu, Anda secara teknis harus menggunakan tanda kurung di sekitar fungsi jika Anda ingin menggunakannya sebagai fungsi yang tidak disebutkan namanya, jadi bagaimanapun juga itu adalah jumlah byte yang sama.
Martin Ender
@nimi Terima kasih telah memberi tahu saya. :) Apakah Anda melihat hal lain yang dapat dipersingkat? Impor untuk chunksOfitu menyakitkan. Saya tidak benar-benar tahu perpustakaan standar Haskell untuk dapat mengetahui apakah ada fungsi setara yang lebih pendek. Saya mencoba menerapkannya sendiri, tetapi keluar dua atau tiga byte lebih lama daripada impor.
Martin Ender
ohhh, menangkap keduanya []dan [_]sekaligus dengan menempatkan g x=[]kedua benar-benar pintar. Saya akan mencobanya. Terima kasih :)
Martin Ender
Tampak sedikit lebih pendek untuk mendefinisikan seluruh fungsi rekursif: f l=maximum$0:[1+f t|(a:b:t)<-permutations l,a`mod`b<1].
xnor
3

CJam, 22 18 byte

q~e!{2/::%0e=}%:e>

Cobalah online.

Diharapkan input dalam bentuk daftar gaya-CJam.

Ini agak tidak efisien untuk daftar yang lebih besar (dan Java mungkin akan kehabisan memori kecuali Anda memberi lebih banyak).

Penjelasan

q~     e# Read and evaluate input.
e!     e# Get all distinct permutations.
{      e# Map this block onto each permutation...
  2/   e#   Split the list into (consecutive) pairs. There may be a single element at the
       e#   end, which doesn't participate in any pair.
  ::%  e#   Fold modulo onto each chunk. If it's a pair, this computes the modulo, which
       e#   yields 0 if the first element is a multiple of the second. If the list has only
       e#   one element, it will simply return that element, which we know is positive.
  0e=  e#   Count the number of zeroes (valid pairs).
}%
:e>    e# Find the maximum of the list by folding max() onto it.
Martin Ender
sumber
Itu tidak memberikan output untuk [1 2 3 4 5 6 7 8 9 10]Namun [7 1 9 9 4 9 9 1 3 9 8 1]yang merupakan daftar yang lebih panjang, berfungsi dengan baik. Mengapa demikian?
ghosts_in_the_code
@ghosts_in_the_code Karena yang pertama memiliki permutasi yang lebih berbeda. 10! = 3628800, Tapi 12! / 5! / 3! = 665280. Jadi kehabisan memori untuk kasus pertama. Jika Anda menjalankannya dari konsol dengan Java interpreter, Anda bisa memberi tahu Java untuk menggunakan lebih banyak memori dan case pertama akan bekerja dengan baik (walaupun mungkin butuh beberapa saat, tidak tahu).
Martin Ender
3

Pyth, 13 byte

eSm/%Mcd2Z.pQ

Kompleksitas waktu dan penyimpanan sangat mengerikan. Hal pertama yang saya lakukan adalah membuat daftar dengan semua permutasi dari daftar awalnya. Ini membutuhkan n*n!penyimpanan. Input list dengan panjang 9 sudah memakan waktu yang cukup lama.

Cobalah online: Demonstrasi atau Test Suite

Penjelasan:

eSm/%Mcd2Z.pQ
            Q   read the list of integer
          .p    create the list of all permutations
  m             map each permutation d to:
      cd2          split d into lists of length 2
    %M             apply modulo to each of this lists
   /     Z         count the zeros (=number of pairs with the first 
                   item divisible by the second)
 S              sort these values
e               and print the last one (=maximum)
Jakube
sumber
2

Mathematica, 95 93 87 83 79 60 58 byte

Max[Count[#~Partition~2,{a_,b_}/;a∣b]&/@Permutations@#]&

Butuh beberapa detik untuk contoh yang lebih besar.

LegionMammal978
sumber
0

Matlab (120 + 114 = 234)

  function w=t(y,z),w=0;for i=1:size(z,1),w=max(w,1+t([y,z(i,:)],feval(@(d)z(d(:,1)&d(:,2),:),~ismember(z,z(i,:)))));end

utama:

  a=input('');h=bsxfun(@mod,a,a');v=[];for i=1:size(h,1) b=find(~h(i,:));v=[v;[(2:nnz(b))*0+i;b(b~=i)]'];end;t([],v)

  • fungsi puncak disebut oleh bagian utama.

  • inputnya ada di form [. . .]

Abr001am
sumber
0

Matlab (365)

  j=@(e,x)['b(:,' num2str(e(x)) ')'];r=@(e,y)arrayfun(@(t)['((mod(' j(e,1) ',' j(e,t) ')==0|mod(' j(e,t) ',' j(e,1) ')==0)&',(y<4)*49,[cell2mat(strcat(r(e(setdiff(2:y,t)),y-2),'|')) '0'],')'],2:y,'UniformOutput',0);a=input('');i=nnz(a);i=i-mod(i,2);q=0;while(~q)b=nchoosek(a,i);q=[cell2mat(strcat((r(1:i,i)),'|')) '0'];q=nnz(b(eval(q(q~=0)),:));i=i-2;end;fix((i+2)/2)

  • Ini rupanya lebih lama, tetapi hanya di bawah standar dan eksekutif, dan saya berhasil melarikan diri dari permsfungsi karena butuh selamanya.

  • Fungsi ini membutuhkan banyak reprises untuk berjalan dengan tenang karena fungsi anonim, saya terbuka untuk saran di sini :)

Abr001am
sumber