Pertanyaannya telah berubah, jadi jawaban ini berisi versi yang berbeda, dengan dan tanpa jalur tertutup.
Perl, jalur terbuka, 69 byte
print"@$_$/"for sort{$$a[0]<=>$$b[0]||$$a[1]<=>$$b[1]}map{[/\S+/g]}<>
Setiap titik diharapkan dalam STDIN sebagai garis, dengan koordinat dipisahkan oleh ruang putih.
Semua format angka didukung oleh Perl yang diinterpretasikan sebagai angka (termasuk angka floating point).
Contoh:
0 0
4 4
0 4
4 0
-2 1
2 -2
2 4
3.21 .56
.035e2 -7.8
0 2
Keluaran:
-2 1
0 0
0 2
0 4
2 -2
2 4
3.21 .56
.035e2 -7.8
4 0
4 4
Tidak Disatukan:
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
Varian sirkuit
Dalam versi pertanyaan pertama, ada koneksi antara titik terakhir dan pertama untuk membuat sirkuit.
Titik tengah tidak ada, 253 byte
Varian ini bisa gagal, jika pusat adalah salah satu poin, lihat contoh 3.
Suntingan:
Dalam jawabannya, swish menyadarinya, bahwa titik harus dipusatkan di sekitar titik asal untuk memastikan sirkuit bebas silang:
- Penyortiran membutuhkan transformasi koordinat.
- Representasi string asli dari angka-angka perlu disimpan untuk output.
Perbaikan bug: kasus khusus untuk sumbu x negatif telah menyertakan sumbu x positif.
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]}<>
Contoh 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
Output 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
Contoh 2:
Menguji representasi angka dan transformasi koordinat.
.9e1 9
7 7.0
8.5 06
7.77 9.45
Output 2:
7 7.0
8.5 06
.9e1 9
7.77 9.45
Tidak Disatukan:
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
Tanpa batasan, 325 byte
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]}<>
Dalam versi sebelumnya, pusat diletakkan di awal dan titik-titik terakhir pada sumbu negatif diurutkan dalam urutan terbalik untuk mendapatkan cross-free ke pusat lagi. Namun, ini tidak cukup, karena poin terakhir bisa terletak pada garis yang berbeda. Jadi contoh 3 berikut akan gagal.
Ini diperbaiki dengan memindahkan titik pusat sedikit ke atas dan kanan. Karena keterpusatan, harus ada setidaknya satu titik dengan nilai x positif dan titik dengan nilai y positif. Dengan demikian minimum nilai x dan y positif diambil dan dikurangi menjadi sembilan (setengah atau ketiga bisa cukup). Poin ini tidak dapat menjadi salah satu poin yang ada dan dijadikan asal baru.
Perawatan khusus asal dan sumbu x negatif dapat dihilangkan, karena ada titik yang terletak pada asal baru.
Contoh 3:
-2 -2
-1 -1
-2 2
-1 1
2 -2
1 -1
2 2
1 1
0 0
Output 3:
0 0
-1 -1
-2 -2
1 -1
2 -2
1 1
2 2
-2 2
-1 1
Contoh 1 sekarang diurutkan secara berbeda:
Tidak Disatukan:
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