| Bytes | Lang | Time | Link |
|---|---|---|---|
| 033 | Jelly | 240730T211150Z | Jonathan |
| 079 | Charcoal | 240729T230836Z | Neil |
| 184 | JavaScript Node.js | 240729T163719Z | l4m2 |
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
a⁹ - {ZeroMask} logical AND {availableCounts} (vectorises, implicit masks of 1)
ạ - {that} absolute difference {availableCounts} -> ZeroedCounts
Ç - call Link 1 as a monad
Ḣ - head
r0ŒpḋṭSạ⁵ƊƊÐṂĠfLɗÐṀĠạ²SɗÞ - Link 1: ZeroedCounts
r0 - {ZeroedCounts} inclusive range to zero (vectorises)
Œp - Cartisian product -> AllPossibleSelections
ÐṂ - keep those minimal under:
Ɗ - last three links as a monad:
ḋ - dot-product with itself -> SumOfSquares
Ɗ - last three links as a monad:
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:
ɗ - last three links as a dyad - f(Potential, OriginalGroups):
Ġ - group indices of {Potential} by respective values
f - filter keep {OriginalGroups}
L - length
Þ - sort by:
ɗ - last three links as a dyad - f(Potential, ZeroedCounts}
ạ - {Potential} absolute difference {ZeroedCounts} (vectorises)
² - squared
S - sum
Charcoal, 87 79 bytes
W∧θΦζ⁻§ηκ№υκ«≔Eι§ηκεF›Lιθ≔⊟Φ⟦…ιθΦι⁻§ηλ⌊εΦι⁼§ηλ⌊εΦι⁼§ηλ⌈ε⟧⁼LλθιFι⊞υκ≧⁻Lιθ»IEη№υκ
Try it online! Link is to verbose version of code. Explanation:
W∧θΦζ⁻§ηκ№υκ«
Repeat until either enough Pikmin have been selected or there are no remaining Pikmin of any of the recommended types.
≔Eι§ηκε
Get a list of the counts of Pikmin of the recommended types where there are some remaining.
F›Lιθ
If there are more recommended types with some remaining then remaining Pikmin to select, then...
≔⊟Φ⟦…ιθΦι⁻§ηλ⌊εΦι⁼§ηλ⌊εΦι⁼§ηλ⌈ε⟧⁼Lλθι
... 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.
Fι⊞υκ≧⁻Lιθ»
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.
IEη№υκ
Count how many of each type of Pikmin were selected.
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)
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<x_j}\left[0,9,1\right]_{\text{sgn}\left(A_i-A_j\right)-1}$$