Jalur terpanjang di pesawat 2d

14

Anda diberikan satu set koordinat Cartesian arbiter, unik, 2d, integer: misalnya [(0,0), (0,1), (1,0)]

Temukan jalur terpanjang yang mungkin dari set koordinat ini, dengan batasan bahwa koordinat dapat "dikunjungi" hanya sekali. (Dan Anda tidak "kembali" ke koordinat tempat Anda mulai).

Penting:

Anda tidak dapat "melewati" koordinat atau sekitarnya. Misalnya, dalam contoh catatan terakhir (Persegi Panjang), Anda tidak dapat berpindah dari D ke A tanpa mengunjungi C (yang mungkin merupakan kunjungan ulang, mematahkan panjang yang ditemukan). Ini ditunjukkan oleh @FryAmTheEggman.

Input Fungsi: Array of 2d Cartesian Coordinates
Function Output: Hanya panjang maksimal
Pemenang: Kode terpendek menang, tidak ada penahan yang dilarang (Bukan yang paling efisien waktu-ruang)


Contohnya

Segitiga Asal

1 : Dalam kasus yang ditunjukkan di atas, jalur terpanjang tanpa koordinat "dikunjungi" dua kali adalah A -> B -> O (atau OBA, atau BAO), dan panjang jalurnya adalah sqrt (2) + 1 = 2.414




Kotak

2 : Dalam kasus yang ditunjukkan di atas, jalur terpanjang tanpa koordinat "dikunjungi" dua kali adalah ABOC (dan jelas COBA, OCAB, dll.), Dan untuk satuan persegi yang diperlihatkan, ia menghitung ke sqrt (2) + sqrt (2) + 1 = 3,828.


Catatan: Ini adalah test case tambahan yang tidak sepele seperti dua contoh sebelumnya. Ini adalah persegi panjang yang terbentuk dari 6 koordinat:

masukkan deskripsi gambar di sini

Di sini, jalur terpanjang adalah: A -> E -> C -> O -> D -> B, yaitu 8,7147
(kemungkinan diagonal berjalan maksimum dan tidak ada tepi yang dilintasi)

BluePill
sumber
Ini pertanyaan yang sangat mirip , walaupun dengan skor berbeda.
Geobits
@ Geobits setuju, tapi saya tidak akan mengatakan "sangat", setelah melalui deskripsi masalah di sana. Dan dalam hal ini, setiap masalah jalur min / maks pada dasarnya adalah beberapa rasa dari tersangka grafik Anda yang biasa. Saya tertarik dengan solusi penghematan byte di sini.
BluePill
@Fatalize Done. Ini 8,7147.
BluePill
Ngomong-ngomong: Selamat datang di PPCG!
Fatalkan
@Formatisasi Terima kasih! (Sebenarnya saya sudah menjadi pengamat di sini untuk sementara waktu, baru aktif dan mulai hari ini). :)
BluePill

Jawaban:

3

Pyth, 105 103 100 92 86 byte

V.pQK0FktlNJ.a[@Nk@Nhk)FdlNI&!qdk&!qdhkq+.a[@Nk@Nd).a[@Nd@Nhk)J=K.n5B)=K+KJ)IgKZ=ZK))Z

              Z = 0 - value of longest path
              Q = eval(input())

V.pQ         for N in permutations(Q):
  K0           K = 0 - value of current path
  FktlN        for k in len(N) - 1:
    J.a          set J = distance of
    [@Nk                 Q[k] and Q[k+1]
    @Nhk)    
    FdlN         for d in len(N):
I&                 if d != k && d != (k + 1)
!qdk
&!qdhk
q+                and if sum of
.a                   distance Q[k] and Q[d]
 [@Nk                
 @Nd)                
.a                   distance Q[d] and Q[k+1]
 [@Nd
 @Nhk)
J                    are equal to J then
  =K.n5              set K to -Infinity
  B                  and break loop
                     ( it means that we passed over point )
  )                   end of two if statements
=K+KJ                  K+=J add distance to our length
)                      end of for
IgKZ                   if K >= Z - if we found same or better path
  =ZK                  Z = K       set it to out max variable
))                     end of two for statements
Z                      output value of longest path 

Coba di sini!

wasikuss
sumber
2

Mathematica, 139 byte

Max[Tr@BlockMap[If[1##&@@(Im[#/#2]&@@@Outer[#/Abs@#&[#-#2]&,l~Complement~#,#])==0,-∞,Abs[{1,-1}.#]]&,#,2,1]&/@Permutations[l=#+I#2&@@@#]]&

Kasus cobaan

%[{{0,0},{0,1},{1,0},{1,1},{2,0},{2,1}}]
(* 3 Sqrt[2]+2 Sqrt[5] *)

%//N
(* 8.71478 *)
njpipeorgan
sumber
1

Perl, 341 322 318 byte

sub f{@g=map{$_<10?"0$_":$_}0..$#_;$"=',';@l=grep{"@g"eq join$",sort/../g}glob"{@g}"x(@i=@_);map{@c=/../g;$s=0;$v=1;for$k(1..$#c){$s+=$D=d($k-1,$k);$_!=$k&&$_!=$k-1&&$D==d($_,$k)+d($_,$k-1)and$v=0 for 0..$#c}$m=$s if$m<$s&&$v}@l;$m}sub d{@a=@{$i[$c[$_[0]]]};@b=@{$i[$c[$_[1]]]};sqrt(($a[0]-$b[0])**2+($a[1]-$b[1])**2)}

Kode ini mendukung hingga 100 poin. Karena menghasilkan semua kemungkinan permutasi titik, 100 poin akan membutuhkan setidaknya 3,7 × 10 134 yottabytes memori (12 poin akan menggunakan 1,8Gb).

Berkomentar:

sub f {
    @g = map { $_<10 ? "0$_" : $_ } 0..$#_; # generate fixed-width path indices
    $" = ',';                               # set $LIST_SEPARATOR to comma for glob
    @l = grep {                             # only iterate paths with unique points
        "@g" eq join $", sort /../g         # compare sorted indices with unique indices
    } glob "{@g}" x (@i=@_);                # produce all permutations of path indices
                                            # and save @_ in @i for sub d
    map {
        @c = /../g;                         # unpack the path indices
        $s=0;                               # total path length
        $v=1;                               # validity flag
        for $k (1..$#c) {                   # iterate path
            $s +=                           # sum path length
                $D = d( $k-1, $k );         # line distance 

              $_!=$k && $_!=$k-1            # except for the current line,
              && $D == d( $_, $k )          # if the point is on the line,
                     + d( $_, $k-1 )
              and $v = 0                    # then reset it's validity
            for 0 .. $#c                    # iterate path again to check all points
        }
        $m=$s if $m<$s && $v                # update maximum path length
    } @l;
    $m                                      # return the max
}

sub d {                                     
    @a = @{ $i[$c[$_[0]]] };                # resolve the index $_[0] to the first coord
    @b = @{ $i[$c[$_[1]]] };                # idem for $_[1]
    sqrt( ($a[0] - $b[0])**2       
        + ($a[1] - $b[1])**2 )      
}

TestCases:

print f( [0,1], [0,0], [1,0] ), $/;        $m=0; # reset max for next call
print f( [0,0], [0,1], [1,0], [1,1] ), $/; $m=0;
print f( [0,0], [0,1], [0,2] ), $/;        $m=0;
print f( [0,0], [0,1], [0,2], 
         [1,0], [1,1], [1,2]),$/;          $m=0;
  • 322 byte: simpan 19 dengan tidak mengatur ulang $", dan beberapa inlining
  • 318 byte: hemat 4 dengan mengurangi jumlah maksimum coord hingga 100.
Kenney
sumber