최대한의 스키 틀 즐거움


17

스키 틀즈 가방을 받았습니다. 모두 다른 맛을 가장 높이 평가하려면 맛 사이를 회전해야한다는 것을 모두 알고 있습니다.

기초:

  1. 한 번에 하나의 스키 틀 만 먹을 수 있습니다
  2. 스키 틀을 먹는 순서는 주기적 이어야 합니다.
  3. 각 기간에는 특정 풍미가 두 번 이상 포함될 수 없습니다.
  4. 가방에는 스키 틀이 너무 많습니다. 당신은 당신의 가방에 나타나는 것보다 특별한 풍미의 더 많은 것을 먹을 수 없습니다.
  5. 가능한 많은 스키 틀을 먹고 싶어합니다 (항상 가능한 것은 아님)

예 :

3 개의 빨간색, 2 개의 파란색 및 3 개의 녹색 가장자리 잘라내기로 시작한다고 가정 해 보겠습니다.

R B G R B G R G       Invalid:  The last R must be followed by a B, not a G
R B G R B G R         Valid, but sub-optimal
R R R                 Valid, but sub-optimal
R G B R G B R G       Valid and optimal
G R B G R B G R       Also valid and optimal (there are multiple good solutions)

입출력

  • 색상 수에 대해 비어 있지 않은 양의 정수 목록이 전달됩니다. 위의 예는 [3,2,3]입니다.
  • 유효하고 최적의 순서가 포함 된 목록을 반환해야합니다.
  • 색상을 사용하는 대신 입력 목록의 색인을 사용합니다. (위의 마지막 출력 예는 [2,0,1,2,0,1,2,0])입니다.
  • 출력은 0 인덱스 또는 1 인덱스 일 수 있습니다. 내 예제는 0으로 색인됩니다

테스트 사례

1                          0
4                          0 0 0 0
4 1                        0 0 0 0
3 1                        0 1 0                   or  0 0 0
5 2 2                      0 1 2 0 1 2 0
2 3 5                      2 1 0 2 1 0 2 1         or  1 2 0 1 2 0 1 2
2 4 5                      2 1 2 1 2 1 2 1 2
3 4 5                      2 1 0 2 1 0 2 1 0 2 1   or  1 2 0 1 2 0 1 2 0 1 2
1 1 1 1 1 6                5 0 1 2 3 4 5           (lots of other solutions)
1 1 1 1 1 8                5 5 5 5 5 5 5 5
2 4 6 8                    3 2 1 3 2 1 3 2 1 3 2 1 3 2

이것은 이므로 원하는 언어로 솔루션을 최대한 짧게 만드십시오!



2
@JonathanAllan 그리고 그것이 나의 스키 틀 즐거움을 보장하기 위해 컴퓨터가 필요한 이유이다 :)
Nathan Merrill

답변:


4

자바 스크립트 (ES6), 177 175 바이트

a=>a.map((n,i)=>[n,l=i]).sort((a,b)=>a[0]-b[0]).reduce((P,x,i,a)=>(v=a.reduce((p,c,j)=>j<i?p:p+Math.min(c[0],x[0]+1),0))>m?[...Array(m=v)].map((_,k)=>a[l-k%(l+1-i)][1]):P,m=0)

형식화 및 의견

a => a                              // given an array a:
.map((n, i) => [n, l = i])          // map it to [value, index] arrays / set l = length - 1
.sort((a, b) => a[0] - b[0])        // sort it by values in ascending order
.reduce((P, x, i, a) =>             // for each reference entry x at position i:
  (v = a.reduce((p, c, j) =>        //   for each entry c at position j:
    j < i ?                         //     if c is before x:
      p                             //       keep the previous sum (which is 0)
    :                               //     else:
      p + Math.min(c[0], x[0] + 1), //       add minimum(value[j], value[i] + 1)
    0                               //   initialize the sum at 0
  )) > m ?                          //   if the new sum v is better than our current best m:
    [...Array(m = v)].map((_, k) => //     update m to v and update the result to an array
      a[l - k % (l + 1 - i)][1]     //     of length m filled with indices picked repeatedly
    )                               //     between i and l
  :                                 //   else:
    P,                              //     keep the previous result
  m = 0                             // start with best score m = 0
)                                   // the final result is returned by the outer reduce()

사용 된 공식

아래 공식 방법 테이블 보이고 F(i, j) = minimum(value[j], value[i] + 1)여기, 작동 i = 0및 입력 [ 5, 2, 2 ].

이 공식은 다음과 같이 해석 될 수 있습니다. 각 스키 틀 유형에 대해 최소 사용 가능한 유형 수에 1을 더한 수를 선택할 수 없습니다.

 j | Sorted    | value[j] | F(0, j) | Selected        | Output
   | input     |          |         | Skittles        | (starting from bottom left)
---+-----------+----------+---------+-----------------+-----------------------------
 0 | 2 2       |     2    |    2    | [2] [2]         | \
 1 | 1 1       |     2    |    2    | [1] [1]         |  > 0 1 2 0 1 2 0
 2 | 0 0 0 0 0 |     5    |    3    | [0] [0] [0] 0 0 | /

테스트 사례


합계 (0)의 초기화가 줄어들고 m"루프"의 끝에 골프가 유도 되는가 아니면 JS가 어떻게 되는가?
Jonathan Allan

@JonathanAllan 이것이 JS 방식입니다 . reduce ()의 초기 값은 콜백 뒤에 있습니다. m=0그러나이 루프의 초기 값에 신경 쓰지 않기 때문에 여기에 넣는 것은 골프에 의한 것입니다 (어쨌든 덮어 씁니다). 초기화 m가 편리합니다.
Arnauld

아아아 아아아 아아아 아아아 아아아 아아아 아아아 아아아 아아아 아아아 아아아 아아아가
Jonathan Allan

@JonathanAllan 그렇습니다. [1,2,3].reduce((x, y) => x+y, 10)JS reduce(lambda x,y: x+y, [1,2,3], 10)에서 파이썬에 있을 것 입니다 (제 생각에) 16.
Arnauld

2

젤리 , 22 바이트

ċЀṢN
ỤṚ;\Ṛẋ"‘Ṣ$ḣ"ÇLÞṪ

1 기반 인덱싱.

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

어떻게?

주어진 스키 틀 백에서 달성 할 수있는 것보다 한 번 더 내림차순으로 정렬 된 색인의 각 접두사를 반복 한 다음, 달성 할 수 있도록 필요한 각 스키 틀을 제거하고, 각 스키 틀을 달성 할 수 있도록합니다. .

한 번의 추가 정기 반복에서 제거해야하는 숫자는 해당 접두사에서 최소 개수를 가진 숫자입니다.

ỤṚ;\Ṛẋ"‘Ṣ$ḣ"ÇLÞṪ - Main link                   e.g. [6,4,2,8]
Ụ                - grade up: sort indices by value  [3,2,1,4]
 Ṛ               - reverse                          [4,1,2,3]
   \             - cumulative reduce with
  ;              -     concatenation (get prefixes) [[4],[4,1],[4,1,2],[4,1,2,3]]
    Ṛ            - reverse                          [[4,1,2,3],[4,1,2],[4,1],[4]]
         $       - last two links as a monad
       ‘         -     increment                    [7,5,3,9]
        Ṣ        -     sort                         [3,5,7,9]
      "          - zip with
     ẋ           -     list repetition              [[4,1,2,3,4,1,2,3,4,1,2,3],[4,1,2,4,1,2,4,1,2,4,1,2,4,1,2],[4,1,4,1,4,1,4,1,4,1,4,1,4,1],[4,4,4,4,4,4,4,4,4]]
            Ç    - call last link (1) as a monad    [-1,-1,-1,-1]
          "      - zip with
           ḣ     - head list to (remove excess)     [[4,1,2,3,4,1,2,3,4,1,2],[4,1,2,4,1,2,4,1,2,4,1,2,4,1],[4,1,4,1,4,1,4,1,4,1,4,1,4],[4,4,4,4,4,4,4,4]]
              Þ  - sort by
             L   -     length                       [[4,4,4,4,4,4,4,4],[4,1,2,3,4,1,2,3,4,1,2],[4,1,4,1,4,1,4,1,4,1,4,1,4],[4,1,2,4,1,2,4,1,2,4,1,2,4,1]]
               Ṫ - tail                             [4,1,2,4,1,2,4,1,2,4,1,2,4,1]

ċЀṢN - Link 1: head amounts (negative of skittle excess of each N+1 repeated period)
   Ṣ  - sort                                        [2,4,6,8]
 Ѐ   - for each mapped over right argument
ċ     - count                                       [1,1,1,1]
    N - negate                                      [-1,-1,-1,-1]

1

파이썬 3, 174 172 167 바이트

생각

예를 들어 3 개의 빨간색, 2 개의 파란색 및 3 개의 녹색 가장자리 잘라내 기가 있으면 색상과 양으로 정렬하여 격자로 정렬 할 수 있습니다.

r g
r g b
r g b

정확히 i 스키 틀을 먹으려 고하면 적어도 i * c 스키 틀을 모두 먹을 수있다. 여기서 c는 r 번째 열의 스키 틀 수, 예를 들어 i = 2 인 경우 적어도 6 개의 스키 틀을 먹을 수있다.

r g
# # #
# # #

남은 것은 불완전한 기간 동안 얼마나 많은 추가 스키 틀을 먹을 수 있는지 세는 것입니다.

골프

def f(a):
 r=range;f=m=0;s=r(len(a));b=sorted(zip(a,s))[::-1]
 for i in s:
  c=b[i][0];n=-~i*c+sum(c<e[0]for e in b)
  if n>m:f,m=i+1,n
 return[b[j%f][1]for j in r(m)]

댓글

def f(a):
    r = range;
    f = m = 0;                          - Some variables we need later on
    s = r(len(a));                      - Integers from 0 to (num_skittles - 1)
    b = sorted(zip(a,s))[::-1]          - Zip with s to remember initial order,
                                          then sort and reverse
    for i in s:
        c = b[i][0]
        n = (i+1)*c                     - If we attempt to eat i different skittles,
                                          we can surely eat (i+1)*c skittles.
          + sum(1 for e in b if e[0]>c) - The additional sum corresponds to an incomplete period.
        if n>m:                         - If a better way of eating skittles is found:
            f,m = i+1,n                 - update variables
    return [b[j%f][1] for j in r(m)]

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

편집 : 2 바이트를 절약하기 위해 대체 (i+1)되었습니다 -~i.

편집 : Dead Possum 덕분에 -5 바이트


당신은 변경할 수 있습니다 sum(1for e in b if e[0]>c)sum(c<e[0]for e in b). True를 암시 적으로 1로 변환하고 5 바이트를 절약합니다.
Dead Possum
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.