งูที่ถูกต้องบนเครื่องบิน


23

แรงบันดาลใจจากหนึ่งในวิดีโอของ Vi Hart (ซึ่งเป็นขุมสมบัติที่เต็มไปด้วยความคิดที่ท้าทาย)

งูประกอบด้วยส่วนที่มีความยาวเท่ากันและการเชื่อมต่อระหว่างแต่ละส่วนนั้นอาจจะตรงหรือเลี้ยว 90 °
เราสามารถเข้ารหัสเช่นงู (ได้ถึงการหมุนซึ่งขึ้นอยู่กับทิศทางเริ่มต้น) โดยการเขียนลงเลื้อยทิศทางของการผลัด (ตรง / ซ้าย / ขวา) ที่ใช้ใน อันนี้เริ่มจากซ้ายบนและชี้ไปทางขวา

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

จะถูกแสดงโดย slither SRSLSSLRLRSSRSRSS

และแน่นอนว่างูระนาบไม่สามารถตัดกัน (เหมือนในSSSSLLLSS) ซึ่งจะส่งผลให้เกมโอเวอร์พิกเซล

งานของคุณคือการตรวจสอบว่า slither ถูกต้องหรือไม่ (ผลในการแยกตนเองอย่างน้อยหนึ่งครั้ง)

อินพุต
สตริงที่ทำจากตัวอักษรSLRด้วย2 < length < 10000
Output
Something Truthy ถ้ามันเป็น slither ที่ถูกต้องและเป็น Falsey ถ้าไม่ใช่

กรณีทดสอบ

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

__Invalid__
SRRLSLLRRLLSLRRSRLLRSRRLLRRSRLLLLRSRRLLRRSRLLRSRRLSLLRRLLSLRR
SRRLSLLRRLLSLRRSRLLRSRRLLSRSSSRSSSSSSSRSRSSSSSSSRRLLRRSRLLRSRRLSLLRRLLSLRR
SRRSRSRSSRSSRSSSRSSSRSSSSSSSSSSRSSSSRSSSSSRSSSSSRSSSSSSRSSSSSSRSSSSSS
SSSSSSSSSSLSSSSSSSLSSSSSSSSLSSSSSLSSSSSSLSSSLLRRLRLRRLLSLSSSRRSSSSRSSSRSSSSSSRSSSSSRSSSSSSSSRSSSSSSSRSSSSSSSSS
LRSLLRLSRSLLSRLSLRSLSSSLRRSSLSRRLRSRLRLSLRLLRLRSSLSLRLRSRSSSSSLSRRLSLSSSRRLRLRLRLRRLLSSLSSSRRLRLRLRLRLSLSSSSSSSSSSSSSRLRLLRLRLRLRLRLRLRLSLSSSLSLSLLSLRLSLRSLRSLRSLSLSLRSRLSLRSLRLSRSLLLRLRLRRRRSLSLSSLLSLSLSLSSLLSLSLLRLRSLLRSRLSLSSLLLLSSSSSSSSSSSSSSSSSSSSRLRLLRRLRLRLLRLRLRLRLRLSSSSLSLRLLRLSLSSLSLSLSLSLRLLRLSLLLSRSSSSSSSSSSSSSSSRLRLRLLRLRLSLSRSRSSSLSRLRLRLRSLSLSLSRLLSRLSLSLSLSLSSLSLSLLSLSRLLRLRLRLRLRLRLRLRLRLRLSLSRLRLSLLRRLSLLSLSLSLSLSLLSLSLSLRLRLRLRLRLRLRLRLRLRRLRSLSLSLSLSLSLSLSSLSSSSSLSLSSSLSLSLSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS

คุณสามารถวาด slithers ที่นี่ (R และ L พลิก แต่ไม่มีผลต่อความถูกต้อง)


ต้องป้อนข้อมูลในโปรแกรมหรืออ่านจากไฟล์ได้หรือไม่?
MI Wright

1
SRRR ควรเป็นจริงหรือเท็จ? มันเชื่อมต่อ แต่ไม่ตัดกัน
orlp

สัมผัสงูท้าทาย NSFW?
Ewan

3
หากคุณวาดSRRRบนกระดาษกราฟที่มีหนึ่งตารางต่อเซ็กเมนต์แล้วมันจะทับซ้อนกันและดังนั้นจึงไม่ถูกต้องRRRอย่างไรก็ตามจะใช้พื้นที่ 2x2 ตารางโดยไม่ทับซ้อนกัน (เหมือนในเกมคลาสสิค)
DenDenDo

คล้ายกัน แต่ไม่ซ้ำกัน (เนื่องจากวัตถุประสงค์และกฎการก่อสร้างที่แตกต่างกัน)
trichoplax

คำตอบ:


20

Pyth, 22 20 ไบต์

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

ลองตัวเองหรือเรียกใช้TestSuite

สังเกตค่า ASCII ของ SRL ตามลำดับ 83, 76, 82 ฉันใช้ความจริงที่ว่า:

ฉัน83 + 1 = 1
ฉัน76 + 1 = ฉัน
ฉัน82 + 1 = -i

จากที่นี่ฉันแค่เก็บตัวแปรสำหรับตำแหน่งปัจจุบันและทิศทางปัจจุบัน สำหรับตัวละครทุกตัวที่ฉันคูณทิศทางปัจจุบันด้วยจำนวนเชิงซ้อนข้างต้นแล้วเพิ่มไปยังตำแหน่งปัจจุบัน

ในตอนท้ายฉันจะตรวจสอบว่าตำแหน่งที่เข้าชมทั้งหมดไม่ซ้ำกันหรือไม่


SRRR = จริง ????
Ewan

@Ewan เมื่อตรวจสอบอย่างใกล้ชิด - ฉันไม่แน่ใจว่าควรจะเป็นเท็จหรือไม่ หัวและหางเชื่อมต่อ แต่อย่าตัดกัน
orlp

แล้ว SRRRS ล่ะ?
Ewan

@Ewan เรื่องเดียวกัน - การเชื่อมต่อ แต่ไม่มีทางแยก คำถามไม่ชัดเจนว่าควรส่งคืนสิ่งใดสำหรับสิ่งเหล่านี้
orlp

1
คุณจะวาด SRRR อย่างไร
Ewan

6

CJam, 30 ไบต์

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

คำอธิบายที่จะตามมาในไม่ช้า

ลองมันออนไลน์ได้ที่นี่หรือเรียกใช้ชุดทั้ง


ประณามอย่างรวดเร็ว ฉันยังไม่ได้คิดถึงอัลกอริทึมที่จะแก้ปัญหาด้วยตัวเอง
DenDenDo

SRRRS = จริง ???
Ewan

@Ewan อืมม, พวกเราสมมติว่า 0 เต็มไปแล้วและนับ?
เครื่องมือเพิ่มประสิทธิภาพ

1
ฉันคิดว่าฉันตีความมันเหมือนเกมงูที่การเคลื่อนไหวนั้นกินพื้นที่ของบล็อก และพวกคุณบางคนตีความว่ามันเป็นเส้นที่มีความกว้างเป็นศูนย์
Ewan

@Ewan คำถามของฉันแตกต่างกันเล็กน้อย เมื่อเรามีการเคลื่อนไหวเพียงครั้งเดียวSหมายความว่างูได้ครอบครองทั้ง (0,0) และ (1,0) แล้วหรือยัง?
เครื่องมือเพิ่มประสิทธิภาพ

6

JavaScript (ES6), 84 89

เรียกใช้ส่วนย่อยใน Firefox เพื่อทดสอบ

หมายเหตุบางส่วน:

  • งูเคลื่อนที่ภายในอาเรย์ f เซลล์ unvisited undefinedมีค่า ในการเยี่ยมชมครั้งแรกผู้ประกอบการตัวหนอนเปลี่ยนเป็น -1 นั่นคือความจริง ในที่สุดการเข้าชมครั้งที่สองการเปลี่ยนแปลงค่าเป็น 0 ที่ผิดพลาดและการeveryวนซ้ำยุติการส่งคืนเท็จ
  • ใน JS องค์ประกอบของอาเรย์ที่มีดัชนีที่ไม่เป็นนิคอน (ไม่ใช่ตัวเลขหรือเชิงลบ) เป็น 'ซ่อน' แต่อย่างใด แต่ก็มีอยู่จริง ที่นี่ฉันใช้ดัชนีเชิงลบโดยไม่มีปัญหา

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 ไบต์

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 สิ่งนี้สร้างรายการของจุดทั้งหมดในระนาบเชิงซ้อนที่งูเข้าเยี่ยมชมโดยเริ่มต้นที่จุดกำเนิด หากรายการไม่มีองค์ประกอบที่ซ้ำกันรหัสจะคืนค่าที่เป็นบวก โปรดทราบว่าในสตริงที่มีองค์ประกอบมากกว่า 999 รายการเครื่องคิดเลขจะไม่สามารถสร้างรายการที่มีความยาวเพียงพอและจะเกิดข้อผิดพลาด

แก้ไข: บันทึกสองไบต์ด้วยค่าความอัปลักษณ์เนื่องจากไม่มีจุดขัดแตะสองจุดบนระนาบเชิงซ้อนสามารถห่างจาก e ^ i ได้เท่ากัน


5

TI-BASIC, 60 58 ไบต์

แก้ไข: ละเว้นทุกสิ่งด้านล่าง: โซลูชัน ti-basic ที่ใช้งานอยู่ที่นี่โดย thomas-kwa โหวตว่า!

เป็นสำคัญและตอบถูก[(-)] [2ND]->[(-)]เรียกใช้โดยใส่คำแนะนำของงูในเครื่องหมายคำพูด ( [ALPHA]->[+]) ตามด้วยเครื่องหมายโคลอนแล้วจึงใช้ชื่อโปรแกรม ตัวอย่างเช่นถ้าคุณชื่อโปรแกรม "งู" คุณต้องการใช้กรณีทดสอบใน OP "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

แก้ไข: SRRLSLLRRRSล้มเหลวใน ฉันมีรุ่นแก้ไขที่ 61 ไบต์ แต่มันล้มเหลวในกรณีทดสอบที่ไม่ถูกต้องครั้งแรก:

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

ฉันจะพยายามแก้ไขพรุ่งนี้


อัปเดต: ดังนั้นปัญหาเป็นจริงที่อัลกอริทึมของฉันมีข้อบกพร่อง ถ้าฉันใช้ For (วนรอบเมื่อเทียบกับ seq ((เพื่อให้ได้สิ่งเดียวกัน)) (อัลกอริทึมทั้งสองข้างต้นจริง ๆ ) สามารถอธิบายได้ดังนี้:

  1. เริ่มต้นตัวแปรตัวนับเป็น 1
  2. อ่านสตริง หากสัญลักษณ์เปลี่ยนให้เพิ่มตัวแปรตัวนับ หากสัญลักษณ์ซ้ำให้ลดระดับลง
  3. หากตัวแปรตัวนับมากกว่า 0 ให้แสดง 1 (ถูกต้อง) มิฉะนั้นแสดง 0 (ไม่ถูกต้อง)

แต่นี้ล้มเหลวใน slithers SRLRLRLRLRRRSSที่ไม่ถูกต้องเช่น ตอนนี้ฉันจะพยายามหาอัลกอริทึมที่ดีกว่า ... หรือขโมยจากคำตอบอื่น


ฉัน 90% แน่ใจว่าสิ่งนี้สามารถถูกแทนที่ด้วยseq(คำสั่งเดียวจริง ๆ แล้ว แต่ตอนนี้มีขนาดเล็กเท่าที่ฉันจะได้รับ หากคุณตั้งใจที่จะสร้างนี้ไปยัง 8XP ใช้Sourcecoderเมื่อเทียบกับการพิมพ์จริงมันออกทราบว่าควรจะถูกแทนที่ด้วย!=และบิตจะถูกแทนที่ด้วย⁻1+~1+


1

ทับทิม 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}

การทดสอบออนไลน์: http://ideone.com/pepeW2

เวอร์ชันที่ไม่ถูกปรับแต่ง:

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

Golfscript 48 49 50

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

คาดว่าสตริงจะมีชีวิตอยู่ในกองและผลตอบแทนอย่างใดอย่างหนึ่งหรือ01

คุณสามารถลองออนไลน์ที่มีการทดสอบที่ถูกต้องและไม่ถูกต้องงู

นี้นั้นเป็นความคิดเช่นเดียวกับในคำตอบของฉันทับทิม เพียงแค่อาเรย์ทิศทางจะได้รับการจัดการแตกต่างกันเนื่องจาก AFAIK Golfscript ไม่มีฟังก์ชั่นการหมุนแบบอาเรย์ ในกรณีนี้ฉันสร้างอาร์เรย์ทิศทางที่ใหญ่พอโดยคูณมัน 10,000 ครั้งแล้วตัดทอนจากองค์ประกอบเริ่มต้น 0, 1 หรือ 3 ขึ้นอยู่กับคำสั่งปัจจุบัน (S, R หรือ L) "ทิศทาง" ในปัจจุบันเพื่อเลื่อนไปยังรายการแรกเสมอในอาร์เรย์

นี่คือความคิดเห็น:

# 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
..&=

แก้ไข:

บันทึก 1 อักขระโดยการปรับเปลี่ยนวิธีการใช้อาร์เรย์ "เส้นทาง"

แก้ไข:

บันทึก 1 อักขระโดยเลื่อนการเพิ่มทีละ 10 แทน 1 เพื่อใช้ประโยชน์จาก?ไวยากรณ์ (กำลัง)

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.