Steampunk: Hoạt hình Clacker


11

Trong tiểu thuyết Steampunk Engine khác biệt được đánh giá thấp , tương đương với các rạp chiếu phim đã cung cấp một hình ảnh chuyển động pixel được hiển thị bằng các ô có thể được lật một cách cơ học. Công cụ điều khiển để phối hợp chuyển động của những viên gạch này là một cỗ máy ồn ào lớn được điều khiển bởi một cỗ bài đục lỗ.

Nhiệm vụ của bạn là mô phỏng một công cụ như vậy và hiển thị một hình ảnh động pixel như được chỉ định bởi một tệp đầu vào. Đầu vào bao gồm các dòng ở định dạng độ rộng cố định, nhưng bạn có thể giả sử bất cứ điều gì thuận tiện cho chỉ báo kết thúc dòng. Định dạng là:

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)

Đầu vào được sắp xếp rõ ràng theo trình tự (nếu bạn từng thả bộ bài của mình xuống sàn, bạn sẽ cảm ơn tôi về phần này). Điều đó có nghĩa là chương trình phải thực hiện sắp xếp ổn định các dòng đầu vào bằng cách sử dụng trường chuỗi làm khóa sắp xếp. Các dòng có cùng số thứ tự phải duy trì thứ tự tương đối ban đầu của chúng. (Nó sẽ hoạt động với một loại không ổn định, nếu bạn nối số dòng thực vào khóa.) Trường chuỗi trống sẽ được hiểu là thấp hơn bất kỳ số nào (chuỗi đối chiếu ascii).

Một dòng lệnh duy nhất chỉ có thể ảnh hưởng đến một tọa độ y, nhưng có thể chỉ định một phạm vi giá trị x liền kề. Giá trị x kết thúc có thể để trống hoặc có thể giống hệt với giá trị ban đầu để ảnh hưởng đến một pixel.

Opcode là một chữ số thập lục phân chỉ định Mã chức năng nhị phân phổ quát được sử dụng làm rasterop. Đối số là 0 hoặc 1. Thao tác raster được thực hiện là

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

Vì vậy, giá trị ban đầu của pixel nhập dưới dạng X trong bảng UBF và giá trị đối số từ câu lệnh nhập là Y. Kết quả của hàm này là giá trị mới của pixel. Và thao tác này được thực hiện theo từng cặp x, y từ xx, YY đến XX, YY được chỉ định trong câu lệnh. Phạm vi được chỉ định bởi xx và XX bao gồm cả hai điểm cuối. Vì thế

0000 0 010F1

nên đặt pixel 0,1,2,3,4,5,6,7,8,9,10 trên hàng 0.

Kích thước đầu ra ( m x n ) tối thiểu phải là 20 x 20, nhưng có thể lớn hơn nếu muốn. Nhưng hạt nên thể hiện, bạn biết không? Nó được cho là pixelated . Cả hai đầu ra đồ họa và nghệ thuật ASCII đều được chấp nhận.

Ví dụ: chúng tôi muốn tạo một hình ảnh của một pixel pixel:

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

   ###
   # #
   # #

Nếu chúng ta vẽ anh ta với một op lật, như XOR, nó có thể được vẽ và xóa bất kể màn hình là đen hay trắng.

    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

Sao chép chuỗi này sẽ làm cho hình xuất hiện và biến mất.

NMM không phải là chuột Mickey

Một hình ảnh động lớn hơn có thể được sắp xếp theo thứ tự, bằng cách chỉ định các "ảnh" khác nhau trong trường trình tự.

   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

Sản xuất:

đen / trắng vs trắng / đen

Đây là để chương trình ngắn nhất (tính theo byte) thắng. Tiền thưởng (-50) nếu động cơ tạo ra tiếng ồn nhấp chuột.


3
Thông thường một yêu cầu làm rõ bằng cách đăng lên hộp cát. Bạn đang cố gắng để đóng hộp cát xuống?
John Dvorak

5
Đối với cá nhân tôi, các hộp cát là một ngõ cụt. Tôi quá giỏi trong việc trì hoãn để hoàn thành chúng. Ở đây, sống, tôi không thể bỏ qua lửa dưới mông của tôi.
luser droog

1
Trình kết nối Boolean hoạt động như thế nào? Có phải nó chỉ tham gia các dòng có cùng số thứ tự? Nếu chúng bị trộn lẫn, có một số hình thức ưu tiên của nhà điều hành? Bạn có bất kỳ trường hợp thử nghiệm dựa trên kết nối Boolean? Tại sao trường hợp thử nghiệm bạn đăng không có bất kỳ số thứ tự? Là phối hợp kết thúc xluôn luôn bao gồm?
Peter Taylor

5
Dưới đây là một số tiếng ồn clack clickety . Tôi có nhận được tiền thưởng không? ;-)
Chấn thương kỹ thuật số

1
Đối với âm thanh, bạn đang suy nghĩ một cái gì đó như bảng lật ga tàu? Ví dụ: bảng solari tại ga xe lửa gare du nord ở paris hoặc Split-flap Display - Mạch điều khiển DIY . Hay bạn đang suy nghĩ nhiều âm thanh tiếp sức cơ học?
Scott Leadley

Câu trả lời:


3

Toán học, 306 281 byte

Điều này hy vọng chuỗi đầu vào sẽ được lưu trữ trong biến 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}]]]

Và ở đây với một số khoảng trắng:

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}]
   ]]

Điều này đã khá lâu chết tiệt. Thử thách này chứa rất nhiều chi tiết khó hiểu và đặc biệt là phân tích cú pháp đầu vào chiếm rất nhiều mã trong Mathicala (gần một nửa trong số đó, 137 byte, chỉ phân tích cú pháp đầu vào). Tôi đã kết thúc chuyển đổi ngôn ngữ hai lần trước khi quyết định Mathematica (tôi nghĩ rằng tôi có thể tiết kiệm trên phân tích đầu vào bằng cách sử dụng Ruby, nhưng sau đó tôi nhận ra kết quả cần phải được hoạt hình , vì vậy tôi quay trở lại với Mathematica).


2

Ví dụ bài viết lộn xộn

Đây là chương trình kiểu "giao thức-prolog", vì vậy dữ liệu ngay lập tức theo cùng một tệp nguồn. Các tập tin gif hoạt hình có thể được tạo bằng converttiện ích của ImageMagick (sử dụng ghostscript) : convert clack.ps clack.gif.

%%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

Thông tin hộp giới hạn được phát hiện bằng cách chạy gs -sDEVICE=bbox clack.ps.
luser droog
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.