Maximaler Kegelgenuss

17

Du hast eine Tüte Kegel bekommen. Jeder weiß, dass man zwischen den Geschmacksrichtungen wechseln muss, um die verschiedenen Geschmacksrichtungen am meisten zu schätzen.

Grundlagen:

  1. Sie können jeweils nur 1 Kegel essen
  2. Die Reihenfolge, in der Sie Ihre Kegel essen, muss regelmäßig sein.
  3. Jede Periode kann einen bestimmten Geschmack nur einmal enthalten.
  4. Ihre Tasche hat nur so viele Kegel. Sie können nicht mehr von einem bestimmten Geschmack von Kegel essen, als in Ihrer Tasche erscheint.
  5. Sie möchten so viele Kegel wie möglich essen (es ist möglicherweise nicht immer möglich)

Beispiele:

Nehmen wir an, Sie beginnen mit 3 roten, 2 blauen und 3 grünen Kegeln:

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

  • Ihnen wird eine nicht leere Liste positiver Ganzzahlen für die Farbanzahl übergeben. (Das obige Beispiel wäre [3,2,3]).
  • Sie müssen eine Liste mit einer gültigen und optimalen Bestellung zurücksenden.
  • Anstatt Farben zu verwenden, verwenden Sie die Indizes aus der Eingabeliste. (Das letzte Beispiel oben wäre [2,0,1,2,0,1,2,0]).
  • Ihre Ausgabe kann 0-indiziert oder 1-indiziert sein. Meine Beispiele werden mit 0 indiziert

Testfälle

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

Dies ist ein , also machen Sie Ihre Lösungen so kurz wie möglich in Ihrer Lieblingssprache!

Nathan Merrill
quelle
1
Auch können verknüpft werden diese
Jonathan Allan
2
@ JonathanAllan und deshalb brauche ich einen Computer, um mein Kegelvergnügen zu gewährleisten :)
Nathan Merrill

Antworten:

4

JavaScript (ES6), 177 bis 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)

Formatiert und kommentiert

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

Verwendete Formel

Unten finden Sie eine Tabelle, in der die Funktionsweise der Formel F(i, j) = minimum(value[j], value[i] + 1), hier mit i = 0und die Eingabe dargestellt sind [ 5, 2, 2 ].

Diese Formel kann wie folgt interpretiert werden: Für jeden Kegel-Typ können wir nicht mehr als die Anzahl der am wenigsten verfügbaren Typen plus eins auswählen.

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

Testfälle

Arnauld
quelle
Werden die Reduktionsinitialisierungen der Summe (0) und mdas Ende der "Loops" golfinduziert oder ist es einfach so, wie JS ist?
Jonathan Allan
@ JonathanAllan Das ist der JS-Weg : Der Anfangswert von redu () befindet sich nach dem Rückruf. Das Putten m=0hier ist jedoch golfbedingt, da mir der Anfangswert dieser Schleife egal ist (er wird sowieso überschrieben). Dort zu initialisieren mist praktisch.
Arnauld
Ah, ich sehe, es ist eher ein Funktionsaufruf als eine Schleife (so wie Pythons Reduktionsfunktion einen optionalen Anfangswert hat).
Jonathan Allan
@ JonathanAllan Ja, genau. [1,2,3].reduce((x, y) => x+y, 10)in JS wäre reduce(lambda x,y: x+y, [1,2,3], 10)in Python (ich denke), beide resultieren in 16.
Arnauld
2

Jelly , 22 Bytes

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

1-basierte Indizierung.

Probieren Sie es online!

Wie?

Wiederholt jedes Präfix der Indizes, sortiert nach absteigendem Wert, um ein weiteres Mal, als dies mit der angegebenen Kegeltüte möglich wäre. Entfernt dann das oder die endgültigen Kegeln aus jedem dieser Indizes, um sie erreichbar zu machen, und gibt denjenigen mit den meisten Kegeln zurück .

Die Zahl, die aus einer zusätzlichen periodischen Wiederholung entfernt werden sollte, ist nur die Zahl mit der Mindestanzahl für dieses Präfix.

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

Python3, 174 172 167 Bytes

Idee

Bei zB 3 roten, 2 blauen und 3 grünen Kegeln kann man sie in einem Raster anordnen, sortiert nach Farbe und Menge:

r g
r g b
r g b

Wenn man versucht, genau i Kegel zu essen, kann man mindestens i * c Kegel insgesamt essen, wobei c die Anzahl der Kegel in der r-ten Spalte ist, z. B. für i = 2 kann man mindestens 6 Kegel essen.

r g
# # #
# # #

Sie müssen nur noch zählen, wie viele zusätzliche Kegel in einem unvollständigen Zeitraum gegessen werden können.

Golf gespielt

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

Kommentiert

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

Probieren Sie es online!

Bearbeiten: Ersetzt (i+1)durch -~i, um 2 Bytes zu sparen.

Edit: -5 Bytes dank Dead Possum

Elvorfirilmathredia
quelle
Sie können ändern , sum(1for e in b if e[0]>c)zu sum(c<e[0]for e in b). Es würde True implizit in 1 konvertieren und Sie 5 Bytes sparen
Dead Possum