최대한 공정하게


33

소개

이 도전에서는 정수를 두 조각으로 나누어야합니다. 더 작은 케이크 조각을 좋아하는 사람은 없기 때문에 목표는 가능한 한 공정해야합니다. 예를 들어 정수 7129를 두 조각으로 나누려면 세 가지 방법이 있습니다.

7,129, 71,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

답변:


11

Brachylog , 12 11 바이트

나의 첫 번째 Brachylog 답변

문자열로 입력하십시오

{~cĊịᵐ-ȧ}ᶠ⌋

온라인으로 사용해보십시오!

설명:

F 의 술어 IND 모든 가능한 출력 {…}과리스트에 보관. ~c출력은 c가 붙었을 때 입력과 같은 목록이라고 말합니다 . 다음 Ċ은 출력의 ~c길이가 2라고 가정합니다.

ịᵐ출력의 두 요소를 정수로 변환하고 (이것은 선행을 제거함 0) 두 요소의 절대 차이를 취합니다.

가능한 모든 출력 목록을 얻으면 최소 요소를 얻습니다.



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

펄 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, 그리고 만약 결정 H분할 작은 방법이다 A.

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

여기서 첫 번째 행은 이 SO 포스트 의 기술을 사용 r(A)하여 정수에서 0~ 에 대한 술어 맵을 본질적으로 수행합니다 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

첫 번째 행은 예를 들어 다른 3 A*Hl(A,H)저장하는 대신 시작할 수 있습니다. 그리고 SWI를 사용하는 경우 TIO 링크를
Emigna

또한, 당신이 필요하다고 생각 ,!하지 않습니까? 그 시점에는 역 추적이 없어야합니다.
Emigna

@Emigna 팁을 주셔서 감사합니다. 곧 구현하겠습니다. 나는 또한 ,!필요하지 않다고 생각 했지만 프로그램을 테스트 할 때 역 추적을 수행합니다. 가능한 모든 순서를 시도한 L다음 모두 정렬하는 것 같습니다. 그것은 동일한 응답 A!시간을 줄 것임을 의미합니다 .
밀 마법사

5

하스켈 , 68 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 바이트

ḌÐƤḊạḌƤṂ

온라인으로 사용해보십시오!

Dennis 덕분에 -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

흠, 당신의 설명은 코드가 실제로하는 것을 반영하지 않는 것 같습니다.
Outgolfer Erik

@EriktheOutgolfer "첫 번째 요소 제거"라고 말해야 할 때 "마지막 요소 제거"부분입니까? 지적 해 주셔서 감사합니다
dylnan


3

레티 나 , 36 바이트

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

Om`^.*
\G1

온라인으로 사용해보십시오!

설명

\B
,$'¶$`

이렇게하면 원래 입력이있는 후행 줄뿐만 아니라 별도의 줄에 가능한 모든 파티션이 생성됩니다.

\d+
$*

각 파티션의 각 숫자를 단항으로 변환하십시오.

(1*),\1

1각 파티션의 두 부분에서 최대 및 동일한 양 의을 제거합니다 (즉, 최소값을 제거하고 최대 값에서 빼면 절대 차이가 발생 함).

Om`^.*

줄을 정렬하십시오.

\G1

1첫 번째 줄 에서 s를 세면 절대 차이가 최소화됩니다.


3

J , 32, 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-감사합니다!
Galen Ivanov

3

자바 스크립트 (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첫 번째 반복에서 문자열로 강제 변환됩니다. 일반적으로 숫자 리터럴에서 선행 0을 조심해야합니다 . 8 진수 값으로 구문 분석 0123 - 10 === 73되기 때문 0123입니다 (이는 더 이상 사용되지 않지만 엄격하지 않은 모드에서는 여전히 유효 함). 그러나 '0123' - '10' === 113이번에는 선행 0이 무시됩니다. 그렇게하는 것이 좋습니다.

문자열에 적용된 추상 연산 의 사양 에서 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등가, {#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)

tio.run/##LYuxCsMgFEV3v@IOb1DaZO8/ZHItDlolBEx4qC2FkG9/…lmap 대신에 바이트를 면도 할 수 있습니다 foreach.
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 웹 사이트에서 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

공통 리스프, 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 바이트 단축 할 수 있음을 알았 습니다 . 여기를 참조하십시오 . 당신이 본하지 않은 경우 , 어쩌면 당신은 몇 가지 팁을 찾을 수 있습니다.
ბიმო
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.