Prenez-en un pour en faire un

23

Défi

Étant donné une liste d'entiers positifs, recherchez s'il existe une permutation où en prenant jusqu'à un bit de chacun des entiers, un nombre binaire composé de tous les 1s peut être créé.

Le nombre de bits du nombre binaire résultant est égal au MSB le plus élevé de la liste des entiers.

Sortie

Votre code doit générer ou renvoyer une valeur truey / falsey indiquant si une telle permutation existe.

Exemples

Vérité:

Avec la liste [4, 5, 2]et sa représentation binaire [100, 101, 10], nous pouvons utiliser les troisième, premier et deuxième bits, respectivement, pour créer 111:

4  ->  100  ->  100  ->  1
5  ->  101  ->  101  ->    1
2  ->  010  ->  010  ->   1
Result                   111

Avec la liste [3, 3, 3], tous les nombres ont à la fois le premier et le deuxième bits définis 1, afin que nous puissions faire notre choix avec un nombre à épargner:

3  ->  11  ->  11  ->  1
3  ->  11  ->  11  ->   1
3  ->  11  ->  11  ->
Result                 11

Falsey:

Avec la liste [4, 6, 2], aucun des nombres n'a le premier bit défini comme 1, donc le nombre binaire ne peut pas être créé:

4  ->  100
6  ->  110
2  ->  010

Avec la liste [1, 7, 1], un seul des deux nombres a les deuxième et troisième bits définis comme 1et le nombre ne peut pas être créé:

1  ->  001
7  ->  111
1  ->  001

De toute évidence, si le nombre maximal de bits définis dépasse le nombre d'entiers, le nombre de résultats ne peut jamais être créé.

Cas de test

Vérité:

[1]
[1, 2]
[3, 3]
[3, 3, 3]
[4, 5, 2]
[1, 1, 1, 1]
[15, 15, 15, 15]
[52, 114, 61, 19, 73, 54, 83, 29]
[231, 92, 39, 210, 187, 101, 78, 39]

Falsey:

[2]
[2, 2]
[4, 6, 2]
[1, 7, 1]
[15, 15, 15]
[1, 15, 3, 1]
[13, 83, 86, 29, 8, 87, 26, 21]
[154, 19, 141, 28, 27, 6, 18, 137]

Règles

Les failles standard sont interdites. Comme il s'agit de , l'entrée la plus courte gagne!

Antti29
la source
Il y a un théorème qui pourrait aider avec ça…
Pas un arbre
Bienvenue chez PPCG! Joli premier défi!
M. Xcoder du
@Notatree: Eh bien, c'est gentil. Je peux utiliser le code le plus court pour me trouver une femme.
Antti29
Ajouté à mon index des problèmes de graphes en tant que correspondance bipartite.
Peter Taylor

Réponses:

8

Gelée , 11 octets

BUT€ŒpṬz0PẸ

Essayez-le en ligne!

Comment ça marche

BUT€ŒpṬz0PẸ  Main link. Argument: A (array)

             Example: A = [4, 5, 2]
B            Binary; convert each n in A to base 2.
                      [[1, 0, 0], [1, 0, 1], [1, 0]]
 U           Upend; reverse all arrays of binary digits.
                      [[0, 0, 1], [1, 0, 1], [0, 1]]
  T€         Truth each; for each binary array, get all indices of 1's.
                      [[3], [1, 3], [2]]
    Œp       Take the Cartesian product of all index arrays.
                      [[3, 1, 2], [3, 3, 2]
      Ṭ      Untruth; map each index array to a binary arrays with 1's at
             at the specified indices.
                      [[1, 1, 1], [0, 1, 1]]
       z0    Zip/transpose the resulting 2D array, filling shorter rows with 0's.
                      [[1, 0], [1, 1], [1, 1]]
         P   Take the columnwise product.
                      [1, 0]
          Ẹ  Any; yield 1 if any of the products is non-zero, 0 otherwise.
                      1
Dennis
la source
7

J , 30 octets

Tout le mérite revient à mon collègue Marshall .

Fonction de préfixe tacite sans nom.

[:+./ .*(1->./@${.|:)^:2@|:@#:

Essayez-le en ligne!

( @est la composition de la fonction)

#: antibase-2

|: transposer

()^:2 Appliquez deux fois la fonction suivante:

1- Boolean negate

>./ le maximum

@ du

$ longueurs d'axe

{. prendre (remplissage avec des zéros) de

|: l'argument transposé

+./ .*"magie déterminante folle" *

[: ne pas accrocher (no-op - sert à composer la partie précédente avec le reste)


* Dans les mots de Marshall.

Adam
la source
6

JavaScript (ES6), 104 ... 93 83 octets

Renvoie 0ou 1.

f=(a,m=Math.max(...a),s=1)=>s>m|a.some((n,i)=>n&s&&f(b=[...a],m,s*2,b.splice(i,1)))

Cas de test

Méthode

Étant donné le tableau d'entrée A = [a 0 , a 1 , ..., a N-1 ] , nous recherchons une permutation [a p [0] , a p [1] , ..., a p [N- 1] ] de A et d'un entier x ≤ N tel que:

  • s = 1 + (a p [0] ET 2 0 ) + (a p [1] ET 2 1 ) + ... + (a p [x-1] ET 2 x-1 ) = 2 x
  • et s est supérieur au plus grand élément m de A

Formaté et commenté

f = (                 // f = recursive function taking:
  a,                  //   - a = array
  m = Math.max(...a), //   - m = greatest element in a
  s = 1               //   - s = current power of 2, starting at 1
) =>                  //
  s > m               // success condition (see above) which is
  |                   // OR'd with the result of this some():
  a.some((n, i) =>    // for each element n at position i in a:
    n & s &&          //   provided that the expected bit is set in n,
    f(                //   do a recursive call with:
      b = [...a],     //     b = copy of a
      m,              //     m unchanged
      s * 2,          //     s = next power of 2
      b.splice(i, 1)  //     the current element removed from b
    )                 //   end of recursive call
  )                   // end of some()
Arnauld
la source
4

Husk , 14 octets

SöV≡ŀToṁ∂Pmo↔ḋ

Essayez-le en ligne!

Explication

SöV≡ŀToṁ∂Pmo↔ḋ  Implicit input, say [4,5,2].
          m  ḋ  Convert each to binary
           o↔   and reverse them: x = [[0,0,1],[1,0,1],[0,1]]
         P      Take all permutations of x
      oṁ∂       and enumerate their anti-diagonals in y = [[0],[0,1],[1,0,0],[1,1],[1]..
S    T          Transpose x: [[0,1,0],[0,0,1],[1,1]]
    ŀ           Take the range up to its length: z = [1,2,3]
                Then z is as long as the longest list in x.
 öV             Return the 1-based index of the first element of y
   ≡            that has the same length and same distribution of truthy values as z,
                i.e. is [1,1,1]. If one doesn't exist, return 0.
Zgarb
la source
4

05AB1E , 23 22 20 octets

-1 octet grâce à Mr.Xcoder

Vrai: 1, Faux: 0

2вí0ζœεvyƶNè})DgLQ}Z

Essayez-le en ligne!

Explications:

2вí0ζœεvyƶNè})DgLQ}Z   Full program (implicit input, e.g. [4, 6, 2])
2в                     Convert each to binary ([1,0,0], [1,1,0], [1,0])
  í                    Reverse each ([0,0,1], [0,1,1], [0,1])
   0ζ                  Zip with 0 as a filler ([0,0,0],[0,1,1],[1,1,0])
     œ                 Get all sublists permutations
      ε           }    Apply on each permutation...
       vyƶNè}            For each sublist...
        yƶ                  Multiply each element by its index
          Nè                Get the element at position == sublist index
             )           Wrap the result in a list
              DgLQ       1 if equal to [1,2,...,length of item]
                   Z   Get max item of the list (1 if at least 1 permutations fill the conditions)
                       -- implicit output
scottinet
la source
3

Wolfram Language (Mathematica) , 65 octets

Max[Tr/@Permutations[n=PadLeft[#~IntegerDigits~2]]]==Tr[1^#&@@n]&

Essayez-le en ligne!

Explication

#~IntegerDigits~2

Nous commençons par convertir toutes les entrées en listes binaires.

n=PadLeft[...]

Ensuite, nous remplissons toutes ces listes de zéros à gauche pour rendre le tableau rectangulaire. Le résultat est stocké npour plus tard.

Permutations[...]

Oui, force brute, obtenons toutes les permutations possibles de l'entrée.

Tr/@...

Ceci obtient la trace de chaque permutation, c'est-à-dire la somme des éléments diagonaux de la permutation. En d'autres termes, nous additionnons le MSB du premier numéro, le MSB suivant du deuxième numéro et ainsi de suite. Si la permutation est valide, toutes ces valeurs seront égales à 1 et il y aura autant de 1 s que le plus grand nombre d'entrée est large.

Max[...]

Nous obtenons la trace maximale, car la trace ne peut jamais être supérieure à celle d'une permutation valide.

...==Tr[1^#&@@n]

Le côté droit est juste une version golfique de Length @ First @ n, c'est-à-dire qu'il obtient la largeur du tableau rectangulaire, et donc la largeur du plus grand nombre d'entrée. Nous voulons nous assurer que la trace d'une permutation est égale à cela.

Martin Ender
la source
3

PHP, 255 243 160 octets

-12 octets, sorti le tri
-83 octets (!) Grâce à Titus

<?function f($a,$v=NULL,$b=[]){($v=$v??(1<<log(max($a),2)+1)-1)||die("1");if($p=array_pop($a))while($p-=$i)($b[$i=1<<log($p,2)]|$v<$i)||f($a,$v-$i,[$i=>1]+$b);}

Essayez-le en ligne!

Imprime 1 pour véridique, rien pour falsey.

Version originale non golfée:

<?php
unset($argv[0]);                                                   // remove filename from arguments
$max = pow(2,floor(log(max($argv),2))+1)-1;                        // get target number (all bits set to 1)
solve($argv,$max,[]);
function solve($array,$value,$bits){
  if(!$value){                                                     // if we've reached our target number (actually subtracted it to zero)
    die("1");                                                      // print truthy
  }
  if(count($array)){                                               // while there are arguments left to check
    $popped = array_pop($array);                                   // get the largest argument
    while($popped > 0 && ($mybit = pow(2,floor(log($popped,2))))){ // while the argument hasn't reached zero, get the highest power of 2 possible
      $popped -= $mybit;                                           // subtract power from argument
      if($value >= $mybit && !$bits[$i]){                          // if this bit can be subtracted from our argument, and we haven't used this bit yet
        $copy = $bits;                                             // create a copy to pass to the function
        $copy[$mybit] = 1;                                         // mark the bit as used in the copy
        solve($array,$value-$mybit,$copy);                         // recurse
      }
    }
  }
}
Jo.
la source
Je ne l'ai pas testé, mais ces 158 octets devraient faire de même:function f($a,$v=NULL,$b=[]){($v=$v??(1<<log(max($a),2)+1)-1)||die("1");if($p=array_pop($a))while($p-=$i)($b[$i=1<<log($p,2)]|$v<$i)||f($a,$v-$i,[$i=>1]+$b);}
Titus
@Titus et ainsi nous voyons à quel point je suis terrible chez codegolf. Et pourquoi la plupart des questions ont une excellente réponse de votre part en PHP. (et quelques autres langues).
Jo.
Terrible pour l'instant. C'est une assez bonne réponse; et les compétences de golf viennent avec l'expérience.
Titus
Pas besoin de la notation de chaîne longue, utilisez simplement quelque chose d'autre qui se traduit par «1» mais n'est pas entier. Par exemple un booléen true: die("1")die(!0).
manatwork
2

Lua 5.2, 85 octets

m=math
x=function(...)print(bit32.bor(...)==2^(m.floor(m.log(m.max(...),2))+1)-1)end

Cela définit x comme une fonction qui accepte un nombre variable d'entrées (qui devrait être des entiers 32 bits) et s'imprime sur stdout soit "true" soit "false".

Usage:

x(13, 83, 86, 29, 8, 87, 26, 21) -- Prints "false"
FulltimeLurker
la source
1
Hmm, cela semble échouer pour certains des faux cas de test? [1,15,3,1]semble revenir trueau lieu de falsepar exemple. Voici votre code le compilateur en ligne de TIO. Les deux autres cas de test qui échouent sont [1,7,1]et [15,15,15]. Tous les autres cas de test produisent les résultats corrects.
Kevin Cruijssen
2

PHP, 121 octets

function f($a,$s=0){($v=array_pop($a))||(0|$g=log($s+1,2))-$g||die("1");for($b=.5;$v<=$b*=2;)$v&$b&&~$s&$b&&f($a,$s|$b);}

Essayez-le en ligne .

panne

function f($a,$s=0)
{
    ($v=array_pop($a))          # pop element from array
    ||                          # if nothing could be popped (empty array)
    (0|$g=log($s+1,2))-$g       # and $s+1 is a power of 2
        ||die("1");                 # then print "1" and exit
    for($b=.5;$v>=$b*=2;)       # loop through the bits:
        $v&$b                       # if bit is set in $v
        &&~$s&$b                    # and not set in $s
            &&f($a,$s|$b);              # then set bit in $s and recurse
}
Titus
la source
2

J , 49 octets

g=.3 :'*+/*/"1+/"2((#y){.=i.{:$#:y)*"2#:(i.!#y)A.,y'

Dois-je également compter le «g =.»? Je suis prêt à l'ajouter.

Un long verbe explicite cette fois. J'en ai essayé un tacite pour le même algorithme, mais il s'est avéré être encore plus long et plus laid que cela. Loin de la solution d'Adám.

Explication: (y est le bon argument de la fonction)

                                             ,y - adds a leading axis to the argument 
                                             (if it's scalar becomes an array of length 1)
                                          .A    - finds the permutations according to the left argument
                                   (i.!#y)      - factorial of the length of the argument, for all permutations
                                 #:             - convert each element to binary
                             *"2                - multiply each cell by identity matrix
           (                )                   - group 
                   =i.{:$#:y                    - identity matrix with size the length
                                                  of the binary representation of the argument 
             (#y){.                             - takes as many rows from the identity matrix 
                                                  as the size of the list (pad with 0 if neded)
    */"1+/"2                                    - sums the rows and multiplies the items
                                                  to check if forms an identity matrix
 *+/                                            - add the results from all permutations and
                                                  returns 1 in equal or greater then 1

Essayez-le en ligne!

Galen Ivanov
la source
1

Python 3 , 126 120 octets

6 octets enregistrés grâce à M. Xcoder

lambda x:g(x,max(map(len,map(bin,x)))-3)
g=lambda x,n:n<0 or any(g(x[:i]+x[i+1:],n-1)for i in range(len(x))if x[i]&2**n)

Essayez-le en ligne!

Halvard Hummel
la source
Pourriez-vous ajouter une version non golfée?
Antti29
[0]+[...]Est inutile non? any(g(x[:i]+x[i+1:],n-1)for i in range(len(x))if x[i]&2**n)devrait suffire.
M. Xcoder
@ Mr.Xcoder Ouais, je pense que je pensais à la fonction max quand je l'ai ajouté
Halvard Hummel
1

Gelée , 17 octets

BUz0Œ!ŒD€Ẏ
ṀBo1eÇ

Un lien monadique prenant une liste de chiffres et revenant 1(véridique) ou 0(falsey).

Essayez-le en ligne!

Cela expirera sur TIO pour le plus long de chacun des cas de test.

Comment?

BUz0Œ!ŒD€Ẏ - Link 1, possibilities (plus some shorter ones & duplicates): list of numbers
                                     e.g. [4, 5, 2]
B          - to binary list (vectorises)  [[1,0,0],[1,0,1],[1,0]]
 U         - upend                        [[0,0,1],[1,0,1],[0,1]]
   0       - literal zero                  0
  z        - transpose with filler        [[0,1,0],[0,0,1],[1,1,0]]
    Œ!     - all permutations             [[[0,1,0],[0,0,1],[1,1,0]],[[0,1,0],[1,1,0],[0,0,1]],[[0,0,1],[0,1,0],[1,1,0]],[[0,0,1],[1,1,0],[0,1,0]],[[1,1,0],[0,1,0],[0,0,1]],[[1,1,0],[0,0,1],[0,1,0]]]
      ŒD€  - diagonals of €ach            [[[0,0,0],[1,1],[0],[1],[0,1]],[[0,1,1],[1,0],[0],[0],[1,0]],[[0,1,0],[0,0],[1],[1],[0,1]],[[0,1,0],[0,0],[1],[0],[1,1]],[[1,1,1],[1,0],[0],[0],[0,0]],[[1,0,0],[1,1],[0],[0],[0,1]]]
         Ẏ - tighten                      [[0,0,0],[1,1],[0],[1],[0,1],[0,1,1],[1,0],[0],[0],[1,0],[0,1,0],[0,0],[1],[1],[0,1],[0,1,0],[0,0],[1],[0],[1,1],[1,1,1],[1,0],[0],[0],[0,0],[1,0,0],[1,1],[0],[0],[0,1]]

ṀBo1eÇ - Main link: list of numbers  e.g. [4, 5, 2]
Ṁ      - maximum                           5
 B     - to binary list                   [1,0,1]
   1   - literal one                       1
  o    - or (vectorises)                  [1,1,1]
     Ç - last link as a monad             [[0,0,0],[1,1],[0],[1],[0,1],[0,1,1],[1,0],[0],[0],[1,0],[0,1,0],[0,0],[1],[1],[0,1],[0,1,0],[0,0],[1],[0],[1,1],[1,1,1],[1,0],[0],[0],[0,0],[1,0,0],[1,1],[0],[0],[0,1]]
    e  - exists in?                        1    --------------------------------------------------------------------------------------------------------------^
Jonathan Allan
la source
1

R , 247 octets 221 octets

function(i){a=do.call(rbind,Map(`==`,Map(intToBits,i),1));n=max(unlist(apply(a,1,which)));any(unlist(g(a[,1:n,drop=F],n)))}
g=function(a,p){if(p==1)return(any(a[,1]));Map(function(x){g(a[x,,drop=F],p-1)},which(a[,p])*-1)}

Essayez-le en ligne!

Version non golfée

f=function(i){                                   #anonymous function when golfed
  a=do.call(rbind,Map(`==`,Map(intToBits,i),1))  #convert integers to binary, then logical
                                                 #bind results together in matrix
  n=max(unlist(apply(a,1,which)))                #determine max number of bits
  any(unlist(g(a[,1:n,drop=F],n)))               #apply recursive function
}

g=function(a,p){
  if(p==1)return(any(a[,1]))                   #check if first bit is available still
  Map(function(x){g(a[x,,drop=F],p-1)},which(a[,p])*-1) #strip row used for current bit
                                                        #and apply the function recursively
}

J'ai réalisé que la vérification sans ligne n'était pas nécessaire avec les drop=Farguments. Suppression également de quelques espaces blancs embêtants.

marque
la source
1

PHP, 152 octets

<?function b($a,$b,$s){$a[$s]=0;$r=$b-1;foreach($a as$i=>$v)if($v&1<<$b)$r=max(b($a,$b+1,$i),$r);return$r;}$g=$argv;$g[0]=0;echo!(max($g)>>b($g,0,0)+1);

N'imprime rien pour faux, 1 pour vrai.

Non golfé:

<?

// Search an array for a value having a bit set at the given bit index.
// For each match, search for a next higher bit index excluding the current match.
// This way it "climbs up" bit by a bit, finally returning the highest bit index reached.
function bitSearch($valArr, $bitInd, $skipInd) {
    unset($valArr[$skipInd]);
    $result = $bitInd - 1;
    foreach ($valArr as $ind => $v) {
        if ($v & (1 << $bitInd)) {
            $result = max(bitSearch($valArr, $bitInd + 1, $ind), $result);
        }
    }
    return $result;
}

$argv[0] = 0;
$r = bitSearch($argv, 0, 0);
// Check if the highest bit index reached was highest in the largest value given.
if (max($argv) >> ($r + 1)) {
    echo("False\n");
} else {
    echo("True\n");
}
Arppa
la source
0

C, 79 octets

b,i;main(a){for(;~scanf("%d",&a);i++)b|=a;puts("false\0true"+(b==(1<<i)-1)*6);}
PrincePolka
la source
Pourriez-vous ajouter une explication? Un try it onlinelien serait également utile.
Antti29
Quelques conseils pour jouer au golf en C: 1 / dans de nombreux défis (celui-ci inclus), vous êtes autorisé à soumettre une fonction au lieu d'un programme complet, 2 / vous devez produire une valeur truey / falsey, cela peut être aussi long car il est cohérent (vous pouvez sortir 0/1 au lieu de "faux" / "vrai"). Enfin, ce code ne semble pas fonctionner: [1, 7, 1]devrait retourner faux, et [52, 114, 61, 19, 73, 54, 83, 29]devrait retourner vrai
scottinet
Vous avez raison, ma mauvaise
PrincePolka