Plaisir maximal

17

On vous a donné un sac de quilles. Tout le monde sait que pour apprécier le plus les différentes saveurs, vous devez alterner entre les saveurs.

Bases:

  1. Vous ne pouvez manger qu'une quille à la fois
  2. L'ordre de manger vos quilles doit être périodique.
  3. Chaque période ne peut pas contenir plus d'une fois une saveur particulière.
  4. Votre sac n'a que tant de quilles. Vous ne pouvez pas manger plus d'une saveur particulière de quille que celle qui apparaît dans votre sac.
  5. Vous voulez manger autant de quilles que vous le pouvez (ce n'est pas toujours possible)

Exemples:

Disons que vous commencez avec 3 quilles rouges, 2 bleues et 3 vertes:

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)

Entrée sortie

  • Vous obtenez une liste non vide d'entiers positifs pour le nombre de couleurs. (L'exemple ci-dessus serait [3,2,3]).
  • Vous devez renvoyer une liste contenant une commande valide et optimale.
  • Au lieu d'utiliser des couleurs, vous utiliserez les indices de la liste d'entrée. (Le dernier exemple de sortie ci-dessus serait[2,0,1,2,0,1,2,0] ).
  • Votre sortie peut être indexée 0 ou indexée 1. Mes exemples seront indexés 0

Cas de test

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

Ceci est un , alors faites vos solutions aussi courtes que possible dans votre langue préférée!

Nathan Merrill
la source
1
Peut aussi être lié à cela
Jonathan Allan
2
@JonathanAllan et c'est pourquoi j'ai besoin d'un ordinateur pour assurer mon plaisir de quilles :)
Nathan Merrill

Réponses:

4

JavaScript (ES6), 177 175 octets

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)

Formaté et commenté

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()

Formule utilisée

Vous trouverez ci-dessous un tableau montrant le fonctionnement de la formule F(i, j) = minimum(value[j], value[i] + 1), ici avec i = 0et l'entrée [ 5, 2, 2 ].

Cette formule peut être interprétée comme suit: pour chaque type de quille, nous ne pouvons sélectionner plus que le numéro du type le moins disponible plus un.

 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 | /

Cas de test

Arnauld
la source
Les initialisations réduites de la somme (0) et le fait d' mêtre à la fin des "boucles" sont-ils induits par le golf ou est-ce juste la façon dont JS est?
Jonathan Allan
@JonathanAllan C'est la manière JS : la valeur initiale de Reduce () est située après le rappel. La mise m=0ici est induite par le golf, cependant, car je ne me soucie pas de la valeur initiale de cette boucle (elle sera de toute façon écrasée). L'initialisation mest pratique.
Arnauld
Ah je vois que cela ressemble plus à un appel de fonction qu'à une boucle (comme la fonction de réduction de Python a une valeur initiale facultative).
Jonathan Allan
@JonathanAllan Oui, exactement. [1,2,3].reduce((x, y) => x+y, 10)en JS serait reduce(lambda x,y: x+y, [1,2,3], 10)en Python (je pense), les deux résultant en 16.
Arnauld
2

Gelée , 22 octets

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

Indexation basée sur 1.

Essayez-le en ligne!

Comment?

Répète chaque préfixe des index triés par valeur descendant une fois de plus que ce qui serait réalisable avec le sac de quilles donné, puis supprime la ou les quilles finales de chacun d'entre eux si nécessaire pour les rendre réalisables, et renvoie celle avec le plus de quilles .

Le nombre qui doit être supprimé d'une répétition périodique supplémentaire est simplement le nombre avec le nombre minimum à travers ce préfixe.

ỤṚ;\Ṛẋ"‘Ṣ$ḣ"Ç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]
Jonathan Allan
la source
1

Python3, 174 172 167 octets

Idée

Étant donné par exemple 3 quilles rouges, 2 bleues et 3 vertes, on peut les disposer dans une grille, triées par couleur et quantité:

r g
r g b
r g b

Si l'on essaie de manger exactement i quilles, on peut au moins manger i * c quilles au total, où c est le nombre de quilles dans la colonne r, par exemple pour i = 2 on peut manger au moins 6 quilles.

r g
# # #
# # #

La seule chose qui reste à faire est de compter combien de quilles supplémentaires peuvent être mangées par une période incomplète.

Golfé

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)]

Commenté

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)]

Essayez-le en ligne!

Modifier: remplacé (i+1)par -~ipour enregistrer 2 octets.

Edit: -5 octets grâce à Dead Possum

Elvorfirilmathredia
la source
Vous pouvez changer sum(1for e in b if e[0]>c)pour sum(c<e[0]for e in b). Cela convertirait True à 1 implicitement et vous ferait économiser 5 octets
Dead Possum