最小の魔法の合計にする


27

この課題を短くしてください。

4つの番号が与えられます:p1、p2、p3、p4。

数値のマジックサムは次のように定義されます。

magic_sum = |p1 - p2| + |p2 - p3| + |p3 - p4| + |p4 - p1|

上記の整数値(p1、p2、p3、またはp4)のいずれかのみを変更できます。値の魔法の合計が最小値になるように値を変更する必要があります。

例えば:

p1、p2、p3、p4 = 17、-6、15、33。この場合、マジックサムの値は78です。

ここで-6を16に変更すると、マジックサムの値は36になります。これは達成可能な最小値です。

数値は正または負の整数になる可能性があることに注意してください。

これはコードゴルフなので、コードの最小バイトが勝ちます。ブラウニーは、レクリエーション言語よりも実用的な言語を使用していることを指摘しています。4日はあなたとありますように。

繰り返します:

サンプル1

入力1

17 -6 15 33

出力1

36

説明1

-6は16に置き換えることができ、達成可能な最小の魔法の合計を与えます。

サンプル2

入力2

10 10 10 10

出力2

0 or 2

どちらでもかまいません

説明2

4つの正の整数の最小合計が0であるため、到達可能な最小の魔法の合計は0です。数値を変更する必要がある場合、10の1つを9に変更して、出力2を生成できます。

サンプル3

入力3

1 2 3 4

出力3

4

説明3

入力はそれ自体で6をマジックサムとして生成します。4を1に変更し、最小のマジックサム(4)を達成します。


10
+1。ただし、他の例でも可能です。
ジョナサンアラン

2
完全に機能する例とさらに2、3のテストケースがあり+1ます。
シャギー

@Shaggyできました。+1はどこですか?:P
コイショアロイ

1
@KoishoreRoyテストケース3は変更なしで6になりませんか?
wizzwizz4

@ wizzwizz4 | 1-2 | + | 2-3 | + | 3-4 | + | 4-1 | = 1 + 1 + 1 + 3 = 6。あなたは正しいです。編集しました。
Koishore Roy

回答:



20

Python 2、44バイト

a,b,c,d=sorted(input())
print min(c-a,d-b)*2

オンラインでお試しください!

入力をa,b,c,d,昇順でソートし、c-aとのうち小さい方を取り、それをd-b2倍にします。なぜこれが機能するのですか?

最初に、要素を変更して距離の巡回合計の合計を最大化する場合、のように近傍に等しくなるように変更することが最適です(または最適に結び付けられている)17, -6, 15, 33 -> 17, 17, 15, 33。これは、左と右の周期的な近隣への新しい合計距離が少なくともそれらの近隣間の距離であるため、これらを等しくすることが最善であるためです。

現在、数値の2つの隣接するコピーの1つを削除すると、距離の同じ循環合計が得られます。例では、これは17, 15, 33です2 + 18 + 16。したがって、4つの数値の1つを置き換える代わりに、3つの数値を残してそれらを削除し、それらの循環距離の合計を使用するのと同じです。

3つの数値では、最大距離は2つの小さい距離の合計になります。我々が持っている数字を並べ替える場合ためですa ≤ b ≤ cそして、|a - c| = |a - b| + |b - c|。言い換えると、最大数と最小数の間を2回移動し、その中の1つをピットストップとして使用します。したがって、3つの距離の合計は、最小値と最大値の間の距離のちょうど2倍になり(c-a)*2ます。

したがって、問題は、残りの3つの数字の最小値と最大値の間の最小距離を取得するために、どの数字を削除するかです。明らかに、数値の最小または最大のいずれかを削除します。それらを呼び出すとa, b, c, d、ソート順に削除a葉をd - b、および削除dの葉をc - a、そして最終的な結果は、いずれか小さい方の二重です。


ここでテストケースを手伝ってください。マジックサムがすでに0で、達成可能な最小の数値である場合はどうなりますか。その場合、答えは0である必要がありますか?または可能な限り次に小さい番号。入力が[10,10,10,10]の場合、マジックサムは0です。2番目に低い値は2です。考えを教えてください。
Koishore Roy

あなたが言うことは、与えられた4つの数字の順序を無視することができるということです(あなたの最初のステップはそれらをソートすることです)。しかし、で5つの番号p1を要求しp5、それでも1つの番号のみを変更できるとしたらどうでしょうか?4桁のケースは簡単すぎるようです(答えを見た後でのみ)。
ジェッペスティグニールセン

@KoishoreRoyどちらかを許可するソリューションが気に入っています。
18:09の

@JeppeStigNielsenはい、順序が重要ではないという事実は4つの数字に特別であり、1つを削除して3つの数字を作成すると、数字のすべてのペアが循環的に隣接するために起こります。5つの数値ではこれは機能せず(例が必ず見つかります)、課題は大きく異なります。
XNOR

二度投票できたらいいのに。美しい観察、よく説明されています。
ジョナ

9

R66 33バイト

function(x)2*min(diff(sort(x),2))

オンラインでお試しください!

xnorのアルゴリズムでははるかに短くなります(説明を読んで投稿に賛成してください!)。

古いバージョン:

R、66バイト

function(x,m=matrix(x,3,4))min(colSums(abs(diff(rbind(m,m[1,])))))

オンラインでお試しください!

入力を4つの整数のベクトルとして受け取ります。

p2p2p1p2p3|p1p2|+|p2p3|p2=p1

変更する番号を選択する方法は4つあります。これらのそれぞれについて、3つの絶対差の合計を計算するだけです。

3×4rbind


4

ゼリー11 10バイト

I;SASƲ$-ƤṂ

オンラインでお試しください!

入力として整数の場合にリストを受け取る単項リンク。任意のリストサイズで動作するはずです。リストから各数値を削除し、マジックサムを計算し、最小値を取ることにより、最小値を取得できることに基づいて機能します。


3

ゼリー、8 バイト

ṁ-Ƥ⁸IA§Ṃ

整数を生成する整数*のリストを受け入れる単項リンク

* 1つ以上ある限り、任意の数を指定できます。同じスタイルの魔法の式を使用して、周囲の相違点をまとめます

オンラインでお試しください!

どうやって?

ṁ-Ƥ⁸IA§Ṃ - Link: list of integers, X       e.g. [17,-6,15,33]
 -Ƥ      - for overlapping "outfixes" of length length(X)-1:
         -                                      [[-6,15,33],[17,15,33],[17,-6,33],[17,-6,15]]
ṁ  ⁸     -   mould like X                       [[-6,15,33,-6],[17,15,33,17],[17,-6,33,17],[17,-6,15,17]]
    I    - incremental differences              [[21,18,-39],[-2,18,-16],[-23,39,-16],[-23,21,2]]
     A   - absolute (vectorises)                [[21,18,39],[2,18,16],[23,39,16],[23,21,2]]
      §  - sums                                 [78,36,78,46]
       Ṃ - minimum                              36

3

Japt -Q、11バイト

ñÍó ®r- ÑÃn

@xnorのアルゴリズムを使用して、4バイト節約しました。

@Shaggyのおかげで5バイト節約

それを試してみてください


正常に動作しているようですが、これがなぜ機能するのか説明してください。
Koishore Roy

@KoishoreRoy説明を追加
無知の

29バイト(私は思う
シャギー

@Shaggy回答を更新したとき、誤ってsumをマップに置き換え、一部のゴルフは無効になりましたが、他のゴルフは良いものになりました
無知の具現化

素敵な(さらに)ゴルフ:) ÃÃ改行に置き換えることで、さらに1バイト節約できます。
シャギー

3

J24 20 18 17バイト

xnorアルゴリズムを使用した代替バージョン:

2*[:<./2 2-/@$\:~

どうやって

ソートされた入力を整形することによって形成された2x2行列の最初の行から2番目の行の2 *最小値の2倍を[:<./引いたもの[:-/2 2$\:~

オンラインでお試しください!

元の回答:J、24バイト

[:<./1(1#.2|@-/\],{.)\.]

オンラインでお試しください!

ニックケネディのアイデアを使用します。

  • 1(...)\.] 括弧の動詞を長さ1のすべての修正に適用します(長さnの修正は、n個の連続した要素が削除されたリストです。したがって、1 elmが削除されたすべての可能なリストが生成されます)
  • (1 #. 2 |@-/\ ] , {.)これは、最初のelmを入力に追加] , {.し、absの差|@-/を長さ2の中置に適用し2 ...\、結果を合計することにより、マジックサムを計算し1 #.ます。
  • [:<./ 分を返します

2

05AB1E11 7 バイト

@xnorのJelly回答のポート。@Emignaの
おかげで-4バイト@Grimyの

{2ô`αß·

オンラインでお試しください。

05AB1Eのレガシーバージョンでのみ機能する7 バイトの代替(必要なのは¥新しいバージョンでは前に):

{2ôø¥W·

オンラインでお試しください。

説明:

{        # Sort the (implicit) input-list
         #  i.e. [17,-6,15,33] → [-6,15,17,33]
 2ô      # Split this list into parts of size 2
         #  → [[-6,15],[17,33]]
   `     # Push both separated to the stack
    α    # And take their absolute differences
         #  → [23,18]
     ß   # Pop and push the minimum
         #  → 18
      ·  # Double it (and output implicitly as result)
         #  → 36

{        # Sort the (implicit) input-list
         #  i.e. [17,-6,15,33] → [-6,15,17,33]
 2ô      # Split this list into parts of size 2
         #  → [[-6,15],[17,33]]
   ø     # Zip/transpose, swapping rows/columns
         #  → [[-6,17],[15,33]]
    ¥    # Get the deltas/forward differences of the inner lists
         #  → [[23],[18]]
     W   # Get the flattened minimum (without popping)
         #  → 18
      ·  # Double it (and output implicitly as result)
         #  → 36

1
レガシーでは7バイト:書き換えでは{2ôø¥W·8 バイト
エミグナ

2
非レガシーの7バイト:{2ô`αW·
Grimmy

@Emigna Smart、ありがとう!
ケビンクルーッセン

@Grimyありがとうございます!
ケビンクルーッセン

1

C ++(gcc)

完全なプログラム:138バイト

#include<iostream>
#include<regex>
using namespace std;int main(){int a[4];for(int&b:a)cin>>b;sort(a,a+4);cout<<min(a[2]-*a,a[3]-a[1])*2;}

オンラインでお試しください!

コア機能:84バイト

#include<regex>
int m(int*a){std::sort(a,a+4);return std::min(a[2]-*a,a[3]-a[1])*2;}

オンラインでお試しください!

また、Python 2の投稿で説明されているアルゴリズムxnorを使用しています。


0

、20バイト

I⌊EEθΦθ⁻κμΣEι↔⁻λ§ι⊕μ

オンラインでお試しください!リンクは、コードの詳細バージョンです。@NickKennedyのアイデアを使用していることがわかりました。説明:

   Eθ                   Map over input array
     Φθ                 Filter over input array where
       ⁻κμ              Outer and inner indices differ
  E                     Map over resulting list of lists
           Eι           Map over remaining values in list
                §ι⊕μ    Get the next value in the list
             ↔⁻λ        Compute the absolute difference with the current value
          Σ             Take the sum of absolute differences
 ⌊                      Take the minimum sum
I                       Cast to string and implicitly print

0

JavaScript(ES6)、51バイト

xnorのはるかに賢い方法を使用する

a=>([a,b,c,d]=a.sort((a,b)=>a-b),b+c<a+d?c-a:d-b)*2

オンラインでお試しください!


元の回答、96バイト

入力を4つの整数の配列として受け取ります。おそらく間違いなく最短のアプローチではありません。

a=>a.map(m=x=>a.map((y,i)=>a[m=a.map(v=>s+=Math.abs(p-(p=v)),a[i]=x,p=a[3],s=0)|m<s?m:s,i]=y))|m

オンラインでお試しください!



0

Java 8 8、235バイト

@xnorのPython回答とアルゴリズムの移植版

import java.util.*;interface M{static void main(String[]A){Scanner I=new Scanner(System.in);int a[]={0,0,0,0};for(int i=0;i<4;a[i++]=I.nextInt());java.util.Arrays.sort(a);System.out.print(2*(a[2]-a[0]>a[3]-a[1]?a[3]-a[1]:a[2]-a[0]));}}

オンラインでお試しください!

Java 10、未検証、222バイト

Java 10では、Scanner宣言の左側をに置き換えるvarことができますが、オンラインでコンパイルできなかったため、トリビアとしてのみ追加できます。ごめんなさい。

interface M{static void main(String[]A){var I=new java.util.Scanner(System.in);int a[]={0,0,0,0};for(int i=3;i<4;a[i++]=I.nextInt());java.util.Arrays.sort(a);System.out.print(2*(a[2]-a[0]>a[3]-a[1]?a[3]-a[1]:a[2]-a[0]));}}

1
私の知る限り、他の答えがどのように行われたかのように、あなたはあなたの提出物としての機能を持つことができます。周囲のクラス、インターフェース、などを含める必要がありません
タウ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.