Ambil satu untuk membuatnya

23

Tantangan

Diberikan daftar bilangan bulat positif, temukan jika ada permutasi di mana mengambil hingga satu bit dari masing-masing bilangan bulat, angka biner yang terdiri dari semua 1s dapat dibuat.

Jumlah bit dalam jumlah biner yang dihasilkan sama dengan MSB tertinggi dalam daftar bilangan bulat.

Keluaran

Kode Anda harus menampilkan atau mengembalikan nilai kebenaran / kesalahan yang menunjukkan jika permutasi semacam itu ada.

Contohnya

Benar:

Dengan daftar [4, 5, 2], dan representasi binernya [100, 101, 10], kita dapat menggunakan bit ketiga, pertama, dan kedua, masing-masing, untuk membuat 111:

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

Dengan daftar [3, 3, 3], semua angka memiliki bit pertama dan kedua ditetapkan sebagai 1, sehingga kita dapat memilih dengan nomor yang akan dicadangkan:

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

Falsey:

Dengan daftar [4, 6, 2], tidak ada angka yang memiliki bit pertama yang ditetapkan 1, sehingga angka biner tidak dapat dibuat:

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

Dengan daftar [1, 7, 1], hanya satu nomor yang memiliki bit kedua dan ketiga ditetapkan sebagai 1, dan nomor tidak dapat dibuat:

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

Jelas, jika jumlah maksimum set bit melebihi jumlah integer, jumlah hasil tidak akan pernah dapat dibuat.

Uji kasus

Benar:

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

Aturan

Celah standar dilarang. Karena ini adalah , entri terpendek menang!

Antti29
sumber
Ada teorema yang mungkin bisa membantu dengan ini ...
Bukan sebatang pohon
Selamat datang di PPCG! Tantangan pertama yang bagus!
Tn. Xcoder
@Natatree: Ya, bagus sekali. Saya dapat menggunakan kode terpendek untuk menemukan saya seorang istri.
Antti29
Ditambahkan ke indeks masalah grafik sebagai pencocokan bipartit.
Peter Taylor

Jawaban:

8

Jelly , 11 byte

BUT€ŒpṬz0PẸ

Cobalah online!

Bagaimana itu bekerja

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

J , 30 byte

Semua kredit jatuh ke tangan rekan saya Marshall .

Fungsi awalan tersembunyi tanpa nama.

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

Cobalah online!

( @adalah komposisi fungsi)

#: antibase-2

|: mengubah urutan

(... )^:2 terapkan fungsi berikut dua kali:

1- Boolean meniadakan

>./ maksimal

@ dari

$ panjang sumbu

{. ambil (padding dengan nol) dari

|: argumen yang dialihkan

+./ .*"sihir penentu gila" *

[: don't hook (no-op - berfungsi untuk menyusun bagian sebelumnya dengan yang lain)


* Dalam kata-kata Marshall.

Adm
sumber
6

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

Pengembalian 0atau 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)))

Uji kasus

metode

Dengan array input A = [a 0 , a 1 , ..., a N-1 ] , kami mencari permutasi [a p [0] , p [1] , ..., p [N- 1] ] dari A dan bilangan bulat x ≤ N sedemikian rupa sehingga:

  • s = 1 + (a p [0] DAN 2 0 ) + (a p [1] DAN 2 1 ) + ... + (a p [x-1] DAN 2 x-1 ) = 2 x
  • dan s lebih besar dari elemen m terbesar dari A

Diformat dan dikomentari

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
sumber
4

Sekam , 14 byte

SöV≡ŀToṁ∂Pmo↔ḋ

Cobalah online!

Penjelasan

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
sumber
4

05AB1E , 23 22 20 byte

-1 byte terima kasih kepada Mr.Xcoder

Benar: 1, Salah: 0

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

Cobalah online!

Penjelasan:

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
sumber
3

Bahasa Wolfram (Mathematica) , 65 byte

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

Cobalah online!

Penjelasan

#~IntegerDigits~2

Kami mulai dengan mengubah semua input ke daftar biner.

n=PadLeft[...]

Lalu kita pad semua daftar itu dengan nol di sebelah kiri untuk membuat array persegi panjang. Hasilnya disimpan nuntuk nanti.

Permutations[...]

Yay, brute force, mari kita dapatkan semua kemungkinan permutasi input.

Tr/@...

Ini mendapatkan jejak untuk setiap permutasi, yaitu jumlah dari elemen diagonal dalam permutasi. Dengan kata lain, kami menjumlahkan MSB dari angka pertama, MSB di sebelah dari angka kedua dan seterusnya. Jika permutasi valid, semua ini akan menjadi 1 dan akan ada sebanyak 1 detik karena jumlah input terbesar lebar.

Max[...]

Kami mendapatkan jejak maksimum, karena jejak tidak pernah bisa lebih dari permutasi yang valid.

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

Sisi kanan hanyalah versi golf Length @ First @ n, yaitu ia mendapatkan lebar array persegi panjang, dan karenanya lebar nomor input terbesar. Kami ingin memastikan bahwa jejak beberapa permutasi sama dengan ini.

Martin Ender
sumber
3

PHP, 255 243 160 byte

-12 byte, mengeluarkan sortir
-83 byte (!) Berkat 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);}

Cobalah online!

Mencetak 1 untuk jujur, tidak untuk falsey.

Versi asli ungolfed:

<?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.
sumber
Saya belum mengujinya, tetapi tesis 158 byte harus melakukan hal yang sama: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
@Itus dan dengan demikian kita melihat betapa mengerikannya aku di codegolf. Dan mengapa sebagian besar pertanyaan memiliki jawaban bagus di PHP. (dan beberapa bahasa lainnya).
Jo.
Mengerikan untuk saat ini. Itu jawaban yang cukup bagus; dan keterampilan bermain golf disertai dengan pengalaman.
Titus
Tidak perlu untuk notasi string yang panjang, cukup gunakan sesuatu yang lain yang diterjemahkan menjadi "1" tetapi tidak bilangan bulat. Misalnya boolean true: die("1")die(!0).
manatwork
2

Lua 5.2, 85 byte

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

Ini menetapkan x menjadi fungsi yang menerima sejumlah variabel input (diharapkan menjadi bilangan bulat 32 bit), dan mencetak ke stdout baik "benar" atau "salah".

Pemakaian:

x(13, 83, 86, 29, 8, 87, 26, 21) -- Prints "false"
FulltimeLurker
sumber
1
Hmm, ini sepertinya gagal untuk beberapa kasus uji yang salah? [1,15,3,1]tampaknya kembali, truebukan falsemisalnya. Ini adalah kode Anda, kompilator TIO online. Dua kasus uji lainnya yang gagal adalah [1,7,1]dan [15,15,15]. Semua test case lainnya menghasilkan hasil yang benar.
Kevin Cruijssen
2

PHP, 121 byte

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);}

Cobalah online .

kerusakan

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
sumber
2

J , 49 byte

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

Apakah saya perlu menghitung juga 'g =.'? Saya siap menambahkannya.

Kata kerja eksplisit yang panjang kali ini. Saya mencoba yang diam-diam untuk algoritma yang sama, tetapi ternyata lebih lama dan lebih buruk dari ini. Jauh dari solusi Adám.

Penjelasan: (y adalah argumen fungsi yang tepat)

                                             ,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

Cobalah online!

Galen Ivanov
sumber
1

Python 3 , 126 120 byte

Disimpan 6 byte karena Tn. 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)

Cobalah online!

Halvard Hummel
sumber
Bisakah Anda menambahkan versi tanpa ungolfed?
Antti29
[0]+[...]Tidak ada gunanya bukan? any(g(x[:i]+x[i+1:],n-1)for i in range(len(x))if x[i]&2**n)harus cukup.
Tn. Xcoder
@ Mr.Xcoder Ya, saya kira saya sedang memikirkan fungsi max ketika saya menambahkannya
Halvard Hummel
1

Jelly , 17 byte

BUz0Œ!ŒD€Ẏ
ṀBo1eÇ

Tautan monadik yang mengambil daftar angka dan kembali 1(benar) atau 0(falsey).

Cobalah online!

Ini akan habis pada TIO untuk yang terlama dari masing-masing kasus uji.

Bagaimana?

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
sumber
1

R , 247 byte, 221 byte

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

Cobalah online!

Versi tidak disatukan

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
}

Saya menyadari bahwa cek tanpa-baris tidak perlu dengan drop=Fargumen. Juga menghapus beberapa ruang putih sial.

Menandai
sumber
1

PHP, 152 byte

<?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);

Mencetak apa pun untuk false, 1 untuk true.

Tidak Disatukan:

<?

// 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
sumber
0

C, 79 byte

b,i;main(a){for(;~scanf("%d",&a);i++)b|=a;puts("false\0true"+(b==(1<<i)-1)*6);}
PrincePolka
sumber
Bisakah Anda menambahkan penjelasan? Juga, try it onlinetautan akan bermanfaat.
Antti29
Beberapa tips saat bermain golf di C: 1 / dalam banyak tantangan (termasuk yang ini), Anda diizinkan untuk mengirimkan fungsi alih-alih program penuh, 2 / Anda harus menampilkan nilai kebenaran / falsey, ini bisa apa saja selama karena konsisten (Anda dapat menampilkan 0/1 bukannya "false" / "true"). Terakhir, kode ini sepertinya tidak berfungsi: [1, 7, 1]harus mengembalikan false, dan [52, 114, 61, 19, 73, 54, 83, 29]harus mengembalikan true
scottinet
Anda benar, salah saya
PrincePolka