Steampunk : Clacker 애니메이션


11

과소 평가 된 Steampunk 소설 인 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)

입력은 명시 적으로 순서화됩니다 (바닥에 카드 덱을 떨어 뜨린 경우이 부분에 대해 감사합니다). 즉, 시퀀스 필드를 정렬 키로 사용하여 프로그램이 입력 라인을 안정적으로 정렬해야합니다. 순서 번호가 동일한 줄은 원래 상대 순서를 유지해야합니다. 실제 행 번호를 키에 추가하면 불안정한 정렬로 작동해야합니다. 빈 시퀀스 필드는 임의의 숫자 (아스키 정렬 순서)보다 낮은 값으로 해석해야합니다.

단일 명령문 행은 단일 y 좌표에만 영향을 줄 수 있지만 x 범위의 연속 범위를 지정할 수 있습니다. 단일 x 값에 영향을주기 위해 종료 x 값은 비워 둘 수 있거나 초기 값과 동일 할 수 있습니다.

opcode는 16 진수 로 래스터 럽으로 사용되는 Universal Binary Function Code 를 지정합니다 . 인수는 0 또는 1입니다. 수행 된 래스터 작업은 다음과 같습니다.

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

따라서 픽셀의 원래 값은 UBF 테이블에서 X로 입력되고 명령문의 인수 값은 Y로 입력됩니다.이 함수의 결과는 새로운 픽셀 값입니다. 그리고이 작업은 명령문에 지정된 xx, YY에서 XX, YY까지의 각 x, y 쌍에서 수행됩니다. xx 및 XX로 지정된 범위에는 두 끝 점이 모두 포함됩니다. 그래서

0000 0 010F1

행 0에서 픽셀 0,1,2,3,4,5,6,7,8,9,10을 설정해야합니다.

출력 치수 ( m x n )는 최소 20 x 20이어야하지만 원하는 경우 더 클 수 있습니다. 하지만 곡물 은 보여야합니다. 픽셀 화 되어야합니다 . 그래픽 및 ASCII 아트 출력이 모두 허용됩니다.

예를 들어, 픽셀 화 된 그림의 이미지를 만들고 싶을 경우 :

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

   ###
   # #
   # #

XOR과 같이 비트-플 래핑 op로 그를 그리면 화면이 검은 색인지 흰색인지에 관계없이 그려 지거나 지울 수 있습니다.

    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

생산 :

블랙 / 화이트 vs 화이트 / 블랙

이것은 이므로 가장 짧은 프로그램 (바이트 수)이 이깁니다. 엔진이 클릭 크랙 소음을내는 경우 보너스 (-50).


3
일반적으로 하나는 샌드 박스에 게시하여 설명을 요청합니다. 샌드 박스를 종료하려고합니까?
John Dvorak

5
개인적으로 샌드 박스는 막 다른 골목입니다. 나는 그것을 끝내기 위해 미루는 데 너무 능숙합니다. 여기, 내 엉덩이 아래의 불을 무시할 수 없어
luser droog

1
부울 커넥터는 어떻게 작동합니까? 시퀀스 번호가 동일한 라인 만 조인합니까? 혼합되어 있으면 어떤 형태의 연산자 우선 순위가 있습니까? 부울 커넥터에 의존하는 테스트 사례가 있습니까? 게시 한 테스트 사례에 시퀀스 번호가없는 이유는 무엇입니까? 결말 코드는 x항상 포함됩니까?
피터 테일러

5
여기 클릭 소리가 나는 소리가 들립니다 . 보너스를 받습니까? ;-)
Digital Trauma

1
소리로, 당신은 기차역 플립 보드와 같은 것을 생각하고 있습니까? 예를 들어 파리의 Gare du nord 기차역 또는 Split-flap Display-DIY 드라이버 회로의 솔라리 보드 . 아니면 더 기계적인 릴레이 사운드를 생각하고 있습니까?
Scott Leadley

답변:


3

수학, 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

Ungolfed Postscript 예제

이것은 "프로토콜 프롤로그"스타일의 프로그램이므로 데이터는 즉시 동일한 소스 파일에서 따릅니다. 애니메이션 GIF 파일은 ImageMagick의 convert유틸리티 (고스트 스크립트 사용) 로 생성 할 수 있습니다 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

를 실행하여 경계 상자 정보를 발견했습니다 gs -sDEVICE=bbox clack.ps.
luser droog가
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.