En Küçük Tamsayı Diski


23

Bu zorluk, verilen bazı noktaları içeren en küçük diski bulmakla ilgilidir. Bu biraz daha zorlaştırılmıştır, ancak, bu zorlukla, diskin koordinatlarının ve yarıçapının her ikisi de tamsayı olması gerektiği gerçeğiyle.

Girdi, tamsayı koordinatlarına sahip xve işaretli noktaların bir listesi olacaktır y. Bunu, bir troller listesi, bir liste listesi veya bir çift koleksiyonunu temsil etmenin herhangi bir yolu olarak kabul edebilirsiniz. xve yher ikisi de (muhtemelen negatif) tamsayılar olacaktır. Her noktanın benzersiz olması garanti edilir ve en az bir nokta olacaktır.

Çıktınız üç sayılar, şeklinde disk olacak X, Yve R. X, Yve Rhepsi tam sayılardır Xve Ydiskin merkezini Rtemsil eder ve yarıçapını gösterir. Verilen her nokta ile merkez arasındaki mesafe eşit veya daha küçük Rolmalı ve Rbu durumu da sağlayan daha küçük bir disk bulunmamalıdır .

Belirli bir giriş için birden fazla olası çözüm olabilir, kodunuz bu durumda bunlardan en az birini vermelidir.

Varsa, dilinizin desteklediği her türlü geometriyi kullanabilirsiniz ve giriş / çıkış sadece sayılar yerine yerleşik nokta / disk nesneleri üzerinden olabilir.

Test Kılıfları

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)

En az bayt kazanır.



Bana bunları işaret sakıncası yoksa, birkaç yazım hataları Bulunan: "Bu biraz yapılır kandırmak i er ..."; "... diskin merkezi temsil eder ve R 'temsil eder t s çapındaki ..."; "... ve orada olmamalıdır var ... Böyle bir disk"
J. Salle

2
Genelde bazı şeyleri tamsayı yapmak kod golfünü kolaylaştırır.
user202729

@KevinCruijssen Bu tesadüf eseridir. Girişler herhangi bir sırada olabilir.
Pavel

1
Girdi @Pavel olabilir herhangi bir sırada, ya da biz alabilir herhangi bir sırada girdi? Olduğu gibi, giriş herhangi bir sırada olabilir ve ilk önce bizim çözümümüzde manuel olarak sıralamalı mıyız, yoksa girişi önceden sıralanmış olarak alabilir miyiz?
Kevin Cruijssen

Yanıtlar:


6

Jöle , 25 24 22 21 20 18 bayt

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

@EriktheOutgolfer'a )1 byte tasarruf sağladığımı bildirdiğiniz için teşekkür ederiz .

2 bayt tasarrufu için @Dennis teşekkürler.

Çevrimiçi deneyin!

açıklama

«/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 Teşekkürler! Jelly'in vektörleşmesi ne zamandan beri kısa listeyi tekrarlıyor, yoksa kaldırılmasını yanlış mı yorumluyorum ?
PurkkaKoodari

Derinlikler önce eşleştirilir. Siz bir çift ve bir çift çift varsa, çift tüm çiftlerle eşleşir.
Dennis,

8

Brachylog v2, 19 bayt

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

Çevrimiçi deneyin!

Bu program yazmak kolay oldu - Brachylog bu tür bir sorun için neredeyse mükemmel - ama golf oynamak zor. Burada bir yerde bir bayt kaydedilmesi beni şaşırtmazdı, herhangi bir etkim var gibi göründüğü için birkaç şey (ve iç içe harita yönergeleri içeriyordu, normalde üye / findall kullanmanız gerektiğinin bir işareti) Bunu yapmanın bir yolunu görmek).

Bu bir işlev sunumu. Giriş, sol argümandan biçimdeki işleve [[x,y],[x,y],…], sağ argümandan biçimdeki çıktıdır [r,[[x,y]]]. (Girişte negatif sayılar denemek istiyorsanız, Brachylog’nun _eksi işareti için kullandığına dikkat edin -. Bu kafa karıştırıcıdır, çünkü işlev → Brachylog’nun komut satırı argümanı kullanılarak istenen tam program sarmalayıcısı Zeksi sayılar gösterecektir. içinde çıkış düzenli eksi işareti.)

açıklama

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

Bu ilginçtir, Brachylog'dan belirli özelliklerin bir değerini bulmasını istiyoruz (bu durumda, Atüm giriş noktalarına uyan bir noktada merkezlenmiş bir diskin yarıçapı ), ancak bunun üzerine herhangi bir gereksinimi zorlaştırıyoruz (tek istediğimiz şey yarıçapı bir sayıdır). Bununla birlikte, Brachylog somut sayıları kullanmaya çalışmak yerine, söz konusu yarıçapı sembolik olarak hesaplayacaktır, bu nedenle finale ulaşıldığında, aynı anda iki şeyi gerçekleştirir: ilk önce, sadece tam sayıların Ayarıçapı için ve yarıçapı için kullanılmasını sağlar (kare yarıçapı kare bir sayı olmaya zorlamak ve ≤ᵛ"maksimum veya daha büyük" bulmak için kullanımını açıklamak ); ikincisi, mümkün olan en küçük yarıçapı bulur (yarıçap, çıktıda birinci gelir).

Programda hiç belirtilmemiş olan bir şey, tüm noktaların bir diskin aynı merkezine göre ölçülmesidir; yazıldığı gibi, her nokta için farklı bir merkez kullanmadığımız konusunda herhangi bir kısıtlama yoktur. Bununla birlikte, tiebreak siparişi (bu durumda üçüncü tarafından ayarlanır ve hangi yapı kısıtlaması olarak ima edilen değer kısıtlamasından önce değerlendirilir ) Amümkün olduğu kadar kısa olmak ister (yani tek bir eleman, her seferinde merkezde olacak, Aönce sıfır uzunluğunu deneyecek, fakat açıkçası işe yaramadığı için bir singleton listesi çalışacaktır. Sonuç olarak, yararlı bir kısıtlama elde ediyoruz (sadece bir diskimiz var) "bedava".

Bu çözüm , kaynak kodunda değişiklik yapılmadan herhangi bir sayıda boyuta genelleme yapar ; Burada işlerin iki boyutlu olduğu varsayımı yoktur. Eğer en küçük tam sayı küresine ihtiyacınız olursa, buna da sahip olabilirsiniz.


3

Perl 6 , 81 bayt

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

Çevrimiçi deneyin!

2 elemanlı liste olarak noktaların bir listesini alır ((X1, Y1), (X2, Y2), ...). Bir liste döndürür (R, (X, Y)). Pietu1998'in Jelly cevabıyla aynı yaklaşımı kullanır:

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

minmaxYöntem, bir döner burada yararlıdır Range. Kartezyen ürün yelpazesi, tüm noktaları tam sayı koordinatlarıyla doğrudan verir.


2

05AB1E , 26 bayt

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

Limanı @ Pietu1998 'ın Jelly cevap .

Çevrimiçi deneyin veya tüm test durumlarını doğrulayın .

Açıklama:

ø                    # 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 bayt

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

Sadece en küçük çözümü (kayan nokta) bulun ve en yakın noktaya yuvarlayın ve yarıçapı tavanlayın (minimax problemi için en kötü durum). Bunun tüm olası durumlar için (hassasiyet dahilinde) doğru çözümü sağlayıp sağlamadığından emin değilim, ancak test durumları için çalışması gerekir (yazma hatası yapmazsam).

İle ara

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)

Haklısınız, ancak fminimax'ın çıktısı [0.500000211699422 0.499999788525202], yani doğru yuvarlanıyor. Bu yüzden burada şanslıyım. Şu anda bu problemi nasıl önleyeceğimi düşünüyorum (sadece şansa göre çalıştığı için).
Jonas

2

Pyth , 34 33 bayt

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

Çıktı biçiminde [R,x,y]

Online Deneyin burada ya bir kerede tüm test durumları doğrulamak burada .

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

Düzenleme: Çıkış biçimini yeniden düzenleyerek bir bayt kaydedildi, önceki sürüm:

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


2

Wolfram Dili (Mathematica) , 66 bayt

İşte kaba kuvvet yaklaşımı. Çok daha kısa bir BoundingRegion[#,"MinDisk"]&fonksiyonu düşündüm ama tamsayı koordinatlarını ve yarıçapı zorlamanın bir yolu yok.

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

Çevrimiçi deneyin!


Güzel. Ama, peki ya {Round@#[[1]], Ceiling@#[[2]]} &@BoundingRegion[#, "MinDisk"]&?
DavidC

@DavidC, merkezin yuvarlanması onu Sqrt [2] /2=.707 değerine kadar hareket ettirebilir, ancak tavana kavuşturmak, buna cevap vermek için yarıçapa yeterli uzunluk kazandırmayabilir. Bence bu başarısızlığa bir örnek sadece iki puan olacaktır {{0,0}, {11,11}}
Kelly Lowder

Ne demek istediğini anlıyorum!
DavidC

2

Java 10, 283 279 277 257 bayt

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 'un kullandığı ipucu sayesinde -20 bayt Math.hypot.

Sonuç dizisi sırada [R,X,Y].

Çevrimiçi deneyin.

Açıklama:

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
İle en az 8 bayt kaydedebilirsiniz Math.hypot.
nwellnhof

@nwellnhof Ah, Math.hypotbu meydan okuma için mükemmel olan , tamamen unuttum ! -20 bayt orada. Teşekkürler. :)
Kevin Cruijssen

1

Javascript, 245 bayt

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]))]}

(Biraz) daha okunaklı versiyon:

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]))]
}

Sadece sınırlama kutusunu bulur ve bu kutudaki her bir koordinatı en iyi olup olmadığını test eder.

Değiştirerek 8 baytı yaklaşık bir cevapla kaydedebiliyordum:

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


Golf için kesinlikle daha fazla şeyler var, ancak JS benim güçlü süitim değil. Yine de, golf can 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]}}için 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);. Ve yerdeki alanı kaldırabileceğinizden eminim return[.
Kevin Cruijssen

1
Muhtemelen kullanarak birkaç bayt kaydedebilirsiniz Math.hypot.
nwellnhof


1

Kömür , 65 bayt

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

Çevrimiçi deneyin! Bağlantı, kodun ayrıntılı bir versiyonudur. Açıklama:

≔Eθ§ι¹ζ

Y koordinatlarını gir z.

≔Eθ§ι⁰η

X koordinatlarını içine al h.

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

Kapsayıcı döngü boyunca, minimumlardan maksimumlara kadar tüm potansiyel disk merkezlerinin listesini oluşturur hve zoluşturur.

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

Tüm disk merkezlerinin üzerinde döngü yapın, sonra tüm orijinal noktaların üzerinde döngü yapın, sonra her iki koordinat üzerinde döngü yapın, çıkarın, çıkarın, toplayın, maksimum alın ve sonuçtaki listeyi kaydedin.

I§υ⌕η⌊η

Minimum maksimum çapın konumunu bulun ve ilgili disk merkezini yazdırın.

I⌈X⌊η·⁵

Minimum maksimum çapı yazdırın, ancak bir sonraki tamsayıya yuvarlayın.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.