สร้างการเอียง Fibonacci ที่ถูกต้อง


9

พื้นหลัง

การเรียงลำดับ Fibonacci เป็นการเรียงต่อกันของบรรทัด (1D) โดยใช้สองส่วน: อันสั้น, S , และอีกอันยาว, L (อัตราส่วนความยาวของพวกเขาคืออัตราส่วนทองคำ แต่ไม่เกี่ยวข้องกับความท้าทายนี้) สำหรับการปูกระเบื้องโดยใช้ prototiles ทั้งสองนี้จริง ๆ แล้วจะเป็นการเรียงแบบ Fibonacci, เงื่อนไขต่อไปนี้จะต้องปฏิบัติตาม:

  • มุงหลังคาไม่ต้องมี subsequence เอสเอส
  • มุงหลังคาไม่ต้องมี subsequence LLL
  • หากการเรียงต่อกันใหม่ถูกสร้างขึ้นโดยดำเนินการการทดแทนต่อไปนี้ทั้งหมดผลลัพธ์จะต้องยังคงเป็นการเรียงแบบ Fibonacci:
    1. LLS
    2. SL
    3. L(สตริงว่าง)

ลองดูตัวอย่าง:

SLLSLLSLLSLS

ดูเหมือนว่าการเรียงไฟล์ที่ถูกต้องเพราะมันไม่มี * S * s หรือสาม * L * s สองอัน แต่ให้ทำการจัดองค์ประกอบ:

LSLSLSLL

นั่นยังคงดูดี แต่ถ้าเราเขียนมันอีกครั้งเราจะได้

LLLS

ซึ่งไม่ใช่การเรียง Fibonacci ที่ถูกต้อง ดังนั้นทั้งสองลำดับก่อนหน้าจึงไม่ถูกต้อง

ในทางกลับกันถ้าเราเริ่มต้นด้วย

LSLLSLSLLSLSLL

และเขียนสิ่งนี้ซ้ำ ๆ เพื่อลำดับที่สั้นกว่า

LSLLSLLS
LSLSL
LL
S

ผลลัพธ์ทั้งหมดเป็นฟีโบนัชชีที่ถูกต้องเนื่องจากเราไม่เคยได้รับSSหรือLLLที่ใดก็ตามภายในสตริงเหล่านั้น

สำหรับการอ่านเพิ่มเติมมีวิทยานิพนธ์ที่ใช้ปูกระเบื้องนี้เป็นแบบ 1D เปรียบเทียบกับการเอียงเพนโรส

ความท้าทาย

เขียนโปรแกรมหรือฟังก์ชั่นซึ่งกำหนดให้เป็นจำนวนเต็มไม่เป็นลบNส่งคืนการเรียงลำดับ Fibonacci ที่ถูกต้องทั้งหมดในรูปแบบของสตริงที่มีอักขระNตัว (เป็นSหรือL)

คุณสามารถรับอินพุตผ่านฟังก์ชันอาร์กิวเมนต์, STDIN หรือ ARGV และส่งคืนหรือพิมพ์ผลลัพธ์

นี่คือรหัสกอล์ฟคำตอบที่สั้นที่สุด (เป็นไบต์) ชนะ

ตัวอย่าง

N      Output
0      (an empty string)
1      S, L
2      SL, LS, LL
3      LSL, SLS, LLS, SLL
4      SLSL, SLLS, LSLS, LSLL, LLSL
5      LLSLL, LLSLS, LSLLS, LSLSL, SLLSL, SLSLL
...
8      LLSLLSLS, LLSLSLLS, LSLLSLLS, LSLLSLSL, LSLSLLSL, SLLSLLSL, SLLSLSLL, SLSLLSLL, SLSLLSLS

ควรเป็นLSLSL-> LLหรือไม่

@tolos อาใช่จับได้ดี ฉันแก้ไขมันแล้ว FYI นี้เกิดขึ้นเพราะที่จริงผมสร้างสตริงรอบวิธีอื่น ๆ ที่เริ่มต้นจากด้านล่างโดยใช้กฎการสลายตัวที่คล้ายกันและเหล่านี้จะไม่ตรงกลับได้เมื่อมันมาถึงขอบเขตของส่วนที่
Martin Ender

คำตอบ:


4

CJam, 70 62 59 ไบต์

Qali{_'L:Xf+\'S:Yf++}*{{_X2*/Xf-Yf/Xf*Y*}h]N*_X3*#\Y2*#=},p

อ่านจาก STDIN ลองออนไลน์

ตัวอย่างการวิ่ง

$ cjam tilings.cjam <<< 5
["LLSLL" "SLSLL" "SLLSL" "LSLSL" "LSLLS" "LLSLS"]

มันทำงานอย่างไร

ความคิดคือการผลักสตริงทั้งหมดของ L และ S ของความยาวที่เหมาะสมนำการแปลงมาใช้อย่างต่อเนื่องจนกว่าผลลัพธ์จะเป็นสตริงว่างเชื่อมต่อลำดับของสตริงและค้นหาสตริงย่อยที่ต้องห้าม

Qa         " Push R := [ '' ].                                                            ";
li{        " Do the following int(input()) times:                                         ";
  _'L:Xf+  " Append (X := 'L') to a copy of all strings in R.                             ";
  \'S:Yf+  " Append (Y := 'S') to all original strings in R.                              ";
  +        " Concatenate the arrays into R.                                               ";
}*         " R now contains all strings of L's and S's of length int(input()).            ";
{          " For each S ∊ R:                                                              ";
  {        "                                                                              ";
    _      " Push a copy of S.                                                            ";
    X2*/   " Split S at 'LL'.                                                             ";
    Xf-    " Remove 'L' from the chunks.                                                  ";
    Yf/    " Split the chunks at 'S'.                                                     ";
    Xf*    " Join the chunks, separating by 'L'.                                          ";
    Y*     " Join, separating by 'S'.                                                     ";
  }h       " If the resulting string is non-empty, repeat.                                ";
  ]N*      " Join the array of resulting strings from S to '', separating by linefeeds.   ";
  _X3*#    " Push the index of 'LLL' a copy in the resulting string (-1 if not present).  ";
  \Y2*#    " Push the index of 'SS' in the original string (-1 if not present).           ";
  =        " Check if the indexes are equal; this happens if and only if both are -1.     ";
},         " Filter: Keep S in R if and only if = pushed 1.                               ";
p          " Print a string representation of R.                                          ";

3

GolfScript (86 ไบต์)

~:|'LS'1/\{{.{1&!'LLS'2/=}%'SS'/'SLS'*[.(1&{'LS'\+}*]{.)1&{'SL'+}*}/}%.&}*['']+{,|=},p

นี่คือวิธีการที่เงินเฟ้อ: มันเริ่มต้นด้วยLและSและขยายได้โดยใช้กฎLL -> SLS, L -> S, S -> LLและนำหน้าหรือต่อท้ายSจะมีLการเพิ่มขอบเขตคำว่า

การสาธิตออนไลน์


@ MartinBüttnerปกติแล้วฉันจะเชื่อมโยงไปยังการสาธิตออนไลน์ด้วย golfscript.apphb.com แต่มันใช้งานเวอร์ชั่นเก่าที่มีข้อผิดพลาดเกี่ยวกับลูปซ้อน (แก้ไขในรุ่น3 ธันวาคม 2012 ) และไม่สามารถเรียกใช้โปรแกรมนี้ได้อย่างถูกต้อง
Peter Taylor

3
@ MartinBüttnerโอ๊ะโอ ขอบคุณมากที่บอกให้ฉันรู้เรื่องบั๊ก ฉันอัปเดตเว็บไซต์ด้วยเวอร์ชัน GS ใหม่ คลิกที่ลิงค์นี้เพื่อสาธิต
Cristian Lupascu

@ w0lf ขอบคุณสำหรับการอัปเดต (และสำหรับการเปลี่ยนแปลงล่าสุดเพื่อเพิ่มการ จำกัด เวลาด้วย)
Peter Taylor

1

Haskell, 217

import Control.Monad
data F=L|S deriving (Eq)
f n=filter s$replicateM n [L,S]
r (L:L:m)=S:r m
r (S:m)=L:r m
r (L:m)=r m
r []=[]
s []=True
s m|v m=s$r m
s _=False
v (L:L:L:_)=False
v (S:S:_)=False
v (_:m)=v m
v []=True

ชี้แจง:

ฉันนิยามฟังก์ชั่น 4 อย่าง:

  • f ใช้จำนวนเต็มและส่งคืนผลลัพธ์

    replicateM n [L,S]สร้างการเรียงสับเปลี่ยนที่เป็นไปได้ทั้งหมด[L,S]ด้วยความยาวn filter s ...จะกรองรายการนี้ (จากรายการ) ด้วยฟังก์ชันs

  • r ลดรายชื่อที่กำหนดลง 1 ระดับ

    สิ่งนี้ทำได้โดยการจับคู่รูปแบบ รายการที่ขึ้นต้นด้วย 2 Lจะกลายเป็นรายการที่ขึ้นต้นด้วยSและส่วนที่เหลือจะลดลง

  • v ตรวจสอบรายการที่กำหนดโดยกฎที่กำหนด (ไม่ต่อเนื่อง 3 L, ไม่ต่อเนื่อง 2 S)

    หากรายการเริ่มต้นด้วยหนึ่งใน 2 ลำดับที่ผิดกฎหมาย (L, L, L หรือ S, S) ผลลัพธ์คือFalseรายการที่ว่างถูกต้องและรายการที่ไม่ว่างจะถูกตรวจสอบอีกครั้งโดยลบองค์ประกอบแรกออก

  • s ตรวจสอบว่ารายการและรายการที่ถูกลดทั้งหมดนั้นถูกต้องหรือไม่

    อีกครั้ง: รายการว่างถูกต้อง (และไม่สามารถลดได้อีก)
    หากรายการที่กำหนดเป็นอาร์กิวเมนต์นั้นถูกต้องรายการนั้นจะถูกลดการตรวจสอบโฆษณาsอีกครั้ง
    มิฉะนั้นผลที่ได้คือFalse

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