Uçakta geçerli yılanlar


23

Vi Hart'ın videolarından birinin ilham kaynağı (potansiyel meydan okuma fikirleriyle dolu bir hazine)

Aynı uzunluktaki bölümlerden bir yılan yapılır ve her bölüm arasındaki bağlantı düz olabilir veya 90 ° dönüş yapabilir.
Böyle bir yılanı (başlangıç ​​yönüne bağlı olan bir dönüşe kadar) bir sicim , dönme yönlerini (Düz / Sol / Sağ) yazarak kodlayabiliriz . Bu, sol üstten başlayıp sağa dönük

-+    +--+    SR    RSSR
 |  +-+  |     S  RSL  S
 +--+  --+     LSSL  SSR

Slither tarafından temsil olurdu SRSLSSLRLRSSRSRSS

Ve elbette düzlemsel bir yılan, kendisiyle kesişemez (içinde olduğu gibi SSSSLLLSS), bu korkunç bir pikselli Game Over ile sonuçlanır.

Göreviniz bir dilimin geçerli olup olmadığını belirlemek (en az bir kendi kesişimiyle sonuçlanır)

Girdi Geçerli bir terimse Çıktı Somut Gerçeği
olan harflerden SLRve eğer değilse, Falsey gibi bir harften oluşan bir dize .2 < length < 10000

Test durumları

__Valid__
SSLSLSRSRSSRSSSLLSSSRRLRSLRLLSSS
SRRLSLLRRLLSLRRSRLLRSRRLLRRSRLLSSLLRSRRLLRRSRLLRSRRLSLLRRLLSLRR (A hilbert curve)
RLLRSRRLSLLRRLLSLRRSRLLRSRRLLRRSRLLSSLLRSRRLLRRSRLLRSRRLSLLRRLLSLRRSRLLRSRRLLRRSRLLSSLLRSRRLLRR
SRRSRSRSSRSSRSSSRSSSRSSSSRSSSSRSSSSSRSSSSSRSSSSSSRSSSSSSRSSSSSS (Spiral)
SSSSSSSSSSLSSSSSSSLSSSSSSSSLSSSSSLSSSSSSLSSSLLRRLLRRLLSLSSSRRSSSSRSSSRSSSSSSRSSSSSRSSSSSSSSRSSSSSSSRSSSSSSSSS (bigger, squigglier spiral)
LRSLLRLSRSLLSRLSLRSLSSSLRRSSLSRRLRSRLRLSLRLLRLRSSLSLRLRSRSSSSSLSRRLSLSSSRRLRLRLRLRRLLSSLSSSRRLRLRLRLRLSLSSSSSSSSSSSSSRLRLLRLRLRLRLRLRLRLSLSSSLSLSLL

__Invalid__
SRRLSLLRRLLSLRRSRLLRSRRLLRRSRLLLLRSRRLLRRSRLLRSRRLSLLRRLLSLRR
SRRLSLLRRLLSLRRSRLLRSRRLLSRSSSRSSSSSSSRSRSSSSSSSRRLLRRSRLLRSRRLSLLRRLLSLRR
SRRSRSRSSRSSRSSSRSSSRSSSSSSSSSSRSSSSRSSSSSRSSSSSRSSSSSSRSSSSSSRSSSSSS
SSSSSSSSSSLSSSSSSSLSSSSSSSSLSSSSSLSSSSSSLSSSLLRRLRLRRLLSLSSSRRSSSSRSSSRSSSSSSRSSSSSRSSSSSSSSRSSSSSSSRSSSSSSSSS
LRSLLRLSRSLLSRLSLRSLSSSLRRSSLSRRLRSRLRLSLRLLRLRSSLSLRLRSRSSSSSLSRRLSLSSSRRLRLRLRLRRLLSSLSSSRRLRLRLRLRLSLSSSSSSSSSSSSSRLRLLRLRLRLRLRLRLRLSLSSSLSLSLLSLRLSLRSLRSLRSLSLSLRSRLSLRSLRLSRSLLLRLRLRRRRSLSLSSLLSLSLSLSSLLSLSLLRLRSLLRSRLSLSSLLLLSSSSSSSSSSSSSSSSSSSSRLRLLRRLRLRLLRLRLRLRLRLSSSSLSLRLLRLSLSSLSLSLSLSLRLLRLSLLLSRSSSSSSSSSSSSSSSRLRLRLLRLRLSLSRSRSSSLSRLRLRLRSLSLSLSRLLSRLSLSLSLSLSSLSLSLLSLSRLLRLRLRLRLRLRLRLRLRLRLSLSRLRLSLLRRLSLLSLSLSLSLSLLSLSLSLRLRLRLRLRLRLRLRLRLRRLRSLSLSLSLSLSLSLSSLSSSSSLSLSSSLSLSLSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS

Şunları yapabilirsiniz buraya slithers çizin (R ve L fiske edilir, ancak geçerliliğini etkilemez görünmez)


Programda giriş yapılması gerekiyor mu yoksa dosyadan okunabilir mi?
MI Wright,

1
SRRR Doğru mu, Yanlış mı? Bağlanır fakat kendini kesmez.
orlp

yılanlara dokunmak NSFW'ye meydan okuyor mu?
Ewan

3
SRRRsegment başına bir kare olan bir grafik kağıdına çizim yaparsanız , üst üste RRRbiner ve bu nedenle geçersiz olur, ancak bununla birlikte, tam olarak üst üste
binmeden

Benzer fakat yinelenmemiş (farklı amaç ve farklı yapım kuralları nedeniyle).
Trichoplax

Yanıtlar:


20

Pyth, 22 20 bayt

ql{m+=Z*=T^.j)hCdzlz

Kendiniz deneyin veya testsuite uygulayın .

SRL'in ASCII değerlerini sırasıyla 83, 76, 82 olarak not edin.

i 83 + 1 = 1
i 76 + 1 = i
i + 82 + 1 = -i

Buradan sadece mevcut pozisyon ve mevcut yön için bir değişken tutuyorum. Her karakter için geçerli yönü yukarıdaki karmaşık sayı ile çarpın, sonra geçerli konuma ekleyin.

Sonunda ziyaret edilen tüm konumların benzersiz olup olmadığını kontrol ediyorum.


SRRR = doğru ????
Ewan

@Ewan Daha yakından bakıldığında - Bunun yanlış olup olmadığından emin değilim. Baş ve kuyruk birbirine bağlanır ancak kesişmez.
orlp

SRRRS'den ne haber?
Ewan

@Ewan Aynı hikaye - bağlantı ancak kesişme yok. Soru, bunlar için neyin iade edilmesi gerektiği net değil.
orlp

1
SRRR'ı nasıl çizersiniz?
Ewan

6

CJam, 30 bayt

q{iF%U+:U[XWe4W1e4]=T+:T}%__&=

Yakında takip edilecek açıklama.

Burada çevrimiçi deneyin veya tüm paketi çalıştırın .


Kahretsin, bu hızlıydı. Henüz kendim çözmek için bir algoritma bile düşünmedim.
DenDenDo

SRRRS = doğru ???
Ewan

@Ewan umm, 0'ın başlangıçta doldurulduğunu ve sayıldığını mı varsayıyoruz?
Doktor,

1
Sanırım hareketleri uzayı engelleyen bir yılan oyunu gibi yorumluyorum. Bazılarınız bunu sıfır genişlikte bir çizgi olarak yorumluyor
Ewan

@Ewan Benim sorum olsa biraz farklı. Tek bir hamle yaptığımızda S, yılanın hem (0,0) hem de (1,0) işgal ettiği anlamına mı geliyor?
Doktor,

6

JavaScript (ES6), 84 89

Test etmek için Firefox'ta snippet'i çalıştırın.

Bazı notlar:

  • Yılan f dizisi içinde hareket eder. Görünmeyen hücrelerin değeri varundefined . İlk ziyarette, tilde operatörü bunu bir gerçek olan -1'e değiştirir. Sonunda, ikinci bir ziyarette 0 değerine everyyanlış olan değer değişir ve döngü yanlış döndürmeyi sonlandırır.
  • JS'de, kanonik olmayan indekslere sahip (sayısal veya negatif olmayan) dizi öğeleri bir şekilde 'gizlidir', ancak varlar. Burada olumsuz endeksleri problemsiz kullanıyorum.

F=s=>[...s].every(c=>f[p+=[1,1e5,-1,-1e5][d=d+{R:1,L:3,S:0}[c]&3]]=~f[p],d=p=0,f=[])

//TEST
$('#S').on('keyup mouseup change', Draw);

function Draw(){
  var s = S.value.toUpperCase();
  if (!s) {
    C.width = C.height = 0;
    return
  }
  C.width = 600;
  C.height = 400;
  
  var ctx = C.getContext("2d");  
  var px, py, int=0;
  
  ctx.strokeStyle = '#008';
  ctx.lineWidth = 2;
  ctx.translate(300,200);
  ctx.beginPath();
  ctx.moveTo(0,0);
  
  [...s].forEach(c=>{
    (f[p+=[1,1e4,-1,-1e4][d=d+{R:1,L:3,S:0}[c]&3]]=~f[p])
    ? 1 
    : (++int)
    if (int==1) ctx.stroke(), ctx.strokeStyle = '#800', ctx.beginPath(), ctx.moveTo(10*px,10*py);
    
    py = (p / 1e4 | 0) - 5e3;
    px = (p % 1e4) -5e3
    ctx.lineTo(10*px, 10*py);
  }, d=0,p=50005000,f=[]);
  ctx.stroke();
  
}

valid=["SSLSLSRSRSSRSSSLLSSSRRLRSLRLLSSS",
"SRRLSLLRRLLSLRRSRLLRSRRLLRRSRLLSSLLRSRRLLRRSRLLRSRRLSLLRRLLSLRR",
"RLLRSRRLSLLRRLLSLRRSRLLRSRRLLRRSRLLSSLLRSRRLLRRSRLLRSRRLSLLRRLLSLRRSRLLRSRRLLRRSRLLSSLLRSRRLLRR",
"SRRSRSRSSRSSRSSSRSSSRSSSSRSSSSRSSSSSRSSSSSRSSSSSSRSSSSSSRSSSSSS",
"SSSSSSSSSSLSSSSSSSLSSSSSSSSLSSSSSLSSSSSSLSSSLLRRLLRRLLSLSSSRRSSSSRSSSRSSSSSSRSSSSSRSSSSSSSSRSSSSSSSRSSSSSSSSS",
"LRSLLRLSRSLLSRLSLRSLSSSLRRSSLSRRLRSRLRLSLRLLRLRSSLSLRLRSRSSSSSLSRRLSLSSSRRLRLRLRLRRLLSSLSSSRRLRLRLRLRLSLSSSSSSSSSSSSSRLRLLRLRLRLRLRLRLRLSLSSSLSLSLL"];
invalid=["SRRLSLLRRLLSLRRSRLLRSRRLLRRSRLLLLRSRRLLRRSRLLRSRRLSLLRRLLSLRR",
"SRRLSLLRRLLSLRRSRLLRSRRLLSRSSSRSSSSSSSRSRSSSSSSSRRLLRRSRLLRSRRLSLLRRLLSLRR",
"SRRSRSRSSRSSRSSSRSSSRSSSSSSSSSSRSSSSRSSSSSRSSSSSRSSSSSSRSSSSSSRSSSSSS",
"SSSSSSSSSSLSSSSSSSLSSSSSSSSLSSSSSLSSSSSSLSSSLLRRLRLRRLLSLSSSRRSSSSRSSSRSSSSSSRSSSSSRSSSSSSSSRSSSSSSSRSSSSSSSSS",
"LRSLLRLSRSLLSRLSLRSLSSSLRRSSLSRRLRSRLRLSLRLLRLRSSLSLRLRSRSSSSSLSRRLSLSSSRRLRLRLRLRRLLSSLSSSRRLRLRLRLRLSLSSSSSSSSSSSSSRLRLLRLRLRLRLRLRLRLSLSSSLSLSLLSLRLSLRSLRSLRSLSLSLRSRLSLRSLRLSRSLLLRLRLRRRRSLSLSSLLSLSLSLSSLLSLSLLRLRSLLRSRLSLSSLLLLSSSSSSSSSSSSSSSSSSSSRLRLLRRLRLRLLRLRLRLRLRLSSSSLSLRLLRLSLSSLSLSLSLSLRLLRLSLLLSRSSSSSSSSSSSSSSSRLRLRLLRLRLSLSRSRSSSLSRLRLRLRSLSLSLSRLLSRLSLSLSLSLSSLSLSLLSLSRLLRLRLRLRLRLRLRLRLRLRLSLSRLRLSLLRRLSLLSLSLSLSLSLLSLSLSLRLRLRLRLRLRLRLRLRLRRLRSLSLSLSLSLSLSLSSLSSSSSLSLSSSLSLSLSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS"];

V.innerHTML=valid.map(s=>F(s)+' '+s).join('\n')
I.innerHTML=invalid.map(s=>F(s)+' '+s).join('\n')
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Type to check and draw <input id=S>
(better full page)<br>
<canvas id=C width=1 height=1 ></canvas><br>
Valid<pre id=V></pre>
Invalid<pre id=I></pre>


6

TI-BASIC, 49 56 53 51 bayt

abs(e^(i)-cumSum(i^cumSum(seq(inString("SL",sub(Ans,X,1))-1,X,1,length(Ans→X
SortA(∟X
min(ΔList(∟X

Orlp yöntemine benzer şekilde, bu, yılan tarafından ziyaret edilen ve başlangıçta başlayan karmaşık düzlemdeki tüm noktaların bir listesini oluşturur. Listede yinelenen öğeler yoksa, kod bazı pozitif değerler döndürür. 999 öğeden daha uzun bir dizgede hesap makinesinin yeterince uzun bir liste oluşturamayacağını ve hatalı olacağını unutmayın.

EDIT: Çirkinlik pahasına iki bayt kurtardı, çünkü karmaşık düzlemde hiçbir iki kafes noktası e ^ i ile aynı mesafede olamaz.


5

TI-BASIC, 60 58 bayt

Düzenleme: Aşağıdaki her şeyi göz ardı et: çalışan bir ti-basic çözümü burada , thomas-kwa tarafından. Git o oyu!

olan [(-)]anahtar ve Ans olduğunu [2ND]->[(-)]. Yılan talimatlarını tırnak işaretleri ( [ALPHA]->[+]) içine aldıktan sonra bir iki noktadan sonra programın adını içine alarak çalıştırın . Örneğin, programa "SNAKE" adını verirseniz, OP'de test senaryosunu çalıştırırsınız "SRSLSSLRLRSSRSRSS":prgmSNAKE.

seq(inString("SRL",sub("0"+Ans,I,1)),I,1,length(Ans
Disp 0<sum(⁻1+2seq(Ans(I)≠(Ans(I-1),I,2,dim(Ans

Düzenleme: Başarısız SRRLSLLRRRS. 61 baytta gözden geçirilmiş bir sürümüm var, ancak ilk geçersiz test durumunda başarısız oldu:

seq(inString("SRL",sub("0"+Ans,I,1)),I,1,length(Ans
cumSum(⁻1+2seq(Ans(I)≠(Ans(I-1),I,2,dim(Ans
Disp 0<Ans(dim(Ans

Yarın düzeltmeye çalışacağım.


Güncelleme: bu yüzden sorun aslında algoritmamın hatalı olmasıdır. Eğer bir For kullanmış olsaydım (sekansın tersine döngü ((aynı şeyi başarmak için)), (yukarıdaki her iki algoritma da aslında) şöyle tanımlanabilirdi:

  1. Sayaç değişkenini 1 olarak sıfırlayın.
  2. Diziyi oku. Simge değişirse, sayaç değişkenini arttırın. Sembol tekrarlanırsa, azaltın.
  3. Sayaç değişkeni 0'dan büyükse, ekran 1 (geçerli). Aksi takdirde, ekran 0 (geçersiz).

Ancak, bu gibi geçersiz slithers başarısız olur SRLRLRLRLRRRSS. Şimdi daha iyi bir algoritma bulmaya çalışacağım ... veya başka bir cevaptan çalacağım.


Bunun% 90'ının tek bir seq(komutla değiştirilebileceğinden eminim , aslında, ama şimdilik bu alabildiğim kadar küçük. Bunu, Sourcecoder kullanarak gerçekten yazmak yerine 8xp'ye çevirmeyi düşünüyorsanız , bunun değiştirilmesi !=ve ⁻1+bitin değiştirilmesi gerektiğini unutmayın ~1+.


1

Ruby 87 89

F=->s{d=[1,w=1e4,-1,-w]
v=[w]+s.chars.map{|c|w+=d.rotate!(c<?R?-1:c>?R?0:1)[0]}
v==v&v}

Çevrimiçi test: http://ideone.com/pepeW2

Ungolfed versiyonu:

F = -> input {
  # Coordinates are expressed using one number,
  # that is computed using the formula `y + x*max_x`.
  # Assume max horizontal field width (max_x) to be 10000,
  # since that's the max length of the input.
  position = max_x = 1e4

  # These are possible directions to move to (coordinate deltas).
  # The current direction is always the first in the array.
  directions = [1,max_x,-1,-max_x]

  visited = [position]

  visited += input.chars.map{|c|
    # adjust current direction...
    directions.rotate! case c
    when ?L
      -1
    when ?R
      1
    when ?S
      0
    end

    # ...and move there
    position += directions[0]
  }

  # Return `true` if `visited` only contains distinct elements, `false` otherwise
  visited == visited & visited
}

0

Golf komut dosyası 48 49 50

[10.4?:z-10z~)]z*z@{'R L S'?@>(@+.`n}%n/@;\;..&=

Dize yığında var olmasını bekler ve ya döndürür ya 0da1 .

Geçerli ve geçersiz testler ile çevrimiçi deneyebilirsiniz yılanlar .

Bu temelde Ruby cevabımdakiyle aynı fikir. . AFAIK Golfscript'in arary döndürme işlevi olmadığı için yalnızca yön dizisi farklı şekilde ele alınmıştır. Bu durumda, geçerli komuta (S, R veya L) bağlı olarak, 10000 kez çarparak ve ardından 0, 1 veya 3 elementin başlangıç ​​kısmından kırparak yeterince büyük bir yön dizisi yapıyorum. Taşınacak geçerli "yön" her zaman dizideki ilk öğedir.

İşte yorumlarla:

# Build the direction array and set current position
[1 10000:z-1z~)]z*z

@{
  # For each character in the input:

  # set current direction by cutting 0, 1 or 3 elements 
  # from the beginning of the directions array
  'SR L'?
  @>

  # move to current direction
  .0=@+.

  # format as number and addd newline
  `n
}%

# split by newlines
n/

# cleanup
@;\;

# return 1 if array contains distinct elements, 0 otherwise
..&=

Düzenle:

"Yön" dizisinin tüketilme şeklini değiştirerek 1 karakter kaydedildi.

Düzenle:

?(güç) sözdizimini kullanmak için 1 yerine 10'luk artışlarla hareket ettirilerek 1 karakter kurtarıldı .

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.