Bisakah Anda mengulang tanpa menabrak?

14

Banyak dari kita yang akrab dengan permainan Tron. Anda mengontrol "siklus cahaya" yang ditempatkan pada kisi. Sepeda ringan selalu bergerak maju (meskipun Anda mengontrol arah) dan meninggalkan jejak permanen di belakangnya. Jika Anda mengalami jejak, Anda menabrak!

Tujuannya di sini adalah untuk menentukan apakah jalur yang diberikan adalah loop yang valid, yaitu, ia kembali ke titik awal tanpa "menabrak". Untuk melakukan ini, kita asumsikan kita mulai dari titik (0,0). Input diberikan dalam bentuk N2E1S2W1, dengan serangkaian arah mata angin ( Nis north, Eis east, and sebagainya), masing-masing diikuti oleh jarak untuk menempuh arah itu. Dalam contoh ini, Anda akan bepergian

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

Jalan dianggap sah jika berakhir (0,0)tanpa mengunjungi koordinat lain lebih dari sekali (mengunjungi (0,0)tepat dua kali. Sekali di awal, dan sekali di akhir). Perlu diingat daripada dalam contoh di atas, untuk mendapatkan dari (0,0)ke (0,2), kita tentu kunjungi (0,1)juga.

Contoh lain:

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

Keluaran Anda bisa dalam bentuk apa pun asalkan memberikan hasil yang sama untuk nilai apa pun yang benar atau salah.

Input dapat diambil sebagai string atau sebagai daftar karakter, baik dalam bentuk S1N2E3... atau SNNEEE... Juga tidak ada batasan pada ukuran kisi, tetapi anggap input tidak akan meluap apa pun. Selama kode tersebut pada dasarnya baik, itu tidak penting untuk menangani kasus seperti N99999999999999.

CATATAN: Anda mungkin mengevaluasi kasus N1S1, E1W1, S1N1, dan W1E1namun Anda ingin. Itu adalah jalur yang secara teknis valid, tetapi bertentangan dengan semangat "Tron" tantangan.

Mencetak gol

Ini , jadi jawaban terpendek menang!

Tuan Farquaad
sumber
N1S1harus benar untuk konsisten dengan definisi Anda karena mencapai (0, 0)dua kali dan (0, 1)sekali, yang berlaku di bawah definisi Anda.
HyperNeutrino
Bisakah saya menerima Nsebagai 1j, Esebagai 1, Ssebagai -1j, dan Wsebagai -1?
Leaky Nun
@ LeakyNun Saya pikir saya setuju dengan itu, karena semua orang harus melakukan sesuatu seperti ini. Pastikan Anda menentukan itu dalam jawaban Anda.
Lord Farquaad
1
@HyperNeutrino tetapi dari sudut pandang Tron, siklus cahaya Anda melewati (0, 0,5) dua kali, bahkan jika input tidak akan pernah menempatkan Anda pada titik seperti itu. Itu sebabnya saya pikir seseorang memiliki output yang fleksibel (meskipun untuk sebagian besar bahasa akan lebih mudah untuk mengembalikan true)
Value Ink
1
@steenbergh (0,0) tidak ada di sudut, sehingga Anda bisa masuk ke bawah atau ke kiri; bahkan keduanya jika Anda merasa gila! Juga, tidak ada batasan keras pada ukuran grid, tetapi anggap saja input tidak akan meluap apa pun. Selama kodenya bagus secara fundamental, saya tidak peduli jika tidak bisa menangani input sepertiN99999999999999
Lord Farquaad

Jawaban:

8

Pyth , 44 39 byte

&!eJsM._smm^.j)x"NESW"hdstd:z".\d+"1{IJ

Suite uji .

Biarawati Bocor
sumber
6

JavaScript, 247 200 byte

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}

nadalah fungsi dari string input syang mengembalikan1 true dan 0for false

Ini versi yang tidak dikoleksi untuk referensi / penjelasan:

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"))

WaffleCohn
sumber
Hapus ruang kosong
HyperNeutrino
tidak memperhatikan itu, terima kasih
WaffleCohn
Tampaknya itu containsbukan fungsi dalam dialek javascript apa pun. Bisakah Anda menentukan dialeknya?
Leaky Nun
Saya hanya menggunakan konsol chrome untuk menguji - itu bekerja dengan baik di sana
WaffleCohn
Sebenarnya ini juga berfungsi di konsol chrome saya ... tapi mungkin Anda akan mempertimbangkan untuk mengubahnya menjadi jawaban yang lebih universal?
Leaky Nun
5

Python 3 , 236 161 150 byte

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])

Cobalah online!

-75 byte terima kasih kepada Leaky Nun
-11 byte terima kasih kepada Leaky Nun Atau, jika kita diizinkan untuk mengambil input sebagai daftar bilangan kompleks yang diterjemahkan dengan run length:

Python 2 , 85 73 byte

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

Cobalah online!

-12 byte terima kasih kepada Tn. Xcoder / -9 byte terima kasih kepada Leaky Nun (digabung menjadi satu edit)

Ini terasa terlalu lama bagiku lol

HyperNeutrino
sumber
3
Selama lebih pendek dari 10 kali solusi Pyth, itu tidak terlalu lama.
Leaky Nun
@ LeakyNun lol oke: P
HyperNeutrino
161 byte
Leaky Nun
@ LeakyNun oh snap bagus. lihat terlalu lama, seperti yang saya katakan: P
HyperNeutrino
76 byte
Leaky Nun
3

Jelly , 14 12 byte

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

Ini adalah pertama kalinya saya bermain golf di Jelly. Saran diterima.

Input adalah sebagai array dari [direction, distance] berpasangan, di mana arahnya diberikan sebagai bilangan kompleks.

Penjelasan:

Œṙ+\µÇȧṛ/¬$   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
Buah Esolanging
sumber
Harus gagal dalam kasus terakhir.
Leaky Nun
0

Retina , 86 byte

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

Cobalah online! Tautan termasuk kasus uji. Penjelasan:

\d+
$*

Ubah angka menjadi unary.

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

Run-length mendekode huruf. N111perlu diubah menjadi NNN, jadi satu dikurangi dari setiap nomor unary dan kemudian masing-masing 1 menduplikasi surat sebelumnya.

.
 $`$&¶

Hasilkan semua awalan (yaitu titik di jalan) sebagai baris terpisah. Ruang diawali untuk menghindari masalah dengan garis kosong.

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

Urutkan semua huruf di setiap baris ke dalam urutan dan kemudian hapus pasangan yang cocok. Kami berakhir dengan kode unik untuk setiap titik di grid.

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

Periksa salah satu dari dua hal: a) titik terakhir tidak berakhir pada spasi (mis. Loop tidak menutup), atau dua titik duplikat di jalur. Jika jalur valid, semua pemeriksaan gagal dan hasilnya nol.

^0

Balikkan hasilnya.

Neil
sumber
0

Perl, 140

Bekerja dengan input string. Mungkin saya bisa mempersingkat dengan array, tapi saya ragu. Senang untuk bantuan golf lebih lanjut :)

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)}
bytepusher
sumber