คำแนะนำสำหรับการจัดเก็บในภาษากอล์ฟ


16

ฉันกำลังเขียนภาษากอล์ฟ

คุณแนะนำตัวแปรสแต็กเทปรีจิสเตอร์และอื่น ๆ สำหรับการจัดเก็บในภาษารหัส - กอล์ฟหรือไม่? สิ่งที่เกี่ยวกับการป้อนข้อมูลโดยนัย?

คำจำกัดความหยาบ:

  • ตัวแปรเป็นเพียงชื่อ (ปกติตัวละครตัวหนึ่งยาวในภาษากอล์ฟ) ที่มีค่าสามารถกำหนดให้และต่อมาเรียกโดยชื่อนั้น
  • การลงทะเบียนเป็นเหมือนตัวแปร แต่มีคำสั่งของตัวเอง (โดยปกติคือไบต์เดียว) สำหรับการตั้งค่า / รับค่า
  • สแต็คเป็นตัวแปรที่มีความยาวอาร์เรย์ / รายการค่าที่มากที่สุดที่เพิ่งเพิ่มค่า (ค่า "ด้านบน") เป็นคนที่มีการปรับเปลี่ยน
  • คิวเป็นเหมือนกองยกเว้นค่า "ที่ด้านล่าง " เป็นคนที่มีการปรับเปลี่ยน
  • เทปเป็นแบบคงที่อาร์เรย์ / รายการค่าที่แต่ละค่ามีดัชนี ข้อแตกต่างที่สำคัญระหว่างสแต็กและเทปคือค่าบนเทปจะถูกแก้ไขแบบแทนที่

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


1
ฉันคิดว่าคุณควรจะมีคำจำกัดความของคำศัพท์เหล่านี้ในคำถามของคุณ
Kritixi Lithos

2
@Falize เทคนิควิธีการเก็บรักษาไม่ได้ขึ้นอยู่กับชนิดของภาษากอล์ฟที่คุณกำลังทำรูปแบบของภาษากอล์ฟขึ้นอยู่กับวิธีการจัดเก็บ ...
ETHproductions

1
@ ETHproductions พวกเขาพึ่งพาซึ่งกันและกันโดยสิ้นเชิง
เสียชีวิต

1
ฉันได้เพิ่มคำจำกัดความคร่าวๆของเงื่อนไขการจัดเก็บต่าง ๆ อย่าลังเลที่จะแก้ไขหรือย้อนกลับหากคุณไม่ชอบ
ETHproductions

2
มีความสัมพันธ์อย่างใกล้ชิดระหว่างวิธีการจัดเก็บกับประเภทของภาษา แต่ฉันคิดว่าคุณต้องดูทั้งสองอย่าง ตัวอย่างเช่นภาษา "คำสั่ง" (ภาษาที่ปฏิบัติตามคำแนะนำอย่างเคร่งครัดจากซ้ายไปขวา) สามารถเป็นแบบสแต็ก (CJam, 05AB1E), แบบเทป (BrainF ***) หรืออย่างอื่นทั้งหมด (V ซึ่งใช้ หนึ่งสตริง 2D ขนาดใหญ่ที่เรียกว่า "บัฟเฟอร์" พร้อมกับการลงทะเบียนไม่กี่) นอกจากนี้ยังมีภาษาที่ใช้คำนำหน้า (Pyth), ภาษาที่ใช้มัด (Japt, Pip และโดยทั่วไปทุกภาษาหลัก), ภาษาที่ใช้ลิงค์ (วุ้น) เป็นต้นซึ่งทั้งหมดนี้แทบจะไม่ใช้วิธีการใด ๆ ที่กล่าวถึง
ETHproductions

คำตอบ:


4

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

นั่นคือสำหรับหน่วยเก็บข้อมูลที่ชัดเจนคุณสามารถสร้างโอเปอเรเตอร์เพื่อดึงค่าที่คำนวณได้ที่ n ก่อนการดำเนินการนี้หรือนำค่าปัจจุบันกลับมาหลังจากการดำเนินการ n หรือคุณสามารถใช้ตำแหน่งสัมบูรณ์จากจุดเริ่มต้นของโปรแกรมหรือทำสิ่งต่าง ๆ เช่นลบองค์ประกอบบางอย่างโดยอัตโนมัติหลังจากการดำเนินการบางอย่าง (เช่นในกองซ้อน) คุณยังสามารถสร้างโอเปอเรเตอร์หลายตัวได้โดยดึงข้อมูลจากหน่วยเก็บข้อมูลที่ต่างกันโดยมีหรือไม่มีการดำเนินการอัตโนมัติเหล่านี้ และคุณควรพยายามทำให้จำนวนสูงสุดที่จำเป็นในการระบุในการดำเนินการเล็กพอสมควรดังนั้นคุณสามารถกำหนดผู้ให้บริการหนึ่งรายสำหรับแต่ละหมายเลข

แต่ในกรณีส่วนใหญ่คุณไม่จำเป็นต้องมีโอเปอเรเตอร์และภาษาจะทำสิ่งนี้โดยปริยาย นั่นคือเมื่อคุณจำเป็นต้องพิจารณารูปแบบที่เป็นมาตรฐานมากขึ้นเช่นสแต็คหรือคิว ที่ประสบความสำเร็จมากที่สุดในตอนนี้ดูเหมือนจะเป็นการเขียนโปรแกรมโดยปริยายซึ่งไม่ได้กล่าวถึงการจัดเก็บโดยตรง

หากคุณต้องการออกแบบโมเดลดังกล่าวใหม่คุณสามารถลองขยายการประเมินเป็น dag และลองคิดถึง dag เริ่มต้นหากไม่มีการระบุสิ่งใดไว้ เป็นไปได้มากว่าค่าเริ่มต้นเป็นเพียงต้นไม้ยกเว้นว่าหลายใบอาจเชื่อมโยงกับอินพุตเดียวกัน ตัวอย่างเช่นคุณสามารถใช้คิวสำหรับต้นไม้ที่มีความสมดุลหรือสแต็คสำหรับต้นไม้ลึกที่ใบส่วนใหญ่จะคงที่หรือสิ่งที่ต้องการเจลลี่สำหรับต้นไม้ลึกที่ใบส่วนใหญ่เป็นสำเนาของอินพุต

แต่โปรดทราบว่าคุณสามารถเข้ารหัสรูปร่างของต้นไม้ไบนารีได้เพียง 2 บิตต่อตัวดำเนินการ ดังนั้นหากภาษาของคุณมีโอเปอเรเตอร์น้อยกว่า 64 คุณอาจเพิกเฉยต่อโมเดลดั้งเดิมและเข้ารหัสต้นไม้ที่สมบูรณ์ในบิตสำรอง (เรียกว่าแฟลกรวม _parent และ Below_leaf) แม้ว่าจะมีโอเปอเรเตอร์เพิ่มขึ้น แต่คุณสามารถตั้งค่าเริ่มต้นได้ค่อนข้างดี (เช่นรุ่นของ Jelly) และ 3 โมเดอเรเตอร์เพื่อเปลี่ยน

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

สำหรับการอ้างอิงขนาดของการเข้ารหัสที่สมบูรณ์แบบของต้นไม้ไบนารีคือลอการิทึมของจำนวนคาตาลัน และขนาดของการเข้ารหัสที่สมบูรณ์แบบของเศษ "ไบนารี" คือลอการิทึมของA082161แต่ทำไม่ได้อย่างเห็นได้ชัด สิ่งนี้จะถือว่าโอเปอเรเตอร์ที่มีอาร์กิวเมนต์ต่างกันสั่งโอเปอเรเตอร์ที่แตกต่างกันสองตัวเพิ่มบิตอื่นเมื่อไม่ใช่

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


7

ฉันแนะนำพวกเขาทั้งหมด!

จริงจังมากขึ้นพวกเขาทั้งหมดมีประโยชน์บางครั้งและยิ่งดี! อินพุตโดยนัยไม่เคยเลวร้ายเพียงแค่ตั้งค่าสถานะเพื่อปิด ตัวแปรมีประโยชน์ดังนั้นจึงไม่จำเป็นต้องพบในสแต็กหรือเทป เช่นเดียวกันกับการลงทะเบียน สแต็คมีประโยชน์ในการจัดเก็บข้อมูลและเพื่อเป็นเทป ฉันขอแนะนำให้พยายามใช้หลาย ๆ อย่างเช่นพูดกองซ้อนและลงทะเบียนหรือกองซ้อนและตัวแปรเช่น GolfScript หากคุณสามารถทำให้แต่ละฟังก์ชั่นหนึ่งไบต์ภาษาของคุณอาจจะมีประสิทธิภาพในการเล่นกอล์ฟเนื่องจากคุณสามารถใช้ข้อดีของแต่ละฟังก์ชั่นได้

ตัวอย่าง:

  • สมมติว่าฉันต้องการใช้ตัวเลขสองตัวเป็นอินพุตและเพิ่มความยาวสตริง
  • ตัวแปรอาจดีกว่าสำหรับสิ่งนี้ (สแต็กอาจไม่ใช่)
  • โค้ดตัวอย่างใน GolfScript (พร้อมอินพุตโดยนัย):

    ~,\,+
    ~ # Eval input (e.g. "1 2" > 1, 2)
    , # Take Length
    \ # Reverse items on the stack
    , # Take Length
    + # Add
      # Implicit output
    

    อย่างไรก็ตามด้วยตัวแปร (ฉันรู้ว่ามันนานกว่านั้นก็ไม่จำเป็นต้องสลับตำแหน่งบนสแต็ก):

    ~,:a;,:b;ab+
    ~ # Eval input
    , # Get length
    :a# Store in "a"
    ; # Discard value left on stack
    , # Length
    :b# Store in "b"
    ; # Discard
    a # Recall a
    b # Recall b
    + # Add
      # Implicit output
    

overloads

สิ่งที่มีประโยชน์อีกอย่างหนึ่งก็คือโหลดเกินพิกัด ตัวอย่างเช่นถ้าคุณมีฟังก์ชั่นการจัดเก็บตัวแปรบางทีมันอาจจะใช้เป็น monad (ฟังก์ชั่นอินพุตเดียวฉันไม่แน่ใจว่าคำว่าด้านนอกของ J / K / APL) เพื่อเพิ่มลงในสแต็กหรือเทป

ตัวอย่าง:

c12 # Stores "1" into register 2
c1] # Pushes "1" onto the stack ("]" is used to denote the end of the monad)

บางทีถ้าอาร์กิวเมนต์ถูกเรียกด้วยชนิดที่ไม่ถูกต้องมันจะถูกเพิ่มเข้าไปในคิวซึ่งจะถูกใช้เพื่อกรอกค่าหากสแต็กว่างเปล่า?
ผลไม้แยกแยะ

5

ฉันขอแนะนำให้มีที่เก็บข้อมูลที่ใช้งานได้อย่างรวดเร็ว (จากที่ได้รับ - เทปคิวสแต็ก) และที่เก็บถาวร (ตัวแปรรีจิสเตอร์) สำหรับสิ่งต่าง ๆ ที่ไม่เข้าทางในขณะที่โปรแกรมกำลังทำสิ่งที่ไม่เกี่ยวข้อง ฉันจะบอกว่าอีกมากจะไม่ค่อยให้อะไรและปล่อยให้ตัวละครเพิ่มเติมฟรีสำหรับคำแนะนำ 1 ไบต์เพิ่มเติม

จากคำจำกัดความที่ระบุสิ่งที่ฉันคิดว่าจะทำงานได้ดีที่สุดจะเป็นกองและทะเบียน
สแต็กเนื่องจากเทปต้องใช้ฟังก์ชันเพื่อเก็บสิ่งใหม่ในขณะที่สแต็กควรมีฟังก์ชั่นการกดและป๊อปง่าย (โดยปกติจะสร้างในคำสั่ง) รีจิสเตอร์เพราะมันมักจะน้อยกว่าไบต์เมื่อเทียบกับตัวแปรและถ้าคุณต้องการเก็บมากกว่า 2-4 อย่างสำหรับบางสิ่งคุณกำลังทำอะไรผิด

อย่า จำกัด ฟังก์ชั่นของพวกเขาเฉพาะกับชื่อหรือคำจำกัดความที่แนะนำให้ใช้ราง - ฟังก์ชันบางอย่างเช่นput the 1st thing of the stack on top of the stackสามารถช่วยได้อย่างแน่นอน


5

โดยทั่วไปมีพื้นที่เก็บข้อมูลสองประเภทที่ต้องจัดการแตกต่างกัน การเข้าถึงค่าที่สร้างขึ้นล่าสุดและ / หรืออินพุต; และการจัดเก็บระยะยาว

สำหรับการจัดเก็บระยะยาวตัวแปรดูเหมือนจะดีที่สุด สิ่งใดก็ตามที่มีตัวเลือกจำนวน จำกัด จะไม่ขยายขนาด (แม้ว่าภาษาที่มีคุณสมบัตินี้เช่นเจลลี่จะสามารถทำได้ดีแม้ในงานขนาดกลาง) อย่างไรก็ตามไม่จำเป็นต้องระบุชื่อตัวแปรเมื่อเก็บตัวแปรส่วนใหญ่ เพียงแค่มีคำสั่งเพื่อเก็บค่าในตัวแปรและสร้างชื่อตามรูปแบบที่สามารถคาดเดาได้อัตโนมัติเพื่อให้การจัดเก็บและเรียกค่าสามารถเป็นหนึ่งคำสั่งในแต่ละกรณีอย่างง่าย (ตัวอย่างเช่นคุณสามารถมีคำสั่งในการกู้คืนตัวแปรที่ได้รับการมอบหมายล่าสุด, ที่สองล่าสุด, ที่สามล่าสุดและอื่น ๆ , ขึ้นอยู่กับจำนวนคงที่ขนาดเล็กรวมทั้งคำสั่งทั่วไปที่ใช้อาร์กิวเมนต์)

สำหรับการจัดเก็บระยะสั้นคุณต้องการให้มากที่สุดเท่าที่จะเป็นไปได้ ภาษากอล์ฟเกือบทั้งหมดที่ฉันเคยเห็นเชื่อมต่อเอาท์พุทของคำสั่งเดียวกับอินพุตต่อไปโดยปริยาย วิธีที่แน่นอนในการทำสิ่งนี้แตกต่างจากภาษาเป็นภาษา แต่โดยปกติแล้วมาในสิ่งเดียวกัน อย่างไรก็ตามอินพุตที่สองสำหรับคำสั่งอินพุต 2 นั้นน่าสนใจกว่า การนำมาจากสแต็กจะทำงานได้ดีในกรณีที่ค่าจะใช้เพียงครั้งเดียว แต่ไม่สามารถปรับขนาดได้เมื่อนำค่ามาใช้ใหม่ (พยายามหลีกเลี่ยงการจัดการสแต็กแบบดั้งเดิมหากคุณต้องใช้มันคุณจะต้องสูญเสียข้อมูลจำนวนมากไป) หรือใช้การป้อนข้อมูลผู้ใช้หรือตัวแปรที่ได้รับเมื่อเร็ว ๆ นี้เนื่องจากอาร์กิวเมนต์ที่สองโดยนัยมีแนวโน้มว่า โปรแกรมง่าย ๆ แม้ว่าคุณจะ

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


0

ฉันขอแนะนำเทปและการลงทะเบียน

ฉันชอบเทปมากกว่าสแต็คเพราะเทปมักจะมีองค์ประกอบน้อยลงทำให้จัดการได้ง่าย นอกจากนี้ความสามารถในการวางองค์ประกอบต่างๆลงในเทปใน register และในทางกลับกันทำให้ง่ายขึ้นด้วยรหัสสั้น ๆ

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