価格の丸めでお金を節約


18

カナダでは、ペニーはもはや流通していません。現金支払いは、最も近い5セントに丸められます。

購入を分割することでお金を節約できます。たとえば、2つの$ 1.02アイテムの価格は2.04ドルであり、切り上げて2.05ドルになりますが、別々の購入でアイテムを購入すると、各価格は合計2.00ドルで1.00ドルに切り上げられます。ただし、2つのアイテムをそれぞれ1.03ドルで購入する場合は、1回の購入で購入することをお勧めします。

お金を節約するもう1つの方法は、クレジットの支払いが丸められないため、丸めが好ましくないときにクレジットカードを使用することです。2つの$ 1.04アイテムが必要な場合、購入の分割方法に関係なく、合計価格は$ 2.10に切り上げられます。したがって、これらのアイテムの代金はクレジットカードで支払う必要があります。

アイテムの価格リストを整数のセントとして受け入れ、現金またはクレジットによる一連の購入を通じて達成できるアイテムの可能な最低価格(セント)を出力する関数またはプログラムを記述します。

最短のコードが優先されます。

テストケース

[] : 0
[48] : 48
[92, 20] : 110
[47, 56, 45] : 145
[55, 6, 98, 69] : 225
[6, 39, 85, 84, 7] : 218
[95, 14, 28, 49, 41, 39] : 263
[92, 6, 28, 30, 39, 93, 53] : 335
[83, 33, 62, 12, 34, 29, 18, 12] : 273
[23, 46, 54, 69, 64, 73, 58, 92, 26] : 495
[19, 56, 84, 23, 20, 53, 96, 92, 91, 58] : 583
[3, 3, 19, 56, 3, 84, 3, 23, 20, 53, 96, 92, 91, 58, 3, 3] : 598
[2, 3, 4, 4, 4, 4, 4] : 19

回答:


5

ルビー、119 105文字(93体)

def f s
a,b,c,d=(1..4).map{|i|s.count{|x|x%5==i}}
s.reduce(0,:+)-a-(c-m=c>d ?d:c)/2-2*(b+m+(d-m)/3)
end

空の買い物リストを入力したときにアルゴリズムがクラッシュする可能性がある場合は、2文字を保存できます。


に変更してs.reduce(:+)(通常はパラセトも必要ありませんが、場合によっては...)、m追加の2文字をインライン化できます。
ハワード

そしてもちろんa,b,c,d=(1..4).map{|i|s.count{|x|x%5==i}}
ハワード

@Howard 呼び出し0,から削除するreduceと、空の入力に対してコードが中断します。私は答えでそれを言及しました。インラインmは役に立たないようです。最後の提案をありがとう-それは私から愚かだった。
ジョンドヴォルザーク

1
あなた(c-m=c>d ?d:c)はあなたに2つの文字を与えることができます。
ハワード

@Howard私-はそれよりも優先度が高いので壊れると思った=。(左側のオペランドが左辺値であることを保証するために)割り当ての左側に高い優先度があるのですか?
ジョンドヴォルザーク

5

GolfScript(54文字)

~]4,{){\5%=}+1$\,,}%~.2$>$:m- 3/m+@+2*@@m- 2/++~)+{+}*

これは、スペースで区切られた値として標準入力から入力を受け取るプログラムです。入力フォーマットをGolfScript配列として強制することにより、1文字を保存できます。

オンラインのテストケース

最も興味深いトリックは.2$>$、非破壊minオペレーター向けです。


私の数学の分析は、基本的にJanとRayの分析と同じです。値mod 5を考慮すると、節約できるのは1または2のトランザクションのみです。クレジットカードオプションは、切り上げを行わないことを意味します。したがって、5n + 2セントの費用がかかるアイテムは、バンドルの恩恵を受けられません。また、5n + 1セントの価値のあるアイテムもできません(2セントの節約に2つの1セントの節約を組み合わせてもメリットはありません)。0は加法単位元であるので、唯一の興味深いケースは、3および4の値を含む3+3 = 13+4 = 4+4+4 = 2。3と4が混在している場合は3+43+3(厳密に)または4+4+4(同等)よりも優先して最適化します。


+1-これらのスペースは非常に豪華に見えますが、~):m残念ながら、文字数を減らすことなく-m()を保存すると削除できます。
ハワード

@Howard、私も知っています、私も試してみました。:D
ピーターテイラー

3

C ++:126文字

int P(int*m,int i){int t=0,h=0,d;while(i>-1){d=m[i]%5;t+=m[i--];d<3?t-=d:d==4?h++,t-=2:h--;}h<0?t+=h/2:t+=(h-h/3)*2;return t;}

このプログラムを短くするためのガイダンスを提供することを歓迎します。テストプログラムは、tdm-gcc 4.7.1コンパイラでコンパイルし、正常に実行します。

#include<iostream>
using namespace std;

//m[i]表示单个商品的价格,t表示所有商品总价格,
//d为单个商品价格取模后的值,h为单个商品价格取模后值为3的个数,
//f为单个商品价格取模后值为4的个数
int P(int*m,int i){int t=0,h=0,d;while(i>-1){d=m[i]%5;t+=m[i--];d<3?t-=d:d==4?h++,t-=2:h--;}h<0?t+=h/2:t+=(h-h/3)*2;return t;}

int main() {
int p1[1]={48};
int p2[2]={92,20};
int p3[3]={47,56,45};
int p4[4]={55,6,98,69};
int p5[5]={6,39,85,84,7};
int p6[6]={95,14,28,49,41,39};
int p7[7]={92,6,28,30,39,93,53};
int p8[8]={83,33,62,12,34,29,18,12};
int p9[9]={23,46,54,69,64,73,58,92,26};
int p10[10]={19,56,84,23,20,53,96,92,91,58};
int p11[10]={1,2,3,4,5,6,7,8,9,10};
cout<<P(p1,0)<<endl
    <<P(p2,1)<<endl
    <<P(p3,2)<<endl
    <<P(p4,3)<<endl
    <<P(p5,4)<<endl
    <<P(p6,5)<<endl
    <<P(p7,6)<<endl
    <<P(p8,7)<<endl
    <<P(p9,8)<<endl
    <<P(p10,9)<<endl
    <<P(p11,9)<<endl;

return 0;
}

1

R 143

function(x)min(sapply(rapply(partitions::listParts(length(x)),
                             function(i)min(sum(x[i]),5*round(sum(x[i])/5)),h="l"),
                      function(x)sum(unlist(x))))

テスト(P上のコードのエイリアス)

> P(c(48))
[1] 48
> P(c(92, 20))
[1] 110
> P(c(47, 56, 45))
[1] 145
> P(c(55, 6, 98, 69))
[1] 225
> P(c(6, 39, 85, 84, 7))
[1] 218
> P(c(95, 14, 28, 49, 41, 39))
[1] 263
> P(c(92, 6, 28, 30, 39, 93, 53))
[1] 335
> P(c(83, 33, 62, 12, 34, 29, 18, 12))
[1] 273
> P(c(23, 46, 54, 69, 64, 73, 58, 92, 26))
[1] 495
> P(c(19, 56, 84, 23, 20, 53, 96, 92, 91, 58))
[1] 583

1

Mathematicaの112 126 167 157

編集:{3、3}および{4,4,4}のケースは、Peter Taylorとcardboard_boxのおかげで処理されるようになりました。

n_~g~o_ := {a___, Sequence @@ n, b___} :> {a, b, o};
f@s_ := Tr@Join[#[[2]], Sort@#[[1]] //. {1 -> 0, 2 -> 0, g[{3, 4}, 5], g[{3, 3}, 5], 
   g[{4, 4, 4}, 10]}] &[Transpose[{m = Mod[#, 5], # - m} & /@ s]]

注:非購入(テストケース#1)はとして入力されf[{0}]ます。

使い方

  1. 各アイテムについて、お支払い方法に関係なく、それぞれの価格よりも小さい5の最大倍数が支払われます。(それを回避することはできません。)
  2. Mod[n, 5]その後、の残りが処理されます。1と2は0になります。ゼロは変更されません。
  3. 各ペア{3、4}-> {5}。その後、各ペア{3、3}-> {5}; トリプル{4,4,4}-> {10}(該当する場合)。
  4. 残りの4がある場合、変更されません(クレジットカードで支払われます)。
  5. 元の5の倍数に、ステップ(2)から(4)で調整された(またはされていない)残りを加算します。

テスト中

a12{3,3}の a13調整{4,4,4}の調整

a1={0};
a2={48};
a3={92,20};
a4={47,56,45};
a5={55,6,98,69} ;
a6={6,39,85,84,7};
a7={95,14,28,49,41,39};
a8={92,6,28,30,39,93,53};
a9={83,33,62,12,34,29,18,12};
a10={23,46,54,69,64,73,58,92,26};
a11={19,56,84,23,20,53,96,92,91,58};
a12={3,3,19,56,3,84,3,23,20,53,96,92,91,58,3,3};
a13={2,3,4,4,4,4,4};

f /@ {a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13}

{0、48、110、145、225、218、263、335、273、495、583、598、19}


1
{3,3}はどうですか?
ピーターテイラー

@PeterTaylor。いい視点ね。それはすり抜けた。
DavidC

{4,4,4}はどうですか?{3,4}-> {5}、{3,3}-> {5}および{4,4,4}-> {10}(この順序で)で最適な答えが得られると思います。
cardboard_box

@cardboard_boxそのとおりです!更新を参照してください。
DavidC

追加のテストケースを質問に追加しました。私が持っていたものはランダムに生成されたため、これらのコーナーケースは表示されませんでした。
cardboard_box

1

Python 3(115文字)

m=eval(input());t=a=b=0
for v in m:d=v%5;t+=v-d*(d<3);a+=d==3;b+=d==4
d=min(a,b);a-=d;b-=d;print(t-d*2-a//2-b//3*2)

Python 2(106文字)

m=input();t=a=b=0
for v in m:d=v%5;t+=v-d*(d<3);a+=d==3;b+=d==4
d=min(a,b);a-=d;b-=d;print t-d*2-a/2-b/3*2

2
質問では合計価格が要求されるため、リスト全体に対して1つの出力が必要です。たとえば、3セントと4セントのアイテムを組み合わせて5セントで現金で支払う7セントの購入と、それ以外の場合は切り上げられるためクレジットで支払う残りの9セントのアイテムを取得できるため、入力[3,4,9]はを与える必要14があります。
cardboard_box

2
与えられた1, 2, 3, 4, 5, 6, 7, 8, 9, 10、これは与える0.0, 0.0, 2.5, 3.33, 5.0, 5.0, 5.0, 7.5, 8.33, 10.0、それは合計する46.66。ただし、正解は45であるため、印刷する数字の合計は正解ではないため、この解決策は正しくありません。
ノーレンロイヤリティ

この答えは、ジョブがまだ「合計」が含まれていないときwrotedた
AMK

2
削除を推奨する必要があると思います。Askerは要件を変更しませんでした-彼はそれらを明確にしました。各アイテムの価格を個別に希望する場合、「購入/単一購入のシーケンス」の言及と、どちらが有利かについての議論はなぜですか。
ジョンドボラック

間違った答えを削除します。最短のPython回答
AMK

0

APL、58文字

{a b c d←+/(⍳4)∘.=5|⍵⋄(+/⍵)-a-(⌊2÷⍨c-m)-2×b+m+⌊3÷⍨d-m←c⌊d}

このプログラムは、基本的にJan DvorakのRubyソリューションを直接翻訳したものです。


      {a b c d←+/(⍳4)∘.=5|⍵⋄(+/⍵)-a-(⌊2÷⍨c-m)-2×b+m+⌊3÷⍨d-m←c⌊d}⍬
0
      {a b c d←+/(⍳4)∘.=5|⍵⋄(+/⍵)-a-(⌊2÷⍨c-m)-2×b+m+⌊3÷⍨d-m←c⌊d}95 14 28 49 41 39
263
      {a b c d←+/(⍳4)∘.=5|⍵⋄(+/⍵)-a-(⌊2÷⍨c-m)-2×b+m+⌊3÷⍨d-m←c⌊d}19 56 84 23 20 53 96 92 91 58
583

空のベクトルです。


0

ジュリア83C

C=L->let
w,z,x,y=map(i->[i==x%5for x=L]|sum,1:4)
L|sum-(x+2w+3min(x,y)+4z)>>1
end

説明:

1回の購入で、最大2セント節約できます。したがって、2セント節約できる組み合わせがある場合は、そのように購入するだけで楽観的になります。たとえば、x価格が3(mod 5)のyアイテムと価格が4(mod 5)のアイテムがある場合min(x, y)、(3、4)ペアの数を作成して、2 min(x, y)セントを節約できます。次に、残りの3を使用して、max(0, x-min(x,y)) / 2セントを節約します。これも計算できます(max(x,y)-y)/2

w = sum(1 for p in prices if p % 5 == 1)
z = sum(1 for p in prices if p % 5 == 2)
x = sum(1 for p in prices if p % 5 == 3)
y = sum(1 for p in prices if p % 5 == 4)

ans = sum(prices) - (w + 2 z + 2 min(x, y) + div(max(x, y) - y, 2))
    = sum(prices) - (2w + 4z + 4 min(x, y) + x + y - min(x, y) - y) `div` 2
    = sum(prices) - (2w + 4z + 3 min(x, y) + x) `div` 2

編集

この解決策は間違っています。


学ぶのに面白いかもしれない比較的未知の言語を使用するための+1
ジョンドヴォルザーク

活発に開発されている新しい言語です。さまざまな言語の多くの強みを組み合わせています。より多くの人々がそれを知ることができることを願っています。
レイ

分析は完全ではありません。なぜなら、もしあなたが持っているのであれば、2セント節約できる組み合わせですが4 4 4 3 34 4 4そのように購入するのは最適ではないからです。(実際、あなたはまったく4 4 4考慮していないようです。このコードは最後のテストケースに失敗しませんか?)
ピーターテイラー
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.