Vòng lặp mà không 'vòng lặp' [đóng]


85

Một câu hỏi tương tự như thế này đã được hỏi vài năm trước , nhưng câu hỏi này thậm chí còn khó hơn.

Thử thách rất đơn giản. Viết một chương trình (trong ngôn ngữ của bạn lựa chọn) mà liên tục thực thi mã mà không sử dụng bất kỳ cấu trúc lặp lại như while, for, do while, foreachhoặc goto( Vì vậy, cho tất cả các bạn nitpickers, bạn không thể sử dụng một vòng lặp ). Tuy nhiên, đệ quy không được phép, trong hàm gọi chính nó (xem định nghĩa bên dưới) . Điều đó sẽ làm cho thách thức này quá dễ dàng.

Không có hạn chế về những gì cần được thực hiện trong vòng lặp, nhưng đăng một lời giải thích với câu trả lời của bạn để người khác có thể hiểu chính xác những gì đang được thực hiện.

Đối với những người có thể bị treo trên các định nghĩa, định nghĩa của một vòng lặp cho câu hỏi này là:

A programming language statement which allows code to be repeatedly executed.

Và định nghĩa đệ quy cho câu hỏi này sẽ là định nghĩa hàm đệ quy tiêu chuẩn của bạn:

A function that calls itself.

Người chiến thắng sẽ là câu trả lời có nhiều lượt ủng hộ nhất vào ngày 16 tháng 7 lúc 10 giờ sáng theo giờ miền đông. Chúc may mắn!

CẬP NHẬT:

Để làm dịu sự nhầm lẫn vẫn đang được thể hiện, điều này có thể giúp:

Các quy tắc như đã nêu ở trên:

  • Đừng sử dụng các vòng lặp hoặc goto
  • Chức năng không thể tự gọi
  • Làm bất cứ điều gì bạn muốn trong 'vòng lặp'

Nếu bạn muốn thực hiện một cái gì đó và các quy tắc không cho phép rõ ràng, hãy tiếp tục và thực hiện nó. Nhiều câu trả lời đã bẻ cong các quy tắc.


27
Đối với những người muốn có một mẹo dễ dàng, tôi không thể bận tâm đăng nó: P Chỉ cần thực hiện 2 chức năng, function Acuộc gọi function Bfunction Bcuộc gọi function Atrong khi 1 trong số các chức năng thực hiện một cái gì đó. Vì hàm không tự gọi nên nó có hiệu lực dựa trên các tiêu chí ^. ^
Teun Pronk

2
"Thay đổi thành cuộc thi nổi tiếng để tập trung vào sự sáng tạo" Thay đổi câu hỏi là gian lận!
CousinCocaine

4
Định nghĩa của "đệ quy" không hữu ích lắm. Sẽ tốt hơn nếu không cho phép các hàm đệ quy , là các hàm tham chiếu đến chính chúng, trực tiếp hoặc gián tiếp.
LRN

3
Điều không rõ ràng là "định nghĩa" của hàm tạo vòng lặp và đệ quy. Không phải là rất chính xác. Ví dụ: rep(f){f();f();}- đây là một câu lệnh (một khai báo hàm là một câu lệnh trong một số ngôn ngữ) cho phép thực thi mã nhiều lần. Có phải nó không được phép. Bạn yêu cầu mã để thực hiện một vòng lặp. Nếu mã đó về mặt cú pháp là một tuyên bố, bạn đã không cho phép nó. Một ví dụ khác : f(b) { b(); g(b); }; g(b) { f(b); }. Tôi muốn nói flà một hàm đệ quy (bằng cách đệ quy lẫn nhau g). Có phải nó không được phép?
LRN

3
@CailinP, điều tôi " treo lên " là các câu hỏi trên trang web nên có chủ đề cho trang web: điều đó có nghĩa là có một đặc tả khách quan, rõ ràng, mà câu hỏi này không có.
Peter Taylor

Câu trả lời:


258

Hồng ngọc

def method_missing(meth,*args)
  puts 'Banana'
  send(meth.next)
end

def also
  puts "Orange you glad I didn't say banana?"
end

ahem

Bản giới thiệu

Xóa cổ họng của nó, in "Banana" 3070 lần, và cũng đặt "Orange bạn vui vì tôi không nói chuối?".

Điều này sử dụng chức năng định nghĩa phương thức đúng lúc vô lý của Ruby để xác định mọi phương thức nằm theo thứ tự abc giữa các từ 'ahem' và 'cũng' ("ahem", "ahen", "aheo", "ahep", "aheq", "Aher", "ahes", "ahet", "aheu", "ahev" ...) để in Banana đầu tiên và sau đó gọi tiếp theo trong danh sách.


4
Cuối cùng, nó cũng nhấn "cũng", được xác định và do đó không bị thiếu.
lịch sử

77
Đây là sự kích động.
Michael B

4
@barrycarter: Trong Ruby, String#nextđược gọi trong các method_missinghàm ít nhiều giống như thêm 1 vào một số trừ khi nó hoạt động với tất cả các ký tự chữ và số (và không phải là alnums nếu chúng là các ký tự duy nhất trong chuỗi). Xem ruby-doc.org/core-2.1.2/String.html#method-i-next
3Doubloons

2
@NickT có thể sử dụng được trong các lớp như trình tạo XML nơi bạn có thể tạo bất kỳ thẻ nào chỉ bằng cách tạo b.my_tag. Nó cũng được sử dụng trong các mô hình ActiveRecord hoặc OpenStruct. Trong 'Wat talk', ông nói rằng toàn cầu method_missinglà xấu, nhưng phạm vi là tuyệt vời.
Hauleth

2
Tôi nhớ một nhận xét cũ về một chương trình ruby ​​khác: "Tôi thích nó vì nó có meth"
vidya sagar

82

Con trăn - 16

hoặc bất kỳ ngôn ngữ khác với eval.

exec"print 1;"*9

Bạn có thể mô tả những gì chương trình của bạn làm?
CailinP

10
Nó nhận một chuỗi ( "print 1;"), nhân đôi 9 lần ( *9), sau đó thực hiện chuỗi kết quả ( exec). Lặp đi lặp lại một đoạn mã mà không thực sự lặp lại.
Scragar

12
Yay cho phép nhân chuỗi!
Thane Brimhall

2
Cũng làm việc trong Ruby nếu bạn thay đổi execđể eval hoặc các printđể echo.
Ajedi32

80

CSharp

Tôi đã mở rộng mã thành một kiểu dễ đọc hơn vì đây không còn là mã golf nữa và đã thêm một bộ đếm tăng dần để mọi người thực sự có thể thấy rằng chương trình này làm gì đó.

class P{
    static int x=0;
    ~P(){
        System.Console.WriteLine(++x);
        new P();
    }
    static void Main(){
        new P();
    }
}

(Đừng làm điều này bao giờ xin vui lòng).

Khi bắt đầu, chúng ta tạo một thể hiện mới của Plớp, khi chương trình cố gắng thoát lệnh gọi GC sẽ gọi bộ hoàn thiện tạo ra một thể hiện mới của Plớp, khi nó cố gắng dọn sạch sẽ tạo ra một cái mới Pgọi là bộ hoàn thiện .. .

Chương trình cuối cùng đã chết.

Chỉnh sửa: Không thể giải thích điều này chỉ chạy khoảng 45 nghìn lần trước khi chết. Tôi hoàn toàn không biết làm thế nào mà GC tìm ra vòng lặp vô hạn khó khăn của tôi nhưng nó đã làm. Nói ngắn gọn là có vẻ như nó đã không tìm ra và sợi chỉ bị giết sau khoảng 2 giây thực hiện: https://stackoverflow.com/questions/24662454/how-does-a-garbage-collector-avoid-an -infinite-loop-here

Edit2: Nếu bạn nghĩ rằng điều này hơi quá giống như đệ quy, hãy xem xét giải pháp khác của tôi: https://codegolf.stackexchange.com/a/33268/23300

Nó sử dụng sự hợp nhất hóa các phương thức chung để trong thời gian chạy, nó liên tục tạo ra các phương thức mới và mỗi phương thức trong thuật ngữ gọi một phương thức mới được đúc. Tôi cũng tránh sử dụng referencecác tham số kiểu, vì thông thường thời gian chạy có thể chia sẻ mã cho các phương thức đó. Với một valuetham số kiểu, bộ thực thi buộc phải tạo một phương thức mới.


20
Tôi thậm chí không biết C # có chất hủy diệt. +1 để dạy tôi.
xem

4
@TheRare, có nhưng bản chất chúng không mang tính quyết định và có thể không bao giờ được gọi trong khi thực hiện chương trình. Chúng được thực hiện như một ghi đè của phương thức ảo Finalizeđể đôi khi chúng được gọi finalizer. Trong C # thực, bạn nên sử dụng IDisposablemẫu.
Michael B

Có vẻ như có một thời gian chờ xảy ra tại một số điểm. Tôi không nghĩ rằng đó là GC đang dừng chu kỳ của bạn, nhưng thay vào đó, hệ điều hành quyết định rằng chương trình của bạn mất quá nhiều thời gian để kết thúc.
LVBen

Tôi nghĩ rằng đây thực sự là thời gian chạy quyết định giết chương trình không nhất thiết phải là HĐH. Chuỗi trình thu gom rác được gọi vào cuối chương trình được đưa ra giới hạn thời gian cố định là ~ 2 giây trước khi bị giết.
Michael B

Với một số sửa đổi nhỏ (không để chương trình kết thúc, giải phóng đối tượng P thứ 1 cho GC và liên tục gọi GC.Collect), tôi có thể khiến chương trình chạy vô thời hạn.
LVBen

53

Befunge

.

Befunge cũ tốt xuất ra 0 (từ một ngăn xếp trống) gần như mãi mãi, khi các dòng bao quanh.


1
Hà! Tôi thích những mánh khóe như thế này
CailinP

47

Mã não

(f=function(){ console.log('hi!'); eval("("+f+")()") })()

Chức năng vui!

Một chức năng tạo ra một chức năng khác có cùng cơ thể với chính nó và sau đó chạy nó.

Nó sẽ hiển thị hi ở cuối khi đạt đến giới hạn ngăn xếp và toàn bộ sự việc sụp đổ.

Tuyên bố miễn trừ trách nhiệm: bạn sẽ không thể làm bất cứ điều gì trong trình duyệt của mình cho đến khi đạt đến giới hạn ngăn xếp.


Và một điều khác, ác hơn :

function f(){ var tab = window.open(); tab.f = f; tab.f()}()

Nó tạo ra một chức năng mở ra một cửa sổ, sau đó tạo ra một chức năng trong cửa sổ đó là bản sao của chức năng và sau đó chạy nó.

Tuyên bố miễn trừ trách nhiệm: nếu bạn cho phép mở cửa sổ bật lên, cách duy nhất để hoàn thành việc này sẽ là khởi động lại máy tính của bạn


5
Điều này khá là xấu cho chắc chắn;)
CailinP

28
@CailinP Khá eval chắc chắn.
xem

Tôi nghĩ rằng bạn đang thiếu một fphần cuối của chức năng thứ hai của bạn. Nó sẽ được }f()cuối cùng.
Chirag Bhatia - chirag64

2
Thật không may, tôi nhận thấy nó bởi vì tôi đã thử nó. : P
Chirag Bhatia - chirag64

7
-1 - đây chỉ là đệ quy.
dùng253751

39

lắp ráp x86 / DOS

    org 100h

start:
    mov dx,data
    mov ah,9h
    int 21h
    push start
    ret

data:
    db "Hello World!",10,13,"$"

Tôi đã nói không đệ quy đuôi đảo ngược ? Tôi đã làm madame mim rồng tím

Làm thế nào nó hoạt động

Lệnh ret, được sử dụng để trả về từ một hàm, thực sự bật địa chỉ trả về từ ngăn xếp (thường được đặt ở đó bởi tương ứng call) và nhảy đến nó. Ở đây tại mỗi lần lặp, chúng ta sẽ pushghi địa chỉ điểm vào ngăn xếp trước khi quay trở lại, do đó tạo ra một vòng lặp vô hạn.


Tôi đã tự hỏi nếu điều này là có thể trong lắp ráp.
Ian D. Scott


1
Tôi sẽ gọi codegolf.stackexchange.com/a/34295/11259 như một bản sao của cái này, nhưng tôi thấy đó thực sự là câu trả lời trước đó
Digital Trauma

@DigitalTrauma: vâng, tôi nhận thấy sau khi tôi đăng bài viết của mình, nhưng tôi đã được đính kèm với hình ảnh của Madame Mim. :-) May mắn thay, có một số khác biệt (anh ấy hơi khó hiểu hơn và hoạt động trên Linux 32 bit, tôi chơi trực tiếp trên DOS và không có bước nhảy nào khác), nếu không có ai phản đối tôi sẽ rời khỏi đây dù thế nào đi nữa.
Matteo Italia

@MatteoItalia Không bị xáo trộn, chỉ là crappy;) (tho "thêm eax, 4" làm tôi bối rối, tôi không thể tìm thấy bảng kích thước opcode vì vậy tôi chỉ đoán kích thước hoang dã). Tôi đã thực hiện nó trong trình biên dịch trực tuyến trong khi dự án công việc của tôi đang biên dịch để nó trông khủng khiếp. Ý tưởng tuyệt vời của việc sử dụng "bắt đầu:".
PTwr

37

Java

Trực tiếp từ XKCD

Liên kết

Đây là một trò chơi không bao giờ kết thúc giữa cha mẹ và con cái!

Mục tiêu của CHILDđược đặt thành PARENTvà mục tiêu của PARENTCHILD. Khi các PARENTcuộc gọi AIM, nó ném thể hiện của BALLlớp và nó bị bắt bởi câu lệnh bắt. Câu lệnh bắt sau đó gọi PARENT.TARGET.AIMnơi mà mục tiêu là CHILD. Các CHILDví dụ cũng làm như vậy và "ném bóng trở lại" cho phụ huynh.


3
Tôi thích những truyện tranh đó!
Derek 朕 會

1
Sẽ tốt hơn nếu quả bóng thực sự được ném giữa cha mẹ và con. Như vậy, quả bóng luôn được ném và bắt bởi cùng một "người".
Ajedi32

@ Ajedi32 Nó thực sự sẽ xuất hiện và ném nó qua lại; Cha mẹ MỤC TIÊU là trẻ em và mục tiêu của trẻ là cha mẹ. Aim được gọi là cha mẹ, người đập bóng và có đứa trẻ nhắm và ném bóng, vòng lặp cue
Alex Coleman

12
@AlexColeman Mã này tương tự như cha mẹ ném quả bóng lên không trung, bắt nó, sau đó đưa nó cho đứa trẻ làm điều tương tự trước khi trao lại quả bóng cho cha mẹ, v.v.
Ajedi32

11
Lệnh TARGET.AIM(B);trong phương thức AIMlà một cuộc gọi đệ quy. Vì vậy, điều này vi phạm quy tắc "các chức năng không thể tự gọi mình".
Theodore Norvell

31

Bash, 3 ký tự

yes

có sẽ liên tục trả 'y' cho bàn điều khiển

Chỉnh sửa: Mọi người được khuyến khích chỉnh sửa dòng này:

yes something | xargs someaction

(cảm ơn Olivier Dulac)


1
Tại sao điều này sẽ tiếp tục chạy? Tôi không đặt câu hỏi nó chỉ cố gắng để tìm hiểu tại sao.
Teun Pronk

2
@TeunPronk yeslà một lệnh bash in ra từ có cho đến khi nó bị giết hoặc luồng bị đóng. Nếu nó viết lên màn hình, nó sẽ không bao giờ dừng lại cho đến khi bạn giết nó. Mặc dù đó là loại gian lận, vì đó là một lệnh về cơ bản bao gồm một vòng lặp trên printf.
Scragar

1
Vui hơn sẽ được sử dụng yesđể giữ cho một số vòng lặp khác đi.
trlkly

3
@izkata: nhưng sau đó bạn có thể :: yes something | xargs someactionkhông đệ quy (thậm chí bạn có thể thêm -n 1 vào xargs để chỉ có 1 "cái gì đó" trên mỗi dòng, v.v.). Sử dụng xargs mở đường cho những hành vi phức tạp hơn (ngay cả những người không có gì để làm với đầu ra có)
Olivier Dulac

4
@scragar bạn nên vừa trả lời yes.
daviewales

28

C, 35 ký tự

main(int a,char**v){execv(v[0],v);}

Chương trình tự thực thi. Tôi không chắc chắn nếu điều này được coi là đệ quy hay không.


4
@mniip Đuôi đệ quy, sau đó, nếu nó được áp dụng ở cấp độ quy trình
Izkata

3
Đệ quy @Izkata Đuôi vẫn là đệ quy, nhưng đây không phải là đệ quy. Đệ quy hàm ý một hàm (hoặc quá trình trong trường hợp này) 'chờ đợi' cho một lần lặp khác của chính nó chấm dứt. Trong trường hợp này, execkhiến quy trình mới thay thế quy trình ban đầu, do đó, không có ngăn xếp cuộc gọi nào cuối cùng sẽ trả lại hoặc tràn.
millinon

4
@millinon Trong một ngôn ngữ hỗ trợ tối ưu hóa, đệ quy đuôi thay thế cuộc gọi trước đó trong ngăn xếp cuộc gọi, tương tự như cách execthay thế quy trình trước đó. Nó cũng sẽ không tràn.
Izkata

1
@millinon chỉ là siêu mô phạm và kéo dài cuộc thảo luận này lâu hơn, trong ngôn ngữ lập trình Scheme, tối ưu hóa này là một tính năng ngôn ngữ. Đó là trong spec rằng nếu bạn thực hiện một cái đuôi-đệ quy gọi, người phiên dịch / biên dịch sử dụng lại khung ngăn xếp cuối cùng. Điều này là do Scheme không có các cấu trúc vòng lặp tích hợp, vì vậy cách duy nhất để thực hiện một vòng lặp trong Scheme là thực hiện đệ quy đuôi và sẽ rất tệ nếu bạn bị tràn ngăn xếp khi cố gắng lặp quá nhiều lần :)
Ord

2
Nếu bạn muốn đi bộ, Scheme không có "tối ưu hóa cuộc gọi đuôi", nó có "các cuộc gọi đuôi phù hợp". Nó không phải là tối ưu hóa, nó là một yêu cầu cơ bản của tiêu chuẩn ngôn ngữ và việc không cung cấp nó là không được phép, vì vậy "tối ưu hóa" (hoặc gợi ý rằng nó có liên quan gì đến đệ quy) là một thuật ngữ không được khuyến khích.
Leushenko

28

C (với các nội trang GCC - dường như cũng hoạt động với tiếng kêu)

  • Không có vòng lặp rõ ràng
  • Không có hình ảnh rõ ràng
  • Không đệ quy
  • Chỉ cần làm hỏng kiểu cũ với đống đồ (trẻ em, đừng thử điều này ở nhà mà không có sự giám sát):
#include <stdio.h>

void *frameloop (void *ret_addr) {
    void **fp;
    void *my_ra = __builtin_return_address(0);

    if (ret_addr) {
        fp = __builtin_frame_address(0);
        if (*fp == my_ra) return (*fp = ret_addr);
        else fp++;
        if (*fp == my_ra) return (*fp = ret_addr);
        else fp++;
        if (*fp == my_ra) return (*fp = ret_addr);
        else fp++;
        if (*fp == my_ra) return (*fp = ret_addr);
        return NULL;
    } else {
        return (my_ra);
    }
}

int main (int argc, char **argv) {
    void *ret_addr;
    int i = 0;

    ret_addr = frameloop(NULL);
    printf("Hello World %d\n", i++);
    if (i < 10) {
        frameloop(ret_addr);
    }
}

Giải trình:

  • main()cuộc gọi đầu tiên frameloop(NULL). Trong trường hợp này, sử dụng __builtin_return_address()nội dung dựng sẵn để lấy địa chỉ trả về (trong main()) frameloop()sẽ trở về. Chúng tôi trả lại địa chỉ này.
  • printf() để hiển thị chúng tôi đang lặp
  • bây giờ chúng tôi gọi frameloop()với địa chỉ trả lại cho cuộc gọi trước. Chúng tôi xem qua ngăn xếp cho địa chỉ trả lại hiện tại và khi chúng tôi tìm thấy nó, chúng tôi thay thế địa chỉ trả lại trước đó.
  • Chúng tôi sau đó trở về từ frameloop()cuộc gọi thứ 2 . Nhưng vì địa chỉ trả lại đã bị hack ở trên, cuối cùng chúng tôi sẽ quay trở lại điểm main()mà cuộc gọi đầu tiên sẽ quay lại. Vì vậy, chúng tôi kết thúc trong một vòng lặp.

Việc tìm kiếm địa chỉ trả về trong ngăn xếp tất nhiên sẽ sạch hơn như một vòng lặp, nhưng tôi đã không kiểm soát một vài lần lặp lại vì mục đích không lặp lại bất cứ điều gì.

Đầu ra:

$ CFLAGS=-g make frameloop
cc -g    frameloop.c   -o frameloop
$ ./frameloop 
Hello World 0
Hello World 1
Hello World 2
Hello World 3
Hello World 4
Hello World 5
Hello World 6
Hello World 7
Hello World 8
Hello World 9
$ 

2
đẹp! Tôi tự hỏi tại sao những chức năng đó không phải là một phần của thông số C? ;-D
Brian Minton

4
@BrianMinton Trên thực tế, một điều tương tự nên có thể đạt được với setjmp()/ longjmp(). Chúng không có trong tiêu chuẩn c, nhưng nằm trong thư viện tiêu chuẩn . Mặc dù vậy, tôi cảm thấy như sắp xếp ngăn xếp thủ công ngày hôm nay ;-)
Chấn thương kỹ thuật số

@BrianMinton Tôi đoán là bởi vì nó nằm trong thông số kỹ thuật của CPU, điều này làm cho nó (phần cứng) nền tảng phụ thuộc. Và nó khá nguy hiểm khi sử dụng khi stackframe được tạo tự động, tôi sẽ không ngạc nhiên nếu AV sẽ khóc về mã như vậy. Kiểm tra cái này hay cái này cho các phiên bản x86 asm.
PTwr

27

Haskell

Đoạn mã sau không chứa hàm đệ quy (thậm chí là gián tiếp), không lặp nguyên hàm lặp và không gọi bất kỳ hàm đệ quy tích hợp nào (chỉ sử dụng IOđầu ra và ràng buộc), nhưng nó lặp lại một hành động nhất định:

data Strange a = C (Strange a -> a)

-- Extract a value out of 'Strange'
extract :: Strange a -> a
extract (x@(C x')) = x' x

-- The Y combinator, which allows to express arbitrary recursion
yc :: (a -> a) -> a
yc f =  let fxx = C (\x -> f (extract x))
        in extract fxx

main = yc (putStrLn "Hello world" >>)

Chức năng extractkhông gọi bất cứ điều gì, ycchỉ cần gọi extractmainchỉ gọi ycputStrLn>>, mà không phải là đệ quy.

Giải thích: Thủ thuật nằm ở kiểu dữ liệu đệ quy Strange. Đó là một kiểu dữ liệu đệ quy tiêu thụ chính nó, như trong ví dụ, cho phép lặp lại tùy ý. Đầu tiên, chúng ta có thể xây dựng extract x, về cơ bản thể hiện sự tự ứng dụng x xtrong phép tính lambda chưa được đánh dấu. Và điều này cho phép xây dựng tổ hợp Y được định nghĩa là λf.(λx.f(xx))(λx.f(xx)).


Cập nhật: Như đã đề xuất, tôi đang đăng một biến thể gần với định nghĩa của Y trong phép tính lambda chưa được đánh dấu:

data Strange a = C (Strange a -> a)

-- | Apply one term to another, removing the constructor.
(#) :: Strange a -> Strange a -> a
(C f) # x = f x
infixl 3 #

-- The Y combinator, which allows to express arbitrary recursion
yc :: (a -> a) -> a
yc f =  C (\x -> f (x # x)) # C (\x -> f (x # x))

main = yc (putStrLn "Hello world" >>)

3
Cấu trúc dữ liệu đệ quy thay vì các hàm đệ quy ... tốt đẹp.
Tiếp

6
cái này gần với trái tim tôi là một người quan tâm đến việc lập trình chức năng tổng thể. Bạn vừa trình bày cách tạo bộ kết hợp Y với kiểu dữ liệu định kỳ phủ định. Đây là lý do tại sao tổng số ngôn ngữ yêu cầu các loại định kỳ xảy ra ở bên phải của mũi tên và tại sao cây hoa hồng không được phép. Đẹp quá Tôi đã tạo một tài khoản ở đây chỉ để nâng cấp điều này!
Jake

Bạn có thể loại bỏ letràng buộc và định nghĩa yc f = extract $ C $ f.extract, vì letràng buộc có thể là một tính năng ngôn ngữ cho phép đệ quy (cổ điển let x = x in x). Điều này cũng làm giảm một số ký tự :)
Earth Engine

hoặc thậm chíyc = extract . C . (.extract)
Động cơ Trái đất

@EarthEngine Đúng, tôi chỉ muốn giữ cấu trúc gần hơn với định nghĩa ban đầu Y.
Petr Pudlák

26

C ++

Sau đây xuất ra một bộ đếm ngược từ 10 đến "Blast off!" sử dụng siêu lập trình mẫu.

#include <iostream>

template<int N>
void countdown() {
    std::cout << "T minus " << N << std::endl;
    countdown<N-1>();
}

template<>
void countdown<0>() {
    std::cout << "Blast off!" << std::endl;
}

int main()
{
    countdown<10>();
    return 0;
}

Nó có thể trông giống như một ví dụ cổ điển về đệ quy, nhưng thực tế, ít nhất là về mặt kỹ thuật, tùy thuộc vào định nghĩa của bạn. Trình biên dịch sẽ tạo ra mười chức năng khác nhau . countdown<10>in "T trừ 10" và sau đó gọi countdown<9>, và cứ thế countdown<0>, in ra "Blast off!" và sau đó trở về. Đệ quy xảy ra khi bạn biên dịch mã, nhưng tệp thực thi không chứa bất kỳ cấu trúc lặp nào.

Trong C ++ 11, người ta có thể đạt được các hiệu ứng tương tự bằng cách sử dụng constexprtừ khóa, chẳng hạn như chức năng giai thừa này. (Không thể thực hiện ví dụ đếm ngược theo cách này, vì các constexprhàm không thể có tác dụng phụ, nhưng tôi nghĩ có thể có trong C ++ 14 sắp tới.)

constexpr int factorial(int n)
{
    return n <= 1 ? 1 : (n * factorial(n-1));
}

Một lần nữa điều này thực sự trông giống như đệ quy, nhưng trình biên dịch sẽ mở rộng ra factorial(10)vào 10*9*8*7*6*5*4*3*2*1, và sau đó có thể thay thế nó bằng một giá trị không đổi của 3628800, do đó thực thi sẽ không chứa bất kỳ vòng lặp hoặc mã đệ quy.


4
Cái thứ hai trong số này thực sự là đệ quy thuần túy và đơn giản, không phải siêu lập trình. Thứ nhất bởi vì trình biên dịch sẽ (trong trường hợp chung) phát ra một thân hàm thông thường để bạn sử dụng với các đối số không liên tục; và thứ hai bởi vì khi nó thực hiện một hoạt động thời gian biên dịch, nó không thực hiện bất kỳ công cụ "mở rộng" kiểu mẫu nào, nó chạy một đánh giá tại chỗ tiêu chuẩn - giống như thời gian chạy - để sản xuất 3628800trực tiếp mà không cần hình thức trung gian.
Leushenko

@Leushenko vâng tôi biết. Nhưng một lần nữa, ví dụ mẫu lại thực hiện điều tương tự - sử dụng hàm đệ quy trong ngôn ngữ Turing-Complete tại thời gian biên dịch - sự khác biệt duy nhất là constexpr sử dụng ngôn ngữ trông giống C ++ hơn nhiều. Như với tất cả các câu trả lời, câu hỏi này đã bẻ cong các quy tắc, và tôi chỉ thành thật về nó. constexprđược thiết kế đặc biệt để làm cho (một số khía cạnh) mẫu siêu lập trình bị lỗi thời, vì vậy nó chắc chắn có vẻ đáng được đề cập trong một bài viết về chủ đề này.
Nathaniel

1
+1 : &countdown<N-1> != &countdown<N>.
Thomas Eding

21

Java

Hãy chơi với trình nạp lớp Java và đặt nó làm cha mẹ của chính nó:

import java.lang.reflect.Field;

public class Loop {
    public static void main(String[] args) throws Exception {
        System.out.println("Let's loop");
        Field field = ClassLoader.class.getDeclaredField("parent");
        field.setAccessible(true);
        field.set(Loop.class.getClassLoader(), Loop.class.getClassLoader());

    }
}

Vòng lặp này thực sự rất mạnh, bạn sẽ phải sử dụng kill -9để ngăn chặn nó :-)

Nó sử dụng 100,1% CPU Mac của tôi.

100,1% CPU

Bạn có thể thử di chuyển System.outở cuối chức năng chính để thử nghiệm một hành vi hài hước xen kẽ.


cười ngả nghiêng. nhận java bị mắc kẹt trong chính nó :)
masterX244

Yêu hack tải đệ quy JVM.
Isiah Meadows

20

CSharp

Thêm một kẻ độc ác nữa

public class P{

    class A<B>{
        public static int C<T>(){
            System.Console.WriteLine(typeof(T));
            return C<A<T>>();
        }
    }
    public static void Main(){
        A<P>.C<int>();
    }
}

Đây không phải là đệ quy ... đây là sự thống nhất của các mẫu mã. Mặc dù có vẻ như chúng ta đang gọi cùng một phương thức, bộ thực thi liên tục tạo ra các phương thức mới. Chúng tôi sử dụng tham số kiểu của int, vì điều này thực sự buộc nó phải tạo ra một kiểu hoàn toàn mới và mỗi thể hiện của phương thức phải đưa ra một phương thức mới. Nó không thể chia sẻ mã ở đây. Cuối cùng, chúng ta giết ngăn xếp cuộc gọi vì nó chờ đợi vô hạn cho sự trở lại của int mà chúng ta đã hứa nhưng không bao giờ được giao. Theo cách tương tự, chúng tôi tiếp tục viết loại chúng tôi tạo ra để giữ cho nó thú vị. Về cơ bản, mỗi C mà chúng ta gọi là một phương thức hoàn toàn mới chỉ có cùng một cơ thể. Điều này thực sự không khả thi trong một ngôn ngữ như C ++ hoặc D thực hiện các mẫu của họ tại thời điểm biên dịch. Vì, C # JIT là siêu lười biếng, nó chỉ tạo ra thứ này vào thời điểm cuối cùng có thể. Do vậy,


14

Redcode 94 (Chiến tranh cốt lõi)

MOV 0, 1

Hướng dẫn sao chép tại địa chỉ 0 đến địa chỉ một. Bởi vì trong Core War, tất cả các địa chỉ đều liên quan đến địa chỉ PC hiện tại và modulo kích thước của lõi, đây là một vòng lặp vô hạn trong một lệnh, không nhảy ,.

Chương trình này (chiến binh) được gọi là " Imp " và lần đầu tiên được xuất bản bởi AK Dewdney.


3
Imps sẽ diễu hành, sẵn sàng cổng của bạn, sẵn sàng chúng hoặc bạn sẽ bị nghiền nát.
xem

Sẵn sàng SPL 0, 0; MOV 1, -2thực sự của bạn .
dâu

Thật tuyệt, tôi đã hy vọng điều này chưa được đăng. +1
mbomb007

14

Phi tiêu

Tôi đoán đây sẽ là cách thức đệ quy cổ điển mà không có bất kỳ chức năng đệ quy thực tế nào. Không có chức năng dưới đây đề cập đến chính nó theo tên, trực tiếp hoặc gián tiếp.

(Hãy thử tại dartpad.dartlang.org )

// Strict fixpoint operator.
fix(f) => ((x)=>f(x(x))) ((x)=>(v)=>f(x(x))(v));
// Repeat action while it returns true.
void repeat(action) { fix((rep1) => (b) { if (b()) rep1(b); })(action); }

main() {
  int x = 0;
  repeat(() {  
    print(++x);
    return x < 10;
  });
}

6
Tổ hợp Y?
aditsu

5
Về mặt kỹ thuật, tôi đoán đó là tổ hợp Z vì nó dành cho ngôn ngữ nghiêm ngặt. Bộ kết hợp Y yêu cầu một ngôn ngữ lười biếng để tránh mở ra vô hạn. Sự khác biệt duy nhất là phần sau của nó được mở rộng eta.
LRN

12

Mã não

Không nguyên bản nhưng nhỏ. 20 ký tự.

setInterval(alert,1)

Bạn thực sự có thể loại bỏ ,1và nó vẫn sẽ hoạt động,
Derek 會

@Derek 會 nếu tôi làm điều đó, tôi chỉ nhận được một cảnh báo trên Firefox
xem

1
Trong chrome nó hoạt động mà không có tham số cuối cùng. Mã phải được tính là hợp lệ nếu nó hoạt động trong ít nhất một môi trường.
Derek 朕 會

3
@Derek 會setIntervalkhông phải là một tuyên bố, mặc dù; nó chỉ là một chức năng. Nó được sử dụng bên trong một câu lệnh biểu thức và nếu chúng ta không thể sử dụng câu lệnh biểu thức, thì tôi thậm chí không biết nữa.
Keen

1
@Cory - Chà tôi đoán là hợp lệ rồi!
Derek 朕 會

12

Tín hiệu trong C

#include <stdio.h>
#include <signal.h>

int main(void) {
    signal(SIGSEGV, main);
    *(int*)printf("Hello, world!\n") = 0;
    return 0;
}

Hành vi của chương trình này rõ ràng là không xác định được rất nhiều, nhưng ngày nay, trên máy tính của tôi, nó cứ in "Xin chào, thế giới!".


11

Emacs Lisp

Đây là thời điểm tuyệt vời để thể hiện thiết kế mạnh mẽ của Lisp trong đó "mã là dữ liệu và dữ liệu là mã". Cấp, những ví dụ này rất không hiệu quả và điều này không bao giờ nên được sử dụng trong bối cảnh thực tế.

Các macro tạo mã là phiên bản chưa được kiểm soát của vòng lặp được cho là và mã được tạo đó là những gì được đánh giá khi chạy.

repeat-it: cho phép bạn lặp N lần

(defmacro repeat-it (n &rest body)
  "Evaluate BODY N number of times.
Returns the result of the last evaluation of the last expression in BODY."
  (declare (indent defun))
  (cons 'progn (make-list n (cons 'progn body))))

kiểm tra lặp lại:

;; repeat-it test
(progn
  (setq foobar 1)

  (repeat-it 10
    (setq foobar (1+ foobar)))

  ;; assert that we incremented foobar n times
  (assert (= foobar 11)))

lặp lại với chỉ mục:

Macro này giống như repeat-itnhưng nó thực sự hoạt động giống như macro lặp chung, do-timesnó cho phép bạn chỉ định một biểu tượng sẽ được liên kết với chỉ mục vòng lặp. Nó sử dụng ký hiệu thời gian mở rộng để đảm bảo rằng biến chỉ số được đặt chính xác ở đầu mỗi vòng lặp bất kể bạn có sửa đổi giá trị của nó trong thân vòng lặp hay không.

(defmacro repeat-it-with-index (var-and-n &rest body)
  "Evaluate BODY N number of times with VAR bound to successive integers from 0 inclusive to n exclusive..
VAR-AND-N should be in the form (VAR N).
Returns the result of the last evaluation of the last expression in BODY."
  (declare (indent defun))
  (let ((fallback-sym (make-symbol "fallback")))
    `(let ((,(first var-and-n) 0)
           (,fallback-sym 0))
       ,(cons 'progn
              (make-list (second var-and-n)
                         `(progn
                            (setq ,(first var-and-n) ,fallback-sym)
                            ,@body
                            (incf ,fallback-sym)))))))

kiểm tra lặp lại với chỉ số:

Thử nghiệm này cho thấy:

  1. Cơ thể đánh giá N lần

  2. biến chỉ số luôn được đặt chính xác ở đầu mỗi lần lặp

  3. thay đổi giá trị của biểu tượng có tên "dự phòng" sẽ không gây rối với chỉ mục

;; repeat-it-with-index test
(progn
  ;; first expected index is 0
  (setq expected-index 0)

  ;; start repeating
  (repeat-it-with-index (index 50)
    ;; change the value of a  'fallback' symbol
    (setq fallback (random 10000))
    ;; assert that index is set correctly, and that the changes to
    ;; fallback has no affect on its value
    (assert (= index expected-index))
    ;; change the value of index
    (setq index (+ 100 (random 1000)))
    ;; assert that it has changed
    (assert (not (= index expected-index)))
    ;; increment the expected value
    (incf expected-index))

  ;; assert that the final expected value is n
  (assert (= expected-index 50)))

11

Giải tích lambda

λf.(λx.f (x x)) (λx.f (x x))

3
Tôi không chắc liệu điều này có được tính là đệ quy hay không, điều gì với cơ sở lý thuyết cơ bản cho nó ... +1 dù sao đi nữa.
lông mịn

@fluffy Không phải là đệ quy, không có hàm nào tự gọi (đặc biệt là vì các hàm không được đặt tên).
tự hào

IMHO, lambda tính toán là một mô hình tính toán và không phải là ngôn ngữ lập trình (tức là không có mô hình máy cụ thể, chúng ta không thể coi phép tính lambda là PL).
Tạ Thành Đình

Bạn hoàn toàn có thể xây dựng một máy giải thích tính toán lambda. Và cú pháp có thể được sử dụng như một ngôn ngữ lập trình. Xem ví dụ github.com/MaiaVictor/caramel
Arthur B

10

Haskell, 24 ký tự

sequence_ (repeat (print "abc"))

hoặc ở dạng cô đọng, có 24 ký tự

sequence_$repeat$print"" 

(mặc dù văn bản đã được thay đổi, nhưng điều này vẫn sẽ lặp lại - điều này sẽ in hai dấu ngoặc kép và một dòng mới vô hạn)

giải thích: in "abc" về cơ bản là một hành động i / o chỉ in "abc".
repeat là một hàm lấy một giá trị x và trả về một danh sách vô hạn chỉ gồm x.
Sequ_ là một hàm lấy danh sách các hành động i / o và trả về một hành động i / o thực hiện tất cả các hành động theo tuần tự.

vì vậy, về cơ bản, chương trình này tạo một danh sách vô hạn các lệnh in "abc" và liên tục thực thi chúng. không có vòng lặp hoặc đệ quy.


4
Về cơ bản, tôi sẽ đăng câu trả lời tương tự trong Clojure, nhưng tôi nghĩ repeatsẽ như vậy a programming language statement which allows code to be repeatedly executed.
hẹn gặp

3
fix(print"">>), điều này cũng liên quan đến không có chức năng lặp lại được đặt tên rõ ràng.
mniip

1
@TheRare Tôi không biết làm thế nào là đóng, nhưng trong Haskell lặp lại không phải là "một câu lệnh ngôn ngữ lập trình cho phép mã được thực thi nhiều lần" - đó là một hàm tạo danh sách vô hạn. đó là một vòng lặp giống như "int [] Array = {x, x, x};" là một vòng lặp.
tự hào

1
đúng, nhưng một cái gì đó phải được thực hiện bằng cách sử dụng đệ quy, bởi vì nếu không có nó thì về cơ bản là không thể
tự hào

3
Trên thực tế, mọi chức năng có trong mã này đều được xác định bằng cách sử dụng đệ quy - ngay cả in
tự hào

10

ASM (x86 + I / O cho Linux)

Không quan trọng các ngôn ngữ cấp cao trừng phạt của bạn sẽ vật lộn đến mức nào, nó vẫn sẽ chỉ là thao tác con trỏ lệnh ẩn. Cuối cùng, nó sẽ là một loại "goto" (jmp), trừ khi bạn đủ chán để bỏ vòng lặp trong thời gian chạy.

Bạn có thể kiểm tra mã trên Ideone

Bạn cũng có thể kiểm tra phiên bản tinh chỉnh hơn của ý tưởng này trong mã Matteo Italia DOS .

Nó bắt đầu bằng chuỗi 0..9 và thay thế nó bằng A..J, không có bước nhảy trực tiếp nào được sử dụng (vì vậy hãy nói rằng không có "goto" nào xảy ra), cũng không tái phát.

Mã có thể có thể nhỏ hơn với một số lạm dụng tính toán địa chỉ, nhưng làm việc trên trình biên dịch trực tuyến thật khó chịu vì vậy tôi sẽ để nó như vậy.

Phần cốt lõi:

mov dl, 'A' ; I refuse to explain this line!
mov ebx, msg ; output array (string)

call rawr   ; lets put address of "rawr" line on stack
rawr: pop eax ; and to variable with it! In same time we are breaking "ret"

add eax, 4 ; pop eax takes 4 bytes of memory, so for sake of stack lets skip it
mov [ebx], dl ; write letter
inc dl ; and proceed to next 
inc ebx
cmp dl, 'J' ; if we are done, simulate return/break by leaving this dangerous area
jg print

push eax ; and now lets abuse "ret" by making "call" by hand
ret

Toàn bộ mã

section     .text
global      _start                              

_start:

;<core>
mov dl, 'A'
mov ebx, msg

call rawr
rawr: pop eax

add eax, 4
mov [ebx], dl
inc dl
inc ebx
cmp dl, 'J'
jg print

push eax
ret
;</core>

; just some Console.Write()
print:
    mov     edx,len
    mov     ecx,msg
    mov     ebx,1
    mov     eax,4
    int     0x80

    mov     eax,1
    xor     ebx, ebx
    int     0x80

section     .data

msg     db  '0123456789',0xa
len     equ $ - msg

Tôi sẽ gọi đây là bản sao của codegolf.stackexchange.com/a/34298/11259 , nhưng tôi thấy đây là câu trả lời trước đó. +1
Chấn thương kỹ thuật số

@DigitalTrauma oh, tôi thấy ai đó đã thực hiện phiên bản tinh tế của ý tưởng của tôi - thủ thuật cũ, nhưng trong thời đại của mã được quản lý, mọi người có xu hướng quên cách mọi thứ thực sự hoạt động. (Tôi không thích chơi gôn, quá thường xuyên, nó được giảm xuống thành "nhìn mẹ! Tôi có thể khiến mọi thứ xảy ra bằng cách nhấn một phím!")
PTwr

9

C Tiền xử lý

Một "kỹ thuật" nhỏ mà tôi đã nghĩ ra trong một thử thách khó khăn. Không có đệ quy hàm, nhưng có ... đệ quy tập tin?

noloop.c:

#if __INCLUDE_LEVEL__ == 0
int main() 
{
    puts("There is no loop...");
#endif
#if __INCLUDE_LEVEL__ <= 16
    puts(".. but Im in ur loop!");
    #include "noloop.c"
#else
    return 0;
}
#endif

Tôi đã viết / kiểm tra điều này bằng cách sử dụng gcc. Rõ ràng trình biên dịch của bạn cần hỗ trợ __INCLUDE_LEVEL__macro (hoặc thay vào đó là __COUNTER__macro với một số điều chỉnh) để biên dịch. Nó khá rõ ràng về cách thức hoạt động của nó, nhưng để giải trí, hãy chạy bộ tiền xử lý mà không biên dịch mã (sử dụng -Ecờ với gcc).


8

PHP

Đây là một với PHP. Vòng lặp bằng cách bao gồm cùng một tệp cho đến khi bộ đếm đạt $ max:

<?php
if (!isset($i))
    $i = 0;        // Initialize $i with 0
$max = 10;         // Target value

// Loop body here
echo "Iteration $i <br>\n";

$i++;               // Increase $i by one on every iteration

if ($i == $max)
    die('done');    // When $i reaches $max, end the script
include(__FILE__);  // Proceed with the loop
?>

Giống như một vòng lặp for:

<?php
for ($i = 0; $i < 10; $i++) {
    echo "Iteration $i <br>\n";
}
die('done');
?>

Chết tiệt, điều này cũng được tính là đệ quy, phải không?
Pichan

Đừng nghĩ đó là - sự giống nhau xuất hiện trong ví dụ của @ Nathaniel: bộ tiền xử lý sẽ bao gồm các tệp này sau đó được đánh giá đồng thời.

@Pichan Tôi sẽ nói rằng đó là nhiều hơn về vòng lặp mở ra, khi bạn kết thúc với các bản sao của mã trong bộ nhớ.
PTwr

Tôi chỉ thấy câu hỏi ngày hôm nay và đưa ra mã gần như giống hệt nhau. Quá muộn cho tôi!
TecBrat

Được header("Location: .?x=".$_GET['x']+1);tính là đệ quy?
Charlie

8

Con trăn

Đoạn mã sau không chứa hàm đệ quy (trực tiếp hoặc gián tiếp), không có vòng lặp nguyên thủy và không gọi bất kỳ hàm dựng sẵn nào (ngoại trừ print):

def z(f):
    g = lambda x: lambda w: f(lambda v: (x(x))(v), w)
    return g(g)

if __name__ == "__main__":
    def msg(rec, n):
        if (n > 0):
            print "Hello world!"
            rec(n - 1)
    z(msg)(7)

In "Xin chào thế giới!" một số lần nhất định.

Giải thích: Hàm zthực hiện bộ kết hợp điểm cố định Z nghiêm ngặt , (trong khi không được xác định đệ quy) cho phép thể hiện bất kỳ thuật toán đệ quy nào.


Tôi sẽ gọi grất nhiều đệ quy gián tiếp.
xem

@TheRare Tại sao? Lập luận của bạn là gì? Cái gì ggọi mà gọi glại? Tất nhiên rằng mánh khóe là tự áp dụng g(g), nhưng không có đệ quy liên quan. Bạn thực sự sẽ gọi gđệ quy gián tiếp nếu bạn chưa thấy g(g)? Đây là cách tiêu chuẩn để làm điều đó trong các ngôn ngữ không cho phép định nghĩa đệ quy, chẳng hạn như phép tính lambda.
Petr Pudlák

Bạn đưa ra gnhư là đối số xvà sau đó gọi x(x).
xem

2
@TheRare Một hàm (hoặc một tập hợp các hàm) không đệ quy hoặc không đệ quy theo cách nó được sử dụng, điều này được xác định chỉ bằng định nghĩa của nó.
Petr Pudlák

1
tất cả các câu trả lời gian lận theo cách này hay cách khác: luôn luôn có đệ quy hoặc một vòng lặp ở đâu đó , nếu không có trong câu trả lời, thì trong mã, câu trả lời sẽ được gọi. Tôi thích cách này gian lận.
Wayne Conrad

8

mã máy z80

Trong môi trường nơi bạn có thể thực thi tại mọi địa chỉ và ánh xạ ROM ở mọi nơi, hãy ánh xạ 64kb ROM chứa đầy số không vào toàn bộ không gian địa chỉ.

Nó làm gì: không có gì. Nhiều lần.

Cách thức hoạt động: bộ xử lý sẽ bắt đầu thực thi, byte 00là một noplệnh, vì vậy nó sẽ tiếp tục, tiếp cận địa chỉ $ffff, bao quanh $0000và tiếp tục thực thinop s cho đến khi bạn đặt lại nó.

Để làm cho nó thú vị hơn một chút, hãy lấp đầy bộ nhớ bằng một số giá trị khác (cẩn thận để tránh các hướng dẫn luồng điều khiển).


Bạn có thể lấp đầy bộ nhớ bằng các số 0 và đặt một chương trình thực sự ở đó vào đâu đó.
xem

Vì vậy, bạn có thể đưa vào một chương trình 64k, không có phân nhánh nào, và nó sẽ liên tục thực hiện?
Bill Woodger

@BillWoodger bạn có thể, đặc biệt nếu bạn không có sự gián đoạn nào trên nền tảng (hoặc không được kích hoạt)
harold

Loại niềm vui :-)
Bill Woodger

8

Perl-regex

(q x x x 10) =~ /(?{ print "hello\n" })(?!)/;

bản giới thiệu

hoặc thử nó như:

perl -e '(q x x x 10) =~ /(?{ print "hello\n" })(?!)/;'

Không (?!)bao giờ phù hợp. Vì vậy, công cụ regex cố gắng khớp từng vị trí có độ rộng bằng 0 trong chuỗi khớp.

Điều (q x x x 10)này giống như (" " x 10)- lặp lại spacemười lần.

Chỉnh sửa: thay đổi "ký tự" thành các vị trí có độ rộng bằng 0 để chính xác hơn để dễ hiểu hơn. Xem câu trả lời cho câu hỏi stackoverflow này .


6

T-SQL -12

print 1
GO 9

Trên thực tế, nhiều hơn một chút của Sql Server Management Studio. GO là một dấu tách tập lệnh và không phải là một phần của ngôn ngữ T-SQL. Nếu bạn chỉ định GO theo sau bởi một số, nó sẽ thực thi khối đó nhiều lần.


1
Tôi sử dụng T-SQL gần như hàng ngày và không biết rằng bạn có thể làm điều này với GO. +1
CailinP

Về mặt kỹ thuật, đó không phải là T-SQL. GOthực sự là một lệnh SSMS, đó là lý do tại sao bạn không thể đặt nó trong các đối tượng kịch bản T-SQL, như nói một thủ tục được lưu trữ.
RBarryYoung

Vâng, tôi đã thêm rằng trong bình luận spoiler của tôi. Tôi nghĩ rằng sử dụng sqlcmd sẽ là quá nhiều gian lận.
Michael B

6

C #

In ra tất cả các số nguyên từ uint.MaxValue thành 0.

   class Program
   {
      public static void Main()
      {
          uint max = uint.MaxValue;
          SuperWriteLine(ref max);
          Console.WriteLine(0);
      }

      static void SuperWriteLine(ref uint num)
      {
          if ((num & (1 << 31)) > 0) { WriteLine32(ref num); }
          if ((num & (1 << 30)) > 0) { WriteLine31(ref num); }
          if ((num & (1 << 29)) > 0) { WriteLine30(ref num); }
          if ((num & (1 << 28)) > 0) { WriteLine29(ref num); }
          if ((num & (1 << 27)) > 0) { WriteLine28(ref num); }
          if ((num & (1 << 26)) > 0) { WriteLine27(ref num); }
          if ((num & (1 << 25)) > 0) { WriteLine26(ref num); }
          if ((num & (1 << 24)) > 0) { WriteLine25(ref num); }
          if ((num & (1 << 23)) > 0) { WriteLine24(ref num); }
          if ((num & (1 << 22)) > 0) { WriteLine23(ref num); }
          if ((num & (1 << 21)) > 0) { WriteLine22(ref num); }
          if ((num & (1 << 20)) > 0) { WriteLine21(ref num); }
          if ((num & (1 << 19)) > 0) { WriteLine20(ref num); }
          if ((num & (1 << 18)) > 0) { WriteLine19(ref num); }
          if ((num & (1 << 17)) > 0) { WriteLine18(ref num); }
          if ((num & (1 << 16)) > 0) { WriteLine17(ref num); }
          if ((num & (1 << 15)) > 0) { WriteLine16(ref num); }
          if ((num & (1 << 14)) > 0) { WriteLine15(ref num); }
          if ((num & (1 << 13)) > 0) { WriteLine14(ref num); }
          if ((num & (1 << 12)) > 0) { WriteLine13(ref num); }
          if ((num & (1 << 11)) > 0) { WriteLine12(ref num); }
          if ((num & (1 << 10)) > 0) { WriteLine11(ref num); }
          if ((num & (1 << 9)) > 0) { WriteLine10(ref num); }
          if ((num & (1 << 8)) > 0) { WriteLine09(ref num); }
          if ((num & (1 << 7)) > 0) { WriteLine08(ref num); }
          if ((num & (1 << 6)) > 0) { WriteLine07(ref num); }
          if ((num & (1 << 5)) > 0) { WriteLine06(ref num); }
          if ((num & (1 << 4)) > 0) { WriteLine05(ref num); }
          if ((num & (1 << 3)) > 0) { WriteLine04(ref num); }
          if ((num & (1 << 2)) > 0) { WriteLine03(ref num); }
          if ((num & (1 <<  1)) > 0) { WriteLine02(ref num); }
          if ((num & (1 <<  0)) > 0) { WriteLine01(ref num); }
      }

      private static void WriteLine32(ref uint num) { WriteLine31(ref num); WriteLine31(ref num); }
      private static void WriteLine31(ref uint num) { WriteLine30(ref num); WriteLine30(ref num); }
      private static void WriteLine30(ref uint num) { WriteLine29(ref num); WriteLine29(ref num); }
      private static void WriteLine29(ref uint num) { WriteLine28(ref num); WriteLine28(ref num); }
      private static void WriteLine28(ref uint num) { WriteLine27(ref num); WriteLine27(ref num); }
      private static void WriteLine27(ref uint num) { WriteLine26(ref num); WriteLine26(ref num); }
      private static void WriteLine26(ref uint num) { WriteLine25(ref num); WriteLine25(ref num); }
      private static void WriteLine25(ref uint num) { WriteLine24(ref num); WriteLine24(ref num); }
      private static void WriteLine24(ref uint num) { WriteLine23(ref num); WriteLine23(ref num); }
      private static void WriteLine23(ref uint num) { WriteLine22(ref num); WriteLine22(ref num); }
      private static void WriteLine22(ref uint num) { WriteLine21(ref num); WriteLine21(ref num); }
      private static void WriteLine21(ref uint num) { WriteLine20(ref num); WriteLine20(ref num); }
      private static void WriteLine20(ref uint num) { WriteLine19(ref num); WriteLine19(ref num); }
      private static void WriteLine19(ref uint num) { WriteLine18(ref num); WriteLine18(ref num); }
      private static void WriteLine18(ref uint num) { WriteLine17(ref num); WriteLine17(ref num); }
      private static void WriteLine17(ref uint num) { WriteLine16(ref num); WriteLine16(ref num); }
      private static void WriteLine16(ref uint num) { WriteLine15(ref num); WriteLine15(ref num); }
      private static void WriteLine15(ref uint num) { WriteLine14(ref num); WriteLine14(ref num); }
      private static void WriteLine14(ref uint num) { WriteLine13(ref num); WriteLine13(ref num); }
      private static void WriteLine13(ref uint num) { WriteLine12(ref num); WriteLine12(ref num); }
      private static void WriteLine12(ref uint num) { WriteLine11(ref num); WriteLine11(ref num); }
      private static void WriteLine11(ref uint num) { WriteLine10(ref num); WriteLine10(ref num); }
      private static void WriteLine10(ref uint num) { WriteLine09(ref num); WriteLine09(ref num); }
      private static void WriteLine09(ref uint num) { WriteLine08(ref num); WriteLine08(ref num); }
      private static void WriteLine08(ref uint num) { WriteLine07(ref num); WriteLine07(ref num); }
      private static void WriteLine07(ref uint num) { WriteLine06(ref num); WriteLine06(ref num); }
      private static void WriteLine06(ref uint num) { WriteLine05(ref num); WriteLine05(ref num); }
      private static void WriteLine05(ref uint num) { WriteLine04(ref num); WriteLine04(ref num); }
      private static void WriteLine04(ref uint num) { WriteLine03(ref num); WriteLine03(ref num); }
      private static void WriteLine03(ref uint num) { WriteLine02(ref num); WriteLine02(ref num); }
      private static void WriteLine02(ref uint num) { WriteLine01(ref num); WriteLine01(ref num); }
      private static void WriteLine01(ref uint num) { Console.WriteLine(num--); }
   }

1
Tôi thực sự không biết nếu điều này được tính. Bạn rõ ràng đang gọi WriteLine01 Int.MaxValue lần. Nó chỉ phát nổ đằng sau một lượng lớn callstack.
Michael B

Làm thế nào nó không được tính? Không có vòng lặp và không có đệ quy.
LVBen

1
Ngoài ra, ngăn xếp cuộc gọi không ở bất cứ đâu gần khối lượng lớn trừ khi bạn có thể coi mức cao của 32 cuộc gọi là lớn.
LVBen

1
Tại sao chỉ có 32 lần thay vì 4294967296 lần?
LVBen

4
@ ja72 Nếu tôi từng làm việc trong một dự án nguồn mở mà tôi không thể sử dụng các vòng lặp hoặc đệ quy, thì tôi hoàn toàn sẽ đóng góp mã như thế này!
LVBen

6

JS (trong trình duyệt)

Còn cái này thì sao?

document.write(new Date());
location = location;

In thời gian hiện tại và tải lại trang.


Ôi bắn. Tôi chỉ đăng một câu trả lời với khái niệm cơ bản tương tự. Tôi đã quét trang "JavaScript" hoặc bất cứ thứ gì hiển thị thẻ HTML. Tôi cho rằng tôi có thể để lại câu trả lời của mình, chỉ vì nó xử lý trường hợp góc trong đó vị trí chứa "#". Dù sao, +1.
Keen

Trong Firefox 30:[Exception... "The operation is insecure." code: "18" nsresult: "0x80530012 (SecurityError)" location: "<unknown>"]
Alex Reynold

@AlexReynold Huh, lạ thật. Của tôi chỉ hoạt động tốt trên FF 30.
Pichan

Tôi chỉ sao chép và dán mã của bạn như nó đã được viết. Nó không hoạt động. Có lẽ bạn có một số tùy chọn bảo mật đặc biệt được kích hoạt để làm cho công việc này?
Alex Reynold

@AlexReynold Không, không bao giờ thay đổi bất kỳ cài đặt bảo mật. Và nó cũng hoạt động trên Chrome.
Pichan
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.