クラッシュせずにループできますか?


14

私たちの多くは、Tronというゲームに精通しています。グリッドに配置された「ライトサイクル」を制御します。ライトサイクルは常に前方に移動し(方向を制御しますが)、その背後に永続的なトレイルを残します。トレイルにぶつかると、クラッシュします!

ここでの目標は、特定のパスが有効なループであるかどうか、つまり「クラッシュ」せずに開始点に戻るかどうかを判断することです。これを行うために、ポイントから開始すると仮定し(0,0)ます。入力はN2E1S2W1、一連の基本方向(Nis northEis east、など)の形式で与えられ、それぞれにその方向に移動する距離が続きます。この例では、旅行します

N2 : North 2 to (0,2)
E1 : East 1  to (1,2)
S2 : South 2 to (1,0)
W1 : West 1  to (0,0)

パスは(0,0)、他の座標(0,0)に2回以上アクセスすることなく終了する場合に有効と見なされます(正確に2回アクセスします。開始時に1回、終了時に1回)。上記の例よりも注意し(0,0)(0,2)ください(0,1)。からに到達するには、必ずアクセスする必要があります。

他の例:

input        -> output
N1E1S1W1     -> true
N1E1N1E1S2W2 -> true
N1S1E1W1     -> false     // Visits (0,0) 3 times
N4E2S2W4S2E2 -> false     // Visits (0,2) twice
N3E2S3       -> false     // Does not return to (0,0)
N1S1         -> anything  //I don't care how you evaluate this case

出力は、trueまたはfalseの値に対して同じ出力を提供する限り、どのような形式でもかまいません。

入力は、S1N2E3...またはSNNEEE... の形式で、文字列または文字のリストとして取得できます。グリッドサイズには厳密な制限もありませんが、入力がオーバーフローしないことを前提としています。コードが基本的に健全である限り、などのケースを処理することは重要ではありませんN99999999999999

注:ケースを評価することができるN1S1E1W1S1N1、とW1E1しかし、あなたがしたいと思います。それらは技術的には有効なパスですが、チャレンジの「トロン」精神に反します。

得点

これはなので、最短の答えが勝ちです!


N1S1定義に一致するのは(0, 0)2回と(0, 1)1回であり、これは定義のもとで有効であるためです。
ハイパーニュートリノ

私が取ることができますNように1jEなど1Sなど-1j、とW-1
リーキー修道女

@LeakyNun私はそれで大丈夫だと思う、とにかく誰もが多かれ少なかれこのようなことをやっているはずだから。回答でそれを必ず指定してください。
主ファルカード

1
@HyperNeutrinoですが、トロンの観点からすると、入力がそのようなポイントに決して到達しない場合でも、ライトサイクルは(0、0.5)を2回通過します。私は1つの柔軟な出力を持っていると思う理由は、(ほとんどの言語のために、trueを返すことが容易になりますが)だ
バリューインク

1
@steenbergh(0,0)は角にないので、その下または左に行くことができます。気が狂っている場合でも両方です!また、グリッドサイズに厳密な制限はありませんが、入力がオーバーフローしないことを前提としています。それは次のように入力を処理できない場合、長いコードは基本的に健全であるように、私は気にしないN99999999999999
主Farquaad

回答:



6

JavaScript、247 200バイト

n=s=>{r=s.match(/\w\d+/g)
x=y=z=0
e=""
for(d of r){a=d[0]
b=d.slice(1)
while(b--){
y+=a=="N"
y-=a=="S"
x+=a=="E"
x-=a=="W"
p=[x,y]+";"
if(~e.indexOf(p))if(!x&!y)z++
else return 0
e+=p}}return!x&!y&!z}

ntrueとfalse sを返す入力文字列の関数です10

参照/説明用の未使用バージョンは次のとおりです。

function n(s)
{
    var dir = s.match(/\w\d+/g);
    var x = y = z = 0;
    var been = "";
    for (d of dir)
    {
        var a = d[0];
        var b = 1*d.substring(1);
        while(b-- > 0)
        {
            if (a == "N") y++;
            if (a == "S") y--;
            if (a == "E") x++;
            if (a == "W") x--;
            var pt = [x,y] + ";";
            if (~been.indexOf(pt))
                if (x==0 && y==0)
                    z++;
                else
                    return false;
            been += pt;
        }
    }
    return (x == 0 && y==0 && z == 0);
}

n=s=>{r=s.match(/\w\d+/g)
x=y=z=0
e=""
for(d of r){a=d[0]
b=d.slice(1)
while(b--){
y+=a=="N"
y-=a=="S"
x+=a=="E"
x-=a=="W"
p=[x,y]+";"
if(~e.indexOf(p))if(!x&!y)z++
else return 0
e+=p}}return!x&!y&!z}

console.log(n("N1E1S1W1"))
console.log(n("N1E1N1E1S2W2"))
console.log(n("N1S1E1W1"))
console.log(n("N4E2S2W4S2E2"))
console.log(n("N3E2S3"))



気づかなかった、ありがとう
ワッフルコーン

containsjavascriptの方言の関数ではないようです。方言を指定してもらえますか?
リーキー修道女

私はテストするためにクロムコンソールを使用していました-それはそこで完全に動作します
ワッフルコーン

実際、それは私のchromeコンソールでも機能します...
リーキー修道女

5

Pythonの3236の 161 150バイト

import re
p=0
a=[]
for i in''.join(s[0]*int(s[1:])for s in re.findall(r".\d+",input())):p+=1j**"NESW".find(i);a+=[p]
print(len({*a})-len(a)==0==a[-1])

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

Leaky Nunのおかげで-75バイトLeaky Nunの
おかげで-11バイト

パイソン285の 73バイト

c=0;k=[]
for i in input():c+=i;k+=[c]
print(k[-1]==0==len(set(k))-len(k))

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

Mr. Xcoderのおかげで-12バイト/ Leaky Nunのおかげで-9バイト(1つの編集に統合)

これは私には長すぎます


3
Pythソリューションの10倍より短い限り、長すぎません。
リーキー修道女

@LeakyNun大丈夫:P
HyperNeutrino


@LeakyNunああいいスナップ。私が言ったように、あまりにも長い間見る:P
HyperNeutrino


3

ゼリー14 12バイト

Œṙ+\µQ⁼ȧṛ/¬$

ゼリーでのゴルフは初めてです。提案は大歓迎です。

入力は[direction, distance]ペアの配列であり、方向は複素数として指定されます。

説明:

Œṙ+\µÇȧṛ/¬$   Main link. Argument: n     = [[i, 3], [1, 2], [-i, 3]]
Œṙ            Run-length decode          = [i, i, i, 1, 1, -i, -i, -i]
  +\          Cumulative sum             = [i, 2i, 3i, 3i+1, 3i+2, 2i+2, i+2, i]
    µ         Begin a new monadic chain
     Q        Remove duplicates          = [i, 2i, 3i, 3i+1, 3i+2, 2i+2, i+2]
      ⁼       Equal to original?         = 0
           $  Make a monadic link:
        ṛ/      Reduce by right argument   = i
                (Gets the last element)
          ¬     Logical NOT:               = 0
       ȧ      Logical AND the two values = 0

最後のケースで失敗するはずです。
リーキー修道女

0

網膜、86バイト

\d+
$*
1(1*)
$1
+`(.)1
$1$1
.
 $`$&¶
%O`.
+`NS|E(.*)W
$1
M`\w$|(?m)(^.+$)(?s).+^\1$
^0

オンラインでお試しください!リンクにはテストケースが含まれます。説明:

\d+
$*

数値を単項に変換します。

1(1*)
$1
+`(.)1
$1$1

ランレングスは文字をデコードします。N111に変換する必要があるNNNため、各単項数から1を減算し、各1が前の文字を複製します。

.
 $`$&¶

すべてのプレフィックス(パス上のポイント)を個別の行として生成します。空行の問題を回避するために、スペースが先頭に付けられます。

%O`.
+`NS|E(.*)W
$1

各行のすべての文字を順番に並べ替えてから、一致するペアを削除します。最終的に、グリッド上の任意のポイントに対して一意のコードが作成されます。

M`\w$|(?m)(^.+$)(?s).+^\1$

次の2つのうちのいずれかを確認します。a)最後のポイントがスペースで終わっていない(ループが閉じていない)か、パス内の2つの重複したポイント。パスが有効な場合、すべてのチェックは失敗し、結果はゼロになります。

^0

結果を反転します。


0

Perl、140

文字列入力で動作します。おそらく配列で短くすることができますが、私はそれを疑います。さらなるゴルフの助けに満足:)

sub w{$i=$_[0];%d=(E,[0],S,[1,-1],W,[0,-1]);$i=~s/(.)(.)/($d,$o)=(@{$d{$1}},1,1);for(1..$2){$s[$d]+=$o;$r+=$d{"@s"}++}/eg;!($s[0]+$s[1]+$r)}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.