Oblicz liczbę macierzy z odpowiednimi sumami

12

Podczas mnożenia monomialów w podstawie Milnora dla algebry Steenroda część algorytmu obejmuje wyliczenie pewnych „dopuszczalnych macierzy”.

Biorąc pod uwagę dwie listy nieujemnych liczb całkowitych r 1 , ..., r m oraz s 1 , ..., s n , macierz nieujemnych liczb całkowitych X

matryca

jest dozwolone, jeśli

  1. Suma kolumnie j jest mniejsza lub równa s j :

    ograniczenie sumy kolumn

  2. Suma-tego rzędu ważony potęgi 2 jest mniejsza niż lub równa r I :

    ograniczenie sum wierszy

Zadanie

Napisz program, który pobiera parę list r 1 , ..., r m i s 1 , s 1 , ..., s n i oblicza liczbę dopuszczalnych macierzy dla tych list. Twój program może opcjonalnie wziąć m i n jako dodatkowe argumenty, jeśli zajdzie taka potrzeba.

  • Liczby te mogą być wprowadzane w dowolnym formacie, który lubią, na przykład pogrupowane w listy lub zakodowane jako jednoargumentowe lub cokolwiek innego.

  • Wyjście powinno być dodatnią liczbą całkowitą

  • Obowiązują standardowe luki.

Punktacja

To jest kod golfowy: wygrywa najkrótsze rozwiązanie w bajtach.

Przykłady:

Dla [2]i [1]istnieją dwie dopuszczalne matryce:

Przykład 1

Dla [4]i [1,1]istnieją trzy dopuszczalne macierze:

przykład 2

Dla [2,4]i [1,1]istnieje pięć dopuszczalne macierze:

przykład 3

Przypadki testowe:

   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
kaptur
źródło
1
IMO łatwiej byłoby zrozumieć definicję, jeśli stracisz pierwszy wiersz i kolumnę macierzy, indeks od 1 i użyjesz <= zamiast ==.
Peter Taylor
OK, zrobi. Właśnie skopiowałem definicję z podręcznika do matematyki i miał on rzeczywiste zastosowanie w tych wpisach.
Hood

Odpowiedzi:

3

JavaScript (ES7), 163 bajty

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)

Przypadki testowe

Uwaga : usunąłem dwa najbardziej czasochłonne przypadki testowe z tego fragmentu, ale one również powinny przejść pomyślnie.

Skomentował

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[]
Arnauld
źródło
1

Galaretka , 26 bajtów

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

Pełny program przyjmujący S , R, który drukuje liczbę

Wypróbuj online!

W jaki sposób?

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
Jonathan Allan
źródło
1

Wolfram Language (Mathematica) , 101 bajtów

Niech Mathematica rozwiąże to jako system nierówności względem liczb całkowitych. Ustawiłem tablicę symboliczną fi prześledziłem trzy zestawy nierówności. Join@@po prostu spłaszcza listę Solve.

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

Wypróbuj online!

Kelly Lowder
źródło
0

Mathematica 139 bajtów

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

Wypróbuj online

Objaśnienie: Przegrody każdy z R ı do potęgi 2, a następnie sprawia, że wszystkie krotki z jednym do rozkładu sił dwa dla każdej liczby całkowitej, odejmowanie sumy kolumn z listy z s i . Policz liczbę krotek, które sprawiają, że wszystkie pozostałe wpisy są dodatnie.

kaptur
źródło
2
zazwyczaj odradza się podejmowanie własnych wyzwań, dopóki inni nie podadzą się już w tym języku.
HyperNeutrino,
@HyperNeutrino Mogę to usunąć, jeśli uważasz, że to dobry pomysł. To nie jest bardzo starannie gra w golfa, więc jest bardzo prawdopodobne, że inni mogą zrobić lepiej.
Hood
3
Chociaż udowodnienie, że jest to możliwe do rozwiązania, nie jest złą rzeczą, ale nie polecam psucia rozwiązania tak szybko. Może poczekać tydzień lub coś innego.
Erik the Outgolfer
Czy powinienem go usunąć, czy zostawić teraz, gdy go opublikowałem?
Hood
Zostawiłbym to. Pace Erik Nie sądzę, żeby to wszystko zepsuło: istnienie rozwiązania jest oczywiste z faktu, że macierze uwzględniające ograniczenie sumy kolumn są skończone i łatwe do wygenerowania.
Peter Taylor