このアルカサルを私のために解決してください


39

最近、アルカザールと呼ばれるゲームをプレイしています。ボードパズルゲームです。1つのドアから入り、すべての広場を通過し、別のドアから出ることが目標です。唯一のルールは次のとおりです。

  • 一度入力し、一度離れます。
  • すべての正方形を通過します。
  • 正方形を複数回通過しないでください

以下の画像は、アルカサルのボードとその右側の解決済みパズルの例を示しています(もちろんこれは簡単なパズルです)。

アルカサルパズルのサンプル

http://www.theincrediblecompany.com/try-alcazarでさらにパズルを見つけて、PlayStoreでゲームをダウンロードできます(PS:広告ではありません)。

私の問題は、1つのレベルを除いて、ゲームをほぼ終了したことです。私はそれを解決する方法を見つけることができません。したがって、私が提案する課題は、通常の1可解2アルカサルレベルを解決するアルゴリズムを作成することです。

もちろん、画像を読み取ってパズルを解くために画像インタープリターを作成するように誰かに求めているわけではありません(または私ですか?)。そこで、私はボックス描画文字を使用して上記のパズルを作り直しました。パズルとその解決策は次のようになります。

╔═══════╗         ╔═══════╗
║▒ ▒ ▒ ▒║         ║┌─┐ ┌─┐║
║     ║ ║         ║│ │ │║│║
╣▒ ▒ ▒║▒╠         ╣│ └─┘║└╠
║ ══╦═╩═╣         ║│══╦═╩═╣
║▒ ▒║▒ ▒║         ║└─┐║┌─┐║
║   ║   ║   ==>   ║  │║│ │║
╣▒ ▒║▒ ▒║         ╣┐ │║│ │║
║ ║ ║   ║         ║│║│║│ │║
╣▒║▒ ▒ ▒║         ╣│║└─┘ │║
║ ║     ║         ║│║    │║
║▒ ▒ ▒ ▒║         ║└─────┘║
╚═══════╝         ╚═══════╝

上のボードには、満たされるセルがあります。

セル間に垂直方向と水平方向のギャブがあることがわかります。これは、壁を追加するためにセル間にスペースを挿入する必要があったためです。つまり、重要なセルは、各セルの上、下、左、右にあるものだけです。対角線は、情報を失うことなく削除できます。たとえば、以下のボードでは、両方とも同じパズルを表しています。

╔════╩╗         ═ ═ ╩ 
║▒ ▒ ▒║        ║▒ ▒ ▒║
║ ═══ ║           ═   
║▒ ▒ ▒║   ==   ║▒ ▒ ▒║
║     ║               
║▒ ▒ ▒║        ║▒ ▒ ▒║
╚╦════╝         ╦═ ══ 

これはソリューションにも有効です。つまり、セルを接続する必要はありません。

╔════╩╗        ╔════╩╗        ╔════╩╗
║▒ ▒ ▒║        ║┌───┘║        ║┌ ─ ┘║
║ ═══ ║        ║│═══ ║        ║ ═══ ║
║▒ ▒ ▒║   ==   ║└───┐║   =>   ║└ ─ ┐║
║     ║        ║    │║        ║     ║
║▒ ▒ ▒║        ║┌───┘║        ║┌ ─ ┘║
╚╦════╝        ╚╦════╝        ╚╦════╝

上記の例では、両方のソリューションの意味は同じです。

はい、テストケース。どうぞ:

パズル1

╔════╩╗        ╔════╩╗
║▒ ▒ ▒║        ║┌ ─ ┘║
║ ═══ ║        ║ ═══ ║
║▒ ▒ ▒║   =>   ║└ ─ ┐║
║     ║        ║     ║
║▒ ▒ ▒║        ║┌ ─ ┘║
╚╦════╝        ╚╦════╝

パズル2

╔═════╗        ╔═════╗
║▒ ▒ ▒║        ║┌ ─ ┐║
║   ║ ║        ║   ║ ║
╣▒ ▒║▒║        ╣└ ┐║│║
║ ║ ║ ║   =>   ║ ║ ║ ║
╣▒║▒ ▒╠        ╣┐║│ │╠
║ ║   ║        ║ ║   ║
║▒ ▒ ▒║        ║└ ┘ │║
╚════╦╝        ╚════╦╝

パズル3

╔════╩══╗        ╔════╩══╗
║▒ ▒ ▒ ▒║        ║┌ ┐ └ ┐║
║ ║   ║ ║        ║ ║   ║ ║
╣▒║▒ ▒║▒╠        ╣┘║└ ┐║│╠
║ ╚══ ║ ║        ║ ╚══ ║ ║
║▒ ▒ ▒ ▒╠   =>   ║┌ ─ ┘ │╠
║   ═══ ║        ║   ═══ ║
║▒ ▒ ▒ ▒║        ║│ ┌ ┐ │║
║   ║   ║        ║   ║   ║
║▒ ▒║▒ ▒║        ║└ ┘║└ ┘║
╚═══╩═══╝        ╚═══╩═══╝

パズル4

╔═══════╗        ╔═══════╗
║▒ ▒ ▒ ▒║        ║┌ ┐ ┌ ┐║
║     ║ ║        ║     ║ ║
╣▒ ▒ ▒║▒╠        ╣│ └ ┘║└╠
║ ══╦═╩═╣        ║ ══╦═╩═╣
║▒ ▒║▒ ▒║        ║└ ┐║┌ ┐║
║   ║   ║   =>   ║   ║   ║
╣▒ ▒║▒ ▒║        ╣┐ │║│ │║
║ ║ ║   ║        ║ ║ ║   ║
╣▒║▒ ▒ ▒║        ╣│║└ ┘ │║
║ ║     ║        ║ ║     ║
║▒ ▒ ▒ ▒║        ║└ ─ ─ ┘║
╚═══════╝        ╚═══════╝

パズル5

╔══╩══════╗        ╔══╩══════╗
║▒ ▒ ▒ ▒ ▒║        ║┌ ─ ┐ ┌ ┐║
║   ║     ║        ║   ║     ║
║▒ ▒║▒ ▒ ▒╠        ║└ ┐║└ ┘ │╠
║   ╠════ ║        ║   ╠════ ║
║▒ ▒║▒ ▒ ▒║   =>   ║┌ ┘║┌ ─ ┘║
║   ║     ║        ║   ║     ║
║▒ ▒║▒ ▒ ▒╠        ║└ ┐║└ ─ ─╠
║   ╠═════╣        ║   ╠═════╣
║▒ ▒║▒ ▒ ▒║        ║┌ ┘║┌ ─ ┐║
║   ║     ║        ║   ║     ║
║▒ ▒ ▒ ▒ ▒║        ║└ ─ ┘ ┌ ┘║
╚══╦═══╦══╝        ╚══╦═══╦══╝

パズル6

╔═══════════╗        ╔═══════════╗
║▒ ▒ ▒ ▒ ▒ ▒║        ║┌ ┐ ┌ ┐ ┌ ┐║
║           ║        ║           ║
║▒ ▒ ▒ ▒ ▒ ▒║        ║│ └ ┘ └ ┘ │║
║       ═══ ║        ║       ═══ ║
║▒ ▒ ▒ ▒ ▒ ▒║        ║└ ┐ ┌ ─ ─ ┘║
║     ═══   ║        ║     ═══   ║
╣▒ ▒ ▒ ▒ ▒ ▒╠   =>   ╣┐ │ │ ┌ ┐ ┌╠
║           ║        ║           ║
║▒ ▒ ▒ ▒ ▒ ▒║        ║│ │ │ │ │ │║
║   ║   ║   ║        ║   ║   ║   ║
║▒ ▒║▒ ▒║▒ ▒║        ║│ │║│ │║│ │║
║   ║   ║   ║        ║   ║   ║   ║
║▒ ▒ ▒ ▒ ▒ ▒║        ║└ ┘ └ ┘ └ ┘║
╚═══════════╝        ╚═══════════╝

パズル7

╔════╩════════╦╩╗        ╔════╩════════╦╩╗
║▒ ▒ ▒ ▒ ▒ ▒ ▒║▒║        ║┌ ─ ─ ─ ─ ─ ┐║│║
║ ║       ║   ║ ║        ║ ║       ║   ║ ║
║▒║▒ ▒ ▒ ▒║▒ ▒ ▒║        ║│║┌ ─ ─ ┐║┌ ┘ │║
║ ║ ║ ═══ ║     ║        ║ ║ ║ ═══ ║     ║
║▒ ▒║▒ ▒ ▒ ▒ ▒ ▒╠        ║│ │║┌ ─ ┘ └ ┐ │╠
║   ║           ║        ║   ║           ║
║▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒║        ║│ │ └ ┐ ┌ ┐ └ ┘║
║     ║ ║     ══╣        ║     ║ ║     ══╣
║▒ ▒ ▒║▒║▒ ▒ ▒ ▒║        ║│ └ ┐║│║│ └ ─ ┐║
║     ║ ║       ║        ║     ║ ║       ║
║▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒║        ║│ ┌ ┘ │ └ ┐ ┌ ┘║
║           ║ ══╣   =>   ║           ║ ══╣
║▒ ▒ ▒ ▒ ▒ ▒║▒ ▒║        ║└ ┘ ┌ ┘ ┌ ┘║└ ┐║
╠══       ║ ╚══ ║        ╠══       ║ ╚══ ║
║▒ ▒ ▒ ▒ ▒║▒ ▒ ▒║        ║┌ ┐ └ ┐ │║┌ ─ ┘║
║     ║ ║ ║     ║        ║     ║ ║ ║     ║
║▒ ▒ ▒║▒║▒ ▒ ▒ ▒║        ║│ └ ┐║│║│ └ ─ ┐║
║ ║   ║ ║ ╔══   ║        ║ ║   ║ ║ ╔══   ║
║▒║▒ ▒ ▒ ▒║▒ ▒ ▒║        ║│║┌ ┘ │ │║┌ ┐ │║
║ ║     ║ ║     ║        ║ ║     ║ ║     ║
║▒ ▒ ▒ ▒║▒ ▒ ▒ ▒║        ║│ └ ─ ┘║└ ┘ │ │║
║       ╚══     ║        ║       ╚══     ║
║▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒║        ║└ ─ ─ ─ ─ ─ ┘ │║
╚════╦═╦═╦═════╦╝        ╚════╦═╦═╦═════╦╝

パズル8(申し訳ありませんが、これに対する解決策はありません)

╔══╩╦══╩═══╩═╩═╩═══╩╗
║▒ ▒║▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒║
║   ║               ║
╣▒ ▒║▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒║
║   ╚══ ╔══     ╔═══╣
╣▒ ▒ ▒ ▒║▒ ▒ ▒ ▒║▒ ▒╠
║       ║   ╔══ ║   ║
╣▒ ▒ ▒ ▒ ▒ ▒║▒ ▒ ▒ ▒╠
║           ║       ║
║▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒╠
║           ║       ║
╣▒ ▒ ▒ ▒ ▒ ▒║▒ ▒ ▒ ▒╠
║   ╔═══╗   ╚══     ║
╣▒ ▒║▒ ▒║▒ ▒ ▒ ▒ ▒ ▒║
║   ║   ║           ║
╣▒ ▒║▒ ▒║▒ ▒ ▒ ▒ ▒ ▒╠
║ ══╝   ║       ╔══ ║
║▒ ▒ ▒ ▒║▒ ▒ ▒ ▒║▒ ▒║
║   ══╗ ╚══ ╔══ ║   ║
╣▒ ▒ ▒║▒ ▒ ▒║▒ ▒ ▒ ▒╠
║     ║     ║   ║   ║
╣▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒║▒ ▒║
║   ═══   ══╗   ║   ║
╣▒ ▒ ▒ ▒ ▒ ▒║▒ ▒ ▒ ▒╠
╠══ ║       ║   ╔══ ║
║▒ ▒║▒ ▒ ▒ ▒ ▒ ▒║▒ ▒╠
║   ╚══ ║   ║   ║   ║
╣▒ ▒ ▒ ▒║▒ ▒║▒ ▒ ▒ ▒╠
║       ║   ║       ║
║▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒║
╚══╦═══╦═══╦═╦═╦═╦═╦╝

入力

コードの入力は、次の規則に従う限り、任意の表現を使用できます。

  1. グラフィカルな入力である必要があります。そのため、たとえば座標リストを読み取ることはできません。

  2. 水平の壁、垂直の壁、およびドアは明確でなければならず、それらは目に見えるキャラクター(空白キャラクターなし)で作られていなければなりません。

  3. 空白で置き換えることができます。別のキャラクターを使ってそれらを強調表示しただけです。

出力

出力は、これらの規則に従う限り、任意の表現を持つこともできます。

  1. グラフィカルな出力でなければなりません。つまり、パスを見ることでパスを見ることができます。

  2. ルール番号1は、パス文字が異なることを意味します。つまり、少なくとも6つのパス文字があります。水平、垂直、および角。

  3. 答えを有効にするには、すべてのセル(私の表現では)が入力された状態で、出力が(明らかに)入力と同じボードでなければなりません。セル間のギャップを埋めることはオプションです。

得点

これはであるため、バイト単位の最短コードが優先されます。

1オプションのセルとトンネルがあるいくつかのアルカサルレベルがあります。これらは考慮されません。

2不可能なアルカザールボードがいくつかあります。


2
私のプログラムはパズル8の解決策を見つけられません。それは解決可能ですか?多分タイプミス?
edc65

1
ここでは、@ edc65同じ- #8のための無ソリューション
NGN

回答:


5

Pythonの3809 728 723 714 693 688 684 663 657 641 639 627 610 571 569バイト

編集:@Felipe Nardi Batistaのおかげで55バイト保存

TIOで60秒以内に最後のテストケースを実行しませんが、それでも正しく動作するはずです。パスの座標のリストを返します。約400バイトは、I / Oからデータリストを取得するために使用されます。

A=enumerate
I,J="═║"
B=range
L=len
K=-1
Z=1,0
X=0,1
C=K,0
V=0,K
E=lambda a,b,p:(((a,b)in d)*L(p)==H*h)*p or max([E(q+a,w+b,p+[(q+a,w+b)])for q,w in y[a][b]if~-((q+a,w+b)in p)*-h>w+b>K<q+a<H]+[[]])
x=input().split("\n")
h=L(x[0])//2
H=L(x)//2
y=[[{C,Z,V,X}for i in B(h)]for j in B(H)]
d=[]
exec('d+=[(%s,i)for i,a in A(x[%s][1::2])if I<a]\nfor i,u in A(x[%s:%s:2]):\n d+=[(i,0)]*(J<u[0])+[(i,h-1)]*(J<u[K])\n for j,w in A(u[%s:%s:2]):\n  if"%s"==w:y[i][j]-={%s};y[i+%s][j+%s]-={%s}\n'*2%(0,*X,"",2,K,J,X,*X,V,H-1,K,2,K,1,"",I,Z,*Z,C))
print(max(E(*D,[D])for D in d))

オンラインでお試しください!


@HalvardHummelさて、チャレンジの定式化が残念です。そこで、私は以下を提案します。スコアは、バイト数に実行時間を掛けて計算されるため、実行時間とバイト数の両方に報酬が与えられます。どう思いますか?
Phelype Oleinik

1
@PhelypeOleinik私はそれが非常に良いスコアリングシステムだとは思わない。男女共学のゴルフにそれを保つことはよりよい解決策ですが、あなたが本当に解決策を探しているなら、私はこれがより効率的になるように修正できると確信しています。
ケアニアン共犯

@cairdcoinheringaahing最もエレガントな解決策はそのままにしておくことです。しかし、8x12パズルボードを解くのに「数日または数か月」かかるアルゴリズムは、なんとなく非効率的です。私の考えでは、問題が少しでも長くなるとしても、問題をより短時間で解決するアルゴリズムが報われるはずです。
Phelype Oleinik

3
@PhelypeOleinikコードの「効率」は関係ありません。あなたは短いコードを書くように私たちに挑戦しました、そしてそれはあなたの挑戦の基礎です。プログラムを実行する速度をミックスに追加しても、不必要に事態が複雑になるだけでなく、ばかげたスコアのために悪用される可能性もあります。カスタムスコアリングシステムはうまく機能しない傾向があります。短いコードが必要な場合は、コードとゴルフの質問をしてください。高速なコードが必要な場合は、最速のコード質問をしてください。それらを一緒にしようとするのは良い考えではありません。
LyricLy

あなたにはexec(...)、文字列として表さ5つの新しい行がある\n、5 * 2 = 10のバイトが。三重引用符で囲まれた文字列を使用すると、4バイト(...''...''...)が追加されますが、実際の改行文字を使用できるため、5バイトが削除されます。これにより、合計で1バイト節約できます。
ジョナサンフレッチ

5

APL(Dyalog Classic)、319バイト

iNj←⍳1+n←×/N←⌊2÷⍨⍴a←⎕⋄e←↑⊃,/{(,~'#='∊⍨a[(⍵⌽⍳2)∘+¨2×⍳N+⍵=⍳2])/,2,/[⍵]⊃,[⍵]/n i n}¨⍳2
r←{e g c←⍵⋄d←+/j∘.=∊g⋄e⌿⍨←(≠/c[e])∧2>⌈/d[e]⋄n≡≢g:gj/⍨d=10≡≢e:02>⌊/d+D←+/j∘.=,e:0⋄u←,¯1↑e←e[⍒⌊/D[e];]⋄e↓⍨←¯1⋄0≢r←∇e(g⍪u)(c-(-/c[u])×c=c[⊃u]):r⋄∇e g c}e(0e)j
a[1+2×⍳N]←' ??┌?─┐┬?└│├┘┴┤┼'[2⊥(↑(⊂i),¨¨{⊖∘⍉⍣⍵⊢n⍪¯1↓⌽∘⍉⍣⍵⊢i}¨⍳4)∊↓r⍪⌽r]
a

オンラインでお試しください!

入力は、従来の文字セットに収まるようにする=#F7LJ<>^v.代わりに使用します。═║╔╗╚╝╣╠╩╦▒

最後の1つを除くすべてのテストケースは、数秒で合格します。

最後のテストは私のコンピューターで47分かかり、解決策はありません。

結果のパスがコーナー近くのドアを使用すると、誤ってレンダリングされる場合があります(トレイルが分岐して余分な想像上のドアを通過するかのように見えます)が、それでも識別可能で明確です。


とても良い!私が尋ねる場合、あなたのコードはどのアプローチを使用して解決しますか?徹底的な検索またはよりエレガントなものですか?また、私が言ったように、私は最後のパズルを手で解決しませんでした。明確な段階的な解決策はなく、手で解決する場合でも、いくつかの答えを見つけるために当て推量が必要です。このパズルは元のゲームに含まれていますが、解決策がない可能性があるため、おそらく考慮すべきではありません。
Phelype Oleinik

1
@PhelypeOleinikはい、それはかなり洗練されていない大規模な検索です。既存のソリューションをすばやく見つける理由は、より可能性の高いケースを最初に試行するためです(グラフの特定のエッジがある場合とない場合-私のヒューリスティックは2つの頂点の次数の最小値であり、低いほど可能性が高くなります)。最後のケースで恐ろしく動作する理由は、とにかくすべての可能性をテストし、明らかな矛盾のみで再帰をプルーニングするからです。有界次数(≤4近傍)グラフの特別な場合でも、既知の優れたハミルトニアンパスアルゴリズムはないようです。
NGN

3

JavaScript(ES6)、274バイト

複数行の文字列として入力し、各行は改行文字で終了します。ドアには文字「2」が付いています

パスが文字「1」でマークされた複数行の文字列として出力され、非常に簡単に識別できます。

これは深さ優先検索であり、すべてのパスを試行し、立ち往生したときにバックトラッキングします。それはまったく効率的ではありませんが、パズル1 .. 6を1分未満で解決できます。

z=>(w=z.search`
`+1,t=(w-2)*(z.length/w-1)/4,z=[...z],R=(p,l,q)=>[1,-1,w,-w].some(d=>l<t?z[q=p+d]<1&z[q+d]<1&&(R(q+d,++z[q]+l)||--z[q]):z[p+d]>1&&--z[p+d],++z[p])||--z[p],z.some((c,i)=>-c&&(x=i%w,R(i<w?i+w:x?x>w-3?i-1:i-w:i+1,--z[i])||++z[i]*0))&&z.join``.replace(/0/g,' '))

少ないゴルフ

z => (
  w = z.search`\n`+1, // board width and offset to next row
  t = (w-2)*(z.length/w-1)/4, // total size of board, number of cells that must be filled
  z = [...z], // convert string to array
  d = [1, -1, w, -w], // delta to next position in all directions
  // recursive search
  // given a current position, try to move in all directions
  // if the board is not full, look for an emoty cell
  // if the board is full, look for a door
  R = (p, // current position
       l, // fill level
       q  // parameter used as a local variable
      ) => (
        ++z[p], // mark current position
        // .some will terminate early if the called function returns true
        // in case of return true the recursive function returns all way up leaving the path marked
        // in case of return false we need to unmark path and backtrack
        d.some( d => // for each direction, offset in d
          l < t // check if board is full
          ? z[q=p+d] < 1 & z[q+d] < 1 // not full, try to advance 
            && (++z[q], // mark intermediate cell
                R(q+d, 1+l) // recursive call incrementing fill level
                || --z[q] // if R return false, backtrack: unmark intermediate cell
               )
          : z[p+d] > 1 && --z[p+d]
        ) // full, ok only if I find a door nearby
        || --z[p], // if some returns false, unmark and backtrak
  // look for doors and for each door call R 
  // when R returns true, stop and return the marked board
  // if R returns false for each door, no solution, return false
  z.some((c,i) => 
   -c && // if numeric and != 0
    (x = i%w,
     z[i]=1, // marking starting position (door)
     R(i<w ? i+w : x ? x > w-3 ? i-1 : i-w : i+1, 1)
     || (z[i] = 2, false) // if R returned false, unmark a return false
    ) 
  ) && z.join``.replace(/0/g,' ') 
)

テストスニペットの中には、DFSを使用して、パズル7を1分もかからずに(PC上で)解決する制約を使用したソリューションがあります。パズル8には解決策がありません。制約:

  • すべての空のセルは、現在のセルから到達可能である必要があります-空のスペースを2つの部分に分割しないでください
  • 到達可能なドアが必要です
  • セルの構成を複数回探索することはできません
  • 空の隣接セルが1つしかないセルはスキップできません

テスト

パズル7は、ブラウザでのJavaScript実行のタイムアウトをはるかに超えていることに注意してください(ShortおよびSlowソルバーを使用)

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