# Automatic Pikmin Count

Inspired by the feature in Pikmin 4.

In Pikmin 4, you can have up to eight types of pikmin in an onion and up to three types of pikmin outside the onion. Each area recommends three types of pikmin to bring. The onion's interface has an "auto" button which selects pikmin in the following fashion:

• If possible, select equal amounts of each suggested pikmin type.
• If there aren't enough of one type, get all of them and equal amounts of the rest (e.g. if 30, 30, 30 isn't possible, it may do 20, 35, 35).
• If there aren't enough of all the suggested types combined, grab everything there is.
• If the number of pikmin to select isn't a multiple of three, it grabs more of the kind you have most of (e.g. if the number of pikmin of each type is 300, 200, 100 and it needs to select 100 pikmin, it selects 34, 33, 33)
• ...unless there's a tie (e.g. if the pikmin counts are 200, 200, 100 and it needs to grab 100 pikmin, it selects 33, 33, 34).
• If a tie needs to be broken arbitrarily (e.g. a three-way tie), select up to 1 more of the first tied type listed OR up to 1 less of the last tied type listed.

The challenge is to write a function or program that takes three inputs: the number of pikmin that can be brought out (an integer in $$\\left[0, 100\right]\$$), the number of pikmin of each type (eight positive integers), and the recommended pikmin types (three indices into the previous array). You can take the pikmin types as 0- or 1-based indices, and you may assume they are sorted. It should then return an array of eight numbers indicating how many pikmin of each type are to be selected, which will always have at least five 0's. This is , so your score is your answer's length.

## Test cases

Using 0-based indices

# to select; counts; indices => selections

100; [400, 450, 300, 250, 100, 30, 0, 10]; [0, 1, 2] => [33, 34, 33, 0, 0, 0, 0, 0]
100; [400, 450, 300, 250, 100, 30, 0, 10]; [3, 4, 5] => [0, 0, 0, 35, 35, 30, 0, 0]
37; [30, 30, 10, 20, 100, 5, 1, 100]; [0, 1, 3] => [12, 12, 0, 13, 0, 0, 0, 0]
38; [30, 30, 10, 20, 100, 5, 1, 100]; [0, 1, 3] => [13, 13, 0, 12, 0, 0, 0, 0]
38; [30, 30, 10, 20, 100, 5, 1, 100]; [0, 1, 2] => [14, 14, 10, 0, 0, 0, 0, 0]
39; [30, 30, 10, 20, 100, 5, 1, 100]; [0, 2, 3] => [15, 0, 10, 14, 0, 0, 0, 0]
39; [30, 30, 10, 20, 100, 5, 1, 100]; [0, 1, 2] => [15, 14, 10, 0, 0, 0, 0, 0]
37; [30, 30, 10, 20, 100, 5, 1, 100]; [2, 6, 7] => [0, 0, 10, 0, 0, 0, 1, 26]
0; [400, 450, 300, 250, 100, 30, 0, 10]; [5, 6, 7] => [0, 0, 0, 0, 0, 0, 0, 0]
20; [400, 450, 300, 250, 100, 30, 0, 10]; [5, 6, 7] => [0, 0, 0, 0, 0, 10, 0, 10]
100; [10, 10, 10, 10, 10, 10, 10, 10]; [1, 2, 3] => [0, 10, 10, 10, 0, 0, 0, 0]
29; [10, 10, 10, 10, 10, 10, 10, 10]; [1, 2, 3] => [0, 10, 10, 9, 0, 0, 0, 0]
29; [10, 12, 11, 10, 10, 10, 10, 10]; [1, 2, 3] => [0, 10, 10, 9, 0, 0, 0, 0]


## Sample Implementation

Ungolfed Swift implementation: TIO

• So, apply these rules, earlier mean more important: 0) Get enough item 1) be as average as possible. 2) same total amount mean same chosen amount. 3) more total amount, more chosen amount. 4) chosen amount non-increase. Right?
– l4m2
Commented Jul 29 at 15:25
• You mostly got it, but there's a couple of oddities like the fact that it chooses more of the kind you have least of if there's a tie for the kind you have most of. Commented Jul 29 at 15:38
• That's point 2) I mentioned, higher priority than 3)
– l4m2
Commented Jul 29 at 15:42
• I don’t understand what the full array indices add to the challenge versus just allowing the input to be the items selected by the indices? Am I missing something about the challenge? Commented Jul 30 at 19:31
• @Jonah You're right, the other five items in the array are completely irrelevant to the task. Commented Jul 31 at 0:36

# JavaScript (Node.js), 184 bytes

A=>m=>P=g=(n,i=8,...x)=>i--?[0,...Array(A[i]*m.includes(i))].map((_,j)=>g(n--,i,j,...x))&&R:x.map((e,j)=>i+=e*e*9+n*n*99+x.some((f,k)=>y=e<f?(Q=A[j]-A[k])?Q>0:9:0)*y)&&i>=P?R:(P=i,R=x)


Try it online!

Sightly timeout for large cases, n^3 it is

Penalty Function:

$$792\left(N-\sum_i x_i\right)^2 + 9\sum_i x_i^2 + \sum_{x_i

• 99**n seems to work but not sure about float issue
– l4m2
Commented Jul 29 at 16:59

# Charcoal, 87 79 bytes

Ｗ∧θΦζ⁻§ηκ№υκ«≔Ｅι§ηκεＦ›Ｌιθ≔⊟Φ⟦…ιθΦι⁻§ηλ⌊εΦι⁼§ηλ⌊εΦι⁼§ηλ⌈ε⟧⁼ＬλθιＦι⊞υκ≧⁻Ｌιθ»ＩＥη№υκ


Try it online! Link is to verbose version of code. Explanation:

Ｗ∧θΦζ⁻§ηκ№υκ«


Repeat until either enough Pikmin have been selected or there are no remaining Pikmin of any of the recommended types.

≔Ｅι§ηκε


Get a list of the counts of Pikmin of the recommended types where there are some remaining.

Ｆ›Ｌιθ


If there are more recommended types with some remaining then remaining Pikmin to select, then...

≔⊟Φ⟦…ιθΦι⁻§ηλ⌊εΦι⁼§ηλ⌊εΦι⁼§ηλ⌈ε⟧⁼Ｌλθι


... prefer the types with the most remaining, the types with the least remaining, the types that don't have the least remaining, or enough of the types, whichever first makes up the exact number remaining to select.

Ｆι⊞υκ≧⁻Ｌιθ»


Add one Pikmin of each of those types to the list of Pikmin selected and subtract the number of types from the number remaining to select.

ＩＥη№υκ


Count how many of each type of Pikmin were selected.

# Jelly, 33 bytes

r0ŒpḋṭSạ⁵ƊƊÐṂĠfLɗÐṀĠạ²SɗÞ
Ṭ¬a⁹ạÇḢ


A full program that accepts the (1-indexed) types, the numbers of available pikmin, and the request number and prints the resulting selection.

Try it online! (Too slow for the first test case.)

Or see the test-suite. (I have augmented the first two test cases to allow completion. I have also replaced the ⁵, which accesses the third program argument, in the code with ®, which accesses the register instead, to allow multiple test cases to run.)

#### How?

Ṭ¬a⁹ạÇḢ - Main Link: typeIndices, availableCounts
Ṭ       - untruth {typeIndices}
¬      - logical NOT {that} -> ZeroMask
ạ   - {that} absolute difference {availableCounts} -> ZeroedCounts

r0                        - {ZeroedCounts} inclusive range to zero (vectorises)
Œp                      - Cartisian product -> AllPossibleSelections
ÐṂ             - keep those minimal under:
ḋ                     -     dot-product with itself -> SumOfSquares
S                   -       sum
⁵                 -       program's third argument -> RequestNumber
ạ                  -       {sum} absolute difference {RequestNumber} -> Difference
ṭ                    -     tack -> [Difference, SumOfSquares]
-> AllPossibleSelections filtered to SumValidAndEqualish
Ġ      - group indices of {ZeroedCounts} by respective values -> OriginalGroups
ÐṀ       - keep those of {SumValidAndEqualish} maximal under: