8 phải trở thành Vô cực [đóng]


19

Chúng ta hãy xem một vòng lặp điển hình, thường thực hiện 8 lần lặp:

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

Bạn phải làm cho nó vô hạn!


Đây là một cho tất cả các ngôn ngữ hỗ trợ hình thức forvòng lặp như vậy . Vì vậy, giải pháp với số điểm cao nhất (upvotes trừ downvotes) sẽ thắng.

Nếu ngôn ngữ của bạn có dạng forvòng lặp khác, nhưng bạn chắc chắn, bạn có thể làm cho một cái gì đó tuyệt vời với nó, hãy đăng câu trả lời và đánh dấu nó là không thể lọc. Tôi bảo lưu quyền mở rộng phạm vi của các cấu trúc và ngôn ngữ có sẵn, nhưng nó sẽ không bao giờ bị thu hẹp, vì vậy đừng sợ bỏ các giải pháp đúng trước đây.


Giải pháp là gì?

Giải pháp bao gồm hai chương trình.

Chương trình đầu tiên là một chương trình sạch sẽ . Đây là chương trình điển hình trong ngôn ngữ của bạn với forvòng lặp thực hiện 8 lần lặp. Nó phải là chương trình bình thường, bất kỳ nhà phát triển nào cũng có thể viết. Không có bất kỳ hack đặc biệt cho mục đích chuẩn bị. Ví dụ:

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

Chương trình thứ hai được tăng cường. Chương trình này nên chứa tất cả các mã từ chương trình sạch và một số mã bổ sung. Có số lượng điểm mở rộng hạn chế , xem phần quy tắc hoàn chỉnh để biết chi tiết. Một chương trình tăng cường cho chương trình sạch ở trên có thể được

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

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

Đó chỉ là một ví dụ (không thể biên dịch được trong C ++) để hiển thị một ý tưởng. Chương trình tăng cường chính xác thực sự phải được biên dịch, làm việc và có vòng lặp vô hạn.

Hoàn thành quy tắc

Cả hai chương trình:

  • Bất kỳ ngôn ngữ với sự hỗ trợ của các forvòng lặp như vậy là ok.
  • Cơ thể vòng lặp phải trống. Chính xác hơn, bạn có thể đặt một số đầu ra hoặc mã khác vào vòng lặp, nhưng hành vi vòng lặp sẽ giống nhau trong trường hợp vòng lặp trống.

Chương trình sạch:

  • Vòng lặp sử dụng bộ đếm số nguyên hoặc số và thực hiện 8 lần lặp:

    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++
    
  • Các loại do người dùng xác định không được phép.

  • Sử dụng thuộc tính (ngoại trừ biến toàn cục) thay cho biến vòng lặp không được phép.
  • Khai báo biến có thể ở bên trong hoặc bên ngoài vòng lặp. Mã sau là ok:

    int x;
    for(x=0; x<8; ++x);
    
  • Có thể sử dụng tiền tố hoặc tăng tiền tố.

  • Giới hạn vòng lặp 8nên được viết dưới dạng hằng số mà không lưu vào hằng số hoặc biến. Nó được thực hiện để ngăn các giải pháp dựa trên khai báo biến hoặc hằng bằng 8, sau đó gán lại, ghi đè hoặc phủ bóng nó bằng giá trị khác:

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

Chương trình mở rộng:

  • Phải chứa tất cả các mã từ sạch.
  • Nên mở rộng chương trình sạch với số lượng điểm mở rộng hạn chế.
  • Phải thực hiện cùng một for vòng lặp như một vòng lặp vô hạn.
    Đặt vòng lặp vào một cấu trúc vô hạn khác là không ổn.
  • Thời gian chạy hoặc biên dịch mã thời gian biên dịch được cho phép miễn là đại diện văn bản của nó là không thay đổi.
  • Đặt công trình vào một chuỗi và chuyển đến evalkhông được phép.

Điểm mở rộng:

  • Bất cứ nơi nào bên ngoài đoạn có mã sạch, bao gồm các tệp khác hoặc các cụm khác.
  • fortuyên bố (như một mảnh duy nhất - forxây dựng và cơ thể của nó) phải được giữ nguyên.
  • Khai báo biến phải được giữ nguyên.
  • Bất kỳ vị trí nào giữa các câu lệnh đơn giản đều có thể được sử dụng làm điểm mở rộng.
  • Nếu và chỉ khi biến được khai báo bên ngoài vòng lặp và không có giá trị ngay lập tức, thì phép gán đó có thể được thêm vào.
/* 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: Nếu có thể, vui lòng cung cấp một liên kết đến IDE trực tuyến.


2
@Oliver, như tôi biết, "điểm cao nhất (tăng số điểm trừ)" chính xác là mặc định cho cuộc thi phổ biến , ít nhất là nó được viết trong mô tả thẻ: "Cuộc thi phổ biến là cuộc thi mà câu trả lời có số phiếu cao nhất (upvotes trừ đi downvotes) thắng. " Nhưng tôi có thể thêm nó vào câu hỏi một cách rõ ràng.
Qwertiy

1
@Maltysen, có rất nhiều giải pháp thú vị trong các ngôn ngữ với những công trình này. Có C và C ++ (với các giải pháp hoàn toàn khác nhau), C #, Java, Javascript, php, Perl, Groovy. Tôi chắc chắn có nhiều hơn nữa. Dù sao, tôi mở để phóng to câu hỏi và được quy định trong các quy tắc. Nếu bạn có thể làm một cái gì đó lặp đi lặp lại bằng ngôn ngữ khác - hãy đăng nó. Nếu nó sẽ có reation tích cực, các quy tắc có thể được mở rộng.
Qwertiy

4
Làm điều này như một cuộc thi phổ biến là một chút khó xử vì không có mô tả về những tiêu chí mà cử tri nên chọn khi bỏ phiếu (làm cho điều kiện chiến thắng trở nên chủ quan). Tôi đã làm việc trên một giải pháp golf mã trên cơ sở nhiều người ở đây thấy các giải pháp golf thú vị và do đó nó có thể phổ biến; có vẻ như đó có thể là một điều kiện chiến thắng khả thi cho thử thách.

2
1. "bộ đếm số nguyên hoặc số " là một chút quá mơ hồ. Ví dụ, nó bao gồm java.lang.Integer? 2. Điều này sẽ tốt hơn với một tiêu chí chiến thắng thích hợp.
Peter Taylor

1
1. Vâng, đúng vậy. 2. Chính xác thì chiến thắng là gì? PS: Chúng tôi có thể tiếp tục trên meta .
Qwertiy

Câu trả lời:


33

Python3

Chương trình sạch:

Đây chỉ là một đếm ngược tiêu chuẩn trong khi vòng lặp.

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

Chương trình tăng cường:

import ctypes

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

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

Nó sử dụng bộ nhớ cache int để xác định lại 8như 9mà làm cho có hiệu quả n -= 1một không-op, vì 9-1 = 8đó chỉ đặt ntrở lại 9một lần nữa, gây ra vòng lặp vô hạn.

Bạn có thể thấy int cache trong hành động trực tuyến tại đây (mặc dù rõ ràng không có vòng lặp vô hạn vì nó trực tuyến).


Bạn có thể cung cấp một liên kết đến IDE onlinde không? ideone.com/aI3ZrI - dường như không hoạt động ở đó.
Qwertiy

@Qwertiy, tôi đã thử chạy nó trong repl.it, nhưng nó chỉ đóng băng, đó là điều được mong đợi vì nó sẽ là một vòng lặp vô hạn. Tôi biết công cụ bộ nhớ cache hoạt động ở đó, bởi vì đó là nơi tôi đã thử nghiệm cách đặt 8thành9
Maltysen

Thực sự làm việc ở đó. Điều kỳ lạ là không có giới hạn thời gian như ideone (5 giây). Họ hiển thịPython 3.5.2 (default, Dec 2015, 13:05:11) [GCC 4.8.2] on linux
Qwertiy

Liên kết @Qwertiy không có vòng lặp: repl.it/E4fx/0
Maltysen

Điều đó thật thú vị ...
Qwertiy

22

Con trăn 3

Chương trình sạch:

Cách tiêu chuẩn để làm điều gì đó 8 lần trong python là:

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

Chương trình tăng cường:

Tuy nhiên, nếu chúng ta ghi đè hàm tạo phạm vi thành năng suất vô hạn 1, nó sẽ trở thành một vòng lặp vô hạn ...

def range(x):
    while 1: yield 1

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

Chúng ta có thể thực hiện điều này hơn nữa và tạo ra một hàm tạo, thay vì mang lại vô hạn 1, sẽ tính mãi mãi:

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

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

Kiểm tra trên repl.it


2
Giấu nó ở giữa một mô-đun khổng lồ ...
Benjamin

21

Perl

Dọn dẹp

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

Tăng cường

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

Ideone .


16
Ồ, thật là thông minh. Đối với bất kỳ ai không biết Perl: đây là $ibí danh để trở thành bí danh cho một biến đặc biệt chỉ có khả năng giữ booleans, vì vậy khi đạt đến 1, nó sẽ trở nên miễn nhiễm với việc tăng lên.

10

ES5 + (Javascript)

EDIT : Đã xóa khai báo biến rõ ràng, vì nếu không nó đã được nâng lên và một thuộc tính window.x không thể cấu hình được tạo ra (trừ khi chạy từng dòng trong bảng điều khiển REPL).

Giải trình:

Tạo lợi thế cho thực tế là bất kỳ biến có phạm vi toàn cầu nào cũng là một thuộc tính của đối tượng cửa sổ và xác định lại thuộc tính "window.x" để có giá trị không đổi là 1.

Dọn dẹp

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

Tăng cường

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

LƯU Ý : Để làm cho điều này hoạt động trong Node.js, chỉ cần thay thế "cửa sổ" bằng "toàn cầu" (được thử nghiệm trong Node.js 6.8.0)


1
Nhân tiện, đó là ES5, phải không?
Qwertiy

Ngoài ra, nó không hoạt động với varCrome. Nhưng bạn có thể xóa varkhỏi cả hai chương trình - sẽ ổn thôi.
Qwertiy

@Qwertiy điều này không hoạt động với "var" trong Chrome đối với tôi (Linux / Phiên bản 52.0.2743.82 (64-bit))
zeppelin

> Nhân tiện, đó là ES5, phải không? Đúng, sẽ sửa tiêu đề ngay bây giờ
zeppelin

1
Vấn đề là varvận thăng, vì vậy tại thời điểm sử dụng definePropertynó đã thoát. Nhưng nếu bạn đặt 2 dòng này trong các tập lệnh khác nhau (nhân tiện, nó được phép), nó sẽ hoạt động, vì thuộc tính sẽ được tạo trước và varsau đó sẽ bị bỏ qua. Bằng chứng: i.stack.imgur.com/lSwbE.png
Qwertiy

10

C

Chương trình sạch

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

Chương trình tăng cường

#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 Vòng lặp "for" không nằm trong một cấu trúc vô hạn khác.
coredump

3
@KarlNapf Tôi nghĩ rằng câu trả lời này được cho phép rõ ràng theo quy tắc: • Thời gian chạy mã hoặc thời gian biên dịch mã được cho phép miễn là biểu diễn văn bản của nó không thay đổi.
Omar

Đó là từ ngữ "Phải thực hiện tương tự cho vòng lặp" nhưng vâng, điều này mâu thuẫn với cách trình bày văn bản.
Karl Napf

7

Java

Chương trình sạch:

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

Chương trình mở rộng:

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++);
    }
}

Đặt Số nguyên trong bộ đệm Số nguyên chứa 1 đến 0, thực sự i++không làm gì cả (nó đặt ithành Số nguyên được lưu trong bộ đệm nên chứa 1, nhưng vì Số nguyên đó thực sự chứa 0, nên không có gì thay đổi).


Đánh bại tôi với nó, giải pháp này là giống hệt của tôi.
Hypino

6
Đây thực sự không phải là một vòng lặp Java thành ngữ, có thể sẽ sử dụng unboxed intthay vì tương đối nặng Integer.


6

Python 3 (3.5.0)

Chương trình sạch:

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

Tăng cường

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)

Giải pháp này không giống như các giải pháp khác được viết bằng Python ở chỗ nó thực sự thay đổi mã nguồn một cách nhanh chóng. Tất cả những thứ trong vòng lặp for có thể được thay đổi thành bất kỳ mã nào muốn.

Mã này thay đổi opcode thứ hai thành opcode cuối cùng 113hoặc dễ đọc hơn - JUMP_ABSOLUTE. Nó thay đổi toán hạng thành 160- hướng dẫn nơi vòng lặp for bắt đầu, thực tế là tạo ra một câu lệnh GOTO ở cuối chương trình.

Chương trình tăng cường in các số 0..7vô hạn nhiều lần mà không bị tràn chồng hoặc tương tự.


6

PHP

Tôi nghĩ rằng điều này là theo các quy tắc điểm mở rộng; Tôi không hoàn toàn rõ ràng ở điểm 4. Nó rất giống với câu trả lời perl của @ primo vì vậy tôi nghĩ nó có giá trị.

Dọn dẹp

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

Tăng cường

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

PHP cho phép bạn tăng các chuỗi nhất định, như vậy:

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

Tất cả các chuỗi này ước tính thành 0, do đó, điều này sẽ lặp đi lặp lại thực tế mãi mãi (không sử dụng hết bộ nhớ).


Đó là trên tinh thần của cuộc thi và rất thú vị. Trên thực tế, không có bất cứ điều gì nói về việc sử dụng gánmnet ban đầu, vì vậy đó là một số trường hợp cạnh. Trên thực tế, người ta đã dự đoán rằng không có điểm mở rộng giữa việc gán 0 và lặp. Nhưng tôi sẽ không cho phép điều đó ngay bây giờ vì tôi thấy một số cách xử lý tình huống xen kẽ dựa trên điều đó và không dễ để lạm dụng.
Qwertiy

2
@Qwertiy "vì vậy đó là một số trường hợp cạnh." Tóm lại, PHP
ToXik-YogHurt

6

Perl

Mã sạch

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

Mã tăng cường

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

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

Hầu hết các biến Perl chỉ là biến. Tuy nhiên, ngôn ngữ cũng có một tietính năng, cho phép bạn đưa ra các biến getters và setters một cách hiệu quả. Trong chương trình này, tôi biến gói chính (có tên là chuỗi null) thành tương đương với một lớp từ ngôn ngữ hướng đối tượng, đồng thời có nó là một chương trình. Điều đó cho phép tôi buộc bộ forđếm vòng lặp với chính chương trình. Thực hiện TIESCALARcho phép tiethành công; giá trị trả về TIESCALARcó nghĩa là một tham chiếu đến bất kỳ trạng thái nội bộ nào mà chúng ta cần giữ xung quanh liên quan đến biến, nhưng vì chúng ta không cần bất kỳ, chúng ta trả về một tham chiếu mảng trống dưới dạng giữ chỗ. Sau đó chúng tôi đưa ra các triển khai đơn giản nhất có thể của getter và setter; không ai trong số họ làm bất cứ điều gì, vì vậy cố gắng để gán cho$xkhông có tác dụng và cố gắng đọc nó luôn luôn trả về undef, số này nhỏ hơn 8.


5

WinDbg

Dọn dẹp

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

Tăng cường

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
}

Cách tiếp cận này tạo ra một bí danh cho <as |, vì vậy khi <gặp mã trong bí danh, bí danh được mở rộng thành |và bitwise - hoặc được thực hiện thay vì ít hơn. Trong WinDbg, tất cả các giá trị khác không là trung thực nên anything | 8luôn luôn đúng.

Lưu ý: .blockKhông thực sự cần thiết nếu aS.forthực sự được nhập dưới dạng hai dòng khác nhau như được hiển thị ở đây, nó chỉ được yêu cầu khi aS.fortrên cùng một dòng.


5

Toán học

Dọn dẹp

For[x = 0, x < 8, ++x,]

Tăng cường

x /: (x = 0) := x = -Infinity;
For[x = 0, x < 8, ++x,]

5

Lisp thường gặp

Mã sạch

(dotimes(i 8))

Tăng cường

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

Một macro có tên keyword:dotimes, hay còn gọi :dotimes(xem 11.1.2.3 Gói KEYWORD ) được định nghĩa sẽ mở rộng dưới dạng một vòng lặp vô hạn. Các defmacrolợi vĩ mô tên của vĩ mô được xác định, có thể được làm thức ăn cho shadowing-import. Do đó, các dotimesbiểu tượng mới này che phủ tiêu chuẩn (không nên được xác định lại hoặc ràng buộc từ vựng với một macro khác trong các chương trình di động).

Tăng cường (2)

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

Khi chúng ta đọc ký tự 8, chúng ta thay thế nó bằng (loop). Điều đó có nghĩa là ở trên đọc (dotimes (i (loop)))và vì vậy mã không bao giờ chấm dứt tính toán giới hạn trên. Điều này tác động đến tất cả các lần xuất hiện của 8, không chỉ một lần trong vòng lặp. Nói cách khác, 8 thực sự là viết tắt của vô cùng. Nếu bạn tò mò, khi khả năng đọc được sửa đổi như trên, thì ký tự 8 trở thành "chấm dứt" và tự tách khỏi các số / ký hiệu khác hiện đang được đọc:

(list 6789)

... đọc là:

(list 67 (loop) 9)

Bạn có thể chạy thử nghiệm trên Ideone: https://ideone.com/sR3AiU .


4

Hồng ngọc

Dọn dẹp

Loại vòng lặp for này không được sử dụng nhiều trong Ruby, nhưng một hướng dẫn điển hình sẽ cho bạn biết rằng đây là cách để thực hiện:

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

Tăng cường

Vòng lặp for chỉ gọi (1..8).eachvới khối mã đã cho, vì vậy chúng tôi thay đổi phương thức đó:

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

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

4

Haskell

Phiên bản sạch:

import Control.Monad (forM_)

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

Phiên bản mở rộng:

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

Thực sự nó khá cơ bản: chúng ta chỉ định nghĩa kiểu riêng của mình Tsao cho thể hiện của nó enumFromTolà một chuỗi vô hạn, sau đó sử dụng mặc định kiểu để các giá trị không chú thích kiểu 08được lấy làm kiểu T.


1
Ý tưởng hay để thay đổi loại mặc định cho chữ số quá tải của Haskell.
nimi

3

///

Không có forvòng lặp rõ ràng trong ///, nhưng có thể được mô phỏng (sau tất cả là hoàn thành).

Dọn dẹp:

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

Tăng cường:

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

Chuyện gì đang xảy ra vậy?

Trong khi chương trình cựu đếm ngược 8-0, là thứ hai của /0/0/quy tắc sẽ thay thế 0bởi 0cho đến vĩnh cửu.


Và tôi nghĩ rằng bạn thực sự sẽ làm một cái gì đó như /0/1//1/2/.../7/8//8/8/8để đếm lên thay thế.
Erik the Outgolfer

3

Javascript ES6

OK, đây là phiên bản hoạt động bằng ES6 cho ... cấu trúc vòng lặp. Tôi thậm chí sẽ cung cấp cho bạn một mảng sạch để chúng tôi chắc chắn rằng không có doanh nghiệp hài hước:

Dọn dẹp

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

Tất nhiên, điều đó không ngăn ai đó làm phiền với nguyên mẫu Array ...

Tăng cường

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

Điều này hoạt động bằng cách ghi đè lên trình lặp mặc định để nó không bao giờ kết thúc, do đó khóa mọi thứ vào một vòng lặp vô hạn. Mã thậm chí không có cơ hội để chạy các thứ bên trong vòng lặp.


"hành vi vòng lặp phải giống nhau trong trường hợp vòng lặp trống"
Qwertiy

Chết tiệt, đã bỏ lỡ điều đó - tôi sẽ phải tìm ra một cái gì đó.
Marcus Dirr

Theo như tôi có thể nói, không thể thực hiện thử thách với vòng lặp kiểu C trong Javascript trừ khi bạn phá vỡ quy tắc - bằng cách có một cái gì đó bên trong nó (như giải pháp của tôi) hoặc bằng cách xoa bóp trước vòng lặp khai báo trong mã sạch của bạn (như với Cedric Reichenbach's).
Marcus Dirr

Trên thực tế có một số cách. Cách với biến toàn cục đã được đăng, nhưng có một số nữa, cho phép vartrong vòng lặp.
Qwertiy

Như tôi đã nói, theo như tôi có thể nói. Tôi đã nhìn thấy cách biến toàn cầu sau khi đưa ra nhận xét đó và tự đá mình.
Marcus Dirr

2

C ++

Sử dụng 2 điểm mở rộng:

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;
}

Chương trình sạch giống như trong mô tả.


Đẹp, nhưng có thể được "tối ưu hóa" :) Có một số nội dung thú vị trong C ++ để đưa ra câu trả lời khác.
Qwertiy

2

Brainfuck

Tôi in một '0' mỗi lần lặp, chỉ để dễ dàng đếm số lần lặp. Nhưng bất kỳ mã nào cũng có thể được chèn vào đó mà không thay đổi cách vòng lặp hoạt động.

Dọn dẹp

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

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

Dùng thử trực tuyến

Phiên bản tăng cường phụ thuộc vào việc triển khai Brainfuck phổ biến với các ô 8 bit. Trên các triển khai này, "gia tăng" thực sự là "gia tăng (mod 256)". Do đó, để tìm một vòng lặp sẽ lặp lại chính xác 8 lần trong phiên bản sạch và vô tận trong phiên bản tăng cường, chúng ta chỉ cần tìm một giải pháp cho hệ bất đẳng thức sau.

  • a + b * 8 (mod 256) == 0 (đối với phiên bản sạch)
  • c + a + b * n (mod 256)> 0 cho tất cả n (đối với phiên bản tăng cường)
  • a> 0

Trong trường hợp này, chúng ta để a = 128, b = 16 và c = 1. Rõ ràng là 128 + 16 * 8 = 256 (và 256 (mod 256) = 0) và 128> 0, và vì b là chẵn, c + a + b * n là số lẻ đối với bất kỳ số lẻ a + c nào và do đó sẽ không bao giờ là bội số chẵn của 256 trong các trường hợp như vậy. Chúng tôi chọn c = 1 vì đơn giản. Do đó, thay đổi duy nhất chúng ta cần là một lần duy nhất +vào đầu chương trình.

Tăng cường

+                                            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)
]                                            }

Dùng thử trực tuyến

Tôi để nó cho OP để xác định xem mục này có cạnh tranh không. Brainfuck không có vòng lặp rõ ràng, nhưng dạng vòng lặp tôi đã sử dụng gần giống như bạn có thể nhận được. ++++++++cũng gần với nghĩa đen 8như bạn có thể nhận được; Tôi đã bao gồm khá nhiều trong số đó.

Phiên bản sạch gần như chắc chắn tạo thành một chương trình điển hình được viết bằng ngôn ngữ này, vì ngay cả Brainfuck Hello World ngắn nhất được biết đến phụ thuộc vào mối quan hệ tái phát mô-đun để làm việc.


2

Haskell

Dọn dẹp

import Control.Monad (forM_)

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

Tăng cường

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

Thay thế toán tử ứng dụng chức năng thông thường $ bằng một lặp lại vòng lặp mỗi lần nó kết thúc. Chạy phiên bản sạch in 0 đến 8 rồi dừng; phiên bản tăng cường in 0 đến 8 và sau đó 0 đến 8 lần nữa, v.v.

Tôi gian lận một chút, trong đó forM_ [0..8] $ \i -> print ikhông nhất thiết là cách "sạch nhất" để viết vòng lặp đó trong Haskell; nhiều người Hask sẽ giảm bớt cơ thể vòng lặp để có được forM_ [0..8] printvà sau đó không có $ghi đè. Để bảo vệ tôi đã sao chép mã sạch từ câu trả lời của Cactus , người không cần tài sản đó, vì vậy ít nhất một lập trình viên Haskell thực sự đã viết mã đó mà không có động lực để thêm một cách không cần thiết $!


1

C ++

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

Cho phép xđánh giá đến 7. Không hoạt động trong C vì nó yêu cầu một giá trị khi gán và tăng.


1

Nim

Phiên bản thành ngữ, sử dụng countup:

Dọn dẹp

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

Tăng cường

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

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

Đơn giản và rất giống với câu trả lời của Python xác định lạirange . Chúng tôi xác định lại countup, cách Nim thành ngữ lặp đi lặp lại từ một int (bao gồm) sang một khác, để cung cấp 8 giây vô tận.

Phiên bản thú vị hơn, sử dụng toán tử phạm vi ..:

Dọn dẹp

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

Tăng cường

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

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

Rất giống với giải pháp trước đó, ngoại trừ chúng tôi xác định lại toán tử phạm vi .., thông thường sẽ đưa ra một mảng [1, 2, 3, 4, 5, 6, 7, 8], cho trình lặp từ trước đó.


1

GolfScript

Dọn dẹp

0{.8<}{)}while;

Tăng cường

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

Nó gán hàm trả về n + 1 cho biến 8


1

tcl

Bình thường:

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

Tăng cường:

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

Ý tưởng là xác định lại incrlệnh được sử dụng để tăng biến i, để thực sự không tăng!

Có thể được kiểm tra trên: http://rextester.com/live/QSKZPQ49822


1

x86_64 hội

Chương trình sạch:

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

Loại vòng lặp mà bất kỳ lập trình viên hội nào cũng sẽ sử dụng, theo sau là một tòa nhà thoát để không cho phép thêm một jmp loop_startlệnh sau đó.

Chương trình mở rộng:

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

Ngoài ra, xin lỗi nếu nó không tốt khi chương trình sạch không có điểm vào hoặc section .text


Nó sẽ không dừng lại sau khi tràn số nguyên?
Qwertiy

1
Ồ, ờ ... có lẽ. Nhưng sẽ mất nhiều thời gian? Tôi quên mất rằng điều đó có thể xảy ra, chủ yếu là một lập trình viên ngôn ngữ cấp cao
goose121

0

JavaScript

Dọn dẹp:

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

Tăng cường:

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

Dường như không phải là một vòng lặp điển hình ...
Qwertiy

Vâng, tôi hơi kéo dài thuật ngữ điển hình ...: /
Cedric Reichenbach

0

C ++

Chương trình sạch

Một vòng lặp đẹp, bình thường, lặp từ số 0 đến 7.

#include <iostream>

int main() {

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

}

Chương trình tăng cường

Bộ tiền xử lý của C ++ là một tính năng khá nguy hiểm ...

#include <iostream>
#define short bool

int main() {

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

}

Dòng duy nhất chúng tôi phải thêm là #define short bool. Điều này tạo ra imột boolean thay vì một số nguyên ngắn và do đó toán tử gia tăng ( i++) không làm gì sau khi iđạt 1. Đầu ra sau đó trông như thế này:

0
1
1
1
1
1
...

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.