จำลองระบบ Cyclic Tag


14

ระบบแท็กวงกลมเป็นขนาดเล็กรูปแบบการคำนวณทัวริงสมบูรณ์ประกอบด้วยตัวอักษรสองสัญลักษณ์ (ฉันจะใช้{0,1}) ซึ่งเป็นที่แน่นอนรายการวงจรว่างของโปรดักชั่นที่ประกอบด้วยทั้งสองสัญลักษณ์และมากมายคำซึ่งประกอบด้วย สัญลักษณ์ทั้งสองนั้น

ในแต่ละขั้นตอน:

  • องค์ประกอบแรกในคำจะถูกลบออก
  • ถ้าเป็น0ปัจจุบันการผลิตถูกข้ามไป
  • ถ้ามันเป็น1ปัจจุบันการผลิตถูกผนวกเข้ากับท้ายของคำ
  • การผลิตต่อไปจะเปิดใช้งาน หากนี่เป็นการผลิตครั้งสุดท้ายให้กลับไปผลิตรายการแรก

ระบบหยุดทำงานเมื่อคำว่างเปล่า

ตัวอย่าง (จาก Wikipedia):

Productions: (010, 000, 1111)
Initial word: 11001

Generation  Production   Word (before)            Word (after)
   0           010           11001             →     1001010       
   1           000            1001010          →      001010000
   2           1111            001010000       →       01010000
   3           010              01010000       →        1010000
   4           000               1010000       →         010000000
   5           1111               010000000    →          10000000
   6           010                 10000000    →           0000000010
   7           000                  0000000010 →            000000010
   8           1111                  000000010 →             00000010
   9           010                    00000010 →              0000010

งานของคุณถ้าคุณเลือกที่จะยอมรับมันคือการเขียนโปรแกรมหรือฟังก์ชั่นที่ใช้:

  • รายการโปรดักชั่น
  • คำเริ่มต้นและ
  • รุ่น

และพิมพ์หรือส่งคืนคำที่รุ่นนั้น

ตัวอย่างเช่น,

cyclic_tag(
      prod=[[0,1,0],[0,0,0],[1,1,1,1]], 
      word=[1,1,0,0,1], 
      gen=4) => [1,0,1,0,0,0,0]

รายละเอียดการใช้งาน:

  • ตัวอักษรไม่สำคัญ คุณอาจจะใช้0และ1, TrueและFalse, TและNIL, AและB, หรือแม้กระทั่งการ1และ0หรือสิ่งอื่นที่คุณอาจเกิดขึ้นกับตราบใดที่คุณมีความสอดคล้องกัน อินพุตและเอาต์พุตทุกคนจะต้องใช้ตัวอักษรเดียวกันและคุณจะต้องแสดงให้เห็นว่าสิ่งที่คุณกำลังใช้สำหรับและสิ่งที่สำหรับ01

  • ความยาวของคำต้องไม่ จำกัด ขอบเขตในทางทฤษฎี นั่นคือคุณไม่สามารถฮาร์โค้ดยาวสูงสุดได้ ถ้าฉันรันโปรแกรมของคุณบนคอมพิวเตอร์ในอุดมคติที่มีหน่วยความจำไม่ จำกัด จำนวนโปรแกรมของคุณจะต้องสามารถใช้งานได้ในทางทฤษฎี (คุณอาจเพิกเฉยต่อข้อ จำกัด ของล่าม / ผู้แปล)

  • หากระบบที่กำหนดหยุดการทำงานก่อนถึงรุ่นที่กำหนดคุณต้องส่งคืนหรือพิมพ์คำว่างเปล่า

  • มีการผลิตเปล่าและคุณต้องสามารถจัดการได้ หากคุณเขียนโปรแกรมแบบเต็ม I / O ของคุณจะต้องสามารถจัดการได้

แก้ไข : เดิมทีฉันตั้งใจจะให้กำเนิด0เพื่อเป็นคำอินพุตและการสร้าง1เป็นผลลัพธ์ของขั้นตอนแรก คือฉันตั้งใจให้คุณคืนคอลัมน์ก่อนหน้า แต่ที่ผมยังไม่ได้รับเพียงพอที่ชัดเจนในการระบุนี้ฉันจะยอมรับทั้งสองตัวเลือก ; สำหรับแต่ละรุ่นคุณสามารถส่งคืนค่าในคอลัมน์ก่อนหรือหลัง คุณต้องระบุว่าคุณกำลังติดตามคอลัมน์หลังหากคุณทำเช่นนั้น คุณต้องสอดคล้องในคอลัมน์ที่คุณเลือกด้วย

ฉันจะให้รางวัลรหัสที่เล็กที่สุดต่อสัปดาห์นับจากนี้ (10/27/2014)


อืมคุณแน่ใจหรือว่าผลลัพธ์ในตัวอย่างนั้นถูกต้อง? ขึ้นอยู่กับตัวอย่างอื่น ๆ ของคุณให้ผมคิดว่าเป็น Gen 5 ...
FryAmTheEggman

เราสามารถรับอินพุตในลำดับที่แตกต่างกันได้หรือไม่?
Martin Ender

1
@FryAmTheEggman: ถูกต้องฉันหมายถึงคอลัมน์ 'ก่อนหน้า' หากมีคนทำผิดพลาดขึ้นฉันจะเปลี่ยนคำถามเพื่อยอมรับ ฉันยอมรับว่าฉันไม่ชัดเจน
marinus

@ MartinBüttner: ตราบใดที่คุณระบุคำสั่งซื้อมันไม่สำคัญ
marinus

คำตอบ:


4

GolfScript (17 ถึง 19 ไบต์ขึ้นอยู่กับรูปแบบอินพุตและรูปแบบเอาต์พุตที่ยอมรับ)

18 ไบต์:

~.@*<{\1,or(@*+}/`

จะเข้าในรูปแบบและให้การส่งออกในรูปแบบ[1 1 0 0 1] [[0 1 0] [0 0 0] [1 1 1 1]] 4 [1 0 1 0 0 0 0](อาจจะเป็น17 ไบต์โดยไม่ต้องสุดท้าย`ถ้าออกเป็น1010000เป็นที่ยอมรับ)

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

19 ไบต์:

~.@*<{\0`or(1&@*+}/

"11001" ["010" "000" "1111"] 4จะเข้าในรูปแบบ

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

การผ่า

~        # Evaluate input: stack: word productions gen
.@*<     # Produce a list of the right number of productions with suitable repetition
{        # For each of those productions:
  \      #   Bring the word to the top
  0`or   #   Ensure that we don't get an error if the word is empty
  (1&    #   Pop the first char from the word and evaluate it
  @*     #   Repeat the production that many times
  +      #   Concatenate 0 or 1 copies of the production to the rest of the word
}/       # Endforeach

มอบเครดิตให้แก่โซลูชัน CJamของMartin Büttnerสำหรับแนวคิดในการสร้างรายการผลิตโดยการทำซ้ำและตัดทอน


คุณเชื่อมโยงกับโซลูชัน CJam ที่คุณอ้างถึงดังนั้นฉันจึงเลือกคำตอบนั้น หากคุณโกนไบต์อีกปิดผมจะพิจารณา :)
marinus

@marinus คุณยอมรับรุ่น 17 ไบต์ที่ฉันอ้างถึงในข้อความคำตอบของฉันหรือไม่
Peter Taylor

ไม่เห็นว่ามัน แต่มันดูถูกต้อง คุณควรทำเครื่องหมายให้ชัดเจนยิ่งขึ้น
marinus

5

Haskell, 55 53 51

(t:w)%p|t=w++p|0<1=w
x%_=x
e w=(!!).scanl(%)w.cycle

การใช้งานนี้Trueเป็น1และเป็นFalse 0ตัวอย่างการเรียกใช้:

*Main> let t=True ; f=False
*Main> e [t,f,t] [[f,f,f],[t,t,t]] 4
[False,False,False,False,False]

3

CJam, 31 30 28 27 24 18 ไบต์

{_@*<{\_0a?(@*+}/}

สิ่งนี้กำหนดบล็อก (สิ่งที่ใกล้เคียงที่สุดกับ functioN) ซึ่งคาดว่าอินพุตจะอยู่ในสแต็กเช่นนี้

[1 1 0 0 1] [[0 1 0] [0 0 0] [1 1 1 1]] 9

มันจะปล่อยอาร์เรย์ของ0s และ1s ไว้ในสแต็กเหมือนกัน

ทดสอบที่นี่ วางอินพุตหนึ่งบรรทัดแรกโค้ดในบรรทัดที่สามและผนวก a ~เพื่อประเมินบล็อกจริง เช่น

[1 1 0 0 1] [[0 1 0] [0 0 0] [1 1 1 1]] 9
{_@*<{\_0a?(@*+}/}~

หากเอาต์พุตไม่จำเป็นต้องมีรูปแบบเดียวกับอินพุต

คำอธิบาย:

_@*<{\_0a?(@*+}/
_@               "Duplicate the generation and pull the productions to the top.";
  *<             "Repeat the productions N times and take the first N elements.";
    {         }/ "For each element in that list, run this block.";
     \           "Swap production and current word W.";
      _0a?       "W = (W != []) ? W : [0]. This is to ensure we can unshift an element.";
          (      "Unshift the first 0 or 1 from the word.";
           @     "Rotate the stack, pulling the production to the top.";
            *    "Repeat it 0 or 1 times.";
             +   "Append to the word.";

สถานะสุดท้ายของคำจะถูกทิ้งไว้บนสแต็ก

ขอบคุณ Peter Taylor ที่ทำให้ฉันทบทวนสิ่งนี้


1
l~{_,g{('1=@(:Pa+@@P*+}*}*\;28 และยังคงขอบเขตสำหรับการปรับปรุง (โดยเฉพาะ(:Pส่วน) แต่เวลาสำหรับอาหารกลางวัน
เครื่องมือเพิ่มประสิทธิภาพ

@Optimizer Ah ความคิดที่ดี ขอขอบคุณ. และใช่:Pก็เป็นที่น่ารำคาญฉัน: D
Martin Ender

l~{_,g{(si@(:Pa+@@P*+}*}*\;: 27 และหลังจากดูแล้วมัน:Pมีประสิทธิภาพจริง ๆ : P
เครื่องมือเพิ่มประสิทธิภาพ

_,gยังสามารถถูกแทนที่ด้วย_!!แต่ไบต์เดียวกัน
เครื่องมือเพิ่มประสิทธิภาพ

@Optimizer ฉันเช่นกันอาจจะใช้_{...}{}?แล้ว
Martin Ender

2

Mathematica, 84 80 77 ตัวอักษร

f[_,w_,_]=w;f[p_,{x_,y___},n_/;n>0]:=f[RotateLeft@p,Flatten@{y,p~Take~x},n-1]

ตัวอย่าง:

f[{{0, 1, 0}, {0, 0, 0}, {1, 1, 1, 1}}, {1, 1, 0, 0, 1}, 4]

{1, 0, 1, 0, 0, 0, 0}


2

Pyth 22

ต้องการอาร์กิวเมนต์ทั้งหมด 3 รายการเป็นอินพุตแยกกัน

#Vvw=z+tz*@Q%NlQshz)zq

รับอาร์กิวเมนต์เช่น:

11001
["010","000","1111"]
4

คำอธิบาย:

                        : Implicit: z = input(); Q=eval(input())
#                       : Loop until an exception is thrown
 Vvw               )    : for N in range(eval(input()))
    =z                  : assign to z
      +tz               : the sum of the tail of z and
         *@Q%NlQ        : Q[N%len(Q)] times
                shz     : the numeric value of the first character in z
                    zq  : print z then throw exception

Python 2 - 61 67 91 105 124

c=lambda p,w,g:g*w and c(p[1:]+p[:1],w[1:]+w[0]*p[0],g-1)or w

พริตตี้โจคำตอบพื้นฐาน สมมติว่าการผลิตที่ว่างเปล่าคือ[[]]ถือว่าการผลิตที่ว่างเปล่า

ขอบคุณ @xnor สำหรับการชี้ให้เห็นว่าการตีกอล์ฟตอนตีสองเป็นการตัดสินใจที่ไม่ดี

ขอขอบคุณเพิ่มเติม @xnor ซึ่งฉันคิดว่าเป็นหนี้ 50% ของคะแนนของฉัน

ตัวอย่าง:

>>> c([[0,1,0],[0,0,0],[1,1,1,1]],[1,1,0,0,1],4)
[1, 0, 1, 0, 0, 0, 0]

1
แน่นอนว่าการใช้แลมบ์ดานั้นสั้นกว่าและเขียนเพียงg and wเพื่อx? นอกจากนี้ฉันคิดว่าg*wควรทำงานเพื่อให้คุณค่าความจริงเมื่อทั้งคู่gไม่ใช่ศูนย์และwไม่ว่างเปล่า
xnor

ฉันไม่เข้าใจด้านในif x else wด้วย จะไม่xเป็นจริงเสมอไปเพราะรหัสนี้ทำงานเพียงอย่างเดียวif xหรือฉันขาดอะไรไปหรือเปล่า
xnor

@xnor แน่นอนคุณมีความถูกต้องทั้งหมด :)
FryAmTheEggman

1
บางคนเล่นกอล์ฟมากขึ้นด้วยand/ orเคล็ดลับและหมุนpแทนการเพิ่มn:c=lambda p,w,g:g*w and c(p[1:]+p[:1],w[1:]+w[0]*p[0],g-1)or w
XNOR

@xnor ขอบคุณ :) ตอนนี้เมื่อคุณทำให้มันเป็นฟังก์ชั่นของตัวแปร 3 ตัวฉันคิดว่าฉันแปลมันเป็น
Pyth

1

Javascript ES6 - 88 ไบต์

f=(p,w,g,n)=>g?w.replace(/(.)(.*)/,(_,a,b)=>f(p,a*1?b+p[(n=n||0)%p.length]:b,g-1,n+1)):w

ดูคล้ายคำตอบของ Fry ที่ผุดขึ้นมาในเบราว์เซอร์ของฉัน (ไม่มีการคัดลอกฉันสาบานอย่างเคร่งขรึม)

มันจะปรากฏว่าเขาไปตามเส้นทางอาเรย์ในขณะที่ฉันไปเส้นทางสตริง / regex อย่างไรก็ตาม

ขยาย:

f = (p,w,g,n) =>
    g ?
        w.replace( /(.)(.*)/, (_,a,b) =>
            f( p, a*1 ? b + p[(n=n||0)%p.length] : b, g-1, n+1 )
        )
    :
        w

ตัวอย่างผลลัพธ์

f(['010','000','1111'],'11001',4)
"1010000"

ตอนนี้ดูภาษากอล์ฟเข้ามาและสังหารหมู่พวกเราทั้งคู่ : D


ฉันลบโพสต์ของฉันเพราะฉันได้รับคำตอบที่แตกต่างกันสำหรับสองตัวอย่าง คุณลองตัวอย่างที่เขาไปรุ่นต่อรุ่น? ดูเหมือนว่าจะถูกปิดโดยหนึ่งเมื่อเทียบกับตัวอย่างการโทรแบบเต็มเขา ...
FryAmTheEggman

และไม่ต้องกังวลฉันเชื่อว่าคุณไม่ได้คัดลอกฉัน: P
FryAmTheEggman

@FryAmTheEggman: Mine สร้างคอลัมน์ "before" อย่างต่อเนื่องสำหรับการสร้างหมายเลข นี่สอดคล้องกับตัวอย่างใน OP และดูเหมือนว่า "รุ่น 0" จะส่งคืนอินพุตโดยไม่ต้องประมวลผลซึ่งสอดคล้องกับการตีความนี้ บังเอิญฉันเพิ่ม "คัดลอก" ข้อจำกัดความรับผิดชอบเพราะวิธีการแก้ปัญหาที่คล้ายกันอย่างแปลกประหลาดในบางประเด็น เราใช้ชื่ออาร์กิวเมนต์เดียวกัน, โครงสร้างการเรียกซ้ำพื้นฐานเดียวกันและเรายังเพิ่มอาร์กิวเมนต์ที่สี่ของ phantom เหมือนกัน, n. จิตใจยอดเยี่ยมใช่มั้ย : D
COTO

โอเคฉันเดาว่าถ้าเราคนใดคนหนึ่งผิดเราทั้งคู่ต่างก็ผิด! สหเรายืน
FryAmTheEggman

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