Hitung jumlah matriks dengan jumlah yang sesuai


12

Ketika mengalikan monomial dalam basis Milnor untuk aljabar Steenrod, bagian dari algoritma melibatkan enumerasi "matriks yang diijinkan" tertentu.

Diberikan dua daftar bilangan bulat non-negatif r 1 , ..., r m dan s 1 , ..., s n , sebuah matriks bilangan bulat non-negatif X

sebuah matriks

diizinkan jika

  1. Jumlah kolom j kurang dari atau sama dengan s j :

    kendala jumlah kolom

  2. Jumlah baris ke-i yang diberi bobot oleh kekuatan 2 kurang dari atau sama dengan r i :

    batasan jumlah baris

Tugas

Tulis sebuah program yang mengambil sepasang daftar r 1 , ..., r m dan s 1 , s 1 , ..., s n dan menghitung jumlah matriks yang diijinkan untuk daftar ini. Program Anda secara opsional dapat menggunakan m dan n sebagai argumen tambahan jika perlu.

  • Angka-angka ini dapat dimasukkan dalam format apa pun yang disukai, misalnya dikelompokkan ke dalam daftar atau disandikan di unary, atau apa pun.

  • Output harus berupa bilangan bulat positif

  • Celah standar berlaku.

Mencetak gol

Ini adalah kode golf: Solusi terpendek dalam byte yang menang.

Contoh:

Untuk [2]dan [1], ada dua matriks yang diijinkan:

Contoh 1

Untuk [4]dan [1,1]ada tiga matriks yang diijinkan:

contoh 2

Untuk [2,4]dan [1,1]ada lima matriks yang diijinkan:

contoh 3

Kasus uji:

   Input: [1], [2]
   Output: 1

   Input: [2], [1]
   Output: 2

   Input: [4], [1,1]
   Output: 3

   Input: [2,4], [1,1]   
   Output: 5      

   Input: [3,5,7], [1,2]
   Output: 14

   Input: [7, 10], [1, 1, 1]
   Output: 15       

   Input: [3, 6, 16, 33], [0, 1, 1, 1, 1]
   Output: 38      

   Input: [7, 8], [3, 3, 1]
   Output: 44

   Input: [2, 6, 15, 18], [1, 1, 1, 1, 1]
   Output: 90       

   Input: [2, 6, 7, 16], [1, 3, 2]
   Output: 128

   Input: [2, 7, 16], [3, 3, 1, 1]
   Output: 175

1
IMO definisi akan lebih mudah dipahami jika Anda kehilangan baris dan kolom pertama dari matriks, indeks dari 1, dan gunakan <= bukannya ==.
Peter Taylor

Oke, akan lakukan. Saya baru saja menyalin definisi dari buku teks matematika dan itu sebenarnya digunakan untuk entri tersebut.
Hood

Jawaban:


3

JavaScript (ES7), 163 byte

f=([R,...x],s)=>1/R?[...Array(R**s.length)].reduce((k,_,n)=>(a=s.map((_,i)=>n/R**i%R|0)).some(c=>(p+=c<<++j)>R,p=j=0)?k:k+f(x,s.map((v,i)=>v-a[i])),0):!/-/.test(s)

Uji kasus

NB : Saya telah menghapus dua test case yang paling memakan waktu dari snippet ini, tetapi mereka harus lulus juga.

Berkomentar

f = (                               // f = recursive function taking:
  [R,                               //   - the input array r[] splitted into:
      ...x],                        //     R = next element / x = remaining elements
  s                                 //   - the input array s[]
) =>                                //
  1 / R ?                           // if R is defined:
    [...Array(R**s.length)]         //   for each n in [0, ..., R**s.length - 1],
    .reduce((k, _, n) =>            //   using k as an accumulator:
      (a =                          //     build the next combination a[] of
        s.map((_, i) =>             //     N elements in [0, ..., R - 1]
          n / R**i % R | 0          //     where N is the length of s[]
        )                           //
      ).some(c =>                   //     for each element c in a[]:
        (p += c << ++j)             //       increment j; add c * (2**j) to p
        > R,                        //       exit with a truthy value if p > R
        p = j = 0                   //       start with p = j = 0
      ) ?                           //     end of some(); if truthy:
        k                           //       just return k unchanged
      :                             //     else:
        k +                         //       add to k the result of
        f(                          //       a recursive call to f() with:
          x,                        //         the remaining elements of r[]
          s.map((v, i) => v - a[i]) //         s[] updated by subtracting the values of a[]
        ),                          //       end of recursive call
      0                             //     initial value of the accumulator k
    )                               //   end of reduce()
  :                                 // else:
    !/-/.test(s)                    //   return true if there's no negative value in s[]

1

Jelly , 26 byte

UḄ€Ḥ>⁴
0rŒpṗ⁴L¤µS>³;ÇẸµÐḟL

Program penuh mengambil S , R yang mencetak hitungan

Cobalah online!

Bagaimana?

UḄ€Ḥ>⁴ - Link 1, row-wise comparisons: list of lists, M
U      - upend (reverse each)
 Ḅ€    - convert €ach from binary (note bit-domain is unrestricted, e.g. [3,4,5] -> 12+8+5)
   Ḥ   - double (vectorises) (equivalent to the required pre-bit-shift by one)
     ⁴ - program's 2nd input, R
    >  - greater than? (vectorises)

0rŒpṗ⁴L¤µS>³;ÇẸµÐḟL - Main link: list S, list R
0r                  - inclusive range from 0 to s for s in S
  Œp                - Cartesian product of those lists
       ¤            - nilad followed by link(s) as a nilad:
     ⁴              -   program's 2nd input, R
      L             -   length
    ṗ               - Cartesian power = all M with len(R) rows & column values in [0,s]
        µ      µÐḟ  - filter discard if:
         S          -   sum (vectorises) = column sums
           ³        -   program's 1st input, S
          >         -   greater than? (vectorises) = column sum > s for s in S
             Ç      -   call the last link (1) as a monad = sum(2^j × row) > r for r in R
            ;       -   concatenate
              Ẹ     -   any truthy?
                  L - length

1

Bahasa Wolfram (Mathematica) , 101 byte

Biarkan Mathematica menyelesaikannya sebagai sistem ketidaksetaraan atas bilangan bulat. Saya mengatur array simbolis di fdan utas tiga set ketidaksetaraan. Join@@hanya meratakan daftar untuk Solve.

Length@Solve[Join@@Thread/@{Tr/@(t=f~Array~{q=(l=Length)@#2,l@#})<=#2,2^Range@q.t<=#,t>=0},Integers]&

Cobalah online!


0

Mathematica 139 byte

Tr@Boole[k=Length[a=#]+1;AllTrue[a-Rest[##+0],#>=0&]&@@@Tuples[BinCounts[#,{2r~Prepend~0}]&/@IntegerPartitions[#,All,r=2^Range@k/2]&/@#2]]&

Cobalah online

Penjelasan: Partisi masing-masing r i menjadi kekuatan 2 dan kemudian buat semua tupel dengan satu dekomposisi menjadi kekuatan dua untuk setiap bilangan bulat, kurangi total kolom dari daftar s i . Hitung jumlah tupel yang membuat semua entri yang tersisa positif.


2
biasanya tidak disarankan untuk menjawab tantangan Anda sendiri sampai orang lain sudah mengirimkan dalam bahasa itu.
HyperNeutrino

@HyperNeutrino saya dapat menghapusnya jika Anda pikir itu ide yang bagus. Ini bukan golf super hati-hati, jadi sangat mungkin orang lain bisa melakukan lebih baik.
Hood

3
Meskipun bukan hal yang buruk untuk dapat membuktikan itu dapat dipecahkan, saya tidak merekomendasikan memanjakan solusinya dengan cepat. Mungkin menunggu seminggu dulu atau apalah.
Erik the Outgolfer

Jadi haruskah saya menghapusnya atau meninggalkannya sekarang setelah saya mempostingnya?
Hood

Saya akan meninggalkannya. Pace Erik Saya tidak berpikir itu merusak apa pun: keberadaan solusi jelas dari kenyataan bahwa matriks sehubungan dengan batasan jumlah kolom terbatas dan mudah dihasilkan.
Peter Taylor
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.