Godimento massimo di birilli


17

Ti è stata data una borsa di birilli. Tutti sanno che per apprezzare di più i diversi sapori, è necessario ruotare tra i sapori.

Nozioni di base:

  1. Puoi mangiare solo 1 birillo alla volta
  2. L'ordine in cui mangi i tuoi birilli deve essere periodico.
  3. Ogni periodo non può contenere un sapore particolare più di una volta.
  4. La tua borsa ha solo tanti birilli. Non puoi mangiare più di un particolare sapore di fragole di quello che appare nella tua borsa.
  5. Vuoi mangiare più birilli che puoi (potrebbe non essere sempre possibile)

Esempi:

Diciamo che inizi con 3 birilli rossi, 2 blu e 3 verdi:

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)

Input Output

  • Viene passato un elenco non vuoto di numeri interi positivi per i conteggi dei colori. (L'esempio sopra sarebbe [3,2,3]).
  • È necessario restituire un elenco contenente ordini validi e ottimali.
  • Invece di usare i colori, utilizzerai gli indici dall'elenco di input. (L'ultimo esempio di output sopra sarebbe [2,0,1,2,0,1,2,0]).
  • L'output può essere 0 indicizzato o 1 indicizzato. I miei esempi saranno indicizzati 0

Casi 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

Questo è un , quindi rendi le tue soluzioni il più brevi possibile nella tua lingua preferita!


1
Può anche essere collegato a questo
Jonathan Allan il

2
@JonathanAllan ed è per questo che ho bisogno di un computer per garantire il mio divertimento birillo :)
Nathan Merrill

Risposte:


4

JavaScript (ES6), 177 175 byte

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)

Formattato e commentato

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

Formula usata

Di seguito una tabella che mostra come funziona la formula F(i, j) = minimum(value[j], value[i] + 1), qui coni = 0 e l'input [ 5, 2, 2 ].

Questa formula può essere interpretata come segue: per ogni tipo di Skittle, non possiamo selezionare più del numero del tipo meno disponibile più uno.

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

Casi test


Le riduzioni di inizializzazione della somma (0) e l' messere alla fine dei "loop" sono indotte dal golf o è proprio come JS?
Jonathan Allan,

@JonathanAllan Questo è il modo JS : il valore iniziale di reduce () si trova dopo il callback. Mettere m=0qui è indotto dal golf, perché non mi interessa il valore iniziale di questo circuito (verrà comunque sovrascritto). L'inizializzazione mè conveniente.
Arnauld

Ah, vedo che è più simile a una chiamata di funzione che a un loop (come la funzione di riduzione di Python ha un valore iniziale opzionale).
Jonathan Allan,

@JonathanAllan Sì, esattamente. [1,2,3].reduce((x, y) => x+y, 10)in JS sarebbe reduce(lambda x,y: x+y, [1,2,3], 10)in Python (penso), entrambi risultanti 16.
Arnauld

2

Gelatina , 22 byte

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

Indicizzazione basata su 1.

Provalo online!

Come?

Ripete ogni prefisso degli indici ordinati per valore decrescente una volta più di quanto sarebbe possibile ottenere con il sacchetto di birilli dato, quindi rimuove il birillo o i birilli finali da ciascuno di questi come necessario per renderli realizzabili e restituisce quello con il maggior numero di birilli .

Il numero che dovrebbe essere rimosso da una ripetizione periodica aggiuntiva è solo il numero con il conteggio minimo attraverso quel prefisso.

ỤṚ;\Ṛẋ"‘Ṣ$ḣ"Ç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

python3, 174 172 167 byte

Idea

Dato ad esempio 3 birilli rossi, 2 blu e 3 verdi, è possibile disporli in una griglia, ordinati per colore e quantità:

r g
r g b
r g b

Se si cerca di mangiare esattamente i birilli, si può almeno mangiare i birilli in totale, dove c è il numero di birilli nella colonna r-es, ad esempio per i = 2 si possono mangiare almeno 6 birilli.

r g
# # #
# # #

L'unica cosa che resta da fare è contare quanti birilli aggiuntivi possono essere consumati in un periodo incompleto.

golfed

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

Commentate

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

Provalo online!

Modifica: sostituito (i+1)con -~iper salvare 2 byte.

Modifica: -5 byte grazie a Dead Possum


Puoi cambiare sum(1for e in b if e[0]>c)in sum(c<e[0]for e in b). Converti True in 1 implicitamente e ti risparmierebbe 5 byte
Dead Possum il
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.