可能な限り公正であること


33

前書き

この課題では、整数を2つの部分に分割する必要があります。誰も小さなケーキを手に入れるのが好きではないので、あなたの目標は可能な限り公平になることです。たとえば、整数7129を2つに分割する場合、3つの方法があります。

7,12971,29および712,9すべての可能性が71,29ありますが、2つの違いを最小限に抑えるため、2つの部分に分割する最も公平な方法です。

7 129 -> |7-129| = 122
71 29 -> |71-29| = 42
712 9 -> |712-9| = 703

チャレンジ

整数が与えられた場合、上記のように整数を分割する最善の方法を決定し、結果の差報告します。

ルール

  • 分割は、長さが少なくとも2の整数に対してのみ意味があり、入力は常に10以上です。
  • 入力は、整数、数字のリスト、または文字列のいずれかです
  • 無効な入力を処理する必要はありません

テストケース

結果の違いのみを報告する必要があります。パーティション分割は、説明のためにのみここにあります。

10 -> 1,0 -> 1
11 -> 1,1 -> 0
12 -> 1,2 -> 1
13 -> 1,3 -> 2
101 -> 1,01 -> 0
128 -> 12,8 -> 4
313 -> 3,13 -> 10
1003 -> 1,003 -> 2
7129 -> 71,29 -> 42
81128 -> 81,128 -> 47
999999 -> 999,999 -> 0
9999999 -> 999,9999 or 9999,999 -> 9000

回答:


11

Brachylog12 11バイト

初めてのBrachylogの回答

入力を文字列として受け取る

{~cĊịᵐ-ȧ}ᶠ⌋

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

説明:

意志Fでの述語のためのINDすべての可能な出力{…}と、リストに格納します。~c出力場合、リストであることを言うcが oncatenated、入力と同じです。次にĊ、の出力の~c長さが2 であることをアサートします。

ịᵐ出力の両方の要素を整数に変換し(先頭0のs を取り除きます)、2つの要素の絶対差を取ります。

すべての可能な出力のリストを取得したら、最小要素を取得します。



9

05AB1E、9バイト

コード:

ā¤âε£ÆÄ}W

05AB1Eエンコードを使用します。オンラインでお試しください!

説明

ā            # Get the array [1, 2, .., len(input)]
 ¤â          # Cartesian product with the last element, (e.g. for input 12345:
               [[1, 5], [2, 5], [3, 5], [4, 5], [5, 5]])
   ε   }     # For each element:
    £        #   Get the substrings (12345 [3, 5] £ --> [123, 45])
     Æ       #   Reduce by subtraction
      Ä      #   Get the absolute value
        W    # Take the minimum of all results

1
交換£する°‰場合は¤âもう必要ありません。
エミグナ


7

Perl 6、40バイト

{min map {abs [-] @$_},m:ex/^(.+)(.+)$/}

試して

拡張:

{  # bare block lambda with implicit parameter 「$_」

  min
    map
      {
        abs
          [-]    # reduce with &infix:«-»
            @$_  # the input of this inner block as a Positional
      },

      # split 「$_」 into 2 in every possible way
      m
      :exhaustive
      /^ (.+) (.+) $/
}



6

プロローグ(SWI) 195の 189 154 117 112バイト

Emingaのおかげで35バイト節約

A*H:-findall(X,(between(0,A,I),r(A,I,X)),L),sort(L,[H|_]),!.
r(A,B,C):-Z is 10**B,divmod(A,Z,X,Y),C is abs(X-Y).

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

これはプロローグゴルフでの私の最初の試みなので、少し恐ろしいかもしれません。仕組みは次のとおりです。

最高レベルでは**とを取りA、分割する最小の方法であるHかどうかを決定します。HA

    A*H:-
      findall(X,(between(0,A,I),call(r,A,I,X)),L),
      sort(L,[H|_]),
      !.

ここの最初の行は、このSOポストからのテクニックを使用して、r(A)から0までの整数に対して述語のマップを本質的に実行しますAr各パーティションの値を確認するので、これによりすべての可能なパーティションの値に加えて、余分なジャンクの全体の負荷が得られます。これらのパーティションはすべて、L順不同で保存されます。それが完了したら、リストをソートして最小の要素を見つけます。次に、バックトレースを防ぐためにカットを使用します。

次に、の定義がありrます。まずr、それらを命名分割の二つの結果を計算Xし、をY

r(A,B,C):-
  Z is 10**B,
  divmod(A,Z,X,Y),
  C is abs(X-Y).

そしてC、それがそれらの違いであり、ポジティブであると断言します。

  C is abs(X-Y).

X is div(A,10**B),Y is div(A,10**B)常に与えるように、ここには間違いがあるようですC=0(つまり、H常に0にもなります)。Y is mod(A,10**B)推測すべきでしょう。
エミグナ

2行目でもr(A,B,C):-Z is 10**B,divmod(A,Z,X,Y),C is abs(X-Y).32バイトを節約できます(少なくともSWIプロローグを使用している場合、他のバージョンについてはわかりません)。
エミグナ

最初の行で始まる可能性がたとえばA*Hの代わりに、l(A,H)別の3そして、あなたはSWIを使用している場合、あなたは追加することができます保存TIOリンク
Emigna

また、私はあなたが必要とは,!思わない?その時点でバックトラックする必要はありません。
エミグナ

@Emignaヒントをありがとう、すぐに実装します。私も,!必要ではないと思いましたが、プログラムをテストするときにバックトレースを行います。すべての可能な順序付けを試してLから、それらをすべてソートするようです。つまり、同じ回答A!時間が得られます。
小麦ウィザード


4

、14バイト

I⌊Eθ↔⁻I…θκI✂θκ

オンラインでお試しください!リンクは、コードの詳細バージョンです。便利なことに、の2引数のバリアントを使用できますSlice。説明:

   θ            Input string
  E             Map over characters
        θ   θ   Input string
         κ   κ  Current map index
       …        Mold to length (i.e. head)
           ✂    Slice (i.e. tail)
      I   I     Cast to integer
     ⁻          Subtract
    ↔           Absolute value
 ⌊              Minimum
I               Cast to string
                Implicitly print

4

ゼリー9 8バイト

ḌÐƤḊạḌƤṂ

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

デニスのおかげで-1バイト。入力は数字のリストです。

説明

ḌÐƤḊạḌƤṂ
ḌÐƤ          Convert to integer from decimal for all Ƥostfixes. [1,2,3]->[123,23,3]
   Ḋ         Remove the first element ->[23,3]
     ḌƤ      Convert to integer from decimal for all Ƥrefixes [1,2,3]->[1,12,123]
    ạ        Absolute difference. [23,3]ạ[1,12,123]->[22,9,123]
       Ṃ     Minimum

うーん、あなたの説明はあなたのコードが実際に行っていることを反映していないようです。
エリックアウトゴルファー

@EriktheOutgolfer「最初の要素を削除する」と言う必要があるのは、「最後の要素を削除する」部分ですか?私はそれを指摘し、おかげでそれを修正します
dylnan


3

網膜、36バイト

\B
,$'¶$`
\d+
$*
(1*),\1

Om`^.*
\G1

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

説明

\B
,$'¶$`

これにより、可能なすべてのパーティションが個別の行に生成され、元の入力の末尾の行も生成されます。

\d+
$*

各パーティションの各数値を単項に変換します。

(1*),\1

1各パーティションの両方の部分から最大で等しい量のsを削除します(つまり、最小値を削除し、最大値から減算します。これにより、絶対差が得られます)。

Om`^.*

行を並べ替えます。

\G1

1最初の行のsをカウントします。これにより、絶対差が最小になります。


3

J32、27 23バイト

FrownyFrogのおかげで-5バイト!入力が文字列の場合、-4バイト。

[:<./}:@(".\)|@-1}.".\.

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

オリジナル:入力として数字を受け取ります

(".\(}:@[([:<./|@-)}.@])".\.)@":

使い方:

                             @": - convert the number to list of chars and
(".\                    ".\.)    - form all prefixes/suffixes and convert them to numbers
    (}:@[          }.@])         - drop the last prefix / first suffix
         (     |@-)              - find the absolute differences
          [:<./                  - find the minimum

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


@FrownyFrog-ありがとう!
ガレンイワノフ

3

JavaScript(ES6)、64バイト

入力を文字列として受け取ります。

f=([c,...s],l=0)=>c?Math.min(Math.abs((l+=c)-s.join``),f(s,l)):l

テストケース

コメント済み

f = ([c, ...s],           // c = current character, s = array of remaining characters
                l = 0) => // l = left part of the integer, initialized to 0 (see footnote)
  c ?                     // if c is defined:
    Math.min(             //   return the minimum of:
      Math.abs(           //     1) the absolute value of:
        (l += c) -        //       the updated left part
        s.join``          //       minus the right part
      ),                  //     end of Math.abs()
      f(s, l)             //     2) the result of a recursive call
    )                     //   end of Math.min()
  :                       // else:
    l                     //   stop the recursion by returning l (now equal to the input)

非再帰(ES7)、65バイト

入力を文字列として受け取ります。

s=>Math.min(...[...s].map(c=>((l+=c)-s.slice(++i))**2,i=l=0))**.5

テストケース

コメント済み

s =>                            // given s
  Math.min(...                  // get the minimum value in the result of this map():
    [...s].map(c =>             //   for each character c in s:
      ((l += c)                 //     append c to l (the left part)
                - s.slice(++i)) //     and subtract the right part from it
      ** 2,                     //     square the result
      i =                       //     start with i = 0 (split position)
      l = 0                     //     and l = 0 (left part, see footnote)
    )                           //   end of map()
  )                             // end of Math.min()
  ** .5                         // return the square root of the smallest square

:両方のバージョンでl、最初の繰り返しで文字列に強制されます。通常、数値リテラルの先行ゼロに注意する必要があります:は8進数値として解析される0123 - 10 === 73ため0123です(これは非推奨になりましたが、非厳密モードでも有効です)。ただし'0123' - '10' === 113、今回は先頭のゼロは無視されます。だから、そうするのは健全だ。

文字列に適用される抽象操作の仕様からToNumber

10進数のStringNumericLiteralは、先頭に0桁の任意の数を持つことができます


3

APL(Dyalog)、27バイト

{⌊/|-/⍎¨↑⊂∘⍵¨↓1,∘.=⍨⍳¯1+≢⍵}

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

どうやって?

¯1+≢⍵- nマイナス1の長さ

∘.=⍨⍳ -アイデンティティ行列

      1,∘.=⍨⍳3
1 1 0 0
1 0 1 0
1 0 0 1

1,- 1各行に追加

-行で分割

⊂∘⍵¨ -それぞれについて、文字列を分割します

      1 0 1 0  '7129'
┌──┬──┐
7129
└──┴──┘

-平らにする

-/ -減算で各ペアを減らす

| -絶対値を取る

⌊/ -最小


APL(Dyalog)、35バイト

{⌊/|-/⍎¨(⊂∘⍵⍤1)1,∘.=⍨⍳¯1+≢⍵}

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


3

ゼリー、11バイト

ŒṖṖLÐṂḌạ/€Ṃ

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

Dylnanのおかげで-3バイト

使い方

ŒṖṖLÐṂḌạ/€Ṃ - Main link. Argument: n (integer)    e.g    7129
ŒṖ          - Partitions of n's digits;                  [[7, 1, 2, 9], [7, 1, [2, 9]], [7, [1, 2], 9], [7, [1, 2, 9]], [[7, 1], 2, 9], [[7, 1], [2, 9]], [[7, 1, 2], 9], [7, 1, 2, 9]]
  Ṗ         - Remove the final element                   [[7, 1, 2, 9], [7, 1, [2, 9]], [7, [1, 2], 9], [7, [1, 2, 9]], [[7, 1], 2, 9], [[7, 1], [2, 9]], [[7, 1, 2], 9]]
    ÐṂ      - Keep the lists with the minimum...         [[7, [1, 2, 9]], [[7, 1], [2, 9]], [[7, 1, 2], 9]]
   L        -   length
      Ḍ     - From digits                                [[7, 129], [71, 29], [712, 9]]
        /   - Reduce...
         €  - ...each...
       ạ    - ...by absolute difference                  [122, 42, 703]
          Ṃ - Take the minimum                           42

あなたは変更することができますL=2$$ÐfṖLÐṂこのケースでは
dylnan



1

MATL、15バイト

"GX@:&)UwU-|vX<

入力は整数を表す文字列です。

オンラインでお試しください!または、すべてのテストケースを確認します

説明

"         % Implicit input. Do the following as many times as input length
  G       %   Push input
  X@      %   Push iteration index (1-based), k
  :       %   Range: gives [1 2 ... k]
  &)      %   Two-ouput reference indexing: gives a substring with the first
          %   k characters in the input and then a substring with the rest
  U       %   Convert to number
  wU      %   Swap, convert to number
  -|      %   Absolute difference
  v       %   Vertically concatenate stack. This concatenates the obtained
          %   absolute difference with the minimum so far; does nothing in 
          %   the first iteration
  X<      %   Minimum of array
          % Implicit end. Implicit display


1

クリーン106 83バイト

import StdEnv
@n#f=toInt o(%)n
=hd(sort[abs(f(0,i)-f(i+1,size n))\\i<-[0..size n]])

@文字列を取得して、関数を定義します。

ほとんど自明ですが、唯一のトリッキーなビットはf=toInt o(%)n次のとおりです。toInt関数クラスを、最初の引数()で既に提供されているoカリー化スライス演算子クラス(%)で構成します(n)。両方のオーバーロードを持ち、実際にコンパイルさStringれるタイプは1つのみ(に相当{#Char})であるため、通常、コンパイラーに提供されるコンテキスト情報が不足しているため、ゴルフ中に関数を構成するのは困難です。%toInt

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


1

ゼリー、12 バイト

JṬ€œṗ€⁸Ḍạ/€Ṃ

数字のリストを取得して整数を返すモナドリンク。

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

どうやって?

JṬ€œṗ€⁸Ḍạ/€Ṃ - Link: list of digits     e.g. [7,1,2,9]
J            - range of length               [1,2,3,4]
 Ṭ€          - untruth €ach                  [[1],[0,1],[0,0,1],[0,0,0,1]]
      ⁸      - chain's left argument         [7,1,2,9]
   œṗ€       - partition at truthy for €ach  [[[],[7,1,2,9]],[7,[1,2,9]],[[7,1],[2,9]],[[7,1,2],9]]
       Ḍ     - undecimal (vectorises)        [[0,7129],[7,129],[71,29],[712,9]]
         /€  - reduce €ach by:
        ạ    - absolute difference           [7129,122,42,703]
           Ṃ - minimum                       42

1

Pyth、10バイト

hSaMv<./Ql

テストスイート

入力を文字列として受け取ります。

これはPythの最新の機能の1つを使用します。つまり、他の動作が定義されていない場合、リストに関数を適用すると、デフォルトでリストに関数がマッピングされます。つまりv、文字列のリストのリストに適用すると、すべての文字列が評価されます。

hSaMv<./Ql
hSaMv<./QlQ    Implicit variable
      ./Q      Form all partitions of the input string.
               Split it in all possible ways, maintaining the order.
               Partitions are ordered from shortest to longest.
     <   lQ    Take the prefix as long as the input string.
               This keeps just the splits into one and two pieces.
    v          Evaluate. All strings are converted to numbers.
  aM           Map the absolute difference function.
hS             Minimum

分割のリストでは1個に分割することができますが、この値は常に最小値よりも大きいため、無視しても安全です。


1

Tcl、116バイト

foreach d [split [set b [set R $argv]] {}] {append L $d
regexp .(.+) $R - R
set b [expr min($b,abs($L-$R))]}
puts $b

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

説明

b ← R ← input number
for each digit (d) in the input number:
  L += d
  strip first digit off of R using a regular expression
  b ← min( b, distance between L and R )
print b

正規表現のトリックを使用することで機能し、常に最小差よりも大きく計算される縮退最終ケースを許可します。「12345」の値は次のとおりです。

1 2345 → 2344
12 345 → 333
123 45 → 78
1234 5 → 1229
12345 5 → 12340 (degenerate case)

あなたは使用してバイト剃ることができますlmap代わりにforeachtio.run/##LYuxCsMgFEV3v@IOb1DaZO8/ZHItDlolBEx4qC2FkG9/...
sergiol


1

APL + WIN、31バイト

⌊/|(⍎¨m↓¨⊂n)-⍎¨(m←⍳¯1+⍴n)↑¨⊂n←⎕

文字列として整数の画面入力を要求します。

説明:

m←⍳¯1+⍴n Create a list of numbers from 1 to length of string - 1

↑¨⊂n←⎕ Using m create a nested vector taking successively characters from the front of the string defined by m

⍎¨ Convert from character to integer

(⍎¨m↓¨⊂n) Using m create a nested vector dropping successively characters from the front of the string defined by m 

⌊/| take the minimum absolute value after subtracting the two vectors of integers

APLがわかりませんが、これをテストする方法はありますか?
ბიმო

残念ながら、APL + WINはTIOにはありません。APLでプレイしたい場合は、Dyalog WebサイトからAPLXのコピーを無料でダウンロードできます。私のコードはそれで動作します。DyalogのTry APLオンラインでは機能しません。dyalog.com/aplx.htm
グラハム


1

C#(.NET Core)112 107 + 18 = 125バイト

n=>Enumerable.Range(1,n.Length-1).Min(i=>System.Math.Abs(int.Parse(n.Remove(i))-int.Parse(n.Substring(i))))

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

カウントにはの18バイトが含まれusing System.Linq;ます。入力をとして受け取りますstring

  • Caius Jardによって5バイトが節約されました!

string.Removeあなたにいくつかのバイトを救うかもしれない
キーズJard

1

Common Lisp、131バイト

私は初めてコードゴルフに参加し、Lispが気に入ったのでLispを使用することにしました。

私の解決策は次のとおりです。

(defun f (s) (loop for i from 1 below (length s) minimizing (abs (- (parse-integer (subseq s 0 i)) (parse-integer (subseq s i))))))

入力は整数またはリストではなく文字列である必要があります。


3
PPCGへようこそ!残念ながら、私はLispを知りませんが、名前のない関数にして空白を削除すると、11バイト短縮できることに気付きましたこちらを参照してください。あなたが見ていない場合は、これを、多分あなたは、いくつかのヒントを見つけることができます。
ბიმო
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.