적절한 합으로 행렬 수 계산


12

Steenrod 대수학에 대해 Milnor 단위로 monomial을 곱할 때 알고리즘의 일부에는 특정 "허용 가능한 행렬"이 열거됩니다.

음이 아닌 정수 주어 두리스트는 r에 1 , ..., R의 ms의 1 , ..., s의 N , 음이 아닌 정수 X의 행렬

행렬

다음과 같은 경우 허용됩니다

  1. j 번째 열의 합은 s j 이하입니다 .

    열 합 제약

  2. 2의 거듭 제곱으로 가중치가 부여 된 i 번째 행의 합은 r i 보다 작거나 같습니다 .

    행 합 제약

직무

한 쌍의리스트 r 1 , ..., r ms 1 , s 1 , ..., s n 을 취하여 이들리스트에 허용되는 행렬의 수를 계산하는 프로그램을 작성하십시오. 필요한 경우 프로그램에서 선택적으로 m 및 n을 추가 인수로 사용할 수 있습니다.

  • 이 숫자는 원하는 형식으로 입력 할 수 있습니다. 예를 들어 목록으로 그룹화하거나 단항으로 인코딩하거나 다른 형식으로 인코딩 할 수 있습니다.

  • 출력은 양의 정수 여야합니다

  • 표준 허점이 적용됩니다.

채점

이것은 코드 골프입니다 : 바이트 단위의 최단 솔루션이 승리합니다.

예 :

들어 [2][1],이 허용 행렬이있다 :

예 1

들어 [4][1,1]세 허용 행렬이 있습니다

예 2

들어 [2,4][1,1]다섯 허용 행렬이있다 :

예 3

테스트 사례 :

   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는 행렬의 첫 번째 행과 열을 잃고 1부터 색인을 생성하고 == 대신 <=를 사용하면 정의를 이해하기가 더 쉽습니다.
피터 테일러

알겠습니다 방금 수학 교과서에서 정의를 복사했으며 실제로 해당 항목을 사용했습니다.
후드

답변:


3

자바 스크립트 (ES7), 163 바이트

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)

테스트 사례

NB :이 코드 조각에서 가장 시간이 많이 걸리는 두 가지 테스트 사례를 제거했지만 통과해야합니다.

댓글

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

젤리 , 26 바이트

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

카운트를 인쇄하는 S , R 을 취하는 전체 프로그램

온라인으로 사용해보십시오!

어떻게?

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

Wolfram Language (Mathematica) , 101 바이트

Mathematica가 이것을 정수에 대한 불평등 시스템으로 해결하도록하십시오. 나는 상징적 인 배열을 f설정하고 세 세트의 불평등을 극복합니다. Join@@에 대한 목록을 평평하게 Solve만듭니다.

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

온라인으로 사용해보십시오!


0

Mathematica 139 바이트

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

온라인으로 사용해보십시오

설명 : 각 r i 를 2의 거듭 제곱으로 나눈 다음 하나의 분해로 모든 튜플을 각 정수에 대해 2의 거듭 제곱으로 만들고 s i 목록에서 열 합계를 뺍니다 . 나머지 모든 항목을 양수로 만드는 튜플 수를 계산하십시오.


2
일반적으로 다른 사람들이 이미 해당 언어로 제출할 때까지 자신의 과제에 대답하지 않는 것이 좋습니다.
HyperNeutrino

@HyperNeutrino 좋은 생각이라고 생각하면 삭제할 수 있습니다. 이것은 신중하게 골프를 치는 것이 아니므로 다른 사람들이 더 잘 할 수 있습니다.
후드

3
그것이 해결할 수 있음을 증명할 수있는 것은 나쁘지 않지만 솔루션을 너무 빨리 망치는 것은 권장하지 않습니다. 아마 일주일 먼저 기다려야 할 수도 있습니다.
Outgolfer Erik

게시 한 후 삭제하거나 그대로 두어야합니까?
후드

나는 그것을 떠날 것입니다. 페이스 에릭 나는 그것이 아무것도 망치지 않는다고 생각한다.
피터 테일러
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.