최대한의 스키 틀 즐거움


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.