เขียนโปรแกรมที่ถูกต้องหลังจากเปลี่ยนตัวอักษรแบบวงกลม


17

อาจเป็นเรื่องยากมาก แต่ฉันได้เห็นสิ่งที่น่าอัศจรรย์บางอย่างเกิดขึ้นจากเว็บไซต์นี้

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

การกะตัวอักษรแบบวงกลมคล้ายกับการเลื่อนแบบวงกลมมาก ตัวอย่างบางอย่างชัดเจนขึ้น

สำหรับโปรแกรม int main() { return 0; }

การเลื่อนไปทางซ้าย 6 ตัวอักขระจะทำให้: in() { return 0; }int ma

ขยับไปทางซ้ายโดยอักขระ 1 ตัวให้ผลดังนี้: nt main() { return 0; }i

ขยับไปทางขวา 10 ตัวอักษรให้ผล: eturn 0; }int main() { r

อย่างไรก็ตามโปรแกรมนี้เห็นได้ชัดว่าไม่สอดคล้องกับกฎ

กฎระเบียบ

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

UPDATEฉันคิดว่านี่มันนานพอแล้ว ผู้ชนะที่ได้รับคะแนนเสียงมากที่สุด (รวมคะแนนเสียงเสมือนจริง) คือ Mark Byers ทำได้ดี!


5
มีคำตอบที่อาจเป็นไปได้ที่น่าเบื่อมากในภาษาที่ตัวอักษร int เป็นโปรแกรมที่ถูกต้อง พวกเขาได้รับ -100 เสมือนหรือไม่?
Peter Taylor

1
@PeterTaylor ฉันคิดว่าคำตอบที่น่าเบื่อจะได้รับคะแนนน้อยกว่า
Griffin

"อาจเป็นเรื่องยากมาก"การทำความคุ้นเคยกับภาษาแปลก ๆ หลาย ๆ อย่างเป็นประโยชน์เสมอก่อนที่จะสร้างประโยคแบบนี้โดยทั่วไป ยากใน c หรือ java แน่นอน แต่ในภาษาที่มี 1 คำสั่งตัวอักษรและไวยากรณ์ง่าย ๆ ? ไม่มากนัก.
dmckee

@dmckee ดังนั้น "ที่อาจเกิดขึ้น" ...
กริฟฟิ

@PeterTaylor มีภาษามากมายโปรแกรมที่ว่างเปล่าคือโปรแกรมที่ถูกต้อง
jk

คำตอบ:


31

ใช้ภาษาที่เหมาะสมสำหรับงาน ในกรณีนี้ที่Befunge

ภาษานี้ทำให้สามารถหมุนได้ตามปกติเนื่องจาก:

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

โปรแกรม Befunge นี้พิมพ์ผลลัพธ์เดียวกัน ("Hello") โดยไม่คำนึงว่าคุณใช้ "ตัวอักษรแบบวงกลม" กี่อัน:

86*01p75*1-02p447**1-03p439**04p439**05p455**1+06p662**07p75*1-08p645**2-09p69*4+019+p57*029+p59*1-039+p555**1-049+p88*059+p86*01p75*1-02p447**1-03p439**04p439**05p455**1+06p662**07p75*1-08p645**2-09p69*4+019+p57*029+p59*1-039+p555**1-049+p88*059+p645**2-00p645**2-00p

มันทำงานบนBefungee ต้องการให้บอร์ดเพิ่มขึ้น (ไม่ใช่ค่าเริ่มต้น 80 ตัวอักษร) มันสามารถเรียกใช้เช่นนี้:

python befungee.py -w400 hello.bef

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

สามารถขยายแนวคิดเพื่อสร้างโปรแกรมใด ๆ ที่มีความซับซ้อนตามอำเภอใจ


รายการที่ดีมาก!
ChristopheD

22

Brainf * CK

เลือกเครื่องมือที่เหมาะสมสำหรับงาน - สุภาษิตที่ไม่เคยเกี่ยวข้องมากไปกว่างานนี้ตรงนี้!

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
++++++++++++++++++.>+++++++++++++++++++++++++++++++++++++++++++++
+++++++++++++++++++++++++++.+.>++++++++++++++++++++++++++++++++++
++++++++++++++++++++++++++++++++++++.++++++++++++++.>++++++++++.+

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


ฉันอ่านคำถามและความคิด Brainfuck นั่นเป็นตั๋ว แต่คุณเอาชนะฉันได้
jmoreno

12

พลเรือจัตวา 64 พื้นฐาน

?สั้นสำหรับPRINTและ:เป็นตัวคั่นคำสั่งดังนั้น:

?1:?2:?3:          // prints 1, 2, and 3
:?1:?2:?3          // prints 1, 2, and 3
3:?1:?2:?          // adds a program line 3 :PRINT1:PRINT2:PRINT
?3:?1:?2:          // prints 3, 1, and 2
:?3:?1:?2          // prints 3, 1, and 2
2:?3:?1:?          // adds a program line 2 :PRINT3:PRINT1:PRINT
?2:?3:?1:          // prints 2, 3, and 1
:?2:?3:?1          // prints 2, 3, and 1
1:?2:?3:?          // adds a program line 1 :PRINT2:PRINT3:PRINT

แน่นอนรูปแบบที่ยาวขึ้นเป็นไปได้:

?1:?2:?3:?4:?5:?6:?7:?8:?9:?10:?11:

ฯลฯ ...


11

Golfscript

โปรแกรมนี้พิมพ์ตัวเลขบางตัวที่รวมกันเป็น 2 เสมอโดยไม่คำนึงถึงการเลื่อนโปรแกรม:

10 2 base
0 2 base1
 2 base10
2 base10 
 base10 2
base10 2 
ase10 2 b
se10 2 ba
e10 2 bas

บรรทัดแรกพิมพ์1010(10 ในไบนารี) พิมพ์บรรทัดที่สอง02และพิมพ์บรรทัดอื่น2ทั้งหมด

ปรับปรุง:

โปรแกรมที่สามารถทดสอบได้ที่นี่ โปรดทราบว่าฉันได้เพิ่มns ในตอนท้ายของแต่ละแถวสำหรับการจัดรูปแบบผลลัพธ์เท่านั้น สิ่งเหล่านี้สามารถลบออกได้และโปรแกรมยังคงทำงาน


10

Ruby อาจเป็นหนึ่งในวิธีแก้ปัญหาที่สั้นที่สุด:

p

และอีกอันหนึ่งที่ยาวกว่าและน่าสนใจกว่าเล็กน้อย:

;;p";p;";p

9

x86 16 บิตไบนารี่

สร้างด้วยความช่วยเหลือของเหล่านี้ (ด้วยตนเอง1 2 ) ตาราง NASM และ ndisasm สิ่งนี้จะส่งคืนโดยไม่มีข้อผิดพลาดหรือการวนซ้ำไม่สิ้นสุดเนื่องจากไม่มีการข้ามไบต์หรือเปลี่ยนสแต็กและเต็มไปด้วย NOPs เพื่อจบด้วยretคำสั่งไบต์เดียวในทุกกรณี

ในกรณีส่วนใหญ่นี้จะส่งออกFOOหรือสตริงย่อยของที่ หากใช้AXงานไม่ได้จะเรียกการสุ่มint 10 (ซึ่งเป็นการเปลี่ยนความเร็วของเคอร์เซอร์ที่กระพริบในการทดสอบของฉัน) แต่โดยทั่วไปแล้วจะไม่ส่งผลให้เกิดความผิดพลาด

หากต้องการลองใส่ hexdump ในไฟล์และใช้xxd -r foo.hex > foo.comจากนั้นเรียกใช้ในสภาพแวดล้อม DOS (ฉันใช้ dosbox)

นี่คือการดัมพ์แบบเลขฐานสิบหกของไฟล์นี้:

0000000: b846 0d90 90fe c490 9090 bb05 0090 9043  .F.............C
0000010: 43cd 1090 b84f 0d90 90fe c490 9090 bb05  C....O..........
0000020: 0090 9043 43cd 1090 b84f 0d90 90fe c490  ...CC....O......
0000030: 9090 bb05 0090 9043 43cd 1090 9090 c3    .......CC......

และบางส่วนที่น่าสนใจถอดแยกชิ้นส่วน:

0

00000000  B8420D            mov ax,0xd42
00000003  90                nop
00000004  90                nop
00000005  FEC4              inc ah
00000007  90                nop
00000008  90                nop
00000009  90                nop
0000000A  BB0500            mov bx,0x5
0000000D  90                nop
0000000E  90                nop
0000000F  43                inc bx
00000010  43                inc bx
00000011  CD10              int 0x10
00000013  90                nop
00000014  B84F0D            mov ax,0xd4f
00000017  90                nop
00000018  90                nop
00000019  FEC4              inc ah
0000001B  90                nop
0000001C  90                nop
0000001D  90                nop
0000001E  BB0500            mov bx,0x5
00000021  90                nop
00000022  90                nop
00000023  43                inc bx
00000024  43                inc bx
00000025  CD10              int 0x10
00000027  90                nop
00000028  B84F0D            mov ax,0xd4f
0000002B  90                nop
0000002C  90                nop
0000002D  FEC4              inc ah
0000002F  90                nop
00000030  90                nop 
00000031  90                nop
00000032  BB0500            mov bx,0x5
00000035  90                nop
00000036  90                nop
00000037  43                inc bx
00000038  43                inc bx
00000039  CD10              int 0x10
0000003B  90                nop
0000003C  90                nop
0000003D  90                nop
0000003E  C3                ret

(สำหรับตัวอย่างด้านล่างส่วนที่เหลือของไบนารียังคงใช้ได้)

+1

00000000  42                inc dx
00000001  0D9090            or ax,0x9090
00000004  FEC4              inc ah
00000006  90                nop

2

00000001  0D9090            or ax,0x9090
00000004  FEC4              inc ah
00000006  90                nop

6

00000000  C4909090          les dx,[bx+si-0x6f70]
00000004  BB0500            mov bx,0x5
00000007  90                nop
00000008  90                nop
00000009  43                inc bx
0000000A  43                inc bx
0000000B  CD10              int 0x10

+11

00000000  050090            add ax,0x9000
00000003  90                nop
00000004  43                inc bx
00000005  43                inc bx
00000006  CD10              int 0x10

+12

00000000  00909043          add [bx+si+0x4390],dl
00000004  43                inc bx
00000005  CD10              int 0x10

+18

00000000  1090B84F          adc [bx+si+0x4fb8],dl
00000004  0D9090            or ax,0x9090
00000007  FEC4              inc ah
00000009  90                nop

(ออฟเซ็ตอื่น ๆ เป็นเพียงการทำซ้ำด้านบน)

58

00000000  10909090          adc [bx+si-0x6f70],dl
00000004  C3                ret

7

คำตอบเดียว:

000000 ... 00000

^ 44391 ศูนย์

โปรแกรมแมว ไม่ว่าคุณจะหมุนอย่างไรมันเป็นโปรแกรมเดียวกัน


6

PHP

ที่นี่คุณไปโปรแกรม PHP ที่ถูกต้อง:

Is this still funny?

2
คุณควรใช้คำเช่น "กิน" (ฉันแน่ใจว่ามีอีกต่อไป) เพื่อให้การเปลี่ยนแปลงตัวละครแต่ละตัวยังคงเป็นคำจริง
ปีเตอร์

10
ฉันไม่แน่ใจว่าจะ +1 สิ่งนี้หรือ -1 สิ่งนี้หรือไม่
Lie Ryan

6

สกาล่า

คำพูดซ้อนกัน:

""""""""""""""""""""""""""""""""

C ++ / Java / C # / Scala

หมายเหตุ:

///////////////////////////////////

คำสั่งว่าง:

;;;;;;;;;;;;;;;

ทุบตี

ความคิดเห็น Whitespace และ Shell builtin รวมกัน:

#

:

sed

คำสั่งที่ถูกต้องแบบสแตนด์อโลน:

p P n N g G d D h H

การรวมกันของข้างต้น:

p;P;n;N;g;G;d;D;h;H;

AWK

หากต้องการพิมพ์ทุกบรรทัดของไฟล์:

1

หรือ

//

อย่าพิมพ์อะไร:

0

Perl

abcd

ดูเหมือนว่าฉันจะ SED จะล้มเหลวในการหมุนแปลก ๆ ? คือ;P;n;N;g;G;d;D;h;Hถูกต้อง?
captncraig

@CMP: ใช่ถูกต้อง
เจ้าชายจอห์นเวสลีย์

5

J

ก่อนอื่นสคริปต์เพื่อตรวจสอบการหมุนที่ถูกต้องของโปรแกรมs:

check =: 3 :'((<;(". :: (''Err''"_)))@:(y |.~]))"0 i.#y'

ตัวอย่างเช่นโปรแกรม+/1 5(ผลรวมของ 1 และ 5) ให้:

 check '+/1 5'
┌───────┬───┐
│┌─────┐│6  │
││+/1 5││   │
│└─────┘│   │
├───────┼───┤
│┌─────┐│Err│
││/1 5+││   │
│└─────┘│   │
├───────┼───┤
│┌─────┐│Err│
││1 5+/││   │
│└─────┘│   │
├───────┼───┤
│┌─────┐│6  │
││ 5+/1││   │
│└─────┘│   │
├───────┼───┤
│┌─────┐│6  │
││5+/1 ││   │
│└─────┘│   │
└───────┴───┘

จากนั้นโปรแกรมที่น่าเบื่อและถูกต้อง:

check '1x1'
┌─────┬───────┐
│┌───┐│2.71828│ NB. e^1
││1x1││       │
│└───┘│       │
├─────┼───────┤
│┌───┐│       │ NB. Value of variable x11
││x11││       │ 
│└───┘│       │
├─────┼───────┤
│┌───┐│11     │ NB. Arbitrary precision integer
││11x││       │
│└───┘│       │
└─────┴───────┘

2

กระแสตรง

โปรแกรม dc นั้นใช้งานได้ง่ายในทุกการหมุน ตัวอย่างเช่น:

4 8 * 2 + p  # 34
8 * 2 + p 4  # stack empty / 10
...

1

รหัสเครื่อง

วิธีการเกี่ยวกับ Z80 / อินเทลรหัส 8051 เครื่องNOP

แน่นอนว่ามันไม่มีการใช้งาน แต่มันใช้เวลาถึงหนึ่งหรือสองรอบ ... คุณสามารถมีได้มากหรือน้อยตามที่คุณต้องการ

และผมก็ไม่เห็นด้วยกับทับทิมคำตอบข้างต้น - ผมคิดว่า 00h byte pเดียวสั้นกว่าทับทิม


1

k

.""

หาค่าสตริงว่าง

"."

ส่งคืนอักขระระยะเวลา

"".

ส่งคืนแอปพลิเคชันบางส่วนของ '.' (ฟอร์ม dyanic) ไปยังรายการอักขระที่ว่างเปล่า


1

SH ทุบตี

cc
cc: no input files

ซีซีหมุนเป็นซีซีอีกครั้ง แต่มันไม่เป็นมิตรมากถ้าเรียกว่าเปลือยกายดังนั้น

dh 
dh: cannot read debian/control: No such file or directory
hd 

dh debhelperก็ไม่ได้ให้ความร่วมมือมากในขณะที่hexdumpก็รอการป้อนข้อมูล

gs
sg 

Ghostscriptเริ่มโหมดโต้ตอบในขณะที่กลุ่มสวิทช์แสดงข้อความการใช้งาน - โซลูชันที่ถูกต้องที่นี่เช่นกัน

และนี่คือสคริปต์เพื่อค้นหาผู้สมัครสำหรับโปรแกรมดังกล่าว:

#!/bin/bash
for name in /sbin/* /usr/sbin/* /bin/* /usr/bin/*
do 
    len=${#name}
    # len=3 => 1:2 0:1, 2:1 0:2
    # len=4 => 1:3 0:1, 2:2 0:2, 3:1 0:3
    for n in $(seq 1 $((len-1)))
    do
        init=${name:n:len-n}
        rest=${name:0:n}
        # echo $init$rest
        which /usr/bin/$init$rest 2>/dev/null >/dev/null && echo $name $init$rest $n
    done 
done

หากพบลำดับที่ยาวกว่าเช่น (arj, jar) หรือ (luatex, texlua) ซึ่งไม่ถูกต้องหลังจากการเปลี่ยนทุกครั้ง แต่หลังจากการเลื่อนบางครั้งซึ่งฉันอ่านผิดในการเริ่มต้น แต่มีน้อยดังนั้นจึงเป็นเรื่องง่าย เพื่อกรองออกด้วยมือ


ตัวอย่างของตัวอักษรมากกว่าสองตัวไม่ถูกต้อง OP กล่าวว่า "โปรแกรมจะต้องถูกต้องหลังจากที่ใด ๆการเลื่อนวน" ดังนั้นarj/ jarไม่ถูกต้องเนื่องจากไม่มีrjaคำสั่ง (แม้ว่าฉันชอบตัวอย่างนี้) +1 สำหรับสคริปต์ - เป็นความคิดที่ดีจริงๆ :)
Cristian Lupascu

ตั้งแต่ผมก็ยังไม่แน่ใจและไม่พูดภาษาอังกฤษผมได้รับการพิจารณาเป็นพจนานุกรมที่ผมพบว่ามันคลุมเครือทั้งค่าเฉลี่ยหรือค่าเฉลี่ยevery a random oneตัวอย่างที่มีshift left by 6, left by 1และright by 10ผมมั่นใจในการตีความว่าผมเพียงแค่ต้องค้นหาความเป็นไปได้กะเดียว
ผู้ใช้ที่ไม่รู้จัก

มันไม่ได้คลุมเครือ ถ้าโปรแกรมต้องถูกต้องหลังจากการเลื่อนแบบสุ่มบางอย่างก็จะต้องถูกต้องสำหรับทุกการกะที่เป็นไปได้
กริฟ

@Griffin: โอเค - คุณเขียนคำถาม ฉันลบตัวอย่างที่ยาวกว่านี้ออกไป โชคดีที่มี crptc abbrv prgnms เพียงพอในยูนิกซ์เช่น gs และ sg :) Btw .: คุณเป็นเจ้าของภาษา Englisch หรือไม่? ในประโยคก่อนหน้านี้คุณเขียน... in any language ... - โซลูชันของฉันใช้งานได้เฉพาะใน bash (และ sh, zsh, ash และอื่น ๆ ) แต่โซลูชันอื่น ๆ ทั้งหมดเหล่านั้นใช้ชื่อโปรแกรมด้วย
ผู้ใช้ที่ไม่รู้จัก

0

ตัวอย่าง Python เล็กน้อย:

"a""b""c""d""e""f""g""h""i""j""k""l""m""n""o""p""q""r""s""t""u""v""w""x""y""z""";print

อาจขยับสามตัวอักษรซ้ำไปซ้ำมาเพื่อแสดงตัวอักษรให้มากขึ้นเรื่อย ๆ


ขออภัยฉันควรทำให้คำถามของฉันชัดเจนขึ้น การเปลี่ยนแปลงใด ๆจะต้องสร้างโปรแกรมที่ถูกต้อง ฉันได้อัปเดตคำถามแล้ว
Griffin


0

dcถูกใช้ไปแล้ว แต่โปรแกรมต่อไปนี้จะแสดงผลลัพธ์เหมือนกันเสมอไม่ว่าจะหมุน: D

d

เพื่อถ่ายทอด

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