Kleinste Ganzzahlplatte

23

Bei dieser Herausforderung geht es darum, die kleinste Festplatte zu finden, die bestimmte Punkte enthält. Dies wird jedoch dadurch etwas schwieriger, dass bei dieser Herausforderung die Koordinaten und der Radius der Platte ganze Zahlen sein müssen.

Ihre Eingabe wird eine Liste von Punkten mit ganzzahligen Koordinaten xund sein y. Sie können dies als Liste von Tupeln, als Liste von Listen oder auf eine andere Weise zur Darstellung einer Sammlung von Paaren verwenden. xund ywerden beide (möglicherweise negative) ganze Zahlen sein. Jeder Punkt ist garantiert einzigartig und es gibt mindestens einen Punkt.

Ihr Ausgang wird eine Platte in Form von drei Zahlen, X, Y, und R. X, YUnd Rsind alle ganzen Zahlen, Xund Yrepräsentieren die Mitte der Scheibe und Rstellt seinen Radius. Der Abstand zwischen jedem gegebenen Punkt und der Mitte muss kleiner oder gleich sein R, und es darf keine solche Scheibe mit einer kleineren Scheibe geben R, die auch diese Bedingung erfüllt.

Es ist möglich, dass es mehrere mögliche Lösungen für eine bestimmte Eingabe gibt. In diesem Fall muss Ihr Code mindestens eine davon ausgeben.

Sie können jede Art von Geometrie verwenden, die von Ihrer Sprache unterstützt wird, und die Eingabe / Ausgabe erfolgt möglicherweise über integrierte Punkt- / Plattenobjekte anstelle von Zahlen.

Testfälle

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)

Wenigste Bytes gewinnt.

Pavel
quelle
Sandbox
Pavel
Gefunden ein paar Tippfehler, wenn Sie nichts dagegen haben mich darauf hinzuweisen: "Dies ist etwas Trick gemacht, ich äh ..."; "... repräsentiert die Mitte der Scheibe und R i t s Radius ..."; „... und es muss nicht existieren eine solche Scheibe ...“
J. Sallé
2
Wenn man Dinge ganzzahlig macht, wird Code-Golf normalerweise einfacher.
user202729
@ KevinCruijssen Das ist Zufall. Die Eingaben können in beliebiger Reihenfolge erfolgen.
Pavel
1
@Pavel Die Eingabe kann in beliebiger Reihenfolge oder wir nehmen die Eingabe in beliebiger Reihenfolge? Wie in kann die Eingabe in beliebiger Reihenfolge erfolgen, und wir sollten zuerst in unserer Lösung manuell sortieren, oder können wir die Eingabe bereits vorsortieren?
Kevin Cruijssen

Antworten:

6

Jelly , 25 24 22 21 20 18 Bytes

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

Vielen Dank an @EriktheOutgolfer, der mich darüber informiert )hat und 1 Byte gespart hat.

Vielen Dank an @Dennis für das Speichern von 2 Bytes.

Probieren Sie es online!

Erläuterung

«/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]]
PurkkaKoodari
quelle
@ Tennis Danke! Seit wann hat Jellys Vektorisierung die kürzere Liste wiederholt, oder habe ich die Entfernung von falsch interpretiert ?
PurkkaKoodari
Die Tiefen werden zuerst abgeglichen. Wenn Sie ein Paar und ein Array von Paaren haben, wird das Paar mit allen Paaren abgeglichen.
Dennis
8

Brachylog v2, 19 Bytes

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

Probieren Sie es online!

Dieses Programm war einfach zu schreiben - Brachylog ist fast perfekt für diese Art von Problem - aber schwer zu golfen. Es würde mich nicht überraschen, wenn hier irgendwo ein Byte gespeichert würde, da nur wenige Dinge, die ich zu tun schien, Auswirkungen hatten (und verschachtelte Kartenanweisungen enthalten, normalerweise ein Zeichen dafür, dass Sie member / findall verwenden sollten, aber ich kann nicht siehe einen Weg, um es zu tun).

Dies ist eine Funktionsübermittlung. Die Eingabe erfolgt vom linken Argument zur Funktion im Format [[x,y],[x,y],…], die Ausgabe vom rechten Argument im Formular [r,[[x,y]]]. (Wenn Sie negative Zahlen in der Eingabe ausprobieren möchten, beachten Sie, dass Brachylog _das Minuszeichen verwendet, nicht -. Dies ist verwirrend, da der Funktions- → vollständige Programm-Wrapper, mit dem Brachylog geliefert wird und der über das Befehlszeilenargument angefordert Zwird, negative Zahlen anzeigt in der Ausgabe mit einem regulären Minuszeichen.)

Erläuterung

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

Dies ist insofern interessant, als wir Brachylog bitten, einen Wert für bestimmte Eigenschaften zu finden (in diesem Fall den Radius einer Scheibe, der auf einen Punkt zentriert ist A, der für alle Eingabepunkte passt), aber kaum Anforderungen an sie stellen (alles, was wir benötigen, ist dass der Radius eine Zahl ist). Brachylog berechnet den fraglichen Radius jedoch intern symbolisch, anstatt zu versuchen, konkrete Zahlen zu verwenden. Wenn also das Endergebnis erreicht ist, werden zwei Dinge gleichzeitig ausgeführt: Erstens wird sichergestellt, dass nur Ganzzahlen für die Koordinaten Aund für den Radius verwendet werden (Erzwingen, dass der quadratische Radius eine quadratische Zahl ist, und Erläutern der Verwendung von ≤ᵛ, um ein "Maximum oder mehr" zu finden); zweitens findet es den kleinstmöglichen realisierbaren Radius (da der Radius in der Ausgabe an erster Stelle steht).

Eine Sache, die im Programm überhaupt nicht spezifiziert ist, ist, dass alle Punkte gegen die gleiche Mitte einer Platte gemessen werden; Wie geschrieben, gibt es keine Einschränkungen, dass wir nicht für jeden Punkt einen anderen Mittelpunkt verwenden. Die Tiebreak-Reihenfolge (die in diesem Fall durch die dritte festgelegt wird und die als Strukturbedingung ausgewertet wird, bevor die Wertbedingung durch impliziert wird ) Asoll jedoch so kurz wie möglich sein (dh ein einzelnes Element, also verwenden wir dasselbe zentrieren Sie jedes Mal, es versucht zuerst eine Null-Länge, Aaber das funktioniert offensichtlich nicht, also versucht es als nächstes eine Singleton-Liste). Infolgedessen erhalten wir eine nützliche Einschränkung (wir haben nur eine Festplatte) "kostenlos".

Diese Lösung lässt sich auf eine beliebige Anzahl von Dimensionen verallgemeinern, ohne den Quellcode zu ändern. Es gibt hier keine Annahmen, dass die Dinge zweidimensional sind. Wenn Sie also zufällig die kleinste ganzzahlige Kugel benötigen, können Sie diese auch haben.

ais523
quelle
3

Perl 6 , 81 Bytes

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

Probieren Sie es online!

Nimmt eine Liste von Punkten als Listen mit zwei Elementen auf ((X1, Y1), (X2, Y2), ...). Gibt eine Liste zurück (R, (X, Y)). Verwendet den gleichen Ansatz wie Pietu1998's Jelly-Antwort:

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

Die minmaxMethode ist hier nützlich, da sie a zurückgibt Range. Das kartesische Produkt der Bereiche liefert direkt alle Punkte mit ganzzahligen Koordinaten.

nwellnhof
quelle
2

05AB1E , 26 Bytes

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

Port of @ Pietu1998 ist Gelee Antwort .

Probieren Sie es online aus oder überprüfen Sie alle Testfälle .

Erläuterung:

ø                    # 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]]
Kevin Cruijssen
quelle
2

Matlab, 73 Bytes

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

Finden Sie einfach die kleinste Lösung (Fließkomma) und runden Sie auf den nächsten Punkt und decken Sie den Radius ab (ungünstigster Fall für das Minimax-Problem). Ich weiß nicht genau, ob das die richtige Lösung für alle möglichen Fälle liefert (innerhalb der Genauigkeit), aber für die Testfälle sollte es funktionieren (wenn ich keinen Tippfehler gemacht habe).

Nennen Sie es mit

g([1 4;3 2;4 1;4 5;5 2;7 4])
Jonas
quelle
(0,0),(1,1)fminimax(0,5,0,5)(1,1)2/21(0,0)
Sie haben Recht, aber die Ausgabe von fminimax ist [0.500000211699422 0.499999788525202], also rundet es richtig. Ich habe Glück hier. Ich denke derzeit darüber nach, wie ich dieses Problem umgehen kann (da es nur durch reines Glück funktioniert).
Jonas
2

Pyth , 34 33 Bytes

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

Die Ausgabe erfolgt in der Form [R,x,y]

Versuchen Sie es online hier oder überprüfen alle Testfälle auf einmal hier .

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

Bearbeiten: Ein Byte durch Neuanordnen des Ausgabeformats gespeichert, vorherige Version:

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

Sok
quelle
2

Wolfram Language (Mathematica) , 66 Bytes

Hier ist ein Brute-Force-Ansatz. Ich habe die viel kürzere BoundingRegion[#,"MinDisk"]&Funktion in Betracht gezogen, aber es gibt keine Möglichkeit, ganzzahlige Koordinaten und Radien zu erzwingen.

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

Probieren Sie es online!

Kelly Lowder
quelle
Nett. Aber wie wäre es {Round@#[[1]], Ceiling@#[[2]]} &@BoundingRegion[#, "MinDisk"]&?
DavidC
@DavidC, die Rundung des Mittelpunkts kann ihn möglicherweise um bis zu Sqrt [2] /2=.707 verschieben, aber die Berücksichtigung der Decke wird dem Radius nicht unbedingt genug Länge hinzufügen, um dem entgegenzuwirken. Ich denke, ein Beispiel für dieses Versagen wären nur die beiden Punkte {{0,0}, {11,11}}
Kelly Lowder
Ich verstehe was du meinst!
DavidC
2

Java 10, 283 279 277 257 Bytes

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

-20 Bytes dank @nwellnhofs Verwendungshinweis Math.hypot.

Das Ergebnis-Array ist in der Reihenfolge [R,X,Y].

Probieren Sie es online aus.

Erläuterung:

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`
Kevin Cruijssen
quelle
1
Sie können mit mindestens 8 Bytes speichern Math.hypot.
Nwellnhof
@nwellnhof Ah, völlig vergessen Math.hypot, das ist perfekt für diese Herausforderung! -20 Bytes genau dort. Vielen Dank. :)
Kevin Cruijssen
1

Javascript, 245 Bytes

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

(Etwas) lesbarere Version:

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

Findet einfach den Begrenzungsrahmen und testet jede Koordinate in diesem Rahmen, um festzustellen, ob sie die beste ist.

Ich könnte 8 Bytes mit einer ungefähren Antwort einsparen, indem ich Folgendes ersetze:

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

Spitemaster
quelle
Es gibt sicherlich mehr Dinge zum Golfen, aber JS ist nicht meine starke Suite. Dennoch können Sie Golf 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]}}auf 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);. Und ich bin mir ziemlich sicher, dass Sie das Leerzeichen entfernen können return[.
Kevin Cruijssen
1
Sie können wahrscheinlich mit ein paar Bytes sparen Math.hypot.
Nwellnhof
1

Ruby , 113 Bytes

->l{a=l.flatten;(z=*a.min..a.max).product(z).map{|x,y|[l.map{|u,v|(((x-u)**2+(y-v)**2)**0.5).ceil}.max,x,y]}.min}

Probieren Sie es online!

GB
quelle
1

Kohle , 65 Bytes

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

Probieren Sie es online! Link ist eine ausführliche Version des Codes. Erläuterung:

≔Eθ§ι¹ζ

Holen Sie sich die y-Koordinaten in z.

≔Eθ§ι⁰η

Holen Sie sich die x-Koordinaten in h.

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

Durchlaufen Sie die Inclusive-Bereiche vom Minimum bis zum Maximum hund zgenerieren Sie die Liste aller potenziellen Disc-Center.

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

Führen Sie eine Schleife über alle Disc-Zentren und dann über alle ursprünglichen Punkte durch. Führen Sie dann eine Schleife über beide Koordinaten durch, subtrahieren Sie, quadrieren Sie, summieren Sie, nehmen Sie das Maximum und speichern Sie die resultierende Liste.

I§υ⌕η⌊η

Suchen Sie die Position des minimalen maximalen Durchmessers und drucken Sie die entsprechende Disc-Mitte.

I⌈X⌊η·⁵

Geben Sie den minimalen maximalen Durchmesser aus, runden Sie ihn jedoch auf die nächste Ganzzahl auf.

Neil
quelle