尽可能公平


33

介绍

在这个挑战中,您应该将整数分成两部分。由于没有人喜欢小菜一碟,因此您的目标是尽可能做到公平。例如,如果您想将整数7129分成两部分,则有3种可能的方法。

7,12971,29并且712,9都是可能的,但这71,29是将其分为两部分的最公平的方法,因为它最大程度地减少了两者之间的差异:

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

Answers:


11

Brachylog12 11字节

我的第一个Brachylog答案

将输入作为字符串

{~cĊịᵐ-ȧ}ᶠ⌋

在线尝试!

说明:

˚F IND在谓语所有可能的输出{…},并将它们存储在列表中。~c说,输出是一个列表,当Ç oncatenated,等于输入。Next Ċ断言的输出~c长度为2。

ịᵐ将输出的两个元素都转换为整数(这消除了前导0s),取两个元素的绝对差。

一旦获得所有可能输出的列表,我们将获得具有


10

Haskell,48个字节

f n=minimum[abs$n`div`10^k-n`mod`10^k|k<-[1..n]]

[1..n] 这对于较大的测试用例来说太慢了。

在线尝试!


不错的工作!我对使用字符串感到一头雾水,以至于忘记了可以使用算术。
小麦巫师

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
如果替换£°‰您,则不再需要¤â
Emigna


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).

在线尝试!

这是我第一次尝试序幕打高尔夫球,因此可能有点可怕。下面是它的工作原理。

在最高层次上,我们有**采用Aand H并确定是否H是最小的拆分方法A

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

这里的第一行使用了来自SO的一种技术,实质上是对r(A)0to到整数的谓词进行映射A。由于r确认了每个分区的值,这将为我们提供所有可能分区的值,以及一整堆额外的垃圾。所有这些分区将以L不特定的顺序存储。完成后,我们对列表进行排序以找到最小的元素。然后,我们使用剪切来防止回溯。

接下来,我们定义r。首先r计算两个拆分结果,分别命名为XY

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)我想的。
Emigna

第二行也可以r(A,B,C):-Z is 10**B,divmod(A,Z,X,Y),C is abs(X-Y).节省32个字节(如果您至少使用SWI序言,则不确定其他版本)。
Emigna

例如,第一行可以从开始A*H而不是l(A,H)保存另外3 行开始。如果使用的是SWI,则可以添加TIO链接
Emigna

另外,我认为您不需要,!吗?在这一点上不应该有任何回溯。
Emigna

@Emigna感谢您的提示,我将在短期内实施它们。我也认为,!没有必要,但是当我测试程序时它会回溯。似乎尝试了所有可能的排序,L然后将它们全部排序。这意味着它将给出相同的回答A!时间。
小麦巫师

5

Haskell68 65字节

f x=minimum[abs$read(take i x)-read(drop i x)|i<-[1..length x-1]]

在线尝试!

说明

minimum              -- Minimum of ...
 [abs$               -- The absolute value of ...
  read(take i x)     -- The first i characters of x
  -                  -- Minus ...
   read(drop i x)    -- The last i characters of x
 |i<-[1..length x-1] -- From i=1 to i=length x - 1
 ]

4

木炭,14字节

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

在线尝试!链接是详细版本的代码。方便地,我可以使用的2-arg变体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个字节感谢Dennis。输入是数字列表。

说明

ḌÐƤḊạḌƤṂ
ḌÐƤ          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

嗯,您的解释似乎并未反映出您的代码实际上是做什么的。
暴民埃里克(Erik the Outgolfer)'17年

@EriktheOutgolfer当它说“删除第一个元素”时,它是“删除最后一个元素”部分吗?我会解决此问题,谢谢您指出
dylnan

3

时髦159个 134 99字节

s=>{S={}fori=1i<#s i++{S[#S]=(((v=s::sublist)(0,i)::reduce@..-v(i)::reduce@..)^2)^.5};math.min...S}

实际上,符合规格似乎要短一些。

在线尝试!


3

视网膜,36字节

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

Om`^.*
\G1

在线尝试!

说明

\B
,$'¶$`

这将在单独的行上生成所有可能的分区,并在原始输入的末尾生成行。

\d+
$*

将每个分区中的每个数字转换为一元。

(1*),\1

1从每个分区的两个部分中删除一个最大和相等的s(即删除最小值,然后从最大值中减去它,得出绝对差)。

Om`^.*

排序行。

\G1

1在第一行计数s,这将得出最小的绝对差。


3

J32,27 23字节

-5个字节,感谢FrownyFrog!如果输入为字符串,则为-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-谢谢!
Galen Ivanov

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在第一次迭代时都被强制为字符串。通常,对于数字文字中的前导零,我们应格外小心:0123 - 10 === 73因为0123解析为八进制值(现在已弃用,但在非严格模式下仍然有效)。但是'0123' - '10' === 113,这次的前导零被忽略了。因此,这样做很合理。

从应用于字符串的抽象操作的规范ToNumber

十进制的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 '17



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,等价于{#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的最新功能之一,即如果未定义其他行为,则将功能应用于列表默认情况下会将功能映射到列表上。这意味着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


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网站免费下载APLX的副本,我的代码也可以使用。它在Dyalog的在线Try APL中不起作用。dyalog.com/aplx.htm
Graham


1

C#(.NET核心)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可能会节省您几个字节
Caius Jard

1

Common Lisp,131个字节

第一次参加代码高尔夫,我决定使用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个字节,请参见此处。如果您尚未看到此内容,也许您会找到一些提示。
ბიმო
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.