รหัส Sierpinskified


47

เขียนบล็อกสี่เหลี่ยมของข้อความที่จัดเรียงไว้ในพรม Sierpinskiโดยใช้ช่องว่างขนาดเดียวกันสำหรับส่วนที่ว่างเปล่าสร้างโปรแกรมที่ส่งออกจำนวนการทำซ้ำของพรม

ตัวอย่างเช่นหากบล็อกข้อความของคุณคือ

TXT
BLK

จากนั้นเรียกใช้โปรแกรม

TXTTXTTXT
BLKBLKBLK
TXT   TXT
BLK   BLK
TXTTXTTXT
BLKBLKBLK

ควรส่งออก1เพราะรูปร่างของโปรแกรมแสดงถึงการวนซ้ำครั้งแรกของพรม Sierpinski

ในทำนองเดียวกันวิ่ง

TXTTXTTXTTXTTXTTXTTXTTXTTXT
BLKBLKBLKBLKBLKBLKBLKBLKBLK
TXT   TXTTXT   TXTTXT   TXT
BLK   BLKBLK   BLKBLK   BLK
TXTTXTTXTTXTTXTTXTTXTTXTTXT
BLKBLKBLKBLKBLKBLKBLKBLKBLK
TXTTXTTXT         TXTTXTTXT
BLKBLKBLK         BLKBLKBLK
TXT   TXT         TXT   TXT
BLK   BLK         BLK   BLK
TXTTXTTXT         TXTTXTTXT
BLKBLKBLK         BLKBLKBLK
TXTTXTTXTTXTTXTTXTTXTTXTTXT
BLKBLKBLKBLKBLKBLKBLKBLKBLK
TXT   TXTTXT   TXTTXT   TXT
BLK   BLKBLK   BLKBLK   BLK
TXTTXTTXTTXTTXTTXTTXTTXTTXT
BLKBLKBLKBLKBLKBLKBLKBLKBLK

ควรเอาท์พุท 2 เพราะนี่คือรูปร่างของการทำซ้ำพรม Sierpinski ที่สอง

เรียกใช้บล็อกข้อความตามที่เป็นอยู่

TXT
BLK

ควรเอาต์พุต0เนื่องจากสามารถพิจารณาการวนซ้ำได้

สิ่งนี้จะทำงานได้สำหรับการทำซ้ำทั้งหมด (อย่างน้อยในทางทฤษฎีสมมติว่าคอมพิวเตอร์มีหน่วยความจำและทั้งหมด)

รายละเอียด

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

คุณสามารถใช้ตัวอย่างสแต็กนี้เพื่อสร้างพรมสำหรับบล็อกข้อความที่กำหนดในการทำซ้ำใด ๆ :

<style>#o,#i{font-family:monospace;}</style><script>function c(e){e=e.split("\n");for(var n=new Array(3*e.length),t=0;t<n.length;t++){var l=t%e.length;n[t]=e[l]+(t>=e.length&&t<2*e.length?e[l].replace(/./g," "):e[l])+e[l]}return n.join("\n")}function f(){for(i=document.getElementById("i").value,n=parseInt(document.getElementById("n").value);n>0;)i=c(i),n--;document.getElementById("o").value=i}</script><textarea id='i'placeholder='code block...'rows='8'cols='32'></textarea><br>Iterations <input id='n'type='text' value='1'><br><br><button type='button'onclick='f()'>Generate</button><br><br><textarea id='o'placeholder='output...'rows='8'cols='32'style='background-color:#eee'readonly></textarea>

เกณฑ์การให้คะแนน

การส่งที่มีบล็อกข้อความเริ่มต้นน้อยที่สุดตามพื้นที่ (ความสูงคูณความกว้าง) เป็นผู้ชนะ TXT\nBLKตัวอย่างคือ 3 โดย 2 คะแนน 6. (โดยทั่วไปที่สั้นที่สุดชนะรหัสจึงแท็กรหัสกอล์ฟ.)

Tiebreaker ไปที่การส่งที่ใช้อักขระที่ต่างกันน้อยที่สุดในบล็อกข้อความ หากยังคงผูกคำตอบที่โพสต์ชนะครั้งแรก

คำตอบ:


23

CJam, 9 ไบต์

ฉันคิดว่าสิ่งนี้สามารถปรับปรุงได้ แต่ตอนนี้ไปกับมัน ...

];U):U8mL

มันทำงานอย่างไร :

];             "Wrap everything on stack in an array and discard it";
               "Before this point, the only thing on array can be the log 8 result of";
               "last updated value of U, or nothing, if its the first code";
  U):U         "Increment by 1 and update the value of U (which is pre initialized to 0)";
      8mL      "Take log base 8 of U. This is the property of Sierpinski carpet that";
               "the occurrence of the code is 8 to the power iteration count, indexed 0";

ลองออนไลน์ได้ที่นี่


35

piet - 32 * 6 = 192

ป้อนคำอธิบายรูปภาพที่นี่

ฉันเติมพื้นที่ว่างด้วยลวดลายตัวตรวจสอบ ฉันคิดว่ามันทำให้ Sierpinski ดูน่าสนใจขึ้นเล็กน้อย

นี่คือการทำซ้ำครั้งที่สอง: ป้อนคำอธิบายรูปภาพที่นี่

ต้นฉบับ: 32 * 7

ป้อนคำอธิบายรูปภาพที่นี่


19

> <> , 11 * 2 = 22

";n"00pbi1v
+$3*:@3-0.>

ที่นี่เราใช้วิธีการที่แตกต่างกันโดยใช้ฟังก์ชันการกระโดด / การเคลื่อนย้ายทางไกล

โปรแกรมเรียกใช้งานบล็อกในแถวบนสุดเท่านั้นเรียกใช้บล็อกที่ 1/2 จากนั้นบล็อกที่ 3/4 บล็อก 9/10 บล็อก 27/28 บล็อก ฯลฯ (ขึ้นไปในอำนาจของ 3) เนื่องจากแถวบนสุดมี3^nบล็อกเฉพาะnบล็อกจะถูกดำเนินการก่อนที่โปรแกรมจะย้อนกลับไปที่จุดเริ่มต้นเอาท์พุทด้านบนของสแต็กและหยุดการทำงาน (เนื่องจากnคำสั่งถูกวางไว้ผ่านp)

โปรแกรมใช้ประโยชน์จากกฎ "ไม่มีอินพุต" เนื่องจากiคำสั่งพุช -1 ลงบนสแต็กหากตรงตาม EOF ดังนั้นเพื่อทดสอบสิ่งนี้คุณจะต้องไพพ์เป็นไฟล์เปล่า


การส่งก่อนหน้า, 7 * 4 = 28

l"v"10p
v>:1=?v
3  ;n{<
<^}+1{,

บรรทัดแรกผลักความยาวของสแต็กอย่างต่อเนื่องสำหรับทุกบล็อกและเปลี่ยนเครื่องหมาย"คำพูดแรกเป็นลูกศรลงvโดยใช้pคำสั่ง put เมื่อถึงเวลาที่บรรทัดแรกสิ้นสุดลงสแต็กจะมีลักษณะเหมือนกัน

[0, 1, 2, .., 3^n]

(โปรดทราบว่าการlใช้ครั้งแรกจะถูกใช้สองครั้ง)

สามบรรทัดสุดท้ายแล้วนับจำนวนครั้งที่เราต้องหารด้วย 3 ก่อนที่เราจะกด 1 (เนื่องจาก> <> ไม่มีฟังก์ชั่นบันทึก) ศูนย์ด้านล่างจะใช้ในการติดตามการนับ


13

Perl, 26

$_+=.91/++$n;
die int."\n";

สิ่งนี้ใช้ชุดฮาร์มอนิกเพื่อประมาณลอการิทึมฐาน 3 ฉันคิดว่ามันใช้งานได้ แต่ฉันได้ลองเพียงเล็กน้อยเท่านั้น ขอขอบคุณที่ ossifrage dieคลื่นไส้สำหรับความคิดของการใช้

รุ่นเก่า (34):

$n--or$n=3**$s++;
print$s-1if!$o++;

นั่นมันเรียบร้อยมาก!
ossifrage คลื่นไส้

10

Perl, 30 (15 × 2)

ครั้งแรกของทั้งหมดที่ฉันจะอ้างว่า 10 ซ้ำเป็นวงเงินที่เหมาะสมไม่ได้ 2 32 หลังจากการวนซ้ำ 10 ครั้งโปรแกรมที่ประกอบด้วยNไบต์จะขยายเป็น ( N × 3 20 ) ไบต์ (บวกตัวแบ่งบรรทัด) ซึ่งมีขนาดมากกว่า 3 กิกะไบต์แม้กระทั่งN = 1 สถาปัตยกรรมแบบ 32 บิตจะไม่สามารถจัดการ 11 ซ้ำได้อย่างสมบูรณ์ (และเห็นได้ชัดว่ามีอนุภาคไม่เพียงพอในจักรวาลสำหรับการวนซ้ำ2 32ครั้ง)

ดังนั้นนี่คือทางออกของฉัน:

$n++; $_=log$n;
print int;exit;

สิ่งนี้ทำงานโดยการเพิ่มตัวแปร$nในบรรทัดแรกและคำนวณลอการิทึมของมันในแต่ละขั้นตอน บรรทัดที่สองพิมพ์ส่วนจำนวนเต็มของลอการิทึมนี้และออก

ลอการิทึมแบบง่ายไปยังฐานe (2.718 .. ) อยู่ใกล้พอที่จะให้ผลลัพธ์ที่ถูกต้องสำหรับการทำซ้ำ 10 ครั้งแรก


2
ตาม OP มันควรจะทำงานในเชิงทฤษฎีสำหรับการทำซ้ำทั้งหมด
Nathan Merrill

2
@NathanMerrill ก็โอเค แต่เพื่อให้สอดคล้องกับสเป็คดั้งเดิมมันจะต้องทำงานในจักรวาลอื่นด้วย คำถามได้รับการแก้ไขตั้งแต่นั้นมา
ossifrage คลื่นไส้

ฉันเปลี่ยนคำถามเพราะจุดดีที่ทำที่นี่ ผมเห็นว่าการใช้บันทึกธรรมชาติคือค่อนข้างพื้นที่สีเทา แต่ตรงไปตรงมาผมไม่ได้กังวลมากเกินไปตั้งแต่นี้จะไม่ชนะ
งานอดิเรกของ Calvin

การส่งเหล่านี้ส่วนใหญ่จะควบคุมเฉพาะในแถวบนสุดของไพ่ 3 ^ nx 1 หากคุณเพิ่งสร้างส่วนของพรมนั้นคุณสามารถเพิ่มขนาดได้อีกเล็กน้อย เกือบจะถึงข้อผิดพลาดในการปัดเศษซึ่งจะทำให้คุณแตกหัก
captncraig

1
ขณะที่ผมกล่าวแล้วคำถามเดิมถามหารหัสที่สามารถปรับขนาดให้เป็นตัวเลขที่ "สมเหตุสมผล" ซ้ำ (ไม่เกิน 2 ^ 32) หากคุณทำคณิตศาสตร์คุณจะพบว่าแม้แต่ไบต์เดียวก็จะขยายเกิน 10 ^ 4098440370 ไบต์หลังจากการทำซ้ำหลายครั้ง ฉันเสนอคำตอบที่ฉันคิดว่ามีเหตุผลมากกว่านี้เล็กน้อยแต่หลังจากนั้นคำว่า "สมเหตุสมผล" ก็หายไปจากคำถาม: - / ดูสิฉันทำไปแล้ว เพียงลงคะแนนคำตอบนี้หากคุณไม่ชอบ
ossifrage คลื่นไส้

9

Golfscript, 9 * 2 = 18

0+       
,3base,(}

(โปรดทราบว่าบรรทัดแรกมีช่องว่างต่อท้ายเพื่อให้เป็นรูปสี่เหลี่ยมผืนผ้า)

ฉันไม่พบฟังก์ชันบันทึกสำหรับ Golfscript ดังนั้นbaseต้องทำ

Golfscript เริ่มต้นด้วยสตริงว่างดังนั้น0+เพียงเพิ่มความยาวของสตริงโดย 1 (โดย coersion) ตามเวลาที่บรรทัดแรกสิ้นสุดลงสแต็กจะมีสตริงที่มีความยาว3^nซึ่งเราจะใช้ log ฐานที่ 3 ก่อนที่เราจะคอมเม้นท์สุด ๆ nจะถูกพิมพ์โดยอัตโนมัติ


คุณสามารถบันทึก 2 ตัวอักษรโดยใช้จำนวนเต็มแทนสตริงและด้วยเหตุนี้การบันทึก,ในบรรทัดที่สอง บรรทัดแรก: 0or); 3base,(}บรรทัดที่สอง เป้าหมายที่ชัดเจนอื่น ๆ คือ(ในบรรทัดที่สอง นี่คือเล่ห์เหลี่ยมมากขึ้น แต่ยังสามารถลบออกได้โดยการแทนที่บรรทัดแรกด้วย1+~abs(สี่เหลี่ยมผืนผ้า 7 * 2
Peter Taylor

8

C, 12x8 = 96

แรงบันดาลใจจาก @ciamej ฉันได้ลดความมันลงไปแล้ว มันใช้การแบ่ง 3 อย่างด้วยกันบวกกับการตระหนักว่าพรมเปลี่ยนจากเดิมเป็นวงในขณะที่

รหัสถูกทดสอบบน gcc / Ubuntu เพื่อทำซ้ำได้สูงสุด 3

#ifndef A //
#define A //
x;main(a){//
a++;/*    */
if(a/=3)x++;
printf(   //
"%d",x);} //
#endif    //

โซลูชันก่อนหน้า: C, 11x12

ไม่ใช่ผู้ชนะขนาด แต่เฮ้มันคือ C

พบ log2 ของ blockcount ด้วยการเปลี่ยนบิตจากนั้นใช้หมายเลขเวทย์มนตร์และการตัดทอน int เพื่อประมาณ log3 คณิตศาสตร์ควรทำงานได้ถึง 26 ซ้ำ (หมายเลข 42 บิต)

#ifndef A//
#define A//
int n=0;//_
int main//_
(v,c){//___
n+=1;/*..*/
while(n//__
>>=1)v++;//
n=.3+.62*v;
printf(//__
"%d",n);}//
#endif//__

สวัสดีฉันได้โพสต์โซลูชันของคุณสั้นลงแล้ว
ciamej

เคล็ดลับที่ดีถ้านั่น! ;)
ciamej

6

CJam, 9 ไบต์

แนวคิดของการใช้]มาจากเครื่องมือเพิ่มประสิทธิภาพ แต่ใช้วิธีที่แตกต่างกันมากในการนับ

X~]:X,8mL

ลองออนไลน์

มันทำงานอย่างไร:

X~          "push X and dump its contents.  On the zeroth iteration, X is a single number, but later is it an array.";
  ]         "wrap everything into an array.  The stack would contain the contents of X plus the result of the previous instance of the code";
   :X       "store this array back into X.  X is now 1 element longer";
     ,      "take the length of X";
      8mL   "do a base-8 logarithm of it";

อีกสองโซลูชั่น 9 ไบต์

]X+:X,8mL

],X+:X8mL

นี่คือความสัมพันธ์ที่แท้จริงของเครื่องมือเพิ่มประสิทธิภาพแม้จะมี tiebreaker : P Tiebreakerbreaker: โพสต์ก่อนหน้านี้ชนะ
งานอดิเรกของ Calvin

ฉันคิดว่ามันเป็นทางออกที่ดีโดยไม่คำนึงถึง ฉันไม่สามารถเอาชนะ 9 ตัวอักษรได้
PhiNotPi

ฉันคิดว่าวิธีการทั่วไปเหมือนกันเท่านั้น (และเป็นวิธีการเดียวที่เหมาะสม) - มีตัวแปรเพิ่มขึ้นทีละ 1 อย่างใด
เครื่องมือเพิ่มประสิทธิภาพ

4

Python 2, 15 * 3 = 45

m=n=0;E=exit  ;
m+=1;n+=m>3**n;
print n;E()   ;

การดำเนินการตามแนวคิดการนับจำนวนหนึ่งแถวจากนั้นเข้าสู่ระบบสามและออก อาจจะยังสามารถตีกอล์ฟได้มากกว่านี้



2

Golfscript, 7 * 2 = 14

1+~abs(
3base,}

นี่คือแรงบันดาลใจจากคำตอบของ Sp3000 และโดยเฉพาะอย่างยิ่งความต้องการเพิ่มประสิทธิภาพบรรทัดที่สองยาว 3base,สั้นเท่ากับลอการิทึมฐาน 3 ที่จะได้รับใน GS และความคิดเห็นที่}ดีที่สุดนั้นชัดเจนที่สุด

สิ่งที่จำเป็นสำหรับบรรทัดแรกคือการจับคู่สตริงว่าง''จาก stdin เริ่มต้นเป็น 0 จากนั้นจึงจับคู่แต่ละจำนวนที่ไม่เป็นลบกับตัวตายตัวแทน ด้วยวิธีนี้เราจะสิ้นสุดบรรทัดแรกด้วย3^n - 1บนสแต็กและ3base,ไม่ต้องการการลดลงใด ๆ



1

Perl, 76

ฉันรู้ว่าอาจมีจุดไม่มากนักในการโพสต์สิ่งนี้เนื่องจากมันถูกตีอย่างละเอียดแล้ว แต่นี่คือโซลูชันปัจจุบันของฉัน

$_++;                                 
if(not$_&$_-1){print log()/log 8;$_--}

@Alex ดูเหมือนจะไม่ทำงานแม้จะมีการทำซ้ำครั้งที่ 1
PhiNotPi

ใช่มันใช้งานได้ดี คุณได้ทดสอบวิธีการของคุณ?
PhiNotPi

เหมืองแร่ทำงานบน ideone: ideone.com/othumP
PhiNotPi

Gotcha ฉันพลาดรายละเอียดที่สำคัญซึ่งทำให้ไม่สามารถทำงานได้ก่อนหน้านี้ คุณถูกต้องข้อเสนอแนะของฉันไม่ถูกต้อง
Alex A.

1

> <> (ปลา), 12 * 3 = 36

วิธีแก้ปัญหาที่ตรงไปตรงมามากกว่า> <>:

'v'00p0l1+  
>  :2-?v$1+v
^$+1$,3< ;n<

ก่อนอื่นเราเรียกใช้แถวบนสุดของบล็อกด้านบน 'v'00pวางvที่ตำแหน่งแรกสุดของโปรแกรมทั้งหมดโดยให้ตัวชี้โปรแกรมชี้ลงเมื่อกลับสู่จุดเริ่มต้นหลังจากถึงจุดสิ้นสุดของบรรทัด ก่อนหน้านั้นทุกบล็อคจะกด 0 และความยาวของสแต็ก + 1 ลงไป (สแต็คจะเป็น0 2 0 4 0 6 ...)

ในครึ่งแรกของสองและสามเรานับจำนวนครั้งที่เราสามารถแบ่งองค์ประกอบสแต็คด้านบนก่อนที่เราจะได้รับ 2 (เราเก็บสิ่งนี้ในองค์ประกอบที่สองถึงด้านบน)

ในตอนท้ายเราจะเอาองค์ประกอบที่สองขึ้นไปบนสุด



1

PHP, 22 × 2 = 44 27 × 2 = 54

<?php $i++          ?>
<?php die(log($i,3))?>

อีกอันใช้เวลาในการนับ log3-out ไม่เล็กมาก แต่เล่นกอล์ฟครั้งแรกของฉัน;)


ใน PCG.SE เหมือนที่อื่นโปรดตรวจสอบเอกสารก่อนโพสต์ :)
Blackhole

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