Schreiben Sie eine Funktion, die 4 Punkte in der Ebene als Eingabe verwendet und true zurückgibt, wenn die 4 Punkte ein Quadrat bilden. Die Punkte haben ganzzahlige Koordinaten mit absoluten Werten <1000.
Sie können eine beliebige sinnvolle Darstellung der 4 Punkte als Eingabe verwenden. Die Punkte werden nicht in einer bestimmten Reihenfolge vergeben.
Kürzester Code gewinnt.
Beispielquadrate:
(0,0),(0,1),(1,1),(1,0) # standard square
(0,0),(2,1),(3,-1),(1,-2) # non-axis-aligned square
(0,0),(1,1),(0,1),(1,0) # different order
Beispiel Nichtquadrate:
(0,0),(0,2),(3,2),(3,0) # rectangle
(0,0),(3,4),(8,4),(5,0) # rhombus
(0,0),(0,0),(1,1),(0,0) # only 2 distinct points
(0,0),(0,0),(1,0),(0,1) # only 3 distinct points
Sie können für das entartete Quadrat entweder true oder false zurückgeben (0,0),(0,0),(0,0),(0,0)
Antworten:
Python
1769079 BytesDie Funktion S verwendet eine Liste komplexer Zahlen als Eingabe (A). Wenn wir sowohl die Mitte als auch eine Ecke eines Quadrats kennen, können wir das Quadrat rekonstruieren, indem wir die Ecke um 90, 180 und 270 Grad um den Mittelpunkt drehen (c). Auf der komplexen Ebene erfolgt die Drehung um 90 Grad um den Ursprung, indem der Punkt mit i multipliziert wird . Wenn unsere ursprüngliche Form und das rekonstruierte Quadrat die gleichen Punkte haben, muss es ein Quadrat gewesen sein.
quelle
J, 28
172527J hat eigentlich keine Funktionen, aber hier ist ein monadisches Verb, das einen Vektor von Punkten aus der komplexen Ebene entnimmt:
Die Methode ist eine Mischung aus Michael Spencer (arbeitet ausschließlich mit Inter-Vertex-Längen, aber er versagt momentan bei meiner Raute2) und Eelvex (prüfe die Größe der Sets). Lesung von rechts nach links:
-/~
Berechnen Sie alle Punktdifferenzen,
ebnen|
Größe extrahieren/:~
sortieren#/.~
Noppen und zählen4 8 4 -:
Muss genau 4 Äquidistanten (bei 0) haben, 8 etwas größer (Länge 1, Seiten), 4 noch größer (Längesqrt 2
, Diagonalen)Demonstration:
Aus Speichergründen meine vorherige Methode (geordnete Eckpunkte erforderlich, aber reguläre Polygone beliebiger Reihenfolge erkennbar):
Erklärungen und Demo finden Sie im Verlauf. Die aktuelle Methode könnte wahrscheinlich auf andere Polygone erweitert werden, die
4 8 4
einer Binomialverteilung sehr ähnlich sehen.quelle
3 :'4 8 4-:#/.~/:~|,-/~y'
Python, 71
42Update 1) um 4 verschiedene Punkte zu fordern (würde früher für wiederholte Punkte falsch positive Ergebnisse liefern - gibt es noch andere?) 2) um eine Funktion pro Spezifikation zu definieren
Für ein Quadrat muss der Vektor zwischen zwei beliebigen Punkten 0 (derselbe Punkt), eine Seite oder eine Diagonale sein. Die Menge der Größe dieser Vektoren muss also die Länge 3 haben.
quelle
Haskell, 100 Zeichen
So würde ich die J-Lösung von JB in Haskell schreiben. Ohne den Versuch, die Lesbarkeit zu beeinträchtigen, indem nicht benötigte Zeichen entfernt werden, handelt es sich um 132 Zeichen:
Sie können es auf 100 herunterkratzen, indem Sie überschüssige Leerzeichen entfernen und einige Dinge umbenennen
Verwenden wir QuickCheck, um sicherzustellen, dass beliebige Quadrate mit einem Scheitelpunkt bei (x, y) und einem Kantenvektor (a, b) akzeptiert werden:
Versuche es in ghci:
Oh ja, das leere Quadrat wird hier nicht als Quadrat betrachtet, also überarbeiten wir unseren Test:
Und versuche es nochmal:
quelle
d
.s l=[4,8,4]==(map length.group.sort)[(x-a)^2+(y-b)^2|(x,y)<-l,(a,b)<-l]
Faktor
Eine Implementierung in der Programmiersprache Factor :
Und einige Unit-Tests:
quelle
OCaml, 145,
164Laufen Sie wie folgt:
Lassen Sie uns etwas deobfuscieren und erklären.
Zuerst definieren wir eine Norm:
Sie werden feststellen, dass sqrt nicht angerufen wird und hier nicht benötigt wird.
Hier sind a, b, c und d Punkte. Wir gehen davon aus, dass diese Punkte so angeordnet sind:
Wenn wir ein Quadrat haben, müssen alle diese Bedingungen erfüllt sein:
Beachten Sie, dass immer gilt:
Wir werden das nutzen, um unsere Testfunktion weiter unten zu vereinfachen.
Since our input is not ordered, we also have to check all permutations. Without loss of generality we can avoid permuting the first point:
After simplification:
Edit: followed M.Giovannini's advice.
quelle
n
for a reduction in 20 characters:let t a b c d=a%b+a%c=b%c&&d%c+d%b=b%c&&a%b=a%c&&d%c=d%b
.Python (105)
Points are represented by
(x,y)
tuples. Points can be in any order and only accepts squares. Creates a list,s
, of pairwise (non-zero) distances between the points. There should be 12 distances in total, in two unique groups.quelle
f([(0,0),(0,4),(2,2),(-2,2)])
is a squarePython - 42 chars
Looks like its an improvement to use complex numbers for the points
where A = [(11+13j), (14+12j), (13+9j), (10+10j)]
old answer:
Points are specified in any order as a list, eg
quelle
>>> A=[(0,0),(0,0),(1,1),(0,0)] >>> len(set((a-c)**2+(b-d)**2 for(a,b),(c,d)in combinations(A,2)))==2 True
A=[(0,0),(0,4),(2,2),(-2,2)]; len(set((a-c)**2+(b-d)**2 for(a,b),(c,d)in combinations(A,2)))==2
C# -- not exactly short. Abusing LINQ. Selects distinct two-combinations of points in the input, calculates their distances, then verifies that exactly four of them are equal and that there is only one other distinct distance value. Point is a class with two double members, X and Y. Could easily be a Tuple, but meh.
quelle
PHP, 82 characters
quelle
K - 33
Translation of the J solution by J B:
K suffers here from its reserved words(
_sqr
and_sqrt
).Testing:
quelle
OCaml + Batteries, 132 characters
(look, Ma, no spaces!) The list comprehension in
q
forms the list of squared norms for each distinct unordered pair of points. A square has four equal sides and two equal diagonals, the squared lengths of the latter being twice the squared lengths of the former. Since there aren't equilateral triangles in the integer lattice the test isn't really necessary, but I include it for completeness.Tests:
quelle
Mathematica
65 80 6966Checks that the number of distinct inter-point distances (not including distance from a point to itself) is 2 and the shorter of the two is not 0.
Usage
N.B.:
\[And]
is a single character in Mathematica.quelle
Jelly, 8 bytes
Try it online!
Takes a list of complex numbers as a command line argument. Prints
1
or0
.This seems like an enjoyable challenge to revive!
quelle
Haskell (212)
Naive first attempt. Checks the following two conditions for all permutations of the input list of points (where a given permutation represents, say, a clockwise ordering of the points):
Deobfuscated code and tests
quelle
Scala (146 characters)
quelle
JavaScript 144 characters
Mathematically equal to J Bs answer. It generates the 6 lengths and assert that the 2 greatest are equal and that the 4 smallest are equal. Input must be an array of arrays.
quelle
PHP,
161158 charactersProof (1x1): http://codepad.viper-7.com/ZlBpOB
This is based off of eBuisness's JavaScript answer.
quelle
JavaScript 1.8, 112 characters
Update: saved 2 characters by folding the array comprehensions together.
Another reimplementation of J B's answer. Exploits JavaScript 1.7/1.8 features (expression closures, array comprehensions, destructuring assignment). Also abuses
~~
(double bitwise not operator) to coerceundefined
to numeric, with array-to-string coercion and a regexp to check that the length counts are[4, 8, 4]
(it assumes that exactly 4 points are passed). The abuse of the comma operator is an old obfuscated C trick.Tests:
quelle
GoRuby - 66 characters
expanded:
Same algorithm as J B's answer.
Test like:
Outputs
true
for true and blank for falsequelle
ruby -r ./golf-prelude.rb FILE_TO_RUN.rb
and it will work exatcly the same.sort
beforegroup_by
..sort.group_by {...}
should be written as.group_by {...}
Python 97 (without complex points)
This will take lists of point tuples in [(x,y),(x,y),(x,y),(x,y)] in any order, and can handle duplicates, or the wrong number of points. It does NOT require complex points like the other python answers.
You can test it like this:
This will take a little explaining, but the overall idea is that there are only three distances between the points in a square (Side, Diagonal, Zero(point compared to itself)):
To save code characters I am:
I fear someone can find a test case that breaks this. So please do and Ill correct. For instance the fact I just check for three distances, instead of doing an abs() and checking for side length and hypotenuse, seems like an error.
First time I've tried code golf. Be kind if I've broken any house rules.
quelle
Clojure, 159 chars.
Edit: To also explain a little bit.
(Note: the square rooting is not needed and hence in the code saved above.)
quelle
C#, 107 characters
Where points is List of Vector3D containing the points.
Computes all distances squared between all points, and if there are exactly three distinct types (must be 0, some value a, and 2*a) and 4 distinct points then the points form a square.
quelle
Python, 66
Improving paperhorse's answer from 76 to 66:
quelle
Python 2, 49 bytes
Try it online!
Takes a list of four complex numbers as input. Rotates each point 90 degrees around the average, and checks that each resulting point is in the original list.
Same length (though shorter in Python 3 using
{*l}
).Try it online!
quelle
^
can be used instead of==
.Wolfram Language (Mathematica),
3231 bytesTry it online!
Takes a list of points represented by complex numbers, calculates the second and third central moment, and checks that both are zero.
Un-golfed:
or
proof
This criterion works on the entire complex plane, not just on the Gaussian integers.
First, we note that the central moments do not change when the points are translated together. For a set of points
the central moments are all independent of
c
(that's why they are called central):Second, the central moments have a simple dependence on overall complex scaling (scaling and rotation) of the set of points:
This means that if a central moment is zero, then scaling and/or rotating the set of points will keep the central moment equal to zero.
Third, let's prove the criterion for a list of points where the first two points are fixed:
Under what conditions are the real and imaginary parts of the second and third central moments zero?
All of these six solutions represent squares: Therefore, the only way that a list of points of the form
{0, 1, x[3] + I*y[3], x[4] + I*y[4]}
can have zero second and third central moments is when the four points form a square.Due to the translation, rotation, and scaling properties demonstrated in points 1 and 2, this means that any time the second and third central moments are zero, we have a square in some translation/rotation/scaling state. ∎
generalization
The k-th central moment of a regular n-gon is zero if k is not divisible by n. Enough of these conditions must be combined to make up a sufficient criterion for detecting n-gons. For the case n=4 it was enough to detect zeros in k=2 and k=3; for detecting, e.g., hexagons (n=6) it may be necessary to check k=2,3,4,5 for zeros. I haven't proved the following, but suspect that it will detect any regular n-gon:
The code challenge is essentially this code specialized for length-4 lists.
quelle
J,
31 29 2726checks if the 8 smallest distances between the points are the same.checks if there are exactly three kinds of distances between the points (zero, side length and diagonal length).4 2 $
is a way of writing an array in J.quelle
Smalltalk for 106 characters
where p is a collection of points, e.g.
I think the math is sound...
quelle
Mathematica, 123 characters (but you can do better):
Where 'a' is the input in Mathematica list form, eg:
a={{0,0},{3,4},{8,4},{5,0}}
The key is to look at the dot products between all the vectors and note that they must have exactly three values: 0, x, and 2*x for some value of x. The dot product checks both perpendicularity AND length in one swell foop.
I know there are Mathematica shortcuts that can make this shorter, but I don't know what they are.
quelle
Union
instead ofSort@DeleteDuplicates
. I put your 3 lines together also:#[[1]] == 0 && #[[3]]/#[[2]] == 2 &[ Union@Abs@Flatten[Table[c.d, {c, #}, {d, #}]] &[ Flatten[Table[x - y, {x, a}, {y, a}], 1]]]
Haskell, "wc -c" reports 110 characters. Does not check that the input has 4 elements.
I tested on
quelle