가장 작은 정수 디스크


23

이 과제는 특정 지점이 포함 된 가장 작은 디스크를 찾는 것입니다. 그러나이 도전에서는 디스크의 좌표와 반지름이 모두 정수 여야한다는 사실에 의해 다소 까다로워집니다.

귀하의 입력은 정수 좌표 점의 목록이 될 것입니다 xy. 이것을 튜플 목록, 목록 목록 또는 쌍 모음을 나타내는 다른 방법으로 사용할 수 있습니다. x그리고 y둘 다 정수일 것입니다. 모든 포인트는 고유하며 적어도 하나의 포인트가 있습니다.

귀하의 출력은 세 개의 숫자의 형태로 디스크 것 X, Y하고 R. X, Y그리고 R모든 정수는, XY디스크의 센터를 대표하고 R그 반경을 나타냅니다. 모든 주어진 점과 중심 사이의 거리는보다 작거나 같아야하며 R, R이 조건을 만족 하는 더 작은 디스크가 없어야합니다 .

주어진 입력에 대해 여러 가지 가능한 솔루션이있을 수 있습니다.이 경우 코드는 적어도 하나의 솔루션을 출력해야합니다.

언어가 지원하는 모든 종류의 지오메트리 내장 기능을 사용할 수 있으며 입력 / 출력은 숫자 대신 내장 포인트 / 디스크 객체를 통해 이루어질 수 있습니다.

테스트 사례

Input   (Possible) Output(s)
(x,y)   (X,Y,R)
-------------------------
(0,0)   (0,0,0)
-------------------------
(0,1)   (0,0,1)
(1,0)   (1,1,1)
-------------------------
(1,4)   (4,4,3)
(3,2)
(4,1)
(4,5)
(5,2)
(7,4)
-------------------------
(-1,0)  (0,0,2)
(2,0)   (1,0,2)
-------------------------
(-1,0)  (1,0,2)
(2,1)   (0,1,2)
-------------------------
(0,0)   (1,0,1)
(1,1)   (0,1,1)

가장 적은 바이트가 이깁니다.



당신은 내가 그들을 지적 괜찮다면, 몇 오타 발견 : "이것은 어느 정도 만들어 속여 난을 어 ..."; "... 디스크의 중심을 나타내고, R은 I 나타내는 t 의 반경 ..."; "... 저기 안 존재 ... 이러한 디스크를"
J. 셀리

2
일반적으로 정수를 만들면 코드 골프가 쉬워집니다.
user202729

@KevinCruijssen 우연의 일치입니다. 입력 순서는 상관 없습니다.
Pavel

1
입력 @Pavel 수 있습니다 임의의 순서로, 또는 우리가 취할 수있는 임의의 순서로 입력을? 마찬가지로 입력은 순서에 관계없이 솔루션에서 수동으로 먼저 정렬해야합니까, 아니면 입력을 미리 정렬 할 수 있습니까?
케빈 크루이 ssen

답변:


6

젤리 , 25 24 22 21 20 18 바이트

«/r»/Œpµ³_²§½ṀĊ,)Ṃ

에 대해 알려주고 )1 바이트를 절약 한 @EriktheOutgolfer에게 감사드립니다 .

2 바이트를 절약 한 @Dennis에게 감사합니다.

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

설명

«/r»/Œpµ³_²§½ṀĊ,)Ṃ      Main link. Arg: points
                        e.g. [[1,4],[3,2],[3,1]]
«/                      Find minimums by coordinate
                        e.g. [1,1]
   »/                   Find maximums by coordinate
                        e.g. [3,4]
  r                     Inclusive ranges by coordinate
                        e.g. [[1,2,3],[1,2,3,4]]
     Œp                 Cartesian product of the x and y ranges
                        e.g. [[1,1],[1,2],[1,3],[1,4],...,[3,4]]
       µ                    Chain, arg: center
                            e.g. [1,3]
        ³                   Get the original points
                            e.g. [[1,4],[3,2],[3,1]]
         _                  Subtract the center from each
                            e.g. [[0,1],[2,-1],[2,-2]]
          ²                 Square each number
                            e.g. [[0,1],[4,1],[4,4]]
           §                Sum each sublist
                            e.g. [1,5,8]
            ½               Square root of each number
                            e.g. [1,2.24,2.83]
             Ṁ              Find the maximum
                            e.g. 2.83
              Ċ             Round up
                            e.g. 3
               ,            Pair with the center point
                            e.g. [3,[1,3]]
                )       Do the above for all points
                        e.g. [[3,[1,1]],[3,[1,2]],[3,[1,3]],...,[3,[3,4]]]
                 Ṃ      Find the lexicographically smallest pair
                        e.g. [3,[1,1]]

@Dennis 감사합니다! Jelly의 벡터화는 언제부터 더 짧은 목록을 반복 했습니까?
PurkkaKoodari

깊이가 먼저 일치합니다. 쌍과 쌍의 배열이면 쌍이 모든 쌍과 일치합니다.
Dennis

8

Brachylog v2, 19 바이트

;Az{\-ᵐ~√ᵐ+}ᵐ≤ᵛ√;A≜

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

이 프로그램은 쓰기가 쉬웠다 – Brachylog는 이런 종류의 문제에 거의 완벽하지만 골프하기는 어렵다. 내가 효과가있는 것 같지 않은 것처럼 여기에 어딘가에 바이트를 저장 한 경우 놀라지 않을 것입니다 (그리고 중첩 된지도 명령, 일반적으로 회원 / 핀을 사용해야한다는 표시가 포함되어 있지만, 할 수는 없습니다) 방법을 참조하십시오).

이것은 기능 제출입니다. 입력은 형식에서 왼쪽 인수부터 함수까지[[x,y],[x,y],…] 의 오른쪽 인수에서 출력[r,[[x,y]]] . (입력에서 음수를 사용 _하려면 Brachylog가 빼기 기호가 아닌을 사용한다는 점에 유의하십시오 -. Brachylog와 함께 제공되는 함수 → 전체 프로그램 랩퍼가 명령 행 인수를 사용하여 요청 하면 음수가 표시 되므로 혼동 Z됩니다. 에서 출력 정규 마이너스 기호.)

설명

;Az{\-ᵐ~√ᵐ+}ᵐ≤ᵛ√;A≜
;A                   Append something
  z                    to every element of the input
   {       }ᵐ        such that for each resulting element:
     -                 Subtracting
    \ ᵐ                  corresponding elements {of the (input, appended) element}
       ~√              and un-squarerooting
         ᵐ               {the result of} each {subtraction}
          +            and summing {the resulting square numbers}
             ≤       {lets us find} a number at least as large as
              ᵛ        every element {of the list of sums}
               √     which can be square-rooted;
                ;A   append the same list as initially to it.
                  ≜  Find the first integer solution to the above, lexicographically.

Brachylog에 특정 속성 값 (이 경우에는 중심점을 중심으로 한 디스크 반경)을 찾도록 요청한다는 점에서 흥미 롭습니다. A 모든 입력 지점에 맞는 을 하지만 요구 사항을 거의 적용하지 않는다는 반지름은 숫자입니다). 그러나 Brachylog는 콘크리트 숫자를 사용하지 않고 내부적으로 문제의 반지름을 상징적으로 계산하므로 최종 값에 도달하면 두 가지 작업을 한 번에 수행합니다. 먼저 좌표 A와 반지름에 정수만 사용되도록합니다. (제곱 반지름을 제곱수로 강제하고 ≤ᵛ"최대 값 이상"을 찾는 사용법을 설명 ); 둘째, 가능한 가장 작은 가능한 반경을 찾습니다 (반지름이 출력에서 ​​첫 번째가 됨).

프로그램에서 지정되지 않은 한 가지는 모든 포인트가 디스크의 동일한 중심에 대해 측정된다는 것입니다. 작성된 바와 같이, 우리는 각 지점마다 다른 중심을 사용하지 않는다는 제약이 없습니다. 그러나 순위 결정 순서 (이 경우 세 번째에 의해 설정 됨) 구조 제약 조건이 값 제약 조건이 암시하기 전에 평가됨) )는 A가능한 한 짧아야합니다 (예 : 단일 요소이므로 동일한 요소를 사용함) 매번 중앙에; 그것은 A먼저 길이가 0을 시도 하지만 분명히 작동하지 않으므로 다음에 싱글 톤 목록을 시도하십시오). 결과적으로, 우리는 "무료"라는 유용한 제약 (하나의 디스크 만 가지고 있음)을 얻게됩니다.

이 솔루션 은 소스 코드를 변경하지 않고 여러 차원으로 일반화 합니다. 여기에는 사물이 2 차원이라는 가정이 없습니다. 따라서 가장 작은 정수 영역이 필요한 경우에도 마찬가지입니다.


3

펄 6 , 81 바이트

{min [X]([Z]($^p)>>.minmax).map:{$p.map({(@_ Z-$_)>>².sum**.5}).max.ceiling,$_}}

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

점리스트를 2 요소리스트로 취합니다 ((X1, Y1), (X2, Y2), ...). 리스트를 돌려 (R, (X, Y))줍니다. Pietu1998의 Jelly 답변과 동일한 접근 방식을 사용합니다.

[X]([Z]($^p)>>.minmax)  # All possible centers within the bounding box
.map:{ ... }            # mapped to
$p.map({(@_ Z-$_)>>².sum**.5}).max  # maximum distance from any point
.ceiling                # rounded up,
,$_                     # paired with center.
min                     # Find minimum by distance.

minmax메소드는 다음을 반환하므로 유용합니다.Range . 범위의 데카르트 곱은 정수 좌표를 가진 모든 점을 직접 산출합니다.


2

05AB1E , 26 바이트

øεWsàŸ}`âεUIεX-nOt}àîX‚}{н

@ Pietu1998 포트 의 젤리 답변 .

온라인으로 시도 하거나 모든 테스트 사례를 확인하십시오 .

설명:

ø                    # Zip the (implicit) input, swapping the rows and column
                     #  i.e. [[1,4],[3,2],[3,1]] → [[1,3,3],[4,2,1]]
 ε    }              # Map each to:
  W                  #  Push the smallest value (without popping the list)
                     #   i.e. [[1,3,3],[4,2,1]] → [1,1]
   s                 #  Swap so the list is at the top of the stack again
    à                #  Pop the list and push the largest value
                     #   i.e. [[1,3,3],[4,2,1]] → [3,4]
     Ÿ               #  Take the inclusive range of the min and max
                     #   i.e. [[1,2,3],[1,2,3,4]]
`                    # After the map, push both lists separated to the stack
 â                   # And take the cartesian product of the two lists
                     #  i.e. [[1,2,3],[1,2,3,4]]
                     #   → [[1,1],[1,2],[1,3],[1,4],[2,1],[2,2],[2,3],[2,4],[3,1],[3,2],[3,3],[3,4]]
  ε             }    # Map each pair to:
   U                 #  Pop and store the current value in variable `X`
    I                #  Push the input
     ε     }         #  Map each pair in the input to:
      X              #   Push variable `X`
       -             #   Subtract it from the current pair
                     #    i.e. [3,2] - [1,3] → [2,-1]
        n            #   Take the square of each
                     #    i.e. [2,-1] → [4,1]
         O           #   Sum the lists
                     #    i.e. [4,1] → 5
          t          #   Take the square-root of each
                     #    i.e. 5 → 2.23606797749979
            à        #  Pop the converted list, and push its largest value
                     #   i.e. [[3.0,2.23606797749979,2.0],[2.0,2.0,2.23606797749979],...,[2.0,2.0,3.0]]
                     #    → [3.0,2.23606797749979,...,3.0]
             î       #  Round it up
                     #   i.e. [3.0,2.23606797749979,...,3.0] → [3.0,3.0,3.0,4.0,4.0,3.0,3.0,4.0,4.0,3.0,3.0,3.0]
              X     #  Pair it with variable `X`
                     #   i.e. [[3.0,[1,1]],[3.0,[1,2]],...,[3.0,[3,4]]]
                 {   # After the map, sort the list
                  н  # And take the first item (which is output implicitly)
                     #  i.e. [[3.0,[1,1]],[3.0,[1,2]],...,[3.0,[3,4]]] → [3.0,[1,1]]

2

Matlab, 73 바이트

function g(x);[r,~,d]=fminimax(@(a)pdist2(x,a),[0 0]);[round(r) ceil(d)]

가장 작은 솔루션 (부동 소수점)을 찾아 가장 가까운 점으로 반올림하고 반지름을 좁 힙니다 (minimax 문제의 경우 최악). 그것이 가능한 모든 경우 (정확도 내)에 올바른 솔루션을 제공하는지 확실하지 않지만 테스트 사례에서는 입력 오류가 발생하지 않으면 작동합니다.

전화 해

g([1 4;3 2;4 1;4 5;5 2;7 4])

(0,0),(1,1)fminimax(0.5,0.5)(1,1)2/21(0,0).
주세페

맞지만 fminimax의 출력은 [0.500000211699422 0.499999788525202]이므로 올림됩니다. 그래서 나는 운이 좋다. 나는 현재이 문제를 회피하는 방법을 생각하고 있습니다 (순수한 운으로 만 작동하기 때문에).
조나스

2

Pyth , 34 33 바이트

hSm+.EeSm@s^R2-Vdk2Qd*Fm}FhM_BSdC

출력 형태 [R,x,y]

여기 에서 온라인으로 시도 하거나 모든 테스트 사례를 한 번에 확인 하십시오 .

hSm+.EeSm@s^R2-Vdk2Qd*Fm}FhM_BSdCQ   Implicit: Q=eval(input())
                                     Trailing Q inferred
                                CQ   Transpose (group x and y coordinates separately)
                       m             Map each in the above, as d, using:
                              Sd       Sort d
                            _B         Pair with its own reverse
                          hM           Take the first element of each, yielding [min, max]
                        }F             Generate inclusive range
                     *F              Cartesian product of the above two lists, yielding all coordinates in range
  m                                  Map each coordinate in the above, as d, using:
        m          Q                   Map each coordinate in input, as k, using:
              -Vdk                       Take the difference between x and y coordinates in d and k
           ^R2                           Square each
          s                              Sum
         @        2                      Take the square root
      eS                               Take the largest of the result
    .E                                 Rounded up
   +                d                  Prepend to d
 S                                   Sort the result, first element as most significant
h                                    Take first element

편집 : 이전 버전의 출력 형식을 재정렬하여 바이트를 저장했습니다.

heDm+d.EeSm@s^R2-Vdk2Q*Fm}FhM_BSdC


2

Wolfram Language (Mathematica) , 66 바이트

다음은 무차별 대입 방식입니다. 훨씬 짧은 BoundingRegion[#,"MinDisk"]&함수를 고려 했지만 정수 좌표 및 반경을 강제로 지정할 방법이 없습니다.

Minimize[{r,RegionWithin[{x,y}~Disk~r,Point@#]},{x,y,r},Integers]&

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


좋은. 그러나 {Round@#[[1]], Ceiling@#[[2]]} &@BoundingRegion[#, "MinDisk"]&어떻습니까?
DavidC

@DavidC, 중심의 반올림은 중심을 Sqrt [2] /2=.707까지 올릴 수 있지만, 천장을 가져와야 반경에 충분한 길이를 추가 할 필요는 없습니다. 나는 그 실패의 예가 {{0,0}, {11,11}}의 두 가지 점일 뿐이라고 생각합니다.
Kelly Lowder

무슨 말인지 알 겠어!
DavidC

2

자바 10, 283 279 277 257 바이트

C->{int M=1<<31,m=M,X=M,Y=M,x=M-1,y=x,t,a,b,r[]={x};for(var c:C){x=(t=c[0])<x?t:x;X=t>X?t:X;y=(t=c[1])<y?t:y;Y=t>Y?t:Y;}for(;y<=Y;y++)for(t=x;t<=X;r=m<r[0]?new int[]{m,t,y}:r,m=M,t++)for(var c:C){a=c[0]-t;b=c[1]-y;a*=a;m=(a=(int)Math.ceil(Math.sqrt(a+=b*=b)))>m?a:m;}return r;}

@nwellnhof 의 팁 덕분에 -20 바이트 Math.hypot.

결과 배열은 순서대로 [R,X,Y]입니다.

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

설명:

C->{                  // Method with 2D int-array as parameter & int-array as return-type
  int M=1<<31,        //  Minimum `M`, starting at -2,147,483,648
      m=M,            //  Temp integer, starting at -2,147,483,648 as well
      X=M,            //  Largest X coordinate, starting at -2,147,483,648 as well
      Y=M,            //  Largest Y coordinate, starting at -2,147,483,648 as well
      x=M-1,          //  Smallest X coordinate, starting at 2,147,483,647
      y=x,            //  Smallest Y coordinate, starting at 2,147,483,647 as well
      t,a,            //  Temp integers, starting uninitialized
      r[]={x};        //  Result-array, starting at one 2,147,483,647
  for(var c:C){       //  Loop over the input-coordinates
    x=(t=c[0])<x?t:x; //   If the X coordinate is smaller than `x`, change it
    X=t>X?t:X;        //   If the X coordinate is larger than `X`, change it
    y=(t=c[1])<y?t:y; //   If the Y coordinate is smaller than `y`, change it
    Y=t>Y?t:Y;}       //   If the Y coordinate is larger than `Y`, change it
 for(;y<=Y;y++)       //  Loop `y` in the range [`y`,`Y`]:
   for(t=x;t<=X       //   Inner loop `t` in the range [`x`,`X`]:
          ;           //     After every iteration:
           r=m<r[0]?  //      If `m` is smaller than the first value:
              new int[]{m,t,y}
                      //       Replace the result with `m,t,y`
             :        //      Else:
              r,      //       Leave `r` unchanged
           m=M,       //      Reset `m` to -2,147,483,648 for the next iteration
           t++)       //      And increase `t` by 1
     for(var c:C)     //    Inner loop over the input-coordinates
       m=(a=(int)Math.ceil(Math.hypot(c[0]-t,c[1]-y)))
                      //     Subtract `t` from the X coordinate;
                      //     subtract `y` from the Y coordinate;
                      //     take the hypot (<- sqrt(x*x+y*y)) of those
                      //     ceil it
                      //     And set `a` to this value
          >m?         //     If `a` is larger than `m`:
           a          //      Set `m` to `a`
          :           //     Else:
           m;         //      Leave `m` unchanged
  return r;}          //  Return the result `r`

1
으로 최소 8 바이트를 저장할 수 있습니다 Math.hypot.
nwellnhof

@nwellnhof Ah, 완전히 잊어 버렸습니다 Math.hypot.이 도전에 완벽합니다! 바로 -20 바이트입니다. 감사. :)
Kevin Cruijssen

1

자바 스크립트, 245 바이트

a=>{[b,c,d,e]=a.reduce(([j,k,l,m],[h,i])=>[j>h?j:h,k<h?k:h,l>i?l:i,m<i?m:i],[,,,,]);for(f=c;f<b;f++){for(g=e;g<d;g++){s=a.reduce((o,[p,q])=>o>(r=(p-f)**2+(q-g)**2)?o:r);n=n?n[2]>s?[f,g,s]:n:[f,g,s]}}return [n[0],n[1],Math.ceil(Math.sqrt(n[2]))]}

더 읽기 쉬운 버전 :

a=>{
    [b,c,d,e]=a.reduce(([j,k,l,m],[h,i])=>[j>h?j:h,k<h?k:h,l>i?l:i,m<i?m:i],[,,,,]);
    for(f=c;f<b;f++){
        for(g=e;g<d;g++){
            s=a.reduce((o,[p,q])=>o>(r=(p-f)**2+(q-g)**2)?o:r);
            n=n?n[2]>s?[f,g,s]:n:[f,g,s]
        }
    }
    return [n[0],n[1],Math.ceil(Math.sqrt(n[2]))]
}

경계 상자를 찾아서 해당 상자의 각 좌표가 최상의 지 여부를 테스트합니다.

다음을 대체하여 대략적인 답변으로 8 바이트를 절약 할 수 있습니다.

Math.ceil(Math.sqrt(n[2]))~~(n[2]+1-1e-9)


골프에는 더 많은 것들이 있지만 JS는 내 강점이 아닙니다. 그래도 골프 for(f=c;f<b;f++){for(g=e;g<d;g++){s=a.reduce((o,[p,q])=>o>(r=(p-f)**2+(q-g)**2)?o:r);n=n?n[2]>s?[f,g,s]:n:[f,g,s]}}를 하실 수 있습니다 for(f=c;f<b;f++)for(g=e;g<d;n=n?n[2]>s?[f,g,s]:n:[f,g,s],g++)s=a.reduce((o,[p,q])=>o>(r=(p-f)**2+(q-g)**2)?o:r);. 에서 공간을 제거 할 수 있다고 확신합니다 return[.
케빈 크루이 ssen

1
을 사용하여 몇 바이트를 절약 할 수 있습니다 Math.hypot.
nwellnhof


1

, 65 바이트

≔Eθ§ι¹ζ≔Eθ§ι⁰ηF…·⌊η⌈ηF…·⌊ζ⌈ζ⊞υ⟦ικ⟧≔Eυ⌈EθΣEιX⁻§λξν²ηI§υ⌕η⌊ηI⌈X⌊η·⁵

온라인으로 사용해보십시오! 링크는 자세한 버전의 코드입니다. 설명:

≔Eθ§ι¹ζ

y 좌표를에 넣습니다 z.

≔Eθ§ι⁰η

x 좌표를로 가져옵니다 h.

F…·⌊η⌈ηF…·⌊ζ⌈ζ⊞υ⟦ικ⟧

의 최대 값으로 최소의 포괄적 인 범위에서 루프 hz모든 잠재적 디스크 센터의 목록을 생성.

≔Eυ⌈EθΣEιX⁻§λξν²η

모든 디스크 중심을 반복 한 다음 모든 원래 점을 반복 한 다음 두 좌표를 반복하고 빼기, 제곱, 합계, 최대 값을 취하고 결과 목록을 저장하십시오.

I§υ⌕η⌊η

최소 최대 직경의 위치를 ​​찾아 해당 디스크 센터를 인쇄하십시오.

I⌈X⌊η·⁵

최소 최대 직경을 인쇄하되 다음 정수로 반올림하십시오.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.