Trouver une correspondance maximale dans la relation de divisibilité

16

On vous donne un ensemble d'entiers positifs. Vous devez les disposer en paires de sorte que:

  • Chaque paire contient 2 nombres, dont l'un est un multiple d'un autre. Par exemple, 8 est un multiple de 4 et 9 est un multiple de 9.
  • Si le même nombre se produit plusieurs fois dans l'ensemble initial, il peut être utilisé autant de fois dans les paires; un nombre peut même être associé à une autre occurrence du même nombre
  • Le nombre maximal de paires possible est obtenu.

La sortie doit être le nombre de paires. Le code le plus court gagne.

Exemples de données

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
la source
3
Quelqu'un sait si ce problème est NP-complet? Je pense que le plus petit ensemble "dur" est 2,3,4,8,9,18. (Chaque nombre dans cette liste est un facteur et / ou un multiple d'au moins deux autres nombres dans la liste, mais il n'a qu'une seule solution.)
Neil

Réponses:

6

Haskell, 109 107 76 70 octets

Merci à nimi d'avoir économisé 33 octets et de m'avoir appris un peu plus de Haskell. :)
Merci à xnor pour avoir sauvé encore 6 octets.

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

Oui, mon premier golf Haskell. Cela fonctionne de la même manière que toutes les réponses jusqu'à présent (enfin, pas tout à fait: il ne compte que la longueur du préfixe le plus long des paires valides dans chaque permutation, mais c'est équivalent et c'est en fait ce que mon code CJam original a fait).

Pour plus de golfitude, il est également très inefficace en générant récursivement toutes les permutations du suffixe chaque fois que les deux premiers éléments d'une permutation sont une paire valide.

Martin Ender
la source
Est-ce f=nécessaire?
Alex A.
@AlexA. Je ne sais pas quelle est la politique standard sur PPCG pour les fonctions sans nom dans Haskell, mais j'ai vérifié quelques autres réponses Haskell et ils ont utilisé des fonctions nommées. En outre, vous devez techniquement utiliser des parenthèses autour de la fonction si vous souhaitez l'utiliser comme une fonction sans nom, de sorte que ce serait le même nombre d'octets de toute façon, je suppose.
Martin Ender
@nimi Merci de m'avoir prévenu. :) Voyez-vous autre chose qui pourrait être raccourci? L'importation chunksOfest douloureuse. Je ne connais pas vraiment la bibliothèque standard de Haskell pour savoir s'il existe une fonction équivalente plus courte. J'ai essayé de l'implémenter moi-même, mais il est sorti deux ou trois octets de plus que l'importation.
Martin Ender
ohhh, attraper les deux []et [_]en même temps en mettant le g x=[]deuxième est vraiment intelligent. Je vais essayer. Merci :)
Martin Ender
On dirait un peu plus court pour définir toute fonction récursive: f l=maximum$0:[1+f t|(a:b:t)<-permutations l,a`mod`b<1].
xnor
3

CJam, 22 18 octets

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

Essayez-le en ligne.

Attend une entrée sous la forme d'une liste de style CJam.

C'est un peu inefficace pour les grandes listes (et Java manquera probablement de mémoire à moins que vous ne lui en donniez plus).

Explication

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
la source
Il ne donne pas de sortie pour [1 2 3 4 5 6 7 8 9 10]Cependant, [7 1 9 9 4 9 9 1 3 9 8 1]qui est une liste plus longue, fonctionne correctement. Pourquoi donc?
ghosts_in_the_code
@ghosts_in_the_code Parce que le premier a des permutations plus distinctes. 10! = 3628800, mais 12! / 5! / 3! = 665280. Il manque donc de mémoire pour le premier cas. Si vous l'exécutiez à partir de la console avec l'interpréteur Java, vous pourriez dire à Java d'utiliser plus de mémoire et le premier cas fonctionnerait également (bien que cela puisse prendre un certain temps, je ne sais pas).
Martin Ender
3

Pyth, 13 octets

eSm/%Mcd2Z.pQ

Le temps et la complexité du stockage sont vraiment terribles. La première chose que je fais est de créer une liste avec toutes les permutations de la liste d'origine. Cela prend du n*n!stockage. Les listes d'entrée de longueur 9 prennent déjà assez de temps.

Essayez-le en ligne: démonstration ou suite de tests

Explication:

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
la source
2

Mathematica, 95 93 87 83 79 60 58 octets

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

Prend quelques secondes pour les exemples plus grands.

LegionMammal978
la source
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

principale:

  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)

  • la fonction topper est appelée par la partie principale.

  • l'entrée est sous la forme [. . .]

Abr001am
la source
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)

  • C'est apparemment plus long, mais oneliner et exécutif, et j'ai réussi à échapper à la permsfonction car cela prend une éternité.

  • Cette fonction prend de nombreuses reprises pour fonctionner correctement grâce aux fonctions anonymes, je suis ouvert aux suggestions ici :)

Abr001am
la source