8 Sonsuzluk Olmalı [Kapalı]


19

Genellikle 8 yineleme gerçekleştiren tipik bir döngüye bir göz atalım:

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

Sonsuz yapmalısın!


Bu tür bir döngüyü destekleyen tüm diller için bir for . Böylece en yüksek puana sahip çözüm (upvotes eksi downvotes) kazanır.

Diliniz başka bir biçime sahipse for döngü , ancak eminseniz, onunla harika bir şey yapabilirsiniz, cevabı gönderebilir ve rakipsiz olarak işaretleyebilirsiniz. Mevcut yapıların ve dillerin kapsamını genişletme hakkını saklıyorum, ancak asla küçülmeyecek, bu yüzden daha önce doğru çözümleri bırakmaktan korkmayın.


Çözüm nedir?

Çözüm aşağıdakilerden oluşur iki programdan .

İlk program temiz bir programdır. for8 yineleme yapan döngü ile kendi dilinizde tipik bir programdır . Bu normal bir program olmalı, herhangi bir geliştirici yazabilir. Hazırlık amaçlı herhangi bir özel saldırı yok. Örneğin:

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

İkinci program artırıldı. Bu program, temiz programdaki tüm kodları ve bazı ek kodları içermelidir. Sınırlı sayıda uzatma noktası vardır, ayrıntılar için kuralların tamamı bölümüne bakın. Yukarıdaki temiz program için artırılmış bir program olabilir

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

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

Bu sadece bir fikir göstermek için bir örnek (C ++ ile derlenemez). Gerçek doğru artırılmış program derlenebilir, çalışır ve sonsuz döngüye sahip olmalıdır.

Tam kurallar

Her iki program:

  • Böyle bir dili destekleyen herhangi bir dil for döngüleri tamam.
  • Döngü gövdesi boş olmalıdır. Daha doğrusu, döngüye bazı çıktılar veya başka kodlar yerleştirebilirsiniz, ancak boş döngü durumunda döngü davranışı aynı olmalıdır.

Programı temizle:

  • Döngü, tamsayı veya sayısal sayaç kullanır ve 8 yineleme gerçekleştirir:

    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++
    
  • Kullanıcı tanımlı türlere izin verilmez.

  • Döngü değişkeni yerine özelliğin (genel değişken hariç) kullanımına izin verilmez.
  • Değişken bildirimi döngü içinde veya dışında olabilir. Aşağıdaki kod tamam:

    int x;
    for(x=0; x<8; ++x);
    
  • Ön ek veya son düzeltme artışı kullanılabilir.

  • Döngü sınırı 8, adlandırılmış sabit veya değişkene kaydedilmeden sabit değişmez olarak yazılmalıdır. Değişken veya sabitin 8'e eşit olarak bildirilmesine ve daha sonra diğer değerle yeniden atanmasına, geçersiz kılmasına veya gölgelenmesine dayanan çözümleri önlemek için yapılır:

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

Artırılmış program:

  • Temiz koddan tüm kodu içermelidir.
  • Temiz programı sınırlı sayıda uzatma noktasında uzatmalıdır.
  • Sonsuz bir döngü ile aynı for döngüyü çalıştırmalıdır .
    Döngünün başka bir sonsuz yapıya yerleştirilmesi uygun değildir.
  • Kodun metinsel gösterimi değişmediği sürece çalışma zamanına veya derleme zamanı düzeltme ekine izin verilir.
  • Yapıyı bir dizgiye yerleştirip geçmesine evalizin verilmez.

Uzatma noktaları:

  • Diğer dosyalar veya diğer montajlar da dahil olmak üzere, parçanın dışında temiz kod içeren herhangi bir yer.
  • forifadesi (tek parça olarak - foryapı ve gövdesi) değişmeden tutulmalıdır.
  • Değişken beyan aynı tutulmalıdır.
  • Basit ifadeler arasındaki herhangi bir yer uzatma noktası olarak kullanılabilir.
  • Değişken döngünün dışında ve değerin hemen atanması olmadan bildirildiyse, bu atama eklenebilir.
/* 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;
}

Not: Mümkünse, lütfen çevrimiçi IDE'ye bir bağlantı sağlayın.


2
@Oliver, bildiğim gibi, "en yüksek puan (upvotes eksi downvotes)" tam olarak popülerlik yarışması için varsayılanlardır , en azından etiket açıklamasında yazılmıştır: "Popülerlik yarışması en yüksek oy çetelesi olan cevabın olduğu bir yarışmadır. (upvotes eksi downvotes) kazanır. " Ama bunu soruya açıkça ekleyebilirim.
Qwertiy

1
@Maltysen, bu yapı ile dillerde birçok ilginç çözüm var. C ve C ++ (kesinlikle farklı çözümlerle), C #, Java, Javascript, php, Perl, Groovy vardır. Eminim çok daha fazlası vardır. Her neyse, soruyu büyütmek için açığım ve bu kurallarda belirtildi. Başka bir dilde iteresting bir şey yapabilirsiniz - gönderin. Olumlu tepki olacaksa, kurallar genişletilebilir.
Qwertiy

4
Bunu bir popülerlik yarışması olarak yapmak biraz gariptir, çünkü seçmenlerin oy verirken hangi kriterleri seçmeleri gerektiği konusunda bir açıklama yoktur (zafer koşulunu öznel hale getirir). Burada birçok kişinin golf çözümlerini ilginç bulması ve dolayısıyla popüler olabilmesi temelinde bir kod-golf çözümü üzerinde çalışıyordum ; bu meydan okuma için uygulanabilir bir zafer koşulu olabilir gibi görünüyor.

2
1. " tamsayı veya sayısal sayaç " biraz fazla belirsiz. Örneğin içerir java.lang.Integermi? 2. Bu, uygun bir kazanma kriteri ile daha iyi olur.
Peter Taylor

1
1. Evet, öyle. 2. Tam olarak kazanan kreteri nedir? Not: Meta olarak devam edebiliriz .
Qwertiy

Yanıtlar:


33

Python3

Temiz Program:

Bu döngü sırasında standart bir geri sayımdır.

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

Artırılmış Program:

import ctypes

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

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

Bu yeniden tanımlama int önbellek kullanır 8olarak 9etkin bir şekilde yapar n -= 1çünkü no-op, 9-1 = 8sadece setleri hangi ngeri 9sonsuz döngü neden tekrar.

Burada int önbelleğini çevrimiçi olarak görebilirsiniz (açıkçası sonsuz döngü olmadığı için açıktır).


Onlinde IDE'ye bir bağlantı verebilir misiniz? ideone.com/aI3ZrI - orada çalışmıyor gibi görünüyor.
Qwertiy

@Qwertiy, repl.it içinde çalıştırmayı denedim, ancak sadece donuyor, bu sonsuz bir döngü olacağı için bekleniyor. int önbellek şeyler orada çalışır biliyorum, çünkü ben nasıl ayarlanır 8ile 9
denedim

Gerçekten orada çalışıyor. Garip ideone gibi zaman sınırı olmadığını garip (5 sn). GösteriPython 3.5.2 (default, Dec 2015, 13:05:11) [GCC 4.8.2] on linux
Qwertiy

Döngü olmadan @Qwertiy bağlantısı: repl.it/E4fx/0
Maltysen

Bu ilginç ...
Qwertiy

22

Python 3

Temiz Program:

Python'da 8 kez bir şey yapmanın standart yolu:

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

Artırılmış Program:

Bununla birlikte, aralık üreteci fonksiyonunu sonsuz 1 vermek için geçersiz kılarsak, sonsuz bir döngü haline gelir ...

def range(x):
    while 1: yield 1

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

Bunu daha ileriye götürebilir ve sonsuza kadar 1 veren, sonsuza kadar sayan bir jeneratör işlevi oluşturabiliriz:

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

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

Repl.it üzerinde test


2
Bunu büyük bir modülün ortasında sakla ...
Benjamin

21

Perl

Temiz

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

Artırılmış

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

Ideone .


16
Oh, bu gerçekten zekice. Perl'i bilmeyen herkes için: bu, $iyalnızca booleans tutabilen özel bir değişken için bir takma ad olmak için takma addır, bu nedenle 1'e ulaştığında, artırılmaya karşı bağışıklık kazanır.

10

ES5 + (Javascript)

EDIT : Açık değişken değişken bildirimi kaldırıldı, aksi takdirde kaldırıldı ve yapılandırılamaz bir window.x özelliği oluşturuldu (REPL konsolunda satır satır çalışmadığı sürece).

Açıklama:

Küresel kapsamdaki herhangi bir değişkenin aynı zamanda pencerenin bir özelliği olması gerçeğinden faydalanır nesnesinin ve "window.x" özelliğini 1 sabit değerine sahip olacak şekilde yeniden tanımlar.

Temiz

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

Artırılmış

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

Not : Bu Node.js çalışmasını sağlamak için, "pencere" yerine "global" değiştirin (Node.js 6.8.0 test)


1
Bu arada, bu ES5, değil mi?
Qwertiy

Ayrıca Crome ile çalışmaz var. Ancak varher iki programdan da kaldırabilirsiniz - sorun olmaz.
Qwertiy

@Qwertiy, bu benim için Chrome'da "var" ile çalışıyor (Linux / Sürüm 52.0.2743.82 (64-bit))
zeppelin

> Bu arada, bu ES5, değil mi? Doğru, şimdi başlığı düzeltir
zeppelin

1
Sorun varvinçler, bu yüzden kullanım anında definePropertyzaten çıkış. Ancak bu 2 satırı farklı komut dosyalarına yerleştirirseniz (bu arada, izin verilir), özellik ilk önce oluşturulacak ve varsonra göz ardı edilecektir. İspat: i.stack.imgur.com/lSwbE.png
Qwertiy

10

C

Programı temizle

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

Artırılmış program

#define for(ever) while(1)

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

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

3
@KarlNapf "for" döngüsü başka bir sonsuz yapı içinde değil.
coredump

3
@KarlNapf Bu cevaba kural tarafından açıkça izin verildiğini düşündüm: • Kodun metinsel gösterimi değişmediği sürece kodun çalışma zamanı veya derleme zamanı yamalamasına izin verilir.
Ömer

"Döngü için aynı şekilde çalıştırılmalıdır" ifadesi ama evet bu metinsel gösterimle çakışıyor.
Karl Napf

7

Java

Programı temizle:

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

Artırılmış program:

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

Tamsayı önbelleğinde 1 ile 0 içermesi gereken tamsayı ayarlar ve etkin bir şekilde i++hiçbir işey yapmaz.


Beni döv, bu çözüm benimkine benziyor.
Hypino

6
Bu, gerçekten intnispeten ağır sikletten ziyade kutusuz olanı kullanacak olan döngüsel bir Java değil Integer.

7

C ++

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

boolsadece 0 veya 1 olabilir. Primo'nun Perl cevabından esinlenilmiştir .


6

Python 3 (3.5.0)

Temiz Program:

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

Artırılmış

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)

Bu çözüm, Python'da yazılmış diğerlerinden farklıdır, çünkü kaynak kodunu anında değiştirir. For döngüsündeki tüm şeyler, istendiği kodla değiştirilebilir.

Kod, ikinci opcode'u 113 opcode'u veya daha okunabilir şekilde değiştirir JUMP_ABSOLUTE. İşleneni olarak değiştirir160 - for döngüsünün başladığı yönerge olarak aslında programın sonunda bir GOTO ifadesi oluşturur.

Artırılmış program, sayıları 0..7yığın taşması veya benzeri olmadan sonsuz sayıda yazdırır .


6

PHP

Bunun uzatma noktası kurallarına uyduğunu düşünüyorum; Nokta 4'te tam olarak net değilim. @ Primo'nun perl cevabına çok benzediğinden önemli olduğunu düşünüyorum.

Temiz

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

Artırılmış

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

PHP, aşağıdaki gibi belirli dizeleri artırmanıza izin verir:

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

Bu dizelerin tümü 0 olarak değerlendirilir, bu yüzden bu pratik olarak sonsuza kadar döngü yapar (bir şekilde hafızanın bitmesi engellenir).


Bu rekabetin ruhunda ve çok ilginç. Aslında ilk atama ağını denetlemekle ilgili bir şey söylenmedi, bu yüzden bazı uç durum. Aslında 0 atama ve yineleme arasında bir uzatma noktasının olmaması bekleniyordu. Ama buna dayanarak bazı kesişen bazı vaka yolları gördüğüm için buna izin vermeyeceğim ve aşırı kullanımı kolay değil.
Qwertiy

2
@ Qwertiy "işte bu son derece önemli." Kısaca PHP :)
ToXik-yogHurt

6

Perl

Kodu temizle

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

Artırılmış kod

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

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

Perl değişkenlerinin çoğu sadece değişkenlerdir. Bununla birlikte, dilin tiedeğişken alıcıları ve ayarlayıcılarını etkili bir şekilde vermenizi sağlayan bir özelliği de vardır . Bu programda, ana paketini (adı null dize olan) bir nesneye yönelik dilden bir sınıfın eşdeğeri haline getirirken, aynı zamanda bir programa sahip olurum. Bu, fordöngü sayacını programın kendisine bağlamamı sağlıyor. Uygulamanın bir etkisi yoktur ve onu okuma girişimleri her zaman geri döner , bu rakam sayısal olarak 8'den azdır.TIESCALAR verir tiebaşarılı olmak için; dönüş değerinin birTIESCALAR , değişkenle ilişkili tutmamız gereken herhangi bir iç duruma referans olması anlamına gelir, ancak herhangi bir şeye ihtiyacımız olmadığından, yer tutucu olarak boş bir dizi başvurusu döndürürüz. Daha sonra alıcı ve ayarlayıcının mümkün olan en basit uygulamalarını veriyoruz; ikisi de hiçbir şey yapmaz, bu yüzden$xundef


5

WinDbg

Temiz

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

Artırılmış

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
}

Bu yaklaşım <as için bir takma ad oluşturur |, bu nedenle <kodda karşılaşıldığında takma ad genişletilir |ve bitsel olarak genişletilir veya küçüktür yerine yerine yapılır. WinDbg'de tüm sıfır olmayan değerler anything | 8doğrudur, bu yüzden her zaman doğrudur.

Not:, .blockeğer gerçekten gerekli değildir aSve .forburada gösterildiği gibi aslında iki farklı çizgiler olarak girilir, sadece gerektiğinde oluyor aSve .foraynı hat üzerindedir.


5

Mathematica

Temiz

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

Artırılmış

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

5

Ortak Lisp

Kodu temizle

(dotimes(i 8))

Artırılmış

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

keyword:dotimesAka adlı bir makro :dotimes(bkz. 11.1.2.3 KEYWORD Paketi ) sonsuz bir döngü olarak genişleyen tanımlanmıştır. defmacroBeslenebilir makro adı tanımlanan makro döner shadowing-import. Bu nedenle, bu yeni dotimessemboller standart olanı gölgelendirir (taşınabilir programlarda yeniden tanımlanmamalı veya başka bir makroya sözlüksel olarak bağlanmamalıdır).

Artırılmış (2)

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

Karakter 8'i okuduğumuzda, onun yerini alırız (loop). Bu, yukarıdaki gibi (dotimes (i (loop)))ve dolayısıyla kodun üst sınırın hesaplanmasını asla sonlandırmayacağı anlamına gelir . Bu, sadece döngüdeki değil, 8'in tüm oluşumlarını etkiler. Başka bir deyişle, 8 gerçekten sonsuzluğu temsil eder. Merak ediyorsanız, okunabilirlik yukarıdaki gibi değiştirildiğinde, karakter 8 "sonlandırılır" ve kendini şu anda okunmakta olan diğer sayılardan / sembollerden ayırır:

(list 6789)

... şu şekilde okunur:

(list 67 (loop) 9)

Ideone'da test yapabilirsiniz: https://ideone.com/sR3AiU .


4

Yakut

Temiz

Bu tür for loop, Ruby'de çok fazla kullanılmaz, ancak tipik bir öğretici, bunun bunun için bir yol olduğunu söyleyecektir:

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

Artırılmış

For döngüsü sadece (1..8).eachverilen kod bloğuyla çağırır , bu yüzden bu yöntemi değiştiririz:

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

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

4

Haskell

Temiz versiyon:

import Control.Monad (forM_)

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

Artırılmış sürüm:

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

Oldukça basit, gerçekten: sadece kendi tipimizi, örneğinin sonsuz bir dizi Tolacağı şekilde tanımlarız enumFromTo, daha sonra tip-açıklamalı olmayan değerler 0ve 8tip olarak alınmaları için tip varsayılanını kullanırız T.


1
Haskell'in aşırı yüklenmiş sayısal değişmez değerleri için varsayılan türü değiştirmek iyi bir fikirdir.
nimi

3

///

for/// içinde açık döngüler yoktur , ancak simüle edilebilir (sonuçta tamamlanır).

Temiz:

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

Artırılmış:

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

Neler oluyor?

Eski Program 8 0 ila geri sayım iken, ikincisi kişinin /0/0/kuralı yerini alacak 0tarafından 0sonsuza dek.


Ve aslında /0/1//1/2/.../7/8//8/8/8bunun yerine saymak gibi bir şey yapacağınızı düşündüm .
Outgolfer Erik

3

Javascript ES6

Tamam, burada döngü yapısının ES6 for ... kullanarak çalışan bir sürümü. Komik bir iş olmadığından emin olmak için size temiz bir dizi bile vereceğim:

Temiz

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

Tabii ki, bu birisinin Array prototipiyle uğraşmasını engellemiyor ...

Artırılmış

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

Bu, varsayılan yineleyicinin üzerine yazarak çalışır, böylece asla sonlandırılmaz, böylece her şeyi sonsuz bir döngüye kilitler. Kodun, döngü içindeki öğeleri çalıştırma şansı bile yok.


"boş döngü durumunda döngü davranışı aynı olmalıdır"
Qwertiy

Lanet olsun, bunu kaçırdım - bir şey bulmam gerekecek.
Marcus Dirr

Anlayabildiğim kadarıyla, bir kuralı ihlal etmedikçe (içinde benim çözümüm gibi) veya döngüye önceden masaj yaparak Javascript'te döngü için bir C stili ile olan zorluğu yapmak mümkün değildir. Temiz kodunuzdaki beyan (Cedric Reichenbach'ınki gibi).
Temmuz

Aslında bazı yollar var. Küresel değişken ile yol zaten yayınlanmıştır, varancak döngüde izin veren biraz daha var .
Qwertiy

Söylediğim gibi, anlayabildiğim kadarıyla. Bu yorumu yaptıktan sonra küresel değişkeni gördüm ve kendimi tekmeledim.
Marcus Dirr

2

C ++

2 uzatma noktası kullanır:

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

Temizleme programı açıklamadaki ile aynıdır.


Güzel, ama "optimize edilebilir" :) C ++ başka bir cevap yapmak için bazı ilginç yerleşik vardır.
Qwertiy

2

brainfuck

Yinelemeleri saymayı kolaylaştırmak için her yinelemeyi bir '0' yazdırıyorum. Ancak, döngünün çalışma şeklini değiştirmeden oraya herhangi bir kod eklenebilir.

Temiz

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

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

Çevrimiçi deneyin

Artırılmış versiyon, 8 bit hücrelerle ortak Brainfuck uygulamasına dayanır. Bu uygulamalarda, "artış" aslında "artış (mod 256)" dir. Böylece, temiz sürümde tam olarak 8 kez ve artırılmış sürümde sonsuz bir şekilde yinelenecek bir döngü bulmak için, aşağıdaki eşitsizlikler sistemine bir çözüm bulabiliriz.

  • a + b * 8 (mod 256) == 0 (temiz sürüm için)
  • c + a + b * n (mod 256)> 0 tüm n için (artırılmış sürüm için)
  • a> 0

Bu durumda, a = 128, b = 16 ve c = 1'e izin verdik. Açıkça 128 + 16 * 8 = 256 (ve 256 (mod 256) = 0) ve 128> 0, ve b eşit olduğu için c + a + b * n, herhangi bir a + c için tuhaftır ve bu nedenle bu gibi durumlarda hiçbir zaman 256'nın katı olamaz. Basitlik uğruna c = 1 seçiyoruz. Böylece ihtiyacımız olan tek değişiklik tek bir+ programın başında .

Artırılmış

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

Çevrimiçi deneyin

Bu girişin rekabet edip etmediğini belirlemek için OP'ye bırakıyorum. Brainfuck'ın döngü için açık bir türü yok, ancak kullandığım döngü formu, alabileceğiniz kadar yakın. ++++++++aynı zamanda 8alabileceğiniz kadar değişmezdir ; Bunlardan birkaçını dahil ettim.

Temiz sürüm neredeyse kesinlikle bu dilde yazılmış tipik bir programdır, çünkü bilinen en kısa Brainfuck Merhaba Dünyası bile çalışma ile modüler bir nüks ilişkisine bağlıdır.


2

Haskell

Temiz

import Control.Monad (forM_)

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

Artırılmış

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

Her zamanki işlev uygulama operatörünü $, her bittiğinde döngüyü tekrar eden bir işlevle değiştirir . Temiz sürümün çalıştırılması 0-8 arası yazdırır ve sonra durur; artırılmış sürüm tekrar 0 ila 8 ve ardından 0 ila 8 yazdırır vb.

Ben biraz hile forM_ [0..8] $ \i -> print i, bu mutlaka Haskell bu döngü yazmak için "temiz" yolu değil; Birçok Haskellers, döngü gövdesini almak için eta-azaltıyordu forM_ [0..8] printve sonra $geçersiz kılınacak bir şey yok . Savunmamda , bu özelliğe ihtiyaç duymayan Cactus'un cevabından temiz kodu kopyaladım , bu yüzden en azından bir Haskell programcısı gereksiz yere eklemek için hiçbir motivasyon olmadan bu kodu yazdı $!


1

C ++

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

Sağlar xbu tahsis edilmesi ve artışı bir lvalue gerektirdiğinden C çalışmıyor 7'ye değerlendirir.


1

Nim

Deyimsel versiyon, countup :

Temiz

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

Artırılmış

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

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

Basit ve yeniden tanımlayan Python cevabınarange çok benzer . countup8'leri sonsuz vermek için deyimsel Nim yöntemini bir int (dahil) 'den diğerine yinelemeyi yeniden tanımlıyoruz.

Aralık operatörünü kullanarak daha ilginç sürüm ..:

Temiz

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

Artırılmış

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

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

Önceki çözüme çok benzer, ancak ..normalde bir dizi verecek olan aralık operatörünü [1, 2, 3, 4, 5, 6, 7, 8]yineleyiciye öncekinden yeniden tanımlamamız dışında .


1

GolfScript

Temiz

0{.8<}{)}while;

Artırılmış

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

Değişken 8'e n + 1 döndüren işlevi atar


1

tcl

Normal:

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

Artırılmış:

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

Fikir, incrdeğişkeni artırmak için kullanılan komutu yeniden tanımlamak, iaslında artırmak değil!

Test edilebilir: http://rextester.com/live/QSKZPQ49822


1

x86_64 Montaj

Programı temizle:

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

Herhangi bir Assembly programcısının kullandığı döngü türü ve ardından bir jmp loop_startkomut ekleme, daha sonra bir talimat eklemeyi etkinleştirmemek için .

Artırılmış program:

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

Ayrıca, temiz programın bir giriş noktası veya bir section .text


Tamsayı taşmasından sonra durmayacak mı?
Qwertiy

1
Oh, ah ... belki. Ama uzun zaman alacak mı? Çoğunlukla üst düzey bir dil programcısı olan bunun olabileceğini unuttum
goose121

0

JavaScript

Temiz:

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

Artırılmış:

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

Tipik bir döngü gibi görünmüyor ...
Qwertiy

Evet, tipik bir terimi biraz uzattım ...: /
Cedric Reichenbach

0

C ++

Programı Temizle

0'dan 7'ye kadar sayılarla yinelenen güzel, normal bir döngü.

#include <iostream>

int main() {

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

}

Artırılmış Program

C ++ 'ın önişlemcisi oldukça tehlikeli bir özelliktir ...

#include <iostream>
#define short bool

int main() {

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

}

Eklemek zorunda olduğumuz tek satırdı #define short bool. Bu, ikısa bir tamsayı yerine bir boolean yapar ve bu nedenle artış operatörü ( i++) i1'e ulaştıktan sonra hiçbir şey yapmaz . Çıktı daha sonra şöyle görünür:

0
1
1
1
1
1
...

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.