Perl、341 322 318バイト
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)}
コードは最大100ポイントをサポートします。すべての可能な点順列を生成するため、100点には少なくとも3.7×10が必要です。 134ヨタバイトのメモリ(12ポイントは1.8Gbを使用します)。
コメント:
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 )
}
テストケース:
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バイト:リセットせずに19を節約し
$"
、いくつかのインライン化
- 318バイト:座標の最大nrを100に減らして4を節約します。