Perl、65 59 55 54バイト
+2を含む -ap
STDINのツリーサイズで実行します。
for i in `seq 24`; do echo -n "$i: "; vines.pl <<< $i; echo; done
vines.pl
:
#!/usr/bin/perl -ap
$_=map{${"-@F"%$_}|=$_=$$_|$"x$p++.1;/.\b/g}1-$_..-1
説明
ツリーを書き換えた場合
3
|
2 4
\ /
1
|
0
各ノードがそのすべての祖先とそれ自体のセットを含むものに:
{3}
|
{2,3} {4}
\ /
\ /
{1,2,3,4}
|
{0,1,2,3,4}
次に、たとえば、4から3までのパスのすべてのノードを次のように記述できます。
- 3を含むが4を含まないすべてのノード(3から下へ)
- 4を含むが3を含まないすべてのノード(4から下がる)
- 3と4の両方を含む最上位ノード(結合)
エッジの数はノードの数よりも1つ少ないため、それを使用して結合ポイントを無視できるため、4から3までのパス上のエッジの数は3です。
- 3ではなく4を含むノードの数:2ノード
- 4を含むが3を含まないノードの数:1ノード
これは、ターゲットに直接到達するパスに対しても機能することに注意してください。たとえば、3から2のパスの場合、エッジの数は1です。
- 2を含むが3を含まないノードの数:0ノード
- 3を含むが2を含まないノードの数:1ノード
その後、これらすべての組み合わせを合計できます。
代わりに先祖が設定されたノード2などのノードだけを見る場合{2,3}
。このノードは2 to 1
、1ではなく2を含むため、パスを処理するときに1回寄与します3 to 2
。2と3の両方があるため、パスには何も寄与しませんが、4 to 3
3いいえ4.一般に、ノードの祖先セット内の番号は、セット内にない各隣接ノード(上位または下位)に1つずつ寄与します。パスが存在しないため、下位3にのみ寄与する最大要素(この場合は4)を除く5 to 4
。Simular 0は片側ですが、0は常にツリーのルートにあり、すべての数値を含みます(最終的な結合であり、結合はカウントしません)。完全にアウト。
そのため、各ノードの祖先セットを調べ、貢献度を数え、すべてのノードで合計することで問題を解決することもできます。
ネイバーを簡単に処理するために、祖先セットをスペースと1の文字列として表します。ここで、位置pの各1は、n-1-pが祖先であることを表します。たとえば、n=5
位置0の1の場合、4が祖先であることを示します。末尾のスペースは省略します。したがって、構築するツリーの実際の表現は次のとおりです。
" 1"
|
" 11" "1"
\ /
\ /
"1111"
ノード0 "11111"
を無視したことに注意してください(ノードは貢献しません)。
下位ネイバーのない祖先は、1のシーケンスの終わりで表されるようになりました。上位のネイバーを持たない祖先は、1のシーケンスの先頭で表されるようになりましたが、5 to 4
存在しないパスを表すため、文字列の先頭でシーケンスの先頭を無視する必要があります。この組み合わせは、正規表現と完全に一致し/.\b/
ます。
祖先文字列の構築は、すべてのノードを順番に処理n-1 .. 1
し、ノード自体の位置に1を設定し、子孫に「または」を実行することによって行われます。
プログラムは理解するのに十分簡単です:
-ap read STDIN into $_ and @F
map{ }1-$_..-1 Process from n-1 to 1,
but use the negative
values so we can use a
perl sequence.
I will keep the current
ancestor for node $i in
global ${-$i} (another
reason to use negative
values since $1, $2 etc.
are read-only
$$_|$"x$p++.1 "Or" the current node
position into its ancestor
accumulator
$_= Assign the ancestor string
to $_. This will overwrite
the current counter value
but that has no influence
on the following counter
values
${"-@F"%$_}|= Merge the current node
ancestor string into the
successor
Notice that because this
is an |= the index
calculation was done
before the assignment
to $_ so $_ is still -i.
-n % -i = - (n % i), so
this is indeed the proper
index
/.\b/g As explained above this
gives the list of missing
higher and lower neighbours
but skips the start
$_= A map in scalar context
counts the number of
elements, so this assigns
the grand total to $_.
The -p implicitly prints
置換/.\b/
により/\b/
、この問題の往復バージョンが解決され、ターザンもパスを取得します。0 to n-1
先祖の文字列がどのように見えるかのいくつかの例(順番に与えられますn-1 .. 1
):
n=23:
1
1
1
1
1
1
1
1
1
1
1
11
1 1
1 1
1 1
11 11
1 1
11 1 1 11
1 1
1111 11 11 1111
111111111 111111111
1111111111111111111111
edges=68
n=24:
1
1
1
1
1
1
1
1
1
1
1
1
1 1
1 1
1 1
1 1
1 1
1 1 1 1
1 1
11 1 1 11
1 1 1 1
1 1 1 1
1 1
edges=82