Steampunk: แอนิเมชัน Clacker


11

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

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

SSSSYYxxXXOA
SSSS: 4 digit sequence no. may be padded by blanks or all blank
    YY: the y coordinate affected by this line (descending, top is 0, bottom is m-1)
      xx: the starting x coordinate
        XX: the ending x coordinate
          O: hexadecimal opcode
           A: argument (0 or 1)

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

บรรทัดคำสั่งเดียวสามารถส่งผลกระทบต่อพิกัด y เดียว แต่อาจระบุช่วงค่า x ที่ต่อเนื่องกัน ค่า x สิ้นสุดอาจเว้นว่างไว้หรืออาจเหมือนกับค่าเริ่มต้นเพื่อส่งผลกระทบต่อพิกเซลเดียว

opcode เป็นเลขฐานสิบหกซึ่งระบุรหัสฟังก์ชันไบนารีสากลซึ่งใช้เป็น rasterop อาร์กิวเมนต์เป็น 0 หรือ 1 การดำเนินการแรสเตอร์ที่ดำเนินการคือ

pixel = pixel OP argument          infix expression
         --or-- 
        OP(pixel, argument)        function call expression

ดังนั้นค่าดั้งเดิมของพิกเซลจะเข้าสู่ X ในตาราง UBF และค่าอาร์กิวเมนต์จากคำสั่งจะถูกป้อนเป็น Y ผลลัพธ์ของฟังก์ชันนี้คือค่าใหม่ของพิกเซล และการดำเนินการนี้จะดำเนินการกับแต่ละคู่ x, y จาก xx, YY ถึง XX, YY ที่ระบุไว้ในคำสั่ง ช่วงที่ระบุโดย xx และ XX มีทั้งจุดสิ้นสุด ดังนั้น

0000 0 010F1

ควรตั้งค่าพิกเซล 0,1,2,3,4,5,6,7,8,9,10 ในแถว 0

ขนาดเอาต์พุต ( m x n ) ควรเป็นอย่างน้อย 20 x 20 แต่อาจใหญ่กว่านี้หากต้องการ แต่เมล็ดควรจะแสดงคุณรู้หรือไม่? มันควรจะเป็นตัวหนังสือ ทั้งเอาต์พุตกราฟิกและ ASCII เป็นที่ยอมรับ

ตัวอย่างเช่นเราต้องการสร้างภาพของตัวหนังสือตัวหนังสือ:

  #   #
   ###
   ##
   ####
    #
#### ####
   # #

   ###
   # #
   # #

หากเราวาดเขาด้วย op-flipping opent เช่น XOR มันสามารถวาดและลบได้โดยไม่คำนึงว่าหน้าจอจะเป็นสีดำหรือสีขาว

    00020261
     0 6 661
     1 3 561
     2 3 461
     3 3 661
     4 4 461
     5 0 361
     5 5 861
     6 3 361
     6 5 561
     8 3 561
     9 3 361
     9 5 561
    10 3 361
    10 5 561

การทำซ้ำลำดับนี้จะทำให้ตัวเลขปรากฏและหายไป

NMM ไม่ใช่มิกกี้เมาส์

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

   100 016F0
   101 016F0
   102 016F0
   103 016F0
   104 016F0
   105 016F0
   106 016F0
   107 016F0
   108 016F0
   109 016F0
   110 016F0
   111 016F0
   112 016F0
   113 016F0
   114 016F0
   115 016F0
   200020261
   2 0 6 661
   2 1 3 561
   2 2 3 461
   2 3 3 661
   2 4 4 461
   2 5 0 361
   2 5 5 861
   2 6 3 361
   2 6 5 561
   2 8 3 561
   2 9 3 361
   2 9 5 561
   210 3 361
   210 5 561
    00020261
     0 6 661
     1 3 561
     2 3 461
     3 3 661
     4 4 461
     5 0 361
     5 5 861
     6 3 361
     6 5 561
     8 3 561
     9 3 361
     9 5 561
    10 3 361
    10 5 561
   300020261
   3 0 6 661
   3 1 3 561
   3 2 3 461
   3 3 3 661
   3 4 4 461
   3 5 0 361
   3 5 5 861
   3 6 3 361
   3 6 5 561
   3 8 3 561
   3 9 3 361
   3 9 5 561
   310 3 361
   310 5 561
    00020261
     0 6 661
     1 3 561
     2 3 461
     3 3 661
     4 4 461
     5 0 361
     5 5 861
     6 3 361
     6 5 561
     8 3 561
     9 3 361
     9 5 561
    10 3 361
    10 5 561

การผลิต:

ดำ / ขาวกับขาว / ดำ

โปรแกรมนี้เป็นสั้นที่สุด (นับจำนวนไบต์) โบนัส (-50) หากเอ็นจิ้นทำให้เกิดเสียง clickity-clack


3
โดยปกติหนึ่งขอชี้แจงโดยการโพสต์ใน sandbox คุณกำลังพยายามปิด sandbox ลงหรือไม่
John Dvorak

5
สำหรับฉันโดยส่วนตัวกล่องทรายนั้นเป็นจุดจบ ฉันเก่งเรื่องผัดวันประกันพรุ่งจนเกินไป ที่นี่มีชีวิตฉันไม่สามารถเพิกเฉยต่อไฟใต้ก้นของฉันได้
luser droog

1
ตัวเชื่อมต่อ Boolean ทำงานอย่างไร มันจะรวมเฉพาะบรรทัดที่มีหมายเลขลำดับเท่ากันหรือไม่ หากผสมกันจะมีรูปแบบของตัวดำเนินการบางอย่างหรือไม่ คุณมีกรณีทดสอบใดบ้างที่ต้องใช้ตัวเชื่อมต่อ Boolean ทำไมกรณีทดสอบที่คุณโพสต์ไม่มีหมายเลขลำดับใด ๆ จุดจบของตอนจบxนั้นรวมอยู่ด้วยเสมอหรือไม่?
Peter Taylor

5
นี่คือบางส่วนเป็นเสียง clickety พูดละล่ำละลัก ฉันจะได้รับโบนัสหรือไม่? ;-)
Digital Trauma

1
สำหรับเสียงคุณกำลังคิดบางอย่างเช่นกระดานพลิกสถานีรถไฟหรือไม่? เช่นคณะกรรมการ Solari ที่ Gare du Nord สถานีรถไฟในปารีสหรือการแสดงผลแยกพนัง - วงจรขับรถ หรือคุณคิดจะถ่ายทอดเสียงเครื่องกลมากขึ้น?
Scott Leadley

คำตอบ:


3

Mathematica, 306 281 ไบต์

สิ่งนี้คาดว่าสตริงอินพุตจะถูกเก็บไว้ในตัวแปร i

ListAnimate[ArrayPlot/@FoldList[({n,y,x,X,o,a}=#2;MapAt[IntegerDigits[o,2,4][[-1-FromDigits[{#,a},2]]]&,#,{y+1,x+1;;X+1}])&,Array[0&,{20,20}],ToExpression/@MapAt["16^^"<>#&,StringTrim/@SortBy[i~StringSplit~"\n"~StringCases~RegularExpression@"^....|..(?!.?$)|.",{#[[1]]&}],{;;,5}]]]

และที่นี่ด้วยช่องว่างบางส่วน:

ListAnimate[ArrayPlot /@ FoldList[(
     {n, y, x, X, o, a} = #2;
     MapAt[
      IntegerDigits[o, 2, 4][[-1 - FromDigits[{#, a}, 2]]] &,
      #,
      {y + 1, x + 1 ;; X + 1}
      ]
     ) &,
   Array[0 &, {20, 20}],
   ToExpression /@ 
    MapAt["16^^" <> # &, 
     StringTrim /@ 
      SortBy[i~StringSplit~"\n"~StringCases~
        RegularExpression@"^....|..(?!.?$)|.", {#[[1]] &}], {;; , 5}]
   ]]

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


2

ตัวอย่าง Postscript ที่ไม่ดี

นี่คือโปรแกรม "โพรโทคอล - โพล็อก" สไตล์ดังนั้นข้อมูลจะตามมาในไฟล์ต้นฉบับเดียวกันทันที ไฟล์ภาพเคลื่อนไหว GIF สามารถผลิตได้ด้วย ImageMagick ของconvertยูทิลิตี้ (ใช้ convert clack.ps clack.gifGhostscript):

%%BoundingBox: 0 0 321 321

/t { token pop exch pop } def
/min { 2 copy gt { exch } if pop } def
/max { 2 copy lt { exch } if pop } def

/m [ 20 { 20 string }repeat ] def
/draw { change {
        m {} forall 20 20 8 [ .0625 0 0 .0625 0 0 ] {} image showpage
    } if } def

%insertion sort from https://groups.google.com/d/topic/comp.lang.postscript/5nDEslzC-vg/discussion
% array greater_function insertionsort array
/insertionsort
{ 1 1 3 index length 1 sub
    { 2 index 1 index get exch % v, j
        { dup 0 eq {exit} if
            3 index 1 index 1 sub get 2 index 4 index exec
            {3 index 1 index 2 copy 1 sub get put 1 sub}
            {exit} ifelse
        } loop
        exch 3 index 3 1 roll put
    } for
    pop
} def

/process {
    x X min 1 x X max { % change? x
        m y get exch  % row-str x_i
        2 copy get  % r x r_x 
        dup         % r x r_x r_x
        0 eq { 0 }{ 1 } ifelse  % r x r_x b(x)
        2 mul a add f exch neg bitshift 1 and   % r x r_x f(x,a)
        0 eq { 0 }{ 255 } ifelse  % r x r_x c(f)
        exch 1 index % r x c(f) r_x c(f)
        ne { /change true def } if
        put
    } for
    draw
} def

{ [ {
     currentfile 15 string
         dup 2 13 getinterval exch 3 1 roll
         readline not{pop pop exit}if
    pop
    [ exch
     /b exch dup 0 1 getinterval exch
     /n exch dup 1 1 getinterval exch
     /seq exch dup 2 4 getinterval exch
     /y exch dup 6 2 getinterval t exch
     /x exch dup 8 2 getinterval t exch
     /X exch dup 10 2 getinterval dup (  ) ne { t exch }{pop 2 index exch} ifelse
     /f exch dup 12 get (16#?) dup 3 4 3 roll put t exch
     /a exch 13 get 48 sub
     /change false def
    >>
}loop ]
dup { /seq get exch /seq get exch gt } insertionsort
true exch
{ begin
    b(A)eq{
        { process } if
    }{
        b(O)eq{
            not { process } if
        }{
            pop
            process
        }ifelse
    }ifelse
    change
    end
} forall
    draw
} exec
   100 016F0
   101 016F0
   102 016F0
   103 016F0
   104 016F0
   105 016F0
   106 016F0
   107 016F0
   108 016F0
   109 016F0
   110 016F0
   111 016F0
   112 016F0
   113 016F0
   114 016F0
   115 016F0
   200020261
   2 0 6 661
   2 1 3 561
   2 2 3 461
   2 3 3 661
   2 4 4 461
   2 5 0 361
   2 5 5 861
   2 6 3 361
   2 6 5 561
   2 8 3 561
   2 9 3 361
   2 9 5 561
   210 3 361
   210 5 561
    00020261
     0 6 661
     1 3 561
     2 3 461
     3 3 661
     4 4 461
     5 0 361
     5 5 861
     6 3 361
     6 5 561
     8 3 561
     9 3 361
     9 5 561
    10 3 361
    10 5 561
   300020261
   3 0 6 661
   3 1 3 561
   3 2 3 461
   3 3 3 661
   3 4 4 461
   3 5 0 361
   3 5 5 861
   3 6 3 361
   3 6 5 561
   3 8 3 561
   3 9 3 361
   3 9 5 561
   310 3 361
   310 5 561
    00020261
     0 6 661
     1 3 561
     2 3 461
     3 3 661
     4 4 461
     5 0 361
     5 5 861
     6 3 361
     6 5 561
     8 3 561
     9 3 361
     9 5 561
    10 3 361
    10 5 561
0000 0 515F1
0000 1 11501
0000 1 115F1

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