| Bytes | Lang | Time | Link |
|---|---|---|---|
| 066 | APLNARS | 250211T072816Z | Rosario |
| 146 | Python 3.10 | 250207T151358Z | SevC_10 |
| nan | Haskell | 250207T193247Z | ShapeOfM |
| 096 | Python | 250207T154641Z | Mukundan |
| 017 | Jelly | 250207T215416Z | Jonathan |
| 070 | Charcoal | 250207T165717Z | Neil |
| 459 | Python3 | 250207T151329Z | Ajax1234 |
| 039 | K ngn/k | 250207T112823Z | ovs |
| 9895 | jq | 250207T100819Z | mousetai |
| 095 | JavaScript Node.js | 250207T052255Z | l4m2 |
APL(NARS), 66 chars
{⌊/+/¨+/¨¨⍺{⍺,(k↓⍵),2÷⍨⍵[⍳k←⌊2÷⍨≢⍵]}¨¨{x[⍵;]⊂y}¨⍳≢x←11 1‼≢y←⍵[⍋⍵]}
This above function has a right input ⍵ that is the list of pizza prices, and a left input ⍺ that is the delivery fee, and would return the min price for these inputs.
The function would order the right input ⍵ in ⍵[⍋⍵] and find all contigues partition in {x[⍵;]⊂y}¨⍳≢x←11 1‼≢y
of the set y←⍵[⍋⍵], then would add in each element of each element of the set result the left input ⍺ the delivery fee
and make the reduction of price in ⍺{⍺,(k↓⍵),2÷⍨⍵[⍳k←⌊2÷⍨≢⍵]}, than find the sum of each spedition +/¨¨ and the sum of
each separate set of speditions +/¨ return the min of that array ⌊/.
Note: I don't know if this code is 100% right {x[⍵;]⊂y}¨⍳≢x←11 1‼≢y, than it seems {⍺,(k↓⍵),2÷⍨⍵[⍳k←⌊2÷⍨≢⍵]} make what I imagine
and this {⍺,(k↓⍵),⍵[⍳k←⌊2÷⍨≢⍵]÷2} make something different.
Test:
f←{⌊/+/¨+/¨¨⍺{⍺,(k↓⍵),2÷⍨⍵[⍳k←⌊2÷⍨≢⍵]}¨¨{x[⍵;]⊂y}¨⍳≢x←11 1‼≢y←⍵[⍋⍵]}
6 f 20
26
6 f 20 30
46
2 f 10 20 30 40 50 60 70 80
288
5 f 16 30 18 10 14 12 20 28
126
Python 3.10, more_itertools, 146 bytes
The solution uses the external library more_itertools. It can be installed with the command pip install more-itertools.
The lambda function takes as input arguments the list of pizza prices and the delivery fee; it returns the minimum total cost.
from more_itertools import*
f=lambda p,s:min([sum(s+sum(sorted(o)[:len(o)//2])/2+sum(sorted(o)[len(o)//2:])for o in g)for g in set_partitions(p)])
Try it online! with the library original source code, thanks to @tata. Here are the results for the test cases:
6 [20] -> 26.0 True
6 [20, 30] -> 46.0 True
6 [20, 20] -> 36.0 True
12 [20, 2200] -> 2222.0 True
6 [20, 30, 40] -> 86.0 True
6 [20, 30, 60] -> 106.0 True
6 [20, 40, 60] -> 112.0 True
6 [20, 30, 40, 50] -> 121.0 True
6 [20, 30, 60, 70] -> 152.0 True
4 [20, 30, 20, 20, 30] -> 103.0 True
4 [30, 30, 20, 20, 30] -> 113.0 True
5 [88, 88, 88, 88, 8, 8] -> 286.0 True
5 [20, 20, 20, 20, 20, 20, 20] -> 115.0 True
100 [10, 20, 10, 20, 10, 20, 10, 20] -> 200.0 True
2 [10, 20, 30, 40, 50, 60, 70, 80] -> 288.0 True
5 [16, 30, 18, 10, 14, 12, 20, 28] -> 126.0 True
Haskell, 174 161 144 bytes
import Data.List
d%x=d+sum x-sum(take(length x`div`2)x)/2
f d=minimum.map(sum.map(d%)).p.sort
p(x:y)=(([x]:)<$>p y)++[(x:a):b|a:b<-p y]
p _=[[]]
The operative function is f, which takes the delivery fee and then the list of pizza prices.
I'm not much experienced at competitive golf; I suspect a great deal more can be shaved off. The import of sort is frustrating. The logic for generating all contiguous partitionings of the sorted list is taken from here, but of course I've scrunched it quite badly. By my count I'm only breaking-even by using ? instead of `div`.
edit: removed (sort) on line one. Also found a denser way of computing the costs.
I'm using the GHC2021 "language", with GHC version 9.10.1.
edit: removed 17 bytes by matteo_c, who implemented a way to avoid splitAt and the ensuing tuple-unpacking.
I've spent way too much time trying to beat 144. There's lots of little ways to factor out redundancies, or even inline %, but none of them seem to earn their keep.
Python, 101 99 96 bytes
-2 bytes thanks to @Jonathan Allan
-3 bytes thanks to @tata
f=lambda x,y,z=0,i=0:min([(z:=z+n-i%2*x[i//2]/2)+y+f(x[(i:=i+1):],y)for n in x.sort()or x]or[0])
Jelly, 17 bytes
ṢṚŒṖŒHHÐeFSƲ€€+§Ṃ
A dyadic Link that accepts the pizza prices on the left as a list of even integers and the delivery price on the right as an integer and yields the minimal cost incurrable by optimally ordering.
Try it online! Or see the test-suite.
How?
There is never any point in making an order which is not a contiguous sublist of an ordered list of the pizza prices since swapping any skipped one (from another order they are therefore currently in) with the next most expensive pizza in the order will either be cheaper or will be the same cost.
ṢṚŒṖŒHHÐeFSƲ€€+§Ṃ - Link: list of integers, PizzaPrices; integer DeliveryCost
Ṣ - sort {PizzaPrices}
Ṛ - reverse {that}
ŒṖ - partitions -> all ways to split that up into contiguous parts
Ʋ€€ - for each part (i.e. order) of each partition:
ŒH - split into two (if odd in length then left half is longer)
Ðe - to those in the right half (cheaper pizzas):
H - halve
F - flatten {this list of lists of costs}
S - sum {these}
+ - add {DeliveryCost} (vectorises across all order-costs)
§ - sums {of that}
Ṃ - minimum
Charcoal, 70 bytes
W⌊⁻ηυF№ηι⊞υι≔⟦⟦…υ¹⟧⟧ηFΦυκ≔⁺Eη⮌E⮌κ⎇νμ⁺μ⟦ι⟧Eη⊞Oκ⟦ι⟧ηI⌊EηΣ⁺θEι⁻Σλ⊘↨…λ⊘Lλ⁰
Try it online! Link is to verbose version of code. Explanation:
W⌊⁻ηυF№ηι⊞υι
Sort the prices into order.
≔⟦⟦…υ¹⟧⟧ηFΦυκ≔⁺Eη⮌E⮌κ⎇νμ⁺μ⟦ι⟧Eη⊞Oκ⟦ι⟧η
Generate all possible orders of pizzas of consecutive prices. (We don't need all partitions because for example 10, 30 and 20, 40 will always be more expensive than 10, 20 and 30, 40.)
I⌊EηΣ⁺θEι⁻Σλ⊘↨…λ⊘Lλ⁰
Calculate the price of each set of orders and output the minimum.
Python3, 459 bytes
S=sorted
E=enumerate
def f(d,p):
q,M,U,D=[([],p,0)],-1,[],{}
while q:
(a,p,c),*q=S(q,key=lambda x:(len(x[1]),x[2]))
if[]==p:M=min(M,c)if M!=-1 else c;continue
for j,k in E(p):
for A in[a+[[k]]]+[a[:J]+[K+[k]]+a[J+1:]for J,K in E(a)]:
if(P:=S(map(S,A)))not in U:
U+=[P];C=sum(d+sum(j*0.5 for j in i[:len(i)//2])+sum(i[len(i)//2:])for i in P)
if not(V:=D.get(str(T:=p[:j]+p[j+1:])))or C<=V:q+=[(P,p[:j]+p[j+1:],C)];D[str(T)]=C
return M
K (ngn/k), 41 39 bytes
thanks to @att for -1 byte
{&/(+/(x+/0.5|*&y[<y]2 0N#)'=)'++\!2&y}
The interesting part is the price calculation for single order, +/0.5|*&2 0N#. We start from a sorted list of pizza prices.
2 0N# splits the list of pizza prices into two rows. If there was an odd number of prices, the second row ends up being longer, which happens to be exactly what we want.
& (deep-where) gives the index (row and column) for each 1 in the array. For larger integers the index is repeated by that integer. * extracts only the rows, 0 for discounted pizzas and 1 for the others. 0.5| increases all 0s to 0.5s, after that
we just need sum everything (+/).
p:2 4 6 6 8
2 0N#p
(2 4
6 6 8)
*&2 0N#p
0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+/0.5|*&2 0N#p
23
jq, 98 95 bytes
- -3 bytes thanks to @ovs
def f(a):sort|[(1+range(length))as$b|(.[$b:]|f(a))+(.[:$b]|add)-(.[:$b/2%$b]+[0]|add/2)+a]|min;
JavaScript (Node.js), 95 bytes
p=>g=(a,s=p)=>~~Math.min(...a.sort((p,q)=>p-q).map((x,i)=>(s+=x-~~a[++i/2-1]/2)+g(a.slice(i))))