가이거 계수기 만들기


29

가이거 계수기는 방사선을 감지하는 데 사용되는 장치입니다.

우리는 가이거 카운터 프로그램을 만들 것입니다.

우리 모두 알다시피, 방사선이 컴퓨터 프로그램에 도달하면 무작위로 정확히 1 바이트를 제거합니다. 가이거 계수기 프로그램은 자체적으로 아무것도하지 않는 프로그램이지만, 바이트가 제거되면 수정 된 프로그램 beep이 방사선의 존재를 표시하기 위해 인쇄합니다 .

더 적은 바이트가 더 좋을수록 바이트 단위로 답이 표시됩니다. 응답은 1 바이트 이상이어야합니다.

프로그램은 beep일관된 줄 바꿈으로 줄 바꿈으로 인쇄하거나 빈 줄 바꿈을 위해 줄 바꿈을 인쇄 할 수 있습니다 . 도에 대해 서로 다른 케이스를 사용할 수 있습니다 귀하의 프로그램 beep과 같은 BEEP, bEEP또는 Beep너무 오래 그렇게 지속적으로 수행한다.



7
BEL 제어 문자를 사용하여 실제 경고음을 출력 할 수 있습니까?
Jo King

2
@JoKing 아이디어를 가지고 놀았지만 재미 있지만 거절해야합니다. 너무 실질적으로 다릅니다.
밀 마법사

2
Retina에서 해결책을보고 싶습니다.
mbomb007

3
SMBF 에서이 작업을 수행하는 방법을 알아 내려고 노력 중입니다 ...하지만 두 셀을 비교하는 유일한 방법은 변경하는 것입니다. SMBF에서 확인해야 할 셀은 프로그램이 현재 실행중인 셀입니다. 하이젠 버그 불확실성 원칙과 같습니다. 따라서 제어 흐름 만 사용하여 변경된 사항이 있는지 확인해야합니다.
mbomb007

답변:


24

분실 , 303 293 263 253 238 228 바이트

v^"peeb"<\>"beepvv"((>@@>>%%>>(((((([[[[[[\
>>>>>>>>>//>>>>>>>>>>>>>>/>>/>>>>>>>>>>>>>\\
>>>>>>>>//>>>>\>>>>>>>>>>/>>>>>>>>>>>>>>>>>\\
>/>>>>>>>/>>>>>>>>>>>>\>>>>>>>>>>>>>>>>>>>>>\\
>>>>>>>>>>>>>>>>>>>>>>\\>>>>\>>>>>>>>>>>>>>>>\

온라인으로 사용해보십시오!

확인 스크립트 ( 사용자 202729의 답변 에서 차용 ) 불행히도 이것은 한 번에 코드의 절반 만 테스트 할 수 있지만 전체 프로그램을 테스트 했으므로 안심하십시오.

흠, 이것은 힘든 일이었습니다. WW의 삭제 된 답변을 인용하겠습니다.

로스트는 아마도이 도전에서 가장 흥미로운 언어 일 것입니다. Lost에서 포인터의 시작 위치와 방향은 전적으로 무작위이므로 결정적인 프로그램을 만들려면 가능한 모든 시작 위치와 방향을 고려해야합니다. 동시에,이 챌린지의 특성상 제거되는 단일 바이트도 고려해야합니다.

불행하게도, 그의 대답은 개행을 제거하는 것을 고려하지 않았고, 모든 것을 망쳤습니다.

설명:

(몇 바이트가 여기 저기있을 수 있습니다.)

먼저 코드의 일반적인 구조에 대해 이야기하겠습니다 :

v^^"peeb"<<\/"beepvv"((>>>@@>>%%>>(((((([[[[[[[\       Processing line
>>>>>>>>>>>//>>>>>>>>>>>>>>>>>>>/>>>>>>>>>>>>>>\\      Beep line
>>>>>>>>>//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\\     Back-up beep line
>//>>>>>>>>>>>>>>>>>>>>\\>>>>>>>>>>>>>>>>>>>>>>>>\\    Back-up return line
>>>>>>>>>>>>>>>>>>>>>>>>\\>>>>>>\>>>>>>>>>>>>>>>>>\    Return line

처리 라인을 제외한 모든 것은 전체적으로 >또는 하나 중 하나로 구성되어야합니다 \/. 왜? 예를 들어, 개행을 제거하겠습니다.

v^^"peeb"<<\/"beepvv"((>>>@@>>%%>>(((((([[[[[[[\>>>>>>>>>>>//>>>>>>>>>>>>>>>>>>>/>>>>>>>>>>>>>>\\
>>>>>>>>>//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\\
>//>>>>>>>>>>>>>>>>>>>>\\>>>>>>>>>>>>>>>>>>>>>>>>\\
>>>>>>>>>>>>>>>>>>>>>>>>\\>>>>>>\>>>>>>>>>>>>>>>>>\

첫 번째 줄은 지금 방법으로 블록의 나머지 부분보다 더 오래. >\/세로 이동으로 캐릭터가 아닌 캐릭터 에 포인터를 스폰 하면 무한 루프에 빠지게됩니다.


가장 큰 방사선 검출기 부분은 각 라인의 끝 부분입니다.

 \
 \\
 >\\
 >>\\
 >>>\

일반적으로 첫 번째 행에서 이것을 통과하는 IP는 마지막 행을 종료합니다. 그러나 줄의 문자가 제거되면 해당 줄이 한 줄 아래로 이동합니다. 예 :

 \
 \\
 >\\
 >\\
 >>>\

그리고 대신 IP는 바이트가 누락 된 라인을 종료합니다 (마지막 라인을 제외하고 두 번째에서 마지막으로 종료합니다).

여기에서 처음 네 줄은 각각 두 번째 줄로 리디렉션됩니다.

v
>>>>>>>>>>
>>>>>>>>//
>/

그러면 두 사람 중 한 사람으로 이어질 것입니다 beep.

v^"peeb"<<\/"beepvv"((>
>>>>>>>>>>//

첫 번째 바이트의 바이트 beep가 제거되면 두 번째 바이트로 이동합니다.

v^^"peb"<<\/"beepvv"((>
>>>>>>>>>>>//

두 사람 모두 beep첫 번째 줄로 돌아가고 종료됩니다 @.

기타 기타 부품 :

(((((([[[[[[[포인터가 스택 전체 첫 번째 라인을 밀어 최대 지수 및 종료 한 쌍의 내부를 시작할 때 스택을 취소하는 데 사용됩니다. 첫 줄을 두 배로 만들기 위해 첫 번째 줄 바꿈을 제거 할 수 있기 때문에 불행히도 길어야합니다. beep따옴표 대신 산술을 사용하여 실험 하는 것이 더 길어졌습니다.

\s와 /라인에 걸쳐 흩어져들 골프가 올바른 라인에 포인터를 리디렉션하여 코드의 상단 라인이 바이트에 있습니다. 하단 라인의 대부분은 필러이므로 상단 라인 만 골프를 칠 수 있습니다. 누군가가 더 짧은 방사선 증거 스택에 대해 더 명확한 아이디어를 가지고 있다면 지금 가지고있는 것을 자유롭게 의견을 말하십시오.


호기심 때문에 채팅에 게시 한 부분 답변이 얼마나 도움이 되었습니까? 이전 버전에서 몇 가지 유사점을 보았으며 올바른 방향으로 가고 있는지 알고 싶습니다.
밀 마법사

@WW 나는 그때까지 이미 그 일을 해왔지만 푸시 \/를 분리 beep하고 따옴표 중 하나만 종료 절이 필요하다는 사실이 도움이되었습니다.
Jo King

20

헥사 고니 , 38 바이트

.....;p;<>b;e;/<b;e;;p...@@.......;@..

온라인으로 사용해보십시오!

검증 프로그램.


설명

우리는 육각형 측면 길이의 Hexagony의 자동 감지를 사용합니다.

바이트가 제거되지 않으면 프로그램의 길이는 4이며 다음과 같습니다.

Program without any bytes removed

그러나 바이트가 제거됩니다. 2 가지 경우가 있습니다.

  1. 제거 된 바이트는 두 번째 이후 <입니다.

    실행 흐름은 다음과 같습니다.

    Program with last byte removed

    연속 2있다 @그래서 그들 중 하나가 제거되는 경우에도 IP 안전하게 충돌 것, 5 라인 @.

  2. 제거 된 바이트는 두 번째 또는 그 이전에 <있습니다.

    그런 다음 후반은 그대로 유지되며 IP는 더 이상 위쪽으로 리디렉션되지 않습니다 <. 실행 흐름 이미지 :

    Program with the second <code><</code> removed


19

헥사 고니 , 34 29 바이트

//..>;e;<b@;p;/|/;e;;\.b@;p<@

온라인으로 사용해보십시오! 확인!

설명:

다음은 HexagonyColorer를 사용하여 올바른 육각형으로 포맷 된 일반 코드입니다 .

No Cancer...

//처음에 이중 은이 경로가 항상 사용되도록합니다. 문자가 제거되면 @경로에서 제거되어 문자가 뒤로 이동하거나 자체적으로 제거됩니다.

Cancer!

이 경우, 다음의 문자를 제거하여 |다음 경로를 따라 인쇄합니다 beep.

First beep

대신 |(또는 |자체) 문자를 제거 하면 다른 경고음 프린터를 따릅니다.

Second beep

그런 다음 모든 가능성을 설명했으며 beep조사되지 않은 프로그램 부분 만 사용합니다.


13

자체 수정 Brainfuck , 73 63 바이트

<<[[[[<<]]>[[.>>..>>.[,>]]]]   bbeepp+[<<<]>>[[>]>>>.>>..>>.,+]

온라인으로 사용해보십시오! 확인!

코드 중간의 공백은 실제로 NUL 바이트를 나타냅니다.

설명:

코드는 중간에 3 NUL 바이트 씩 두 섹션으로 나뉩니다. 두 beep섹션 모두 기본적으로 다른 섹션에 방사선이 조사되면 인쇄 됩니다 (몇 가지 예외가 있음).

먼저, <<[[시작 부분은 모든 ]s가 언제든지 일치 하는지 확인하는 것 입니다. 셀이 양수이면 s 는 [일치하는 것을 찾지 않습니다 . 어떤 경우 대괄호 중 하나에 다시 점프 보통 바로 셀이기 때문에 다시 점프 .]]]0

다음 부분 [[<<]]>은 섹션 2의 길이가 고른 지 확인합니다. 그렇다면 섹션 1의 나머지 절반을 실행하고 섹션 2의 시작 부분에를 beep사용하여 인쇄합니다 bbeepp.

[[.>>..>>.[,>]]]]

그런 다음 섹션 2를 모두 지우므로 실행되지 않습니다.

(2)에서는, 제 1 조의 길이 있는지 확인하고 NUL은로 나누어 바이트 3+[<<<]>>.

[[>]>>>.>>..>>.,+]

마찬가지로, 우리는 인쇄 beep합니다.


10

Z80Golf , 53 36 34 바이트

@Lynn 덕분에 -16 바이트 @@ eil 덕분에
-2 바이트

이것은 단지 Z80 머신 코드이므로, 이것에는 많은 인쇄 할 수없는 것들이 있으므로, xxd -r뒤집을 수있는 16 진 덤프가 있습니다 :

00000000: ddb6 2120 10dd b615 280c 003e 62ff 3e65  ..! ....(..>b.>e
00000010: ffff 3e70 ff76 003e 62ff 3e65 ffff 3e70  ..>p.v.>b.>e..>p
00000020: ff76                                     .v

온라인으로 사용해보십시오! (파이썬의 철저한 테스터)

설명

z80golf는 무정부 골프의 가상 Z80 기계,이다 call $8000하는 putchar입니다 call $8003getchar가있다, halt당신의 프로그램이 배치되고, 인터프리터 출구를 만들어 $0000, 다른 모든 메모리를 제로로 채워진다. 어셈블리에서 프로그램을 방사선으로 방지하는 것은 매우 어렵지만 일반적으로 유용한 기술은 1 바이트 dem 등원 명령어를 사용하는 것입니다. 예를 들어

or c        ; b1    ; a = a | c

는 1 바이트 a | c | c == a | c에 불과하므로 명령어를 반복하여 방사선을 차단할 수 있습니다. Z80에서 8 비트 즉시로드는 2 바이트 (즉, 즉시가 두 번째 바이트에 있음)이므로 일부 를로드 할 수 있습니다. 값을 레지스터에 안정적으로 있습니다. 이것이 내가 프로그램의 시작 부분에서 원래했던 일이므로 답변 맨 아래에 보관 된 더 긴 변형을 분석 할 수 있지만 더 간단한 방법이 있음을 깨달았습니다.

이 프로그램은 두 개의 독립적 인 페이로드로 구성되며 그 중 하나는 방사선으로 인해 손상되었을 수 있습니다. 바이트가 제거되었는지 여부와 일부 절대 메모리 주소의 값을 확인하여 제거 된 바이트가 페이로드의 두 번째 사본 앞에 있는지 여부를 확인합니다.

먼저 방사선이 관찰되지 않으면 종료해야합니다.

    or a, (ix+endbyte) ; dd b6 21 ; a |= memory[ix+0x0021]
    jr nz, midbyte     ; 20 10    ; jump to a halt instruction if not zero

바이트가 제거되면 모든 바이트가 이동하고 $0020마지막을 포함 76하므로 $00210이됩니다. 중복성이 거의 없지만 프로그램 시작을 감당할 수 있습니다.

  • 점프 오프셋 $10이 제거되면 방사선이 올바르게 감지되고 점프가 수행되지 않으며 오프셋이 중요하지 않습니다. 다음 명령어의 첫 번째 바이트가 사용되지만 바이트 제거에 견딜 수 있도록 설계되었으므로 이는 중요하지 않습니다.
  • 점프 opcode $20가 제거되면, 점프 오프셋 $10djnz $ffe4다음 명령어 바이트를 오프셋으로 디코딩 하여 루프 명령어 인 B를 감소시키고 결과가 0이 아닌 경우 점프합니다. ffe4-ffff0으로 채워 지기 때문에 (nop 들), 프로그램 카운터 주위에 감싸고,이 프로그램의 256 회를 시작을 실행 한 다음 마지막으로 나갈 것입니다. 이 작품이 놀랍습니다.
  • 를 제거하면 $dd나머지 스 니펫이로 디코딩되고 or (hl) / ld ($1020), hl프로그램의 다음 부분으로 밉니다. 는 or중요한 레지스터를 변경하지 않으며이 시점에서 HL이 0이므로 쓰기도 취소됩니다.
  • 를 제거하면 $b6나머지는 그대로 디코딩 ld ($1020), ix되고 위와 같이 진행됩니다.
  • 를 제거하면 $21디코더가를 먹고 동작을 $20트리거합니다 djnz.

통합 검사 0 덕분에를 사용 or a, (ix+*)하면 2 바이트 를 절약 ld a, (**) / and a / and a할 수 있습니다.

이제 두 개의 페이로드 사본 중 실행할 사본을 결정해야합니다.

    or (ix+midbyte)  ; dd b6 15
    jr z, otherimpl  ; 28 0c
    nop              ; 00
    ; first payload
    ld a, 'b'        ; 3e 62
    rst $0038        ; ff
    ld a, 'e'        ; 3e 65
    rst $0038        ; ff
    rst $0038        ; ff
    ld a, 'p'        ; 3e 70
    rst $0038        ; ff
midbyte:
    halt             ; 76
otherimpl:
    nop              ; 00
    ld a, 'b'        ; 3e 62
    ; ...            ; ...
    rst $0038        ; ff
endbyte:
    halt             ; 76

두 개의 사본은 nop로 구분됩니다. 상대 점프를 사용하여 선택하기 때문에 복사는 대상 다음에 첫 번째 바이트를 건너 뛰는 방식으로 프로그램을 이동시킬 수 있습니다. 또한 nop는 0으로 인코딩되므로 시프트 된 바이트를 쉽게 감지 할 수 있습니다. 스위치 자체가 손상된 경우 두 페이로드가 모두 안전하기 때문에 어떤 페이로드가 선택되는지는 중요하지 않습니다. 그래도 초기화되지 않은 메모리로 점프하지 않도록하십시오.

  • 삭제 $dd하면 다음 두 바이트가 다음과 같이 디코딩됩니다.or (hl) / dec d . Clobbers D. 별거 아닙니다.
  • 삭제 $b6하면에 대한 문서화되지 않은 더 긴 인코딩이 생성됩니다 dec d. 같은 상기와.
  • 삭제 $15하면 $28대신 오프셋 이 읽히고 $0c아래 에서와 같이 실행이 진행 됩니다.
  • $28사라지면 $0c가로 디코딩됩니다 inc c. 페이로드는 신경 쓰지 않습니다 c.
  • 삭제 $0c-이것이 nop의 목적입니다. 그렇지 않으면 페이로드의 첫 번째 바이트가 점프 오프셋으로 읽히고 프로그램이 초기화되지 않은 메모리로 점프합니다.

페이로드 자체는 매우 간단합니다. 문자열의 작은 크기는이 접근법을 루프보다 작게 만들고 위치 독립적 인 방식을 만드는 것이 더 쉽다고 생각합니다. 은 ebeep반복, 그래서 하나를 면도 할 수 있습니다 ld a. 사이의 모든 메모리 있기 때문에, $0038과가 $8000제로, 내가 그것을 통해 가을과 짧은 사용할 수 rst의 변형 call에 대해서만 작동 지시, $0, $8, $10까지, 등등과$38 .

이전 접근법

64 바이트

00000000: 2e3f 3f2e 3f3f 7e7e a7a7 201f 1e2b 2b1e  .??.??~~.. ..++.
00000010: 2b2b 6b00 7ea7 2814 003e 62cd 0080 3e65  ++k.~.(..>b...>e
00000020: cd00 80cd 0080 3e70 cd00 8076 003e 62cd  ......>p...v.>b.
00000030: 0080 3e65 cd00 80cd 0080 3e70 cd00 8076  ..>e......>p...v

58 바이트

00000000: 2e39 392e 3939 7e7e a7a7 2019 3a25 00a7  .99.99~~.. .:%..
00000010: 2814 003e 62cd 0080 3e65 cd00 80cd 0080  (..>b...>e......
00000020: 3e70 cd00 8076 003e 62cd 0080 3e65 cd00  >p...v.>b...>e..
00000030: 80cd 0080 3e70 cd00 8076                 ....>p...v

53 바이트

편집 히스토리에 대한 설명이 있지만 그다지 다르지 않습니다.

00000000: 3a34 00a7 a720 193a 2000 a728 1400 3e62  :4... .: ..(..>b
00000010: cd00 803e 65cd 0080 cd00 803e 70cd 0080  ...>e......>p...
00000020: 7600 3e62 cd00 803e 65cd 0080 cd00 803e  v.>b...>e......>
00000030: 70cd 0080 76                             p...v

만일의 경우 : 비어 있지 않은 결과물이 삐 소리 대신 괜찮습니다.

1 바이트

v

halts the program normally, but if radiation removes it, then the memory will be full of zeroes, making $8000 execute an infinite number of times, printing a lot of null bytes.


Since a starts at zero, can you not use or a, (N); instead of ld a, (N); and a;? It looks as if you can save a couple of bytes that way.
Neil

@Neil Good question! Unfortunately, on the Z80, only load instructions can take addresses like this.
NieDzejkob

Ugh, it's been too long since I did any Z80 programming... maybe I was thinking of or a, (ix + N)?
Neil

@Neil actually, that exists, and IX starts at zero too... unfortunately, saving a byte in that area makes the bytes shift in such a way that the 20 19 at the beginning becomes 20 18, and removing the 20 creates an unconditional jump backwards, so a nop has to be added after the first jump in the program, reversing the byte save.
NieDzejkob

Ah, that's a shame. Thanks for checking though!
Neil


4

Klein, one of each topology, totaling 291 bytes

After seeing WW's answer using the 001 topology, I decided to see how hard it would be to do a Geiger Counter for each topology. (Spoiler: very hard. It's difficult to figure out where the pointer will go without hand gestures that make me look like I'm figuring out which hand is my left)

Verification!

(I also thought about writing a program that is a valid Geiger counter on all topologies, but that might have to wait. If anyone else wants to try though, I'm offering a 500 rep bounty)

000 and 010, 21 bytes

<<@"peeb"/
.@"peeb"<\

Try 000 online! and Try 010 online!

This is ported from my ><> solution. This obviously works in 000, since that's the default topology for most 2D languages, but I was surprised that it also works in 010.

001 and 011, 26 bytes

!.<<@"peeb"/
.@"peeb"..<..

Try 001 online! and Try 011 online!

This one is copied directly from WW's answer. Thanks!

100, 21 bytes

//@"peeb"\
@"peeb".</

Try it online!

101, 21 bytes

//@"peeb"/
@"peeb".<!

Try it online!

110, 26 bytes

<.<@"peeb"\\
.\@."peeb".\<

Try it online!

111, 24 bytes

<<@"peeb"<\
...@"peeb"//

Try it online!

200, 21 bytes

<<@"peeb"\
@"peeb".!/

Try it online!

201, 31 bytes

\\.\.@"peeb"</./
./...@"peeb"<\

Try it online!

By far the most annoying.

210, 26 bytes

/\\@"peeb"</\
/@.."peeb"<\

Try it online!

211, 27 bytes

\\."peeb"((</
!/@@<"peeb"<\

Try it online!

The only one where I had to handle entering the beeper through the right side.


I'll happily second that bounty.
Wheat Wizard


2

Runic Enchantments, 29 bytes

>>yyLL@"peeb"/
     @"peeb"L\

Try it online!

Essentially the same as the Klein 000 answer or ><> answer (I started with the Klein one). The only change really needed was to turn the < into L and . into  (translation of command symbols), inserting the IP entry points (need 2, otherwise a deletion would result in a non-compiling program) and the insertion of the delay command to get the two IPs to merge (thus printing only one beep), again, needing two. Also required inserting additional NOPs to keep line lengths the same. Klein conveniently also uses @ for "print and terminate."

No ability to utilize the whitespace in the lower left, as any reflectors to change direction inhibits the ability to detect radiation. e.g. (26 bytes, irradiated y):

/yLL@"peeb"/
\<<  @"peeb"L\

Prints no output, due to the bent entry segment causing a re-reflection back to the lower line's terminator.



1

Wumpus, 37 34 32 31 bytes

777*7..@ $o&4"beep"|"@peeb"4&o@

Try it online! Verification!

This solution uses the fact that . jumps to a position modulus the length of the program.

Alternatively for the same amount of bytes


" @o&4"beep"}@
@o&4"beep"}$}  

Try it online! Verification!

This one utilises the difference in the direction of the pointer for odd and even line lengths. (I don't really know how the first " actually works when the newline is removed)


1

Klein (001), 26 bytes

!.<<@"peeb"/
.@"peeb"..<..

Try it online!

Verify!

Explanation

This program takes advantage of Klein's unique topology in particular the 001 topology, which is a Klein bottle.

Unedited the program follows the execution path:

Orange path

Removing a byte from the program can effect the program in 4 ways (each in a different color):

Program sections

The first thing to note is that << will always deflect the ip to the left of the origin at the start. If one of the <s is deleted the other takes its place. So if any byte is removed from the red section the following execution path will be followed:

Red path

If the blue byte is removed we get the very simple path:

enter image description here

If the newline is removed we get the path:

Green path

The yellow path is a bit more complex. Since the bottom line is one longer than the top line, when the program is squared at the beginning of execution a virtual character is added to the end of the first line to make them the same size. If any byte on the second line is removed the line is shortened and that virtual character is not added. This is important because ! normally jumps over the virtual character, but in its absence it jumps over / instead.

Yellow path


1
You could port my ><> solution in 000 for 21 bytes
Jo King

@JoKing I think that would be better as its own answer.
Wheat Wizard

1

Backhand, 25 21 bytes

vv""ppeeeebb""jjHH@

Try it online! Verification!

This uses Backhand's ability to change the pointer step value to skip an instruction every step and neatly solve the redunancy issue. It then uses the j command to check if the code is irradiated by jumping to the last character (@, halt) if not, and jumping to the second last (H, halt and output stack) if so.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.