「ループ」なしのループ[終了]


85

これに似た質問が数年前に聞かれましたが、これはさらにトリッキーです。

挑戦は簡単です。繰り返しのような任意の繰り返し構造を使用せずにコードを実行(選択した言語での)プログラム書きwhilefordo whileforeachまたはgotoだから、すべてあなたnitpickersのために、あなたはループを使用することはできませんが)。ただし、関数自体がセンスを呼び出すため再帰は許可されません(以下の定義を参照)。そうすれば、この課題は非常に簡単になります。

ループで何を実行する必要があるかについての制限はありません、他の人が実装されているものを正確に理解できるように、答えを説明してください

定義にこだわる人のために、この質問のループの定義は次のとおりです。

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

そして、この質問の再帰の定義は、標準の再帰関数定義になります。

A function that calls itself.

勝者は、7月16日午前10時の東部時間に最も投票数が多い回答になります。幸運を!

更新:

まだ表現されている混乱を鎮めるために、これは役立つかもしれません:

上記のルール:

  • ループやgotoを使用しないでください
  • 関数は自分自身を呼び出すことはできません
  • 「ループ」で何でもしたい

何かを実装したいが、ルールで明示的に禁止されていない場合は、先に進んでください。多くの答えがすでにルールを曲げています。


27
簡単なトリックをしたい人のために、私はそれを投稿気にすることはできません:Pは、わずか2つの機能、作るfunction Aの呼び出しfunction Bfunction B呼び出しのfunction A機能の1が何かを実行している間。関数はそれ自体を呼び出さないため、基準に基づいて有効である必要があります^。^
Teun Pronk 14

2
「創造性に焦点を当てた人気コンテストに変更されました」質問の変更はごまかしです!
いとこコカイン14

4
「再帰」の定義はあまり役に立ちません。直接または間接的に自分自身を参照する関数である再帰関数を許可しない方が良いでしょう。
LRN

3
不明な点は、ループコンストラクターと再帰の「定義」です。どちらも非常に正確ではありません。例:rep(f){f();f();}-これは、コードの繰り返し実行を許可するステートメント(関数宣言は一部の言語のステートメントです)です。許可されていません。ループを実装するコードを要求します。そのコードが構文的に文である場合、あなたはそれをちょうど禁止しました。別の例:f(b) { b(); g(b); }; g(b) { f(b); }。私は言うf(再帰関数であるとg)再帰関数です。許可されていませんか?
lrn 14

3
@CailinP、私が「ハングアップ」しているのは、サイト上の質問はサイトのトピックに関するものでなければならないということです。つまり、この質問にはない明確で客観的な仕様を持つことを意味します。
ピーターテイラー14

回答:


258

ルビー

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

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

ahem

デモ

のどを取り除き、「バナナ」を3070回印刷し、「バナナを言わなかったので嬉しいオレンジ?」と書きます。

これは、Rubyのとんでもないメソッド定義機能を使用して、「ahem」と「also」(「ahem」、「ahen」、「aheo」、「ahep」、「aheq」、 「aher」、「ahes」、「ahet」、「aheu」、「ahev」...)で最初にバナナを印刷してから、リストの次を呼び出します。


4
最終的に「また」ヒットします。これも定義されているため、欠落していません。
histocrat

77
これはヒステリックです。
マイケルB 14

4
@barrycarter:RubyではString#nextmethod_missingすべての英数字(および文字列の唯一の文字である場合は非数字)で機能することを除いて、数値に1を追加するような関数で呼び出されます。参照してくださいruby-doc.org/core-2.1.2/String.html#method-i-next
3Doubloons

2
@NickTは、XML Builderのようなクラスで使用でき、そこでのみタグを作成できますb.my_tag。ActiveRecordモデルまたはでも使用されOpenStructます。「Wat talk」で、彼はグローバルmethod_missingは悪いが、スコープは素晴らしいと言っています。
Hauleth

2
私は別のRubyプログラム上の古いコメントを覚えている:「それはメタ持っているので、私はそれが好き」
vidyaのサーガル

82

Python-16

またはevalを持つ他の言語。

exec"print 1;"*9

あなたのプログラムが何をするのか説明できますか?
CailinP 14

10
文字列("print 1;")を取り、9回複製し(*9)、結果の文字列(exec)を実行します。実際にループすることなく、コードの塊を繰り返します。
scragar

12
文字列の乗算に賛成です!
ターネブリムホール14

2
あなたが変更した場合も、Rubyで働くexeceval printecho
Ajedi32 14

80

Cシャープ

これはもはやゴルフのコードではないため、コードをより読みやすい形式に拡張し、このプログラムが何かを実行していることを実際に確認できるようにインクリメントカウンターを追加しました。

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

(これを絶対にしないでください)。

開始時にPクラスの新しいインスタンスを作成します。プログラムが終了しようとすると、Pクラスの新しいインスタンスを作成するファイナライザーを呼び出すGCが呼び出されますP。 。

プログラムは最終的に死にます。

編集:不可解なことに、これは死ぬ前に約45k回だけ実行されます。GCが私のトリッキーな無限ループをどのように理解したかはよくわかりませんが、理解できました。要するに、それはそれを理解していないようで、スレッドは約2秒の実行後に殺されただけです:https : //stackoverflow.com/questions/24662454/how-does-a-garbage-collector-avoid-an -無限ループ-ここ

編集2:これが再帰に少し似ていると思われる場合は、他のソリューションを検討してくださいhttps://codegolf.stackexchange.com/a/33268/23300

ジェネリックメソッドの具体化を使用して、実行時に常に新しいメソッドを生成し、用語の各メソッドが新しく作成されたメソッドを呼び出すようにします。reference通常、ランタイムはこれらのメソッドのコードを共有できるため、型パラメーターの使用も避けます。ではvaluetypeパラメータランタイムは、新しいメソッドを作成することを余儀なくされます。


20
C#にデストラクタがあることすら知りませんでした。教えてくれて+1。
seequ 14

4
@TheRare、そうですが、それらは本質的に非決定論的であり、プログラムの実行中に呼び出されることはありません。これらは仮想メソッドのオーバーライドとして実装されるFinalizeため、時々呼び出されfinalizerます。実際のC#では、IDisposableパターンを使用する必要があります。
マイケルB 14

ある時点でタイムアウトが発生したようです。サイクルを停止しているのはGCであるとは思わないが、代わりにオペレーティングシステムがプログラムの終了に時間がかかりすぎると判断している。
LVBen

これは、実際には、必ずしもOSではなくプログラムを強制終了することを決定するランタイムだと思います。プログラムの終了時に呼び出されるガベージコレクタースレッドには、強制終了されるまでに約2秒の固定時間制限が与えられます。
マイケルB 14

いくつかの小さな変更(プログラムを終了させず、最初のPオブジェクトをGCに解放し、GC.Collectを繰り返し呼び出す)を行うと、無期限に実行することができます。
LVBen 14

53

ベファンジ

.

古き良きBefungeは、行が折り返されるので、(空のスタックから)0をほとんど永久に出力します。


1
ハ!このようなトリックが大好き
CailinP 14

47

JS

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

機能楽しい!

それ自体と同じ本体を持つ別の関数を作成し、それを実行する関数。

スタックの制限に達し、全体が崩壊すると、最後にhiが表示されます。

免責事項:スタック制限に達するまで、ブラウザで何もできません。


そしてもう1つ、もっと

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

ウィンドウを開く関数を作成し、そのウィンドウ内に関数のコピーである関数を作成して実行します。

免責事項:ポップアップを開くことを許可する場合、これを完了する唯一の方法はコンピューターを再起動することです


5
これは確かにかなり悪です;)
CailinP 14

28
@CailinP確かに評価されています。
seequ 14

f2番目の関数の最後にが欠けていると思います。}f()最後にあるはずです。
チラグバティア-chirag64 14

2
残念ながら、私はそれを試したので気づきました。:P
チラグバティア-chirag64 14

7
-1-これは単なる再帰です。
user253751 14

39

x86アセンブリ/ DOS

    org 100h

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

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

逆テール再帰はないと言いましたか?私は? madame mim purple dragons

使い方

ret関数から戻るために使用される命令は、実際に(通常は対応させてそこに置かれているスタックからリターンアドレスをポップcall)とそれにジャンプ。ここで、各反復でpush、戻る前にスタック上のエントリポイントアドレスを取得し、無限ループを生成します。


これがアセンブリで可能かどうか疑問に思っていました。
イアンD.スコット14


1
私はコールアウトするつもりだったcodegolf.stackexchange.com/a/34295/11259をこの1のDUPとして、私はそれが実際に以前の答えである参照
デジタルトラウマ

@DigitalTrauma:ええ、エントリーを投稿した後に気づきましたが、Mimame Mimの写真に執着しました。:-)幸いなことにいくつかの違いがあります(彼はもう少し難読化されており、32ビットLinuxで動作します。私のものはDOSで直接プレイされ、他のジャンプはありません)。
マッテオイタリア14

@MatteoItalia難読化されていない、ただくだらない;)(tho "add eax、4"も私を混乱させました。オペコードサイズテーブルが見つからなかったので、サイズを推測しました)。作業プロジェクトのコンパイル中にオンラインコンパイラで作成したため、恐ろしく見えます。「start:」を使用することをお勧めします。
PTwr 14

37

Java

XKCDから直接

Bonding

それは親と子の間のキャッチの終わりのないゲームです!

のターゲットCHILDはに設定されPARENT、のターゲットはPARENTですCHILD。をPARENT呼び出すAIMと、BALLクラスのインスタンスがスローされ、catchステートメントによってキャッチされます。catchステートメントPARENT.TARGET.AIMは、ターゲットがである場所を呼び出しますCHILDCHILDインスタンスは、同じことをして親に「ボールを投げるバック」。


3
私はそれらの漫画が好きです!
デレク朕會功夫14

1
ボールが実際に親と子の間で投げられていたらもっといいでしょう。現状のまま、ボールは常に同じ「人」に投げられて捕まえられます。
Ajedi32

@ Ajedi32実際に前後にスローするように見えます。親TARGETは子であり、子のターゲットは親です。狙いは親に呼ばれ、ボールを投げ、子供にボールを投げさせ、ボールを投げさせる、キューループ
アレックスコールマン14

12
@AlexColemanこのコードは、親が空中にボールを投げてキャッチし、ボールを親に戻す前に同じことを行う子供に渡すなどに似ています。
Ajedi32 14

11
TARGET.AIM(B);method のコマンドはAIM再帰呼び出しです。したがって、これは「関数は自分自身を呼び出せない」ルールに違反します。
セオドアノーベル

31

バッシュ、3文字

yes

yesはコンソールに「y」を繰り返し返します

編集:誰もがこの行を編集することをお勧めします:

yes something | xargs someaction

(Olivier Dulacに感謝)


1
なぜこれが実行され続けるのですか?理由を理解しようとするだけで疑問を投げかけているわけではありません。
テウンプロンク14

2
@TeunPronk yesは、削除されるかストリームが閉じられるまでyesという単語を出力するbashコマンドです。画面に書き込んでいる場合は、強制終了するまで停止しません。基本的にprintfのループで構成されるコマンドであるため、これは一種の不正行為です。
scragar

1
もっと楽しいのはyes、他のループを継続して使用することです。
trlkly 14

3
@izkata:しかし、次のことができます。yes something | xargs someaction::再帰なし(xargsに-n 1を追加して、行ごとに「何か」を1つだけにすることなどもできます)。xargsを使用すると、より複雑な動作(yes出力とはまったく関係のない動作も含む)が可能になります
オリビエデュラック14

4
@scragarはあなたがちょうど答えるべきでしたyes
daviewales

28

C、35文字

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

プログラムはそれ自体を実行します。これが再帰と見なされるかどうかはわかりません。


4
@mniipテール再帰、プロセスレベルで適用する場合
Izkata 14

3
@Izkata Tailの再帰は依然として再帰ですが、これは再帰ではありません。再帰とは、それ自体の別の反復が終了するのを「待機」する関数(この場合はプロセス)を意味します。この場合、exec新しいプロセスが元のプロセスを置き換えるため、最終的に返されるかオーバーフローする呼び出しスタックはありません。
ミリノン14

4
@millinon最適化をサポートする言語でexecは、前のプロセスを置き換える方法と同様に、末尾再帰が呼び出しスタック内の前の呼び出しを置き換えます。オーバーフローもしません。
イズカタ14

1
@millinonは、非常に独創的であり、Schemeプログラミング言語では、この議論をより長く引き出すために、この最適化言語機能です。末尾再帰呼び出しを行う場合、インタプリタ/コンパイラ最後のスタックフレームを再利用する必要があるという仕様にあります。Schemeは何も組み込まれているので、構造をループこれがないので、Schemeでループを実装するための唯一の方法は、末尾再帰を行うことです、そしてあなたがループに何回も試みてからオーバーフローを積み重ねてしまった場合、それは一種の吸うでしょう:)
オード14

2
ペダントリーが必要な場合、Schemeには「テールコールの最適化」がなく、「適切なテールコール」があります。それは最適化ではなく、言語標準の基本的な要件であり、それを提供しないことは許可されないため、「最適化」(または再帰と関係があるという提案)は非常に落胆した用語です。
ルーシェンコ14

28

C(GCCビルトインを使用-clangでも動作するようです)

  • 明示的なループなし
  • 明示的なgotoはありません
  • 再帰なし
  • 昔ながらのスタックをいじるだけです(子供たち、監督なしで家でこれを試さないでください):
#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);
    }
}

説明:

  • main()最初の呼び出しframeloop(NULL)。この場合、__builtin_return_address()組み込み関数を使用して、戻り先の戻りアドレス(main())を取得frameloop()します。このアドレスを返します。
  • printf() ループしていることを示すために
  • 今、私たちframeloop()は前の呼び出しのリターンアドレスで呼び出します。スタックを調べて現在の返信先アドレスを探し、見つかったら以前の返信先アドレスに置き換えます。
  • その後、2回目のframeloop()呼び出しから戻ります。しかし、返信先アドレスが上記のようにハッキングされmain()たため、最初の呼び出しが戻るポイントに戻ることになります。したがって、ループになります。

スタック内のリターンアドレスの検索は、もちろんループとしてはよりクリーンになりますが、ループがまったくないために、いくつかの反復を展開しました。

出力:

$ 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
いいね!これらの関数がC仕様の一部ではないのはなぜですか?;-D
ブライアンミントン

4
@BrianMinton実際には、setjmp()/で同様のことを達成できるはずlongjmp()です。これらはc標準にはありませんが、標準ライブラリにあります。私は;-)かかわらず、今日、手動でスタックをいじるように感じた
デジタルトラウマ

@BrianMinton私の推測では、CPU仕様にあるため、(ハードウェア)プラットフォームに依存します。また、stackframeが自動生成されるときに使用するのはかなり危険です。そのようなコードについてAVが泣いても驚かないでしょう。これまたはx86 asmバージョンについてはこれを確認してください。
PTwr 14

27

ハスケル

次のコードには、再帰関数も(間接的にも)ループプリミティブも含まれておらず、組み込みの再帰関数は呼び出されませんIOの出力とバインディングのみを使用します)が、指定されたアクションを無限に繰り返します:

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" >>)

関数extractは何も呼び出さず、ycjust extractmain呼び出し、just ycputStrLnand を呼び出します>>が、これらは再帰的ではありません。

説明:トリックは再帰データ型にありStrangeます。これは、それ自体を消費する再帰的なデータ型であり、例に示すように、任意の繰り返しを許可します。まず、を構築できますextract x。これは、本質的x xに型指定のないラムダ計算で自己適用を表現します。これにより、と定義されたYコンビネータを構築できますλf.(λx.f(xx))(λx.f(xx))


更新:提案されているように、型なしラムダ計算のYの定義により近いバリアントを投稿しています。

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
再帰関数の代わりに再帰データ構造...いいね。
ApproachingDarknessFish 14

6
これは、完全な機能プログラミングに興味がある人である私の心に近いものです。負の繰り返しデータ型を使用してYコンビネーターを作成する方法を示しました。これが、言語全体で矢印の右側に繰り返しタイプが必要であり、バラの木が許可されていない理由です。良いですね!これを支持するためだけにここでアカウントを作成しました!
ジェイク

あなたは削除できletバインディングを定義してyc f = extract $ C $ f.extractいるので、let間違いなく再帰(古典を可能にする言語機能を結合しますlet x = x in x)。これにより、一部の文字も削減されます:)
Earth Engine 14

またはyc = extract . C . (.extract)
Earth Engine 14

@EarthEngine確かに、構造をの元の定義に近づけたいだけですY
PetrPudlák14年

26

C ++

以下は、10から「Blast off!」へのカウントダウンを出力します テンプレートのメタプログラミングを使用します。

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

再帰の古典的な例のように見えるかもしれませんが、実際には、少なくとも技術的には、定義によって異なります。コンパイラーは、10個の異なる関数を生成します。countdown<10>「T-10」を出力countdown<9>してからを呼び出し、以下同様に、countdown<0>「Blast off!」を出力します。そして戻ります。コードをコンパイルすると再帰が発生しますが、実行可能ファイルにはループ構造が含まれていません。

C ++ 11ではconstexpr、この階乗関数など、キーワードを使用して同様の効果を実現できます。(constexpr関数には副作用がないため、このようにカウントダウンの例を実装することはできませんが、今後のC ++ 14では可能になると思います。)

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

繰り返しますが、これは本当に再帰のように見えますが、コンパイラはに展開さfactorial(10)10*9*8*7*6*5*4*3*2*1、おそらく定数値で置き換えられる3628800ため、実行可能ファイルにはループや再帰的なコードは含まれません。


4
これらの2番目は、純粋で単純な再帰であり、メタプログラミングではありません。第一に、コンパイラは(一般的な場合)非定数の引数で使用するための通常の関数本体を出力するためです。それはコンパイル時の操作を実行したときに、それはそのテンプレートスタイル「拡張」もののいずれかを実行していないため、第二に、それは標準のインプレース評価を実行-実行時のものと同じで-生成する3628800ことなく、直接、中間形式。
ルーシェンコ14

@Leushenkoそうだね。しかし、テンプレート例の例も同じことを行います-コンパイル時にチューリング完全言語で再帰関数を使用します-唯一の違いは、constexprがC ++によく似た言語を使用することです。すべての答えと同様に、これはルールを曲げます、そして私はそれについて正直です。constexprは、テンプレートメタプログラミング(の一部)を廃止するように特別に設計されたため、このテーマに関する投稿で言及する価値があることは間違いありません。
ナサニエル14

1
1: &countdown<N-1> != &countdown<N>
トーマスエディング14

21

Java

Javaクラスローダーで遊んで、それを独自の親として設定しましょう:

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());

    }
}

このループは実際には非常に強いため、a kill -9を使用して停止する必要があります:-)

MacのCPUの10.1%を使用します。

CPUの10.1%

System.outメイン関数の最後にを移動して、別の面白い動作を試すことができます。


笑。Javaがそれ自体で立ち往生する:)
masterX244 14

JVMの再帰的な読み込みハックが大好きです。
イサイアメドウズ14

20

Cシャープ

もう一つの等しく邪悪な::

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

これは再帰ではありません...これはコードテンプレートの具体化です。同じメソッドを呼び出しているように見えますが、ランタイムは常に新しいメソッドを作成しています。intのtypeパラメーターを使用します。これにより、実際には完全に新しい型が作成され、メソッドの各インスタンスが新しいメソッドを作成する必要があります。ここでコードを共有することはできません。最終的には、約束したが配信されなかったintが返されるまで無限に待機するため、呼び出しスタックを強制終了します。同様に、面白くするために作成した型を書き続けます。基本的に、呼び出すCは、まったく同じボディを持つまったく新しいメソッドです。これは、コンパイル時にテンプレートを実行するC ++やDのような言語では実際には不可能です。C#JITは非常に怠zyであるため、可能な限り最後にこのようなものを作成するだけです。副<文>この[前述の事実の]結果として、それ故に、従って、だから◆【同】consequently; therefore <文>このような方法で、このようにして、こんなふうに、上に述べたように◆【同】in this manner <文>そのような程度まで<文> AひいてはB◆【用法】A and thus B <文>例えば◆【同】for example; as an example、


14

Redcode 94(コア戦争)

MOV 0, 1

アドレス0の命令をアドレス1にコピーします。Core Warでは、すべてのアドレスは現在のPCアドレスに関連し、コアのサイズを法とするため、これは1つの非ジャンプ命令の無限ループです。

このプログラム(戦士)は " Imp "と呼ばれ、AK Dewdneyによって最初に公開されました。


3
インプは行進し、あなたの門の準備をし、それらの準備をしなければ、あなたは押しつぶされるでしょう。
seequ 14

SPL 0, 0; MOV 1, -2本当に準備ができています。
wberry 14

ニース、これがまだ投稿されていないことを望んでいました。+1
mbomb007

14

ダーツ

これは、実際の再帰関数なしで再帰を行う古典的な方法だと思います。以下の関数は、それ自体を直接または間接的に名前で参照することはありません。

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
Yコンビネーター?
aditsu

5
厳密に言えば、厳密な言語向けであるため、Zコンビネータだと思います。Yコンビネータには、無限の展開を避けるために遅延言語が必要です。唯一の違いは、後半部分がイータ拡張されていることです。
lrn 14

12

JS

オリジナルではありませんが、小さいです。20文字。

setInterval(alert,1)

あなたが実際に削除することができ,1、それはまだ動作します
デレクを朕會功夫

@Derek朕會功夫私は、私はFirefoxのみで1つのアラートを取得することを行う場合
XEM

1
クロムでは、最後のパラメーターなしで機能します。少なくとも1つの環境で動作する場合、コードは有効であるとカウントする必要があります。
デレク朕會功夫14

3
ただし、@ Derek朕會功夫setIntervalは声明ではありません。それは単なる機能です。式ステートメント内で使用されます。式ステートメントを使用できない場合は、それ以上知りません。
キーン14

1
@Cory-それはそれで有効だと思います!
デレク朕會功夫14

12

Cの信号

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

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

このプログラムの動作は明らかに非常に不明確ですが、今日、私のコンピューターでは「Hello、world!」と表示され続けています。


11

Emacs Lisp

これは、「コードはデータであり、データはコードである」というLispの強力な設計を披露する絶好の機会です。確かに、これらの例は非常に非効率的であり、実際のコンテキストで使用することはできません。

マクロは、想定されるループの展開バージョンであるコードを生成し、その生成されたコードは実行時に評価されます。

repeat-it: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))))

反復テスト:

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

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

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

インデックス付きリピート:

このマクロは似てrepeat-itいますが、実際には一般的なループマクロdo-timesと同じように機能し、ループインデックスにバインドされるシンボルを指定できます。展開時間記号を使用して、ループ本体で値を変更するかどうかに関係なく、各ループの開始時にインデックス変数が正しく設定されるようにします。

(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)))))))

インデックス付き繰り返しテスト:

このテストは次のことを示しています。

  1. ボディはN回評価します

  2. インデックス変数は、各反復の開始時に常に正しく設定されます

  3. 「フォールバック」という名前のシンボルの値を変更しても、インデックスが混乱しない

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

型なしラムダ計算

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

3
これが再帰としてカウントされるかどうか、それに対する基本的な理論的基礎とは何なのかわかりません...とにかく+1。
ふわふわ14

@fluffyそれ自体は再帰的ではなく、どの関数もそれ自体を呼び出しません(特に関数に名前が付けられていないため)。
誇りに思ってhaskeller 14

私見、ラムダ計算は計算のモデルであり、プログラミング言語ではありません(具体的な機械モデルがなければ、ラムダ計算をPLと見なすことはできません)。
Taのタンディン

ラムダ計算を解釈するマシンを絶対に構築できます。また、構文はプログラミング言語として使用できます。たとえば、github.com / MaiaVictor / caramel
アーサーB

10

Haskell、24文字

sequence_ (repeat (print "abc"))

または24文字の圧縮形式

sequence_$repeat$print"" 

(テキストは変更されますが、これでもループします-これは2つの引用符と改行を無限に出力します)

説明:「abc」を印刷することは、基本的に「abc」を印刷するだけの入出力アクションです。
repeatは、値xを取り、xのみで構成される無限リストを返す関数です。
sequence_は、I / Oアクションのリストを取得し、すべてのアクションを順番に実行するI / Oアクションを返す関数です。

そのため、基本的に、このプログラムは印刷「abc」コマンドの無限リストを作成し、それらを繰り返し実行します。ループまたは再帰なし。


4
基本的に同じ答えをClojureに投稿するつもりでしたが、repeatそうなると思いましたa programming language statement which allows code to be repeatedly executed
seequ 14

3
fix(print"">>)、これには明示的に名前が付けられた繰り返し関数も含まれません。
mniip 14

1
@TheRareクロージャにある方法がわかりませんが、Haskellのrepeatは「コードを繰り返し実行できるプログラミング言語ステートメント」ではなく、無限リストを生成する関数です。「int [] arr = {x、x、x};」と同じループです ループです。
誇りに思っているhaskeller 14

1
はい、しかし何かがそれなしで、それは基本的に不可能なので、再帰を使用して実装する必要があります
誇りhaskellerを

3
実際、このコードにあるすべての関数は、再帰を使用して定義されます-印刷さえも
誇りに思ってhaskeller 14

10

ASM(Linux用のx86 + I / O)

あなたのちっぽけな高レベル言語がどれだけ苦労するかは関係ありません、それはまだ隠された命令ポインタ操作です。実行時にループを展開するのに十分退屈でない限り、最終的にはある種の「goto」(jmp)になります。

Ideoneでコードをテストできます

Matteo Italia DOSコードでこのアイデアのより洗練されたバージョンをチェックアウトすることもできます

これは0..9の文字列で始まり、A..Jに置き換えられ、直接ジャンプは使用されません(つまり、「goto」が発生しなかったと言えます)、再発もありません。

アドレス計算の悪用によりコードはおそらく小さくなる可能性がありますが、オンラインコンパイラで作業するのは面倒なので、そのままにしておきます。

コア部分:

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

全コード

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

私はこれをcodegolf.stackexchange.com/a/34298/11259のダップとして呼び出すつもりでしたが、これは以前の答えだと思います。+1
デジタルトラウマ14

@DigitalTraumaああ、誰かが私のアイデアの洗練されたバージョンを作ったのを見ます-古いトリックですが、マネージドコードの時代には人々は物事が本当にどのように機能するかを忘れがちです。(私はゴルフが嫌いで、あまりにも頻繁に「お母さんに見えます!キーを1つ押すだけで
何か

9

Cプリプロセッサ

難読化の課題中に思いついた小さな「テクニック」。関数の再帰はありませんが、ファイルの再帰はありますか?

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

これをgccで作成/テストしました。これをコンパイルするには、明らかにコンパイラーが__INCLUDE_LEVEL__マクロ(または__COUNTER__微調整を加えたマクロ)をサポートする必要があります。これがどのように機能するかは明らかですが、楽しみのために、コードをコンパイルせずにプリプロセッサを実行します(-Egccでフラグを使用します)。


8

PHP

これがPHPの例です。カウンターが$ 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
?>

forループと同じ:

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

くそー、これは再帰としてもカウントされますよね?
ピチャン14

@Nathanielの例のように、類似性が思い浮かびます。プリプロセッサにはこれらのファイルが含まれ、それらのファイルは同時に評価されます。
14

@Pichanメモリ内のコードのコピーで終了するため、ループの展開に近いと言えます。
PTwr 14

今日質問を見て、ほとんど同じコードを思いついた。私には遅すぎる!
TecBrat 14

header("Location: .?x=".$_GET['x']+1);再帰としてカウント?
チャーリー

8

Python

次のコードには、再帰関数(直接または間接)、ループプリミティブは含まれず、組み込み関数を呼び出しません(を除く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)

「Hello world!」を印刷します 指定された回数。

説明:関数zは、厳密なZ固定小数点コンビネーターを実装します(再帰的に定義されていませんが)。これにより、再帰アルゴリズムを表現できます。


私はg非常に間接的に再帰的に呼び出します。
seequ 14

@TheRareなぜですか?あなたの主張は何ですか?何をg呼び出し、呼び出しg再びは?もちろん、トリックは自己適用ですg(g)が、再帰は含まれません。gあなたが見ていない場合、実際に間接的に再帰呼び出しますg(g)か?これは、ラムダ計算などの再帰的な定義を許可しない言語での標準的な方法です。
PetrPudlák14年

あなたは、与えるg引数としてx、次に呼び出しますx(x)
seequ 14

2
@TheRare関数(または関数のセット)は、その使用方法によって再帰的または非再帰的ではなく、これはその定義によってのみ決定されます。
PetrPudlák14年

1
すべての答えは何らかの方法でチートします。答えの中にない場合は、常に再帰またはループがどこかにあり、コード内で答えが呼び出されます。私はこれがチートする方法が好きです。
ウェインコンラッド14

8

z80マシンコード

すべてのアドレスで実行し、どこでもROMをマップできる環境では、ゼロで満たされた64kbのROMをアドレス空間全体にマップします。

それが何をする:何もない。繰り返し。

仕組み:プロセッサは実行を開始し、バイト00nop命令であるため、そのまま続行し、アドレス$ffffに到達し、にラップアラウンドし$0000、実行を継続しますnopリセットするまでsのます。

少し面白くするには、メモリに他の値を入力します(制御フローの指示を避けるように注意してください)。


メモリをゼロで埋め、どこかに実際のプログラムを配置できます。
seequ 14

それで、あなたは全く分岐せずに64kプログラムを入れることができ、それは繰り返し実行されるでしょうか?
ビル・ウッドジャー14

@BillWoodger、特にプラットフォームで割り込みがない場合(または有効になっていない場合)
ハロルド14


8

Perl正規表現

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

デモ

または次のように試してください:

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

(?!)一致することはありません。そのため、正規表現エンジンは、一致した文字列の幅がゼロの位置との一致を試みます。

(q x x x 10)同じである(" " x 10)繰り返し- space10回。

編集:理解しやすくするために、「文字」をゼロの位置に変更してより正確になるようにしました。このstackoverflowの質問への回答をご覧ください。


6

T-SQL -12

print 1
GO 9

実際には、SQL Server Management Studioのちょっとした癖です。GOはスクリプトセパレーターであり、T-SQL言語の一部ではありません。GOに続けて数字を指定すると、ブロックが何度も実行されます。


1
私はほぼ毎日T-SQLを使用していますが、GOでこれを行えるとは考えていませんでした。+1
CailinP 14

技術的には、これはT-SQLではありません。 GO実際にはSSMSディレクティブであるため、ストアドプロシージャなどのT-SQLスクリプトオブジェクトに配置することはできません。
RBarryYoung

ええ、私はそれをネタバレコメントに追加しました。sqlcmdを使用すると、不正行為が多すぎると考えられます。
マイケルB

6

C#

uint.MaxValueから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
これが重要かどうかはわかりません。WriteLine01 Int.MaxValue回を明示的に呼び出しています。大量のコールスタックの背後で爆発しました。
マイケルB 14

どうしてカウントされないのですか?ループも再帰もありません。
LVBen 14

1
また、コールスタックは、32コールの高さを大規模と見なさない限り、大規模に近い場所にはありません。
LVBen 14

1
4294967296回ではなく、32回しかないのはなぜですか?
LVBen 14

4
@ ja72ループや再帰を使用できないオープンソースプロジェクトに取り組んでいる場合、このようなコードを完全に提供するつもりです。
LVBen 14

6

JS(ブラウザ内)

これはどう?

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

現在の時刻を印刷し、ページをリロードします。


ああ、撃って。同じ基本概念で答えを投稿しました。「JavaScript」などのHTMLタグを表示するページをスキャンしていました。場所に「#」が含まれるコーナーケースを処理するからといって、答えを残してもよいと思います。とにかく、+ 1。
キーン14

Firefox 30の場合:[Exception... "The operation is insecure." code: "18" nsresult: "0x80530012 (SecurityError)" location: "<unknown>"]
アレックスレイノルズ14

@AlexReynoldsええ、変です。鉱山はFF 30上だけで正常に動作
Pichan

コードが記述されたとおりにコピーして貼り付けただけです。機能しません。おそらく、この機能を有効にするために特別なセキュリティ設定がいくつか有効になっていますか?
アレックスレイノルズ14

@AlexReynoldsいいえ、セキュリティ設定を変更することはありません。また、Chromeでも動作します。
ピチャン14
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.