Die Frage hat sich geändert, daher enthält diese Antwort verschiedene Versionen mit und ohne geschlossenen Pfad.
Perl, offener Pfad, 69 Bytes
print"@$_$/"for sort{$$a[0]<=>$$b[0]||$$a[1]<=>$$b[1]}map{[/\S+/g]}<>
Jeder Punkt wird in STDIN als Linie erwartet, wobei die Koordinaten durch Leerzeichen getrennt sind.
Es wird jedes Zahlenformat unterstützt, das Perl als Zahl interpretiert (einschließlich Gleitkommazahlen).
Beispiel:
0 0
4 4
0 4
4 0
-2 1
2 -2
2 4
3.21 .56
.035e2 -7.8
0 2
Ausgabe:
-2 1
0 0
0 2
0 4
2 -2
2 4
3.21 .56
.035e2 -7.8
4 0
4 4
Ungolfed:
print "@$_$/" for # print output line
sort { # sort function for two points $a and $b
$$a[0] <=> $$b[0] # compare x part
|| $$a[1] <=> $$b[1] # compare y part, if x parts are identical
}
map { [/\S+/g] } # convert input line to point as array reference
<> # read input lines
Schaltungsvarianten
In der Version mit der ersten Frage gab es eine Verbindung zwischen dem letzten und dem ersten Punkt, um eine Schaltung herzustellen.
Zentrum ist nicht vorhanden Punkt, 253 Bytes
Diese Variante kann fehlschlagen, wenn die Mitte einer der Punkte ist, siehe Beispiel 3.
Bearbeitungen:
In seiner Antwort bemerkte Swish, dass die Punkte um den Ursprung zentriert sein sollten, um eine kreuzfreie Schaltung zu gewährleisten:
- Das Sortieren erfordert transformierte Koordinaten.
- Die ursprüngliche Zeichenfolgendarstellung der Zahlen muss für die Ausgabe beibehalten werden.
Fehlerbehebung: Der Sonderfall für die negative x-Achse hatte die positive x-Achse enthalten.
print"$$_[2] $$_[3]$/"for sort{($X,$Y)=@$a;($x,$y)=@$b;(!$X&&!$Y?-1:0)||!$x&&!$y||!$Y&&!$y&&$X<0&&$x<0&&$X<=>$x||atan2($Y,$X)<=>atan2($y,$x)||$X**2+$Y**2<=>$x**2+$y**2}map{[$$_[0]-$M/$n,$$_[1]-$N/$n,@$_]}map{$n++;$M+=$$_[0];$N+=$$_[1];$_}map{[/\S+/g]}<>
Beispiel 1:
4 4
-2 0
2 0
1 1
4 0
-2 -2
-3 -1
1 -2
3 0
2 -4
0 0
-1 -2
3 3
-3 0
2 3
-5 1
-6 -1
Ausgabe 1:
0 0
-6 -1
-3 -1
-2 -2
-1 -2
1 -2
2 -4
2 0
3 0
4 0
1 1
3 3
4 4
2 3
-5 1
-3 0
-2 0
Beispiel 2:
Testen der Zahlendarstellung und Koordinatentransformation.
.9e1 9
7 7.0
8.5 06
7.77 9.45
Ausgabe 2:
7 7.0
8.5 06
.9e1 9
7.77 9.45
Ungolfed:
print "$$_[2] $$_[3]$/" for sort { # print sorted points
($X, $Y) = @$a; # ($X, $Y) is first point $a
($x, $y) = @$b; # ($x, $y) is second point $b
(!$X && !$Y ? -1 : 0) || # origin comes first, test for $a
!$x && !$y || # origin comes first, test for $b
!$Y && !$y && $X < 0 && $x < 0 && $X <=> $x ||
# points on the negative x-axis are sorted in reverse order
atan2($Y, $X) <=> atan2($y, $x) ||
# sort by angles; the slope y/x would be an alternative,
# then the x-axis needs special treatment
$X**2 + $Y**2 <=> $x**2 + $y**2
# the (quadratic) length is the final sort criteria
}
map { [ # make tuple with transformed and original coordinates
# the center ($M/$n, $N/$n) is the new origin
$$_[0] - $M/$n, # transformed x value
$$_[1] - $N/$n, # transformed y value
@$_ # original coordinates
] }
map {
$n++; # $n is number of points
$M += $$_[0]; # $M is sum of x values
$N += $$_[1]; # $N is sum of y values
$_ # pass orignal coordinates through
}
map { # make tuple with point coordinates
[ /\S+/g ] # from non-whitespace in input line
}
<> # read input lines
Ohne Einschränkung 325 Bytes
print"$$_[2] $$_[3]$/"for sort{($X,$Y)=@$a;($x,$y)=@$b;atan2($Y,$X)<=>atan2($y,$x)||$X**2+$Y**2<=>$x**2+$y**2}map{[$$_[0]-$O/9,$$_[1]-$P/9,$$_[2],$$_[3]]}map{$O=$$_[0]if$$_[0]>0&&($O>$$_[0]||!$O);$P=$$_[1]if$$_[1]>0&&($P>$$_[1]||!$P);[@$_]}map{[$$_[0]-$M/$n,$$_[1]-$N/$n,@$_]}map{$n++;$M+=$$_[0];$N+=$$_[1];$_}map{[/\S+/g]}<>
In der vorherigen Version wird die Mitte am Anfang gesetzt und die letzten Punkte auf der negativen Achse werden in umgekehrter Reihenfolge sortiert, um wieder kreuzfrei zur Mitte zu gelangen. Dies reicht jedoch nicht aus, da die letzten Punkte auf einer anderen Linie liegen könnten. Somit würde das folgende Beispiel 3 fehlschlagen.
Dies wird behoben, indem der zentrierte Ursprung ein wenig nach oben und rechts verschoben wird. Aufgrund der Zentrierung muss mindestens ein Punkt mit positivem x-Wert und ein Punkt mit positivem y-Wert vorhanden sein. Somit werden die Minima der positiven x- und y-Werte genommen und auf ein Neuntel reduziert (ein halbes oder drittes könnte ausreichen). Dieser Punkt kann nicht einer der vorhandenen Punkte sein und wird zum neuen Ursprung gemacht.
Die speziellen Behandlungen des Ursprungs und der negativen x-Achse können entfernt werden, da es einen Punkt gibt, der auf dem neuen Ursprung liegt.
Beispiel 3:
-2 -2
-1 -1
-2 2
-1 1
2 -2
1 -1
2 2
1 1
0 0
Ausgabe 3:
0 0
-1 -1
-2 -2
1 -1
2 -2
1 1
2 2
-2 2
-1 1
Beispiel 1 ist jetzt anders sortiert:
Ungolfed:
print "$$_[2] $$_[3]$/" for sort { # print sorted points
($X, $Y) = @$a; # ($X, $Y) is first point $a
($x, $y) = @$b; # ($x, $y) is second point $b
atan2($Y, $X) <=> atan2($y, $x) ||
# sort by angles; the slope y/x would be an alternative,
# then the x-axis needs special treatment
$X**2 + $Y**2 <=> $x**2 + $y**2
# the (quadratic) length is the final sort criteria
}
map { [ # make tuple with transformed coordinates
$$_[0] - $O/9, $$_[1] - $P/9, # new transformed coordinate
$$_[2], $$_[3] # keep original coordinate
] }
map {
# get the minimum positive x and y values
$O = $$_[0] if $$_[0] > 0 && ($O > $$_[0] || !$O);
$P = $$_[1] if $$_[1] > 0 && ($P > $$_[1] || !$P);
[ @$_ ] # pass tuple through
}
map { [ # make tuple with transformed and original coordinates
# the center ($M/$n, $N/$n) is the new origin
$$_[0] - $M/$n, # transformed x value
$$_[1] - $N/$n, # transformed y value
@$_ # original coordinates
] }
map {
$n++; # $n is number of points
$M += $$_[0]; # $M is sum of x values
$N += $$_[1]; # $N is sum of y values
$_ # pass orignal coordinates through
}
map { # make tuple with point coordinates
[ /\S+/g ] # from non-whitespace in input line
}
<> # read input lines