8 ควรเป็นอนันต์ [ปิด]


19

ลองมาดูในลูปทั่วไปซึ่งโดยปกติจะทำซ้ำ 8:

for (int x=0; x<8; ++x);

คุณต้องทำให้มันไม่มีที่สิ้นสุด!


เป็นการสำหรับทุกภาษาที่สนับสนุนรูปแบบการforวนซ้ำดังกล่าว ดังนั้นการแก้ปัญหาด้วยคะแนนสูงสุด (upvotes ลบด้วย downvotes) ชนะ

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


ทางออกคืออะไร?

โซลูชันประกอบด้วยสองโปรแกรม

โปรแกรมแรกคือการทำความสะอาดโปรแกรม เป็นโปรแกรมทั่วไปในภาษาของคุณด้วยการforวนซ้ำ 8 รอบ ควรเป็นโปรแกรมปกตินักพัฒนาสามารถเขียนได้ ไม่มีแฮ็กพิเศษเพื่อการเตรียมการ ตัวอย่างเช่น:

int main() 
{
  for (int x=0; x<8; ++x);
  return 0;
}

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

inline bool operator < (const int &a, const int &b)
{
  return true;
}

int main() 
{
  for (int x=0; x<8; ++x);
  return 0;
}

นั่นเป็นเพียงตัวอย่าง (ไม่สามารถคอมไพล์ได้ใน C ++) เพื่อแสดงแนวคิด โปรแกรมเสริมที่ถูกต้องจริงจะต้องสามารถคอมไพล์ทำงานและมีลูปไม่สิ้นสุดได้

ทำตามกฎ

ทั้งสองโปรแกรม:

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

โปรแกรมทำความสะอาด:

  • Loop ใช้ตัวนับจำนวนเต็มหรือตัวนับและดำเนินการซ้ำ 8 ครั้ง:

    for (int          x=0; x<8; ++x);   // C, C++, C#
    for (var          x=0; x<8; ++x);   // C#, Javascript
    for (auto         x=0; x<8; ++x);   // C, C++
    for (auto signed  x=0; x<8; ++x);   // C, C++
    for (register int x=0; x<8; ++x);   // C, C++
    
  • ประเภทที่ผู้ใช้กำหนดไม่ได้รับอนุญาต

  • ไม่อนุญาตการใช้คุณสมบัติ (ยกเว้นตัวแปรกลาง) แทนตัวแปรลูป
  • การประกาศตัวแปรสามารถอยู่ภายในหรือภายนอกของลูป รหัสต่อไปนี้ก็โอเค:

    int x;
    for(x=0; x<8; ++x);
    
  • สามารถใช้ส่วนนำหน้าหรือส่วนเพิ่มหลังได้

  • 8ควรเขียนขีด จำกัด ลูปเป็นตัวอักษรคงที่โดยไม่บันทึกค่าคงที่หรือตัวแปรที่มีชื่อ มันถูกสร้างขึ้นเพื่อป้องกันการแก้ปัญหาโดยการประกาศตัวแปรหรือค่าคงที่เท่ากับ 8 จากนั้นทำการกำหนดใหม่แทนที่หรือทำเงาโดยค่าอื่น:

    const double n = 8;
    
    int main()
    {
      const double n = 9007199254740992;
      for (double x=0; x<n; ++x);
      return 0;
    }
    

โปรแกรมเพิ่ม:

  • ต้องมีรหัสทั้งหมดจากรหัสที่สะอาด
  • ควรขยายโปรแกรมที่สะอาดในจำนวนจุดขยายที่ จำกัด
  • ต้องดำเนินการลูปเดียวกัน forกับการวนซ้ำไม่สิ้นสุด
    การวางลูปในโครงสร้างที่ไม่มีที่สิ้นสุดอีกอันหนึ่งก็ไม่เป็นไร
  • รันไทม์หรือการคอมไพล์เวลาของรหัสได้รับอนุญาตตราบใดที่การแสดงต้นฉบับเดิมของมันจะไม่เปลี่ยนแปลง
  • การวางสิ่งปลูกสร้างลงในสายและevalไม่อนุญาตให้ผ่าน

จุดขยาย:

  • ที่ใดก็ได้ภายนอกของแฟรกเมนต์ที่มีโค้ดสะอาดรวมถึงไฟล์อื่นหรือชุดประกอบอื่น ๆ
  • forคำสั่ง (เป็นชิ้นส่วน - forก่อสร้างและร่างกาย) จะต้องไม่เปลี่ยนแปลง
  • การประกาศตัวแปรต้องเก็บไว้เหมือนเดิม
  • สถานที่ระหว่างคำสั่งง่าย ๆ สามารถใช้เป็นจุดส่วนขยาย
  • ถ้าหากว่ามีการประกาศตัวแปรภายนอกลูปและไม่มีการกำหนดค่าทันทีการมอบหมายดังกล่าวสามารถเพิ่มได้
/* extension point here */
int main()
/* extension point here */
{
  /* extension point here */
  int x /* extension point for assignment here */;
  /* extension point here */
  for (x=0; x<8; ++x);
  /* extension point here */
  return 0;
  /* extension point here */
}
/* extension point here */
int main() 
{
  /* BEGIN: No changes allowed */ int x = 0; /* END */
  /* extension point here */
  /* BEGIN: No changes allowed */ for (x=0; x<8; ++x); /* END */
  return 0;
}

PS: หากเป็นไปได้โปรดระบุลิงก์ไปยัง IDE ออนไลน์


2
@Oliver อย่างที่ฉันรู้"คะแนนสูงสุด (upvotes ลบด้วย downvotes)"เป็นค่าเริ่มต้นสำหรับการประกวดความนิยมอย่างน้อยก็เขียนไว้ในคำอธิบายแท็ก: "การประกวดความนิยมคือการแข่งขันที่คำตอบที่มีคะแนนโหวตสูงสุด (upvotes ลบด้วย downvotes) ชนะ " แต่ฉันสามารถเพิ่มลงในคำถามได้อย่างชัดเจน
Qwertiy

1
@ Maltysen มีวิธีแก้ปัญหาที่น่าสนใจมากมายในภาษาเหล่านี้ มี C และ C ++ (พร้อมโซลูชั่นที่แตกต่างกันอย่างสิ้นเชิง), C #, Java, Javascript, php, Perl, Groovy ฉันแน่ใจว่ามีอีกมาก อย่างไรก็ตามฉันเปิดกว้างสำหรับคำถามและที่ระบุไว้ในกฎ หากคุณสามารถทำสิ่งที่น่าสนใจในภาษาอื่น - โพสต์มัน ถ้ามันจะมีการปันส่วนเป็นบวกกฎสามารถขยายได้
Qwertiy

4
การทำเช่นนี้เป็นการประกวดความนิยมเป็นสิ่งที่น่าอึดอัดใจเล็กน้อยเนื่องจากไม่มีคำอธิบายว่าผู้ลงคะแนนเสียงควรเลือกเกณฑ์อะไรเมื่อลงคะแนน ฉันทำงานเกี่ยวกับวิธีการแก้ปัญหารหัสกอล์ฟบนพื้นฐานที่หลายคนที่นี่หาวิธีแก้ไขปัญหากอล์ฟที่น่าสนใจและดังนั้นจึงอาจเป็นที่นิยม ดูเหมือนว่ามันอาจเป็นเงื่อนไขแห่งชัยชนะที่ใช้การได้สำหรับความท้าทาย

2
1. "ตัวนับจำนวนเต็มหรือตัวนับ " ค่อนข้างคลุมเครือเกินไป เช่นมันรวมjava.lang.Integer? 2. สิ่งนี้จะดีกว่าด้วยเกณฑ์การชนะที่เหมาะสม
Peter Taylor

1
1. ใช่มันเป็นเช่นนั้น 2. creteria ชนะรางวัลอะไรกันแน่? PS: เราสามารถทำเมตาต่อไปได้
Qwertiy

คำตอบ:


33

Python3

ทำความสะอาดโปรแกรม:

นี่เป็นเพียงการนับถอยหลังมาตรฐานขณะวนรอบ

n = 8
while n != 0:
  n -= 1
print("done")

โปรแกรมเพิ่ม:

import ctypes

ctypes.cast(id(8), ctypes.POINTER(ctypes.c_int))[6] = 9

n = 8
while n != 0:
  n -= 1
print("done")

มันใช้แคช int ที่จะกำหนด8เป็น9อย่างมีประสิทธิภาพซึ่งทำให้n -= 1ไม่มีสหกรณ์ตั้งแต่9-1 = 8ที่เพิ่งชุดnกลับไป9อีกครั้งก่อให้เกิดห่วงอนันต์

ท่านสามารถเข้าดูแคช int ในการดำเนินการออนไลน์ที่นี่ ( แต่เห็นได้ชัดโดยไม่ต้องห่วงอนันต์ cuz ออนไลน์)


คุณช่วยระบุลิงก์ไปยัง onlinde IDE ได้ไหม ideone.com/aI3ZrI - ดูเหมือนจะไม่ทำงานที่นั่น
Qwertiy

@Qertert ฉันลองใช้มันใน repl.it แต่มันก็ค้างซึ่งคาดว่าจะเป็นเพราะมันจะเป็นวงที่ไม่มีที่สิ้นสุด ฉันรู้ว่าสิ่งที่แคช int ทำงานอยู่ที่นั่นเพราะนั่นคือสิ่งที่ผมทดลองกับวิธีการตั้งค่า8เพื่อ9
Maltysen

ใช้งานได้จริง แปลกที่ไม่มีเวลา จำกัด เช่นเดียวกับ ideone (5 วินาที) พวกเขาแสดงPython 3.5.2 (default, Dec 2015, 13:05:11) [GCC 4.8.2] on linux
Qwertiy

ลิงค์ @Qwertiy โดยไม่ต้องวนซ้ำ: repl.it/E4fx/0
Maltysen

นั่นเป็นเรื่องที่น่าสนใจ ...
Qwertiy

22

Python 3

ทำความสะอาดโปรแกรม:

วิธีมาตรฐานในการทำสิ่ง 8 ครั้งในไพ ธ อนคือ

for i in range(8): 
    # Do something
    pass

โปรแกรมเพิ่ม:

อย่างไรก็ตามถ้าเราแทนที่ฟังก์ชันตัวสร้างช่วงเพื่อให้ได้ผลลัพธ์ที่ไม่มีที่สิ้นสุด 1 มันจะกลายเป็นวงวนไม่สิ้นสุด ...

def range(x):
    while 1: yield 1

for i in range(8):
    # Infinite loop
    pass

เราสามารถทำสิ่งนี้ต่อไปและสร้างฟังก์ชั่นเครื่องกำเนิดไฟฟ้าซึ่งแทนที่จะให้ผลอนันต์ 1 นับได้ตลอดไป:

def range(x):
    i = 0
    while 1: yield i; i+=1

for i in range(8):
    # Counting from 0 to infinity
    pass

ทดสอบ repl.it


2
ซ่อนไว้ในช่วงกลางของโมดูลขนาดใหญ่ ...
Benjamin

21

Perl

สะอาด

for($i=0; $i<8; $i++) { }

Augmented

*i=*|;
for($i=0; $i<8; $i++) { }

ไอดีโอ


16
โอ้ช่างฉลาดจริงๆ สำหรับผู้ที่ไม่รู้จัก Perl: นี่คือนามแฝงที่$iจะกลายเป็นนามแฝงสำหรับตัวแปรพิเศษที่มีความสามารถในการถือบูลีนเท่านั้นดังนั้นเมื่อมันมาถึง 1 มันจะกลายเป็นภูมิคุ้มกันที่เพิ่มขึ้น

10

ES5 + (Javascript)

แก้ไข : ลบการประกาศตัวแปรที่ชัดเจนเช่นมิฉะนั้นจะถูกยกขึ้นและคุณสมบัติwindow.x ที่ไม่สามารถกำหนดค่าได้ถูกสร้างขึ้น (เว้นแต่จะรันทีละบรรทัดในคอนโซล REPL)

คำอธิบาย:

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

สะอาด

for(x=0; x<8; x+=1) console.log(x);

Augmented

Object.defineProperty(window,'x',{value:1});
for(x=0; x<8; x+=1) console.log(x);

หมายเหตุ : ในการทำให้งานนี้เป็น Node.js เพียงแทนที่"window"ด้วย"global" (ทดสอบใน Node.js 6.8.0)


1
อย่างไรก็ตามมันคือ ES5 ใช่ไหม
Qwertiy

นอกจากนี้ยังไม่สามารถใช้งานได้varใน Crome แต่คุณสามารถลบได้varจากทั้งสองโปรแกรม - มันจะไม่เป็นไร
Qwertiy

@Qwertiy สิ่งนี้ใช้ได้กับ "var" ใน Chrome สำหรับฉัน (Linux / รุ่น 52.0.2743.82 (64- บิต))
zeppelin

> ยังไงก็คือ ES5 ใช่ไหม? จริงจะแก้ไขชื่อทันที
zeppelin

1
ปัญหาคือvarรอกดังนั้นในขณะที่ใช้งานdefinePropertyมันก็ออกจากระบบไปแล้ว แต่ถ้าคุณวาง 2 บรรทัดเหล่านี้ในสคริปต์ที่แตกต่างกัน (โดยวิธีการที่ได้รับอนุญาต) มันจะทำงานได้เนื่องจากคุณสมบัติจะถูกสร้างขึ้นก่อนและvarจากนั้นจะถูกละเว้น หลักฐาน: i.stack.imgur.com/lSwbE.png
Qwertiy

10

ทำความสะอาดโปรแกรม

int main() 
{
  for (int x=0; x<8; ++x);
  return 0;
}

โปรแกรมเติมเต็ม

#define for(ever) while(1)

int main() 
{
  for (int x=0; x<8; ++x);
  return 0;
}

Must execute same for loop as an infinite loop itself. Placing of the loop into another infinite construction is not ok.
Karl Napf

3
@KarlNapf ลูป "for" ไม่ได้อยู่ในโครงสร้างแบบไม่มีที่สิ้นสุดอื่น
coredump

3
@KarlNapf ฉันคิดว่าคำตอบนี้ได้รับอนุญาตอย่างชัดเจนจากกฎ: •รันไทม์หรือการคอมไพล์เวลาของรหัสได้รับอนุญาตตราบใดที่การแสดงข้อความของมันไม่เปลี่ยนแปลง
โอมาร์

มันเป็นถ้อยคำ "ต้องดำเนินการเหมือนกันสำหรับวง" แต่ใช่นี้ขัดแย้งกับการเป็นตัวแทนข้อความ
Karl Napf

7

ชวา

โปรแกรมทำความสะอาด:

public class Main {
    public static void main(String[] args) throws Exception {
        for (Integer i = 0; i < 8; i++);
    }
}

โปรแกรมเพิ่ม:

import java.lang.reflect.Field;

public class Main {
    public static void main(String[] args) throws Exception {
        Class cache = Integer.class.getDeclaredClasses()[0];
        Field c = cache.getDeclaredField("cache");
        c.setAccessible(true);
        Integer[] intcache = (Integer[]) c.get(cache);
        intcache[129] = intcache[128];

        for (Integer i = 0; i < 8; i++);
    }
}

ตั้งค่าจำนวนเต็มในแคชจำนวนเต็มที่ควรมี 1 ถึง 0 โดยi++ไม่ต้องทำอะไรเลย (ตั้งiเป็นจำนวนเต็มในแคชที่ควรมี 1 แต่เนื่องจากจำนวนเต็มนั้นมี 0 จริงจึงไม่มีการเปลี่ยนแปลงใด ๆ )


เอาชนะฉันไปได้โซลูชันนี้เหมือนกันกับฉัน
Hypino

6
นี้ไม่ได้จริงๆ Java สำนวนสำหรับวงซึ่งอาจจะใช้ไม่มีกล่องมากกว่าที่ค่อนข้างหนาint Integer

7

C ++

int main() 
{
#define int bool
  for (int x=0; x<8; ++x);
  return 0;
}

boolเท่านั้นที่สามารถจะเป็น 0 หรือ 1 แรงบันดาลใจจากพรีโม่ของคำตอบ Perl


6

Python 3 (3.5.0)

ทำความสะอาดโปรแกรม:

for i in range(8):
    print(i)

Augmented

import sys

from ctypes import *

code = sys._getframe().f_code.co_code

cast(sys._getframe().f_code.co_code, POINTER(c_char*len(code))).contents[len(code)-4] = 113
cast(sys._getframe().f_code.co_code, POINTER(c_char*len(code))).contents[len(code)-3] = 160

for i in range(8):
    print(i)

วิธีนี้แตกต่างจากวิธีอื่นที่เขียนไว้ใน Python ซึ่งจริงๆแล้วมันเป็นการเปลี่ยนแปลงซอร์สโค้ดทันที ทุกสิ่งในการวนรอบสามารถเปลี่ยนเป็นสิ่งที่ต้องการรหัส

รหัสการเปลี่ยนแปลงที่สองเพื่อ opcode สุดท้ายที่จะเป็น113หรือมากกว่า readably JUMP_ABSOLUTE- มันจะเปลี่ยนตัวถูกดำเนินการเป็น160- คำสั่งที่เริ่มห่วงสำหรับผลการสร้างคำสั่ง GOTO ในตอนท้ายของโปรแกรม

โปรแกรมเติมพิมพ์ตัวเลขจำนวน0..7อนันต์หลายครั้งโดยไม่มีการสแต็คล้นหรือคล้ายกัน


6

PHP

ฉันคิดว่านี่เป็นไปตามกฎของจุดส่วนขยาย ฉันไม่ชัดเจนเลยในประเด็นที่ 4 มันคล้ายกับคำตอบของ perl ของ @ primo ดังนั้นฉันคิดว่ามันน่าจะนับ

สะอาด

for(;$i<8;$i++);

Augmented

$i='a';
for(;$i<8;$i++);

PHP ช่วยให้คุณเพิ่มสตริงบางอย่างเช่น:

'a' -> 'b'
'b' -> 'c'
'z' -> 'aa'
'aa' -> 'ab'
'aab' -> 'aac'
etc

สตริงทั้งหมดเหล่านี้ประเมินเป็น 0 ดังนั้นสิ่งนี้จะวนซ้ำตลอดไป (ยกเว้นหน่วยความจำหมด)


นั่นคือในจิตวิญญาณของการแข่งขันและน่าสนใจมาก จริงๆแล้วมันไม่ได้พูดอะไรเกี่ยวกับ ommiting initialmnetmnet ดังนั้นจึงเป็นกรณีที่ขอบ ที่จริงแล้วคาดว่าจะไม่มีจุดส่วนขยายระหว่างการกำหนด 0 และการวนซ้ำ แต่ตอนนี้ฉันจะไม่ขออนุญาตเนื่องจากฉันเห็นบางกรณีที่มีขอบแบบ interesing บนพื้นฐานของสิ่งนั้นและมันไม่ง่ายเกินไป
Qwertiy

2
@Qwertiy "นั่นคือกรณีที่ขอบ" PHP สั้น ๆ :)
ToXik-yogHurt

6

Perl

รหัสสะอาด

for ($x = 0; $x < 8; $x++) {}

รหัสเติม

sub TIESCALAR {bless []}
sub FETCH {}
sub STORE {}
tie $x, "";

for ($x = 0; $x < 8; $x++) {}

ตัวแปร Perl ส่วนใหญ่เป็นเพียงตัวแปร อย่างไรก็ตามภาษานี้ยังมีtieคุณสมบัติที่ช่วยให้คุณสามารถกำหนดตัวกระจายสัญญาณและตัวตั้งค่าได้อย่างมีประสิทธิภาพ ในโปรแกรมนี้ฉันสร้างแพ็กเกจหลัก (ซึ่งมีชื่อเป็นสตริงว่าง) ลงในคลาสที่เทียบเท่าจากภาษาเชิงวัตถุในขณะที่มันเป็นโปรแกรม ที่ช่วยให้ฉันสามารถผูกforวนเคาน์เตอร์กับโปรแกรมของตัวเอง การดำเนินการTIESCALARช่วยให้tieประสบความสำเร็จ; ค่าส่งคืนของTIESCALARมีไว้เพื่ออ้างอิงถึงสถานะภายในใด ๆ ที่เราต้องการเก็บไว้รอบ ๆ ที่เกี่ยวข้องกับตัวแปร แต่เนื่องจากเราไม่ต้องการใด ๆ เราจึงกลับมาอ้างอิงอาร์เรย์ที่ว่างเปล่าเป็นตัวยึด จากนั้นเราจะให้การใช้งานที่ง่ายที่สุดที่เป็นไปได้ของ getter และ setter ทั้งคู่ไม่ได้ทำอะไรดังนั้นจึงพยายามมอบหมายให้$xไม่มีผลใด ๆ และพยายามที่จะอ่านมันจะกลับมาเสมอundefซึ่งเป็นตัวเลขน้อยกว่า 8


5

WinDbg

สะอาด

.for (r$t0 = 0; @$t0 < 8; r$t0 = @$t0 + 1) { }

Augmented

aS < |;                                            * Create alias of < as |
.block {                                           * Explicit block so aliases are expanded
    .for (r$t0 = 0; @$t0 < 8; r$t0 = @$t0 + 1) { } * Condition is now @$t0 | 8, always true
}

วิธีการนี้จะสร้างนามแฝงเพื่อ<เป็น|ดังนั้นเมื่อ<พบในรหัสนามแฝงจะถูกขยายไป|และบิต - หรือจะทำแทนการน้อยกว่า ใน WinDbg ค่าที่ไม่เป็นศูนย์ทั้งหมดanything | 8เป็นความจริงดังนั้นจึงเป็นจริงเสมอ

หมายเหตุ: .blockไม่จำเป็นต้องใช้จริงถ้าหากaSและ.forถูกป้อนเป็นสองบรรทัดที่แตกต่างกันตามที่แสดงที่นี่จะต้องใช้เมื่อaSและ.forอยู่ในบรรทัดเดียวกันเท่านั้น



5

เสียงกระเพื่อมสามัญ

รหัสสะอาด

(dotimes(i 8))

Augmented

(shadowing-import(defmacro :dotimes(&rest args)'(loop)))
(dotimes(i 8))

แมโครชื่อkeyword:dotimesaka :dotimes(ดู11.1.2.3 แพ็คเกจ KEYWORD ) ถูกกำหนดซึ่งขยายเป็นวงวนไม่สิ้นสุด ผลตอบแทนแมโครชื่อของแมโครที่ถูกกำหนดไว้ซึ่งสามารถนำไปใช้เลี้ยงdefmacro shadowing-importดังนั้นdotimesสัญลักษณ์ใหม่นี้จะทำให้เกิดเงาหนึ่งมาตรฐาน (ซึ่งไม่ควรนิยามใหม่หรือผูกพันกับแมโครอื่นในโปรแกรมแบบพกพา)

เติม (2)

(set-macro-character #\8 (lambda (&rest args) '(loop)))
(dotimes(i 8))

เมื่อเราอ่านตัวอักษรที่ 8 (loop)เราแทนที่มันด้วย นั่นหมายความว่าข้างต้นอ่านเป็น(dotimes (i (loop)))และเพื่อให้รหัสไม่เคยยุติการคำนวณขอบเขตบน สิ่งนี้มีผลต่อการเกิดขึ้นทั้งหมดของ 8 ไม่เพียง แต่เกิดขึ้นในลูป ในคำอื่น ๆ 8 หมายถึงอินฟินิตี้จริงๆ หากคุณอยากรู้อยากเห็นเมื่อมีการปรับเปลี่ยนการอ่านเช่นข้างต้นแล้วตัวละคร 8 กลายเป็น "ยุติ" และแยกตัวเองจากตัวเลข / สัญลักษณ์อื่น ๆ ที่กำลังอ่าน:

(list 6789)

... อ่านเป็น:

(list 67 (loop) 9)

คุณสามารถเรียกใช้การทดสอบบน Ideone: https://ideone.com/sR3AiU


4

ทับทิม

สะอาด

สำหรับลูปแบบนี้ไม่ค่อยได้ใช้ใน Ruby แต่บทแนะนำทั่วไปจะบอกคุณว่านี่เป็นวิธีที่จะทำ:

for x in 1..8
  # Some code here
end

Augmented

การวนรอบเพียงแค่เรียกใช้(1..8).eachกับบล็อกของรหัสที่กำหนดดังนั้นเราจึงเปลี่ยนวิธีการ:

class Range
  def each
    i = first
    loop { yield i; i+= 1 }
  end
end

for x in 1..8
  # Some code here
end

4

Haskell

เวอร์ชั่นสะอาด:

import Control.Monad (forM_)

main = forM_ [0..8] $ \i -> print i

รุ่นเติม:

import Control.Monad (forM_)

data T = C

instance Num T where
    fromInteger _ = C

instance Enum T where
    enumFromTo _ _ = repeat C

instance Show T where
    show _ = "0"

default (T)

main = forM_ [0..8] $ \i -> print i

มันค่อนข้างพื้นฐานจริงๆ: เราเพียงแค่กำหนดประเภทของเราเองTเช่นว่าenumFromToอินสแตนซ์เป็นลำดับอนันต์แล้วใช้ประเภทผิดนัดเพื่อให้ค่ายกเลิกประเภทข้อเขียน0และถูกนำมาเป็นประเภท8T


1
แนวคิดที่ดีในการเปลี่ยนประเภทเริ่มต้นสำหรับตัวอักษรตัวเลขที่มากเกินไปของ Haskell
nimi

3

///

ไม่มีความชัดเจน forลูปที่ใน /// แต่สามารถจำลองได้ (เป็นการทำให้สมบูรณ์หลังจากทั้งหมด)

สะอาด

/1/0/
/2/1/
/3/2/
/4/3/
/5/4/
/6/5/
/7/6/
/8/7/
8

Augmented:

/0/0/
/1/0/
/2/1/
/3/2/
/4/3/
/5/4/
/6/5/
/7/6/
/8/7/
8

เกิดอะไรขึ้น?

ในขณะที่โปรแกรมอดีตนับลง 8-0, หนึ่งหลัง/0/0/กฎจะเข้ามาแทนที่0โดย0จนนิรันดร์


และฉันคิดว่าคุณจะทำสิ่งที่ต้องการ/0/1//1/2/.../7/8//8/8/8นับขึ้นจริง ๆ
Erik the Outgolfer

3

Javascript ES6

ตกลงนี่เป็นรุ่นที่ใช้งานได้กับ ES6 for ... ของการสร้างลูป ฉันจะให้อาเรย์สะอาดกับคุณเพื่อให้เรามั่นใจว่าไม่มีเรื่องตลก:

สะอาด

for(a of [0,1,2,3,4,5,6,7]);

แน่นอนว่านั่นไม่ได้หยุดใครบางคนจากการยุ่งกับต้นแบบ Array ...

Augmented

Array.prototype[Symbol.iterator]=function(){return {next: function(){return {done: false}}}}
for(a of [0,1,2,3,4,5,6,7]);

การทำงานนี้โดยการเขียนตัววนซ้ำเริ่มต้นมากเกินไปเพื่อไม่ให้ยุติดังนั้นจึงล็อคทุกอย่างไว้ในวงวนไม่สิ้นสุด รหัสไม่ได้มีโอกาสเรียกใช้เนื้อหาภายในลูป


"พฤติกรรมการวนซ้ำควรเหมือนกันในกรณีของการวนซ้ำที่ว่างเปล่า"
Qwertiy

ด่านพลาดนั่น - ฉันจะต้องคิดอะไรออก
Marcus Dirr

เท่าที่ฉันสามารถบอกได้มันเป็นไปไม่ได้ที่จะทำในสิ่งที่ท้าทายกับ C-style สำหรับการวนซ้ำใน Javascript เว้นแต่คุณจะทำผิดกฎ - โดยมีบางอย่างอยู่ข้างใน (เช่นวิธีการแก้ปัญหาของฉัน) ประกาศในรหัสสะอาดของคุณ (เช่นเดียวกับของ Cedric Reichenbach)
Marcus Dirr

จริงๆแล้วมีบางวิธี วิธีที่มีการประกาศตัวแปรทั่วโลกได้ถูกโพสต์ไปแล้ว แต่ก็ยังมีอีกจำนวนหนึ่งที่อนุญาตให้varวนซ้ำ
Qwertiy

อย่างที่ฉันพูดเท่าที่ฉันสามารถบอกได้ ฉันเห็นวิธีทั่วโลกหลังจากที่แสดงความคิดเห็นและเตะตัวเอง
Marcus Dirr

2

C ++

ใช้ 2 จุดขยาย:

struct True {
  True(int x){}
  bool operator<(const int&){
    return true;
  }
  void operator++(){}
};


int main() 
{
#define int True
  for (int x=0; x<8; ++x);
  return 0;
}

โปรแกรม Clean เหมือนในคำอธิบาย


ดี แต่สามารถ "ปรับให้เหมาะสม" :) มีบิลด์อินที่น่าสนใจใน C ++ เพื่อให้ได้คำตอบอื่น
Qwertiy

2

brainfuck

ฉันพิมพ์ '0' ทุกการวนซ้ำเพื่อให้ง่ายต่อการนับการวนซ้ำ แต่สามารถใส่รหัสใด ๆ ได้โดยไม่ต้องเปลี่ยนวิธีการวนซ้ำ

สะอาด

>> ++++++ [-<++++++++>] <<                   b = '0' (value to be printed each iteration)

>> ++++++++ [-<< ++++++++ ++++++++ >>] <<    for (a = a plus 128;
[                                              a;
++++++++ ++++++++                              a = a plus 16 (mod 256)) {
>.<                                              loop body (print b)
]                                            }

ลองออนไลน์

เวอร์ชั่นเสริมนั้นขึ้นอยู่กับการนำ Brainfuck มาใช้กับเซลล์ 8 บิต ในการใช้งานเหล่านี้ "การเพิ่ม" เป็นจริง "การเพิ่ม (mod 256)" ดังนั้นในการค้นหาลูปที่จะวนซ้ำ 8 ครั้งในเวอร์ชั่นคลีนด์และในเวอร์ชั่นที่เพิ่มขึ้นอย่างไม่มีที่สิ้นสุดเราก็สามารถหาวิธีแก้ปัญหาสำหรับระบบความไม่เท่าเทียมกันดังต่อไปนี้

  • a + b * 8 (mod 256) == 0 (สำหรับเวอร์ชั่นใหม่ทั้งหมด)
  • c + a + b * n (mod 256)> 0 สำหรับทุก n (สำหรับเวอร์ชั่นเพิ่มเติม)
  • a> 0

ในกรณีนี้เราปล่อย a = 128, b = 16, และ c = 1 เห็นได้ชัดว่า 128 +16 * 8 = 256 (และ 256 (mod 256) = 0) และ 128> 0 และเนื่องจาก b เท่ากับ, c + a + b * n นั้นแปลกสำหรับ a + c ใด ๆ และดังนั้นจะไม่เป็นผลคูณของ 256 ในกรณีเช่นนี้ เราเลือก c = 1 เพื่อเห็นแก่ความเรียบง่าย ดังนั้นการเปลี่ยนแปลงเพียงอย่างเดียวที่เราต้องการคือ+จุดเริ่มต้นของโปรแกรม

Augmented

+                                            increment a (only change)
>> ++++++ [-<++++++++>] <<                   b = '0' (value to be printed each iteration)

>> ++++++++ [-<< ++++++++ ++++++++ >>] <<    for (a = a plus 128;
[                                              a;
++++++++ ++++++++                              a = a plus 16 (mod 256)) {
>.<                                              loop body (print b)
]                                            }

ลองออนไลน์

ฉันปล่อยไว้ที่ OP เพื่อพิจารณาว่ารายการนี้แข่งขันหรือไม่ Brainfuck ไม่มีความชัดเจนสำหรับลูป แต่รูปแบบลูปที่ฉันใช้นั้นใกล้เคียงที่สุดเท่าที่คุณจะได้รับ ++++++++ก็ใกล้เคียงกับตัวอักษร8ที่สุด ฉันได้รวมไว้ไม่กี่อย่าง

เวอร์ชันที่สะอาดเกือบจะถือว่าเป็นโปรแกรมทั่วไปที่เขียนด้วยภาษานี้แม้กระทั่งBrainfuck Hello World ที่รู้จักกันสั้นที่สุดก็ขึ้นอยู่กับความสัมพันธ์ที่เกิดซ้ำแบบแยกส่วนในการทำงาน


2

Haskell

สะอาด

import Control.Monad (forM_)

main = forM_ [0..8] $ \i -> print i

Augmented

import Control.Monad (forM_)

import Prelude hiding (($))
import Control.Monad (when)

f $ x = f (\i -> x i >> when (i == 8) (f $ x))

main = forM_ [0..8] $ \i -> print i

แทนที่ตัวดำเนินการแอปพลิเคชันฟังก์ชั่นปกติ$ด้วยอันที่วนซ้ำอีกครั้งทุกครั้งที่เสร็จสิ้น การรันเวอร์ชั่นคลีนจะพิมพ์ 0 ถึง 8 แล้วหยุด; รุ่นที่เติมจะพิมพ์ 0 ถึง 8 แล้ว 0 ถึง 8 อีกครั้งและอื่น ๆ

ฉันโกงนิดหน่อยซึ่งนั่นforM_ [0..8] $ \i -> print iไม่จำเป็นต้องเป็นวิธีที่ "สะอาด" ในการเขียนลูปใน Haskell Haskellers หลายคนจะกทพ. ลดห่วงร่างกายเพื่อรับforM_ [0..8] printแล้วไม่มี$การแทนที่ ในการป้องกันของฉันฉันคัดลอกโค้ดสะอาดจากคำตอบของ Cactusซึ่งไม่ต้องการคุณสมบัตินั้นดังนั้นโปรแกรมเมอร์ Haskell อย่างน้อยหนึ่งคนจึงเขียนโค้ดนั้นโดยไม่มีแรงจูงใจในการเพิ่ม$!


1

C ++

int main() 
{
  int y;
#define int
#define x (y=7)
  for (int x=0; x<8; ++x);
  return 0;
}

ให้xประเมินเป็น 7 ไม่ทำงานใน C เนื่องจากต้องการค่า lvalue เมื่อการมอบหมายและการเพิ่มขึ้น


1

สะเดา

เวอร์ชั่นสำนวนโดยใช้countup:

สะอาด

for i in countup(1, 8):
  # counting from 1 to 8, inclusive
  discard

Augmented

iterator countup(a: int, b: int): int =
  while true:
    yield 8

for i in countup(1, 8):
  # counting 8s forever
  discard

ที่เรียบง่ายและคล้ายกับคำตอบที่งูหลามซึ่งนิยามใหม่ rangeเรากำหนดcountupวิธีที่เป็นสำนวนนิพจน์ของการวนซ้ำจาก int หนึ่ง (รวม) ไปที่อื่นเพื่อให้ 8s อนันต์

รุ่นที่น่าสนใจยิ่งขึ้นโดยใช้ตัวดำเนินการช่วง..:

สะอาด

for i in 1..8:
  # counting from 1 to 8, inclusive
  discard

Augmented

iterator `..`(a: int, b: int): int =
  while true:
    yield 8

for i in 1..8:
  # counting 8s forever
  discard

คล้ายกับโซลูชันก่อนหน้านี้ยกเว้นเราจะกำหนดตัวดำเนินการช่วง..ใหม่ซึ่งโดยปกติจะให้อาร์เรย์[1, 2, 3, 4, 5, 6, 7, 8]แก่ตัวทำซ้ำก่อนหน้านี้


1

GolfScript

สะอาด

0{.8<}{)}while;

Augmented

{.)}:8;
0{.8<}{)}while;

มันกำหนดฟังก์ชั่นกลับ n + 1 ให้กับตัวแปร 8


1

TCL

ปกติ:

for {set i 0} {$i<8} {incr i} {}

Augmented:

proc incr x {}
for {set i 0} {$i<8} {incr i} {}

ความคิดคือการกำหนดใหม่ incrคำสั่งที่ใช้เพื่อเพิ่มตัวแปรiใหม่เพื่อไม่เพิ่มขึ้นจริง ๆ !

สามารถทดสอบได้ที่: http://rextester.com/live/QSKZPQ49822


1

x86_64 ชุดประกอบ

โปรแกรมทำความสะอาด:

mov rcx, 8
loop_start:
sub rcx, 1
cmp rcx,0
jne loop_start
mov rax, 0x01
mov rdi, 0
syscall

การเรียงลำดับของลูปโปรแกรมเมอร์แอสเซมบลีใด ๆ จะใช้ตามด้วย exit syscall เพื่อไม่ให้เปิดใช้งานการเพิ่ม jmp loop_startคำสั่งในภายหลัง

โปรแกรมเพิ่ม:

global start
section .text
start:
mov rcx, -1
jmp loop_start
mov rcx, 8
loop_start:
sub rcx, 1
cmp rcx,0
jne loop_start
mov rax, 0x01
mov rdi, 0
syscall

นอกจากนี้ขออภัยถ้ามันไม่ดีที่โปรแกรมสะอาดไม่มีจุดเข้าใช้งานหรือ section .text


มันจะไม่หยุดหลังจากล้นจำนวนเต็มหรือไม่
Qwertiy

1
โอ้เอ่อ ... อาจจะ แต่มันจะใช้เวลานานไหม? ฉันลืมไปแล้วว่าอาจเกิดขึ้นได้ส่วนใหญ่เป็นโปรแกรมเมอร์ระดับสูงภาษา
goose121

0

JavaScript

สะอาด

for (var i = 0; !(i > Math.PI * 2.5); i++);

Augmented:

window.Math = {PI: NaN};
for (var i = 0; !(i > Math.PI * 2.5); i++);

ดูเหมือนจะไม่ใช่วงวนทั่วไป ...
Qwertiy

ใช่ฉันค่อนข้างจะยืดคำศัพท์ทั่วไป ... : /
Cedric Reichenbach

0

C ++

ทำความสะอาดโปรแกรม

การวนซ้ำที่ดีปกติวนซ้ำจากตัวเลข 0 ถึง 7

#include <iostream>

int main() {

  for (short i = 0; i < 8; i++) {
    // Print `i` with a newline.
    std::cout << i << std::endl;
  }    

}

โปรแกรมเพิ่ม

ตัวประมวลผลล่วงหน้าของ C ++ ค่อนข้างเป็นคุณลักษณะที่อันตราย ...

#include <iostream>
#define short bool

int main() {

  for (short i = 0; i < 8; i++) {
    // Print `i` with a newline.
    std::cout << i << std::endl;
  }    

}

#define short boolบรรทัดเดียวที่เรามีการเพิ่มเป็น สิ่งนี้ทำให้iบูลีนแทนที่จะเป็นจำนวนเต็มแบบสั้นดังนั้นตัวดำเนินการส่วนเพิ่ม ( i++) จะไม่ทำอะไรเลยหลังจากiถึง 1 แล้วผลลัพธ์จะมีลักษณะดังนี้:

0
1
1
1
1
1
...

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