ドロップ・オブ・カオス(最小限の非周期的シーケンスの構築)


9

ここでの考え方は、ほぼ繰り返しパターンを生成することです。つまり、いくつかのサブシーケンスの繰り返しを回避するために、構築されるシーケンスは最後の瞬間に変更されます。タイプAAおよびABAのサブシーケンスは避けてください(BはAより長くありません)。

例:

説明をわかりやすくするために、小さな例をすべてリストすることから始めます。0から始めましょう。

有効:0

無効:00(AAパターン)
有効:01

無効:010(ABAパターン)
無効:011(AAパターン)
有効:012

有効:0120
無効:0121(ABAパターン)
無効:0122(AAパターン)

無効:01200(AAパターン)
無効:01201(ABAパターン; 01-2-01)
無効:01202(ABAパターン)
有効:01203

今で4は、証明はありませんが、だけが必要な何百もの文字のシーケンスを簡単に見つけたので、a は必要ないことを強く信じています0123。(おそらく、AAパターンを持たない無限ストリングを作成するために必要なのは3文字だけであることに密接に関連しています。これにはWikipediaのページがあります。)

入出力

入力は、単一の正のゼロ以外の整数nです。あなたはそれを仮定するかもしれませんn <= 1000

出力は、n禁止パターン(AAまたはABA)のいずれかに一致するサブシーケンスのない文字シーケンスです。

入力と出力の例

>>> 1
0

>>> 2
01

>>> 3
012

>>> 4
0120

>>> 5
01203

>>> 50
01203102130123103201302103120132102301203102132012

ルール

  • 0123使用できるのは文字のみです。
  • BはAよりも長くありません。これは012345、次の6理由で従う必要がある状況を回避するためです01234511-2345-1。言い換えると、シーケンスは簡単で興味をそそらないものになります。
  • nハードコーディング以外の任意の方法で入力できます。
  • 出力は、どちらが簡単かによって、リストまたは文字列のどちらかになります。
  • 力ずくはありません。の実行時間は、非常に遅いマシンでは数分程度、せいぜい1時間程度にする必要がありますn=1000。(これは、のすべてのn長さの順列をループするだけのソリューションを不適格にすることを目的としている{0,1,2,3}ため、トリックや類似のトリックは許可されていません。)
  • 通常どおり、標準の抜け穴は許可されていません。
  • スコアはバイト単位です。これはので、最も短いエントリが勝ちます(おそらく-ボーナスを参照)。
  • ボーナス:各ステップで許可される最小の桁を選択します。場合13シーケンス内の次の桁のための可能な選択肢があり、選びます1。スコアから5バイトを引きます。ただし、以下のメモに注意してください。

注意!

行き止まりは可能です。プログラムまたは関数はこれらを回避する必要があります。次に例を示します。

切り株:0120310213012310320130210312013210230120310213201230210312013023103201230213203102301203210231201302103123013203102130120321023013203123021032012310213012031023013203123021320123102130120
切り株:0120310213012310320130210312013210230120310213201230210312013023103201230213203102301203210231201302103123013203102130120321023013203123021032012310213012031023013203123021320123102130123
切り株:012031021301231032013021031201321023012031021320123021031201302310320123021320310230120321023120130210312301320310213012032102301320312302103201231021301203102301320312302132012310320
切り株:012031021301231032013021031201321023012031021320123021031201302310320123021320310230120321023120130210312301320310213012032102301320312302103201231021301203102301320312302132012310321301203102130

これらの各シーケンスは、(を使用せずに4)これ以上拡張することはできません。ただし、最初の2つと2つ目の2つの間には決定的な違いがあることにも注意してください。Xこれをより明確にするために、共有された初期サブシーケンスをに置き換えます。

切り株:X2130120
切り株:X2130123
切り株:X320
切り株:X321301203102130

の最後の2桁X10であるため、次の桁の可能な選択肢は2およびのみ3です。選択すると2、シーケンス終了する必要がある状況が発生します。貪欲なアルゴリズムはここでは機能しません(とにかく、バックトラックなしではありません。)


現実的な時間で出力が得られない場合でも、可能なすべての文字列をテストするブルートフォース戦略を使用できますか?すべての人のための解決策があることを知っていますかn?誰かがヒューリスティックな準貪欲アルゴリズムを提供する場合、非常に長い期間問題が発生しないことをどのように確認しますか?一般的な問題は興味深いものであり、パターンの一部の長さを制限するパターン回避については何も見つかりませんでした。誰かが一般的なレシピを作成できる場合、私はそれが最良のアプローチであると期待しています。
XNOR

私は、暴力をルールで禁止したと思います。私はおそらくそれを強調する必要があります。私にはすべての解決策が存在するという証拠はありませんが、n私のプログラムが見つける切り株は毎回平均10桁長くなる傾向があることを考えると、無限のシーケンスが存在することは確かです。セミグリーディアルゴリズムを任意の大きなシーケンスに対してテストする方法がわかりません。要件n= 1000に制限して、それ以上高くする必要はありませんn
El'endia Starman、2015

4
私は空の場所でAA本当にタイプだと思います。これは、いくつかのソリューションを合理化するのに役立つ可能性があります。ABAB
mathmandan 2015

回答:


6

Retina、86バイト-5 = 81

$
_
(r`^(?<-2>.)+_((.)+)\b$
$1!
\b$
0
3#
#
0#
1
1#
2
2#
3
)r`\1(?<-2>.)*((.)+)$
$0#
!
<empty>

Where <empty>は空の後続行を表します。上記のコードは、-sフラグを付けた単一のファイルから実行できます。

入力は、例えば単項で与えられるべき111111です。私はまだ数千のオーダで出力をテストしていません-正規表現の2つはしばらくすると少し遅くなるかもしれませんが、数秒で数百を簡単に処理できます。

説明

これは単純なバックトラッキングソリューションです。

  1. を追加し0ます。
  2. 現在のシーケンスが無効である間に、後続の3をすべて削除し、最後の非をインクリメントします3
  3. 希望する長さの有効なシーケンスになるまで繰り返します。

このバックトラッキングは、正規表現置換のループによって実装されます。ループは、1回の反復で文字列が変更されないままになると中止されます。

$
_

これ_により、入力にa が追加されます。これは、単項入力を、構築しているシーケンスから分離するために使用されます。

(r`^(?<-2>.)+_((.)+)\b$
$1!

これはループの最初の置換です(先行で示されます()。正規表現は、a)文字列の最後に単語文字(つまり、数字)がある場合に一致します(つまり、文字列が有効であることを意味します。以下では、無効なシーケンスが末尾にマークされていることを確認します#)、b)少なくとも入力と同じ数の文字がシーケンスに含まれます(これは、バランスグループを使用してチェックされます)。その場合は、入力を削除してを追加し!ます。これ!により、ループ内のすべての正規表現が失敗し、終了します。

\b$
0

末尾に単語文字がある場合(つまり、シーケンスが有効で、ループが前の手順で終了していない場合)は、を追加し0ます。

3#
#

(代わりに)シーケンスが無効とマークされてで終わっていた場合は3、それを削除します3(ただし、現在のプレフィックスに継続があり得ないため、シーケンスを無効のままにします...したがって、次の文字もバックトラックする必要があります)。

0#
1
1#
2
2#
3

シーケンスに無効のマークが付けられており3、最後にない数字がある場合は、数字を増やしてマーカーを削除します。

)r`\1(?<-2>.)*((.)+)$
$0#

ループの最後の置換(で示される))。文字列が末尾にあるかどうかをチェックしますABA(ここで、Bは長くないAが空になる可能性があります)。との相対的な長さはABバランスグループを使用して再度チェックされ、の繰り返しはA、単純な後方参照でチェックされます。

この正規表現が一致する場合は、を追加してシーケンスに無効のマークを付けます#

!
<empty>

ループが終了したら、!あとは削除するだけで、目的の出力が残ります。


2

Python 2、175-5 = 170バイト

n=input();s='';u=j=-1
while n>len(s):
 while u>2:u=int(s[0]);s=s[1:]
 u+=1;t=`u`+s;m=c=0
 while t[c:]*0**m:c+=1;i=t[c:].find(t[:c]);m=j<i<=c
 if c>=len(t):s=t;u=j
print s[::j]

これは、バックトラッキングを使用した貪欲なアルゴリズムです。もっと短くなればいいのに。私はそれが正しいことを願っています(以下を参照)。

文字列は一度に1桁ずつ作成されます。dすでに見つかった数字の文字列を指定すると、a 0(d+1)stの数字として追加しようとします。それでも問題が解決しない場合は、それをしようと1、それから2、それから3。これらのいずれも機能しない場合は、dth桁に戻ってそれをインクリメントするか(未満の場合3)、または削除します(と等しい3場合、前の値をインクリメントするなど)。

妥当性のチェックはその中の行.findです。誰かが私のコードを読むことにした場合に備えて、このプログラムは実際には文字列を逆方向に格納している、つまり、前に数字を追加していると言うべきです。したがって、チェックでは、最初の c数字が文字列内で後で再び出現する場所(最初のc数字の後の任意の場所)を探し、そのような場所がある場合は、介在する長さが最大かどうかを調べcます。

(もちろん、印刷する前に文字列を反転させます。)

また、簡単に高速化することもできます。元々、効率を上げるためにさまざまなループを早期に終了させて​​いましたが、そのために貴重なバイトが消費されていました。n=1000ただし、の範囲では問題ありません。

とにかく、プログラムは小さい数字を優先するように見えますが、それは非常に強い優先ではありません。例えば、とそれを実行すると、n=2000私の文字列与えた523ゼロ、502もの、497補数と478で終わるスリーを、30210312013021。したがって、他の誰かが貪欲なアルゴリズムに取り組んでいる場合、多分彼らはこの結果を確認することができます。またはn=1000私は[263, 251, 248, 238]数字でカウントを得ました。

最後に、私たちは一様分布で開始し、その後のいくつかの変換したかのようにこれらのカウントは(いない厳密にいえ)ほとんど、ソート対称性を示唆であることを言及う3さんへ0のとの数2のへ1"をs。しかし、明らかにそれは偶然かもしれません。何も思いつきません!


弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.