8 powinno stać się Nieskończonością [zamknięte]

19

Rzućmy okiem na typową pętlę, która zwykle wykonuje 8 iteracji:

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

Musisz uczynić to nieskończonym!


To dla wszystkich języków obsługujących taką formę forpętli. Tak więc wygrywa rozwiązanie z najwyższym wynikiem (głosowanie pozytywne i głosowanie negatywne).

Jeśli Twój język ma inną formę forpętli, ale jesteś pewien, możesz zrobić z nim coś fajnego, opublikuj odpowiedź i oznacz ją jako niekonkurencyjną. Zastrzegam sobie prawo do rozszerzenia zakresu dostępnych konstrukcji i języków, ale nigdy się nie zmniejszy, więc nie bój się upuścić wcześniej poprawnych rozwiązań.


Co to jest rozwiązanie

Rozwiązanie składa się z dwóch programów.

Pierwszy program to czysty program. Jest to typowy program w Twoim języku z forpętlą wykonującą 8 iteracji. Powinien to być normalny program, który mógł napisać każdy programista. Żadnych specjalnych hacków do celów przygotowawczych. Na przykład:

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

Drugi program jest rozszerzony. Ten program powinien zawierać cały kod z czystego programu i trochę dodatkowego kodu. Liczba punktów rozszerzeń jest ograniczona , szczegółowe informacje można znaleźć w pełnej sekcji reguł. Może być rozszerzonym programem dla powyższego czystego programu

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

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

To tylko przykład (niekompilowalny w C ++), aby pokazać pomysł. Prawdziwie poprawny program rozszerzony musi być kompatybilny, działać i mieć nieskończoną pętlę.

Kompletne zasady

Oba programy:

  • Każdy język z obsługą takich forpętli jest w porządku.
  • Korpus pętli musi być pusty. Mówiąc dokładniej, możesz umieścić jakiś wynik lub inny kod w pętli, ale zachowanie pętli powinno być takie samo w przypadku pustej pętli.

Czysty program:

  • Pętla używa licznika liczb całkowitych lub liczbowych i wykonuje 8 iteracji:

    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++
    
  • Typy zdefiniowane przez użytkownika są niedozwolone.

  • Używanie właściwości (oprócz zmiennej globalnej) zamiast zmiennej pętli jest niedozwolone.
  • Deklaracja zmiennej może znajdować się wewnątrz lub na zewnątrz pętli. Poniższy kod jest w porządku:

    int x;
    for(x=0; x<8; ++x);
    
  • Można użyć przyrostu przedrostka lub przyrostka.

  • Limit pętli 8należy zapisać jako stały literał bez zapisywania nazwanej stałej lub zmiennej. Ma na celu zapobieganie rozwiązaniom opartym na zadeklarowaniu zmiennej lub stałej równej 8, a następnie zmianie przypisania, zastąpienia lub zacienienia przez inną wartość:

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

Program rozszerzony:

  • Musi zawierać cały kod z czystego.
  • Powinien rozszerzyć czysty program w ograniczonej liczbie punktów rozszerzenia.
  • Musi wykonać tę samą for pętlę, co sama pętla nieskończona.
    Umieszczenie pętli w innej nieskończonej konstrukcji nie jest w porządku.
  • Dopasowanie kodu w czasie wykonywania lub kompilacji jest dozwolone, o ile jego tekstowa reprezentacja pozostaje niezmieniona.
  • Umieszczanie konstrukcji w sznurku i przechodzenie do niej evaljest zabronione.

Punkty rozszerzenia:

  • W dowolnym miejscu poza fragmentem z czystym kodem, w tym innymi plikami lub innymi zestawami.
  • foroświadczenie (jako pojedynczy element - forkonstrukcja i jego korpus) musi pozostać niezmienione.
  • Deklaracja zmiennej musi pozostać taka sama.
  • Dowolne miejsce między prostymi instrukcjami może być wykorzystane jako punkt rozszerzenia.
  • Jeśli i tylko jeśli zmienna została zadeklarowana poza pętlą i bez natychmiastowego przypisania wartości, takie przypisanie można dodać.
/* extension point here */
int main()
/* extension point here */
{
  /* extension point here */
  int x /* extension point for assignment here */;
  /* extension point here */
  for (x=0; x<8; ++x);
  /* extension point here */
  return 0;
  /* extension point here */
}
/* extension point here */
int main() 
{
  /* BEGIN: No changes allowed */ int x = 0; /* END */
  /* extension point here */
  /* BEGIN: No changes allowed */ for (x=0; x<8; ++x); /* END */
  return 0;
}

PS: Jeśli to możliwe, proszę podać link do internetowego IDE.

Qwertiy
źródło
2
@Oliver, jak wiem, „najwyższy wynik (upvotes minus downvotes)” to dokładnie wartości domyślne dla konkursu popularności , przynajmniej jest napisany w opisie tagu: „Konkurs popularności to konkurs, w którym odpowiedź z najwyższym wynikiem głosów (upvotes minus downvotes) wygrywa. ” Ale mogę dodać to wprost do pytania.
Qwertiy
1
@Maltysen, istnieje wiele ciekawych rozwiązań w językach z tymi konstrukcjami. Istnieją C i C ++ (z absolutnie różnymi rozwiązaniami), C #, Java, JavaScript, php, Perl, Groovy. Jestem pewien, że jest o wiele więcej. W każdym razie jestem otwarty na powiększenie pytania i jest to określone w zasadach. Jeśli możesz zrobić coś interesującego w innym języku - opublikuj to. Jeśli będzie to miało pozytywny wpływ, zasady można rozszerzyć.
Qwertiy,
4
Robienie tego jako konkursu popularności jest trochę niewygodne, ponieważ nie ma opisu, jakie kryteria powinni wybrać wyborcy podczas głosowania (czyniąc warunek zwycięstwa subiektywnym). Pracowałem nad rozwiązaniem do gry w golfa na podstawie tego, że wielu ludzi uważa golfa za interesujące i dlatego może być popularne; wydaje się, że może to być wykonalny warunek zwycięstwa dla wyzwania.
2
1. „ Liczby całkowite lub liczbowe ” są nieco zbyt niejasne. Np. Czy to obejmuje java.lang.Integer? 2. Lepiej byłoby to przy odpowiednim kryterium wygranej.
Peter Taylor
1
1. Tak. 2. Co dokładnie wygrywa creteria? PS: Możemy kontynuować na meta .
Qwertiy

Odpowiedzi:

33

Python3

Czysty program:

To tylko standardowe odliczanie podczas pętli.

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

Program rozszerzony:

import ctypes

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

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

Używa int cache przedefiniować 8jak 9co skutecznie sprawia, że n -= 1nie-Op, od 9-1 = 8której po prostu ustawia nz powrotem 9ponownie, powodując nieskończoną pętlę.

Można zobaczyć w akcji int cache internetowego tutaj (choć oczywiście bez nieskończoną pętlę bo jej w Internecie).

Maltysen
źródło
Czy mógłbyś podać link do IDE onlinde? ideone.com/aI3ZrI - wydaje się, że tam nie działa.
Qwertiy
@Qwertiy, próbowałem uruchomić go w repl.it, ale po prostu zawiesza się, czego należy się spodziewać, ponieważ będzie to nieskończona pętla. wiem, że rzeczy int cache tam pracuje, bo to gdzie eksperymentowali z jak ustawić 8aby9
Maltysen
Naprawdę tam działa. Dziwne, że nie mają limitu czasu jak ideone (5 sekund). PokazująPython 3.5.2 (default, Dec 2015, 13:05:11) [GCC 4.8.2] on linux
Qwertiy
@Qwertiy link bez pętli: repl.it/E4fx/0
Maltysen
To interesujące ...
Qwertiy,
22

Python 3

Czysty program:

Standardowy sposób zrobienia czegoś 8 razy w Pythonie to:

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

Program rozszerzony:

Jeśli jednak zastąpimy funkcję generatora zasięgu, aby uzyskać nieskończenie wartość 1, staje się ona nieskończoną pętlą ...

def range(x):
    while 1: yield 1

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

Możemy pójść dalej i stworzyć funkcję generatora, która zamiast nieskończenie dawać 1, liczy się na zawsze:

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

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

Przetestuj na repl.it

FlipTack
źródło
2
Ukryj to w środku ogromnego modułu ...
Benjamin,
21

Perl

Czysty

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

Rozszerzony

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

Ideone .

primo
źródło
16
Och, to naprawdę sprytne. Dla każdego, kto nie zna Perla: aliasing $istaje się aliasem specjalnej zmiennej, która jest w stanie pomieścić booleany, więc gdy osiągnie 1, staje się odporny na zwiększanie.
10

ES5 + (JavaScript)

EDYCJA : Usunięto jawną deklarację zmiennej, ponieważ w przeciwnym razie została podniesiona i utworzono nieokonfigurowalną właściwość window.x (chyba że uruchomiono wiersz po wierszu w konsoli REPL).

Wyjaśnienie:

Korzysta z faktu, że dowolna zmienna o zasięgu globalnym jest również własnością obiektu window , i redefiniuje właściwość „window.x”, aby miała stałą wartość 1.

Czysty

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

Rozszerzony

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

UWAGA : Aby wykonać tę pracę w node.js, wystarczy wymienić „okno” z „globalne” (testowane w node.js 6.8.0)

zepelin
źródło
1
Nawiasem mówiąc, to jest ES5, prawda?
Qwertiy,
Również nie działa z varCrome. Ale możesz usunąć varz obu programów - wszystko będzie dobrze.
Qwertiy,
@ Qwertiy to działa z „var” w Chrome dla mnie (Linux / Wersja 52.0.2743.82 (64-bit))
zeppelin
> Nawiasem mówiąc, to jest ES5, prawda? To prawda, poprawi teraz tytuł
zeppelin
1
Problemem są varpodnośniki, więc w momencie korzystania z definePropertyniego już wychodzimy. Ale jeśli umieścisz te 2 wiersze w różnych skryptach (nawiasem mówiąc, jest to dozwolone), zadziałałoby, ponieważ właściwość zostanie utworzona jako pierwsza, a varnastępnie zostanie zignorowana. Dowód: i.stack.imgur.com/lSwbE.png
Qwertiy
10

do

Czysty program

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

Rozszerzony program

#define for(ever) while(1)

int main() 
{
  for (int x=0; x<8; ++x);
  return 0;
}
Omar
źródło
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 Pętla „for” nie znajduje się w innej nieskończonej konstrukcji.
coredump
3
@KarlNapf Myślałem, że ta odpowiedź jest wyraźnie dozwolona przez regułę: • Dopuszczalne jest łatanie w czasie wykonywania lub kompilacji kodu, o ile jego tekstowa reprezentacja pozostaje niezmieniona.
Omar
Jest to sformułowanie „Należy wykonać to samo dla pętli”, ale tak, to koliduje z reprezentacją tekstową.
Karl Napf,
7

Jawa

Czysty program:

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

Program rozszerzony:

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

Ustawia liczbę całkowitą w pamięci podręcznej liczb całkowitych, która powinna zawierać od 1 do 0, skutecznie i++nie rób nic (ustawia ina buforowaną liczbę całkowitą, która powinna zawierać 1, ale ponieważ ta liczba całkowita faktycznie zawiera 0, nic się nie zmienia).

wstaw nazwę_tutaj
źródło
Pobij mnie, to rozwiązanie jest identyczne z moim.
Hypino,
6
To nie jest tak naprawdę idiomatyczna pętla Java for, która prawdopodobnie użyłaby intraczej rozpakowanego niż stosunkowo ciężkiego Integer.
7

C ++

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

boolmoże być tylko 0 lub 1. Zainspirowany odpowiedzią Perla primo .

Karl Napf
źródło
6

Python 3 (3.5.0)

Czysty program:

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

Rozszerzony

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)

To rozwiązanie różni się od innych napisanych w Pythonie, ponieważ w rzeczywistości zmienia kod źródłowy w locie. Wszystkie elementy w pętli for można zmienić na dowolny kod.

Kod zmienia kod operacji od drugiego do ostatniego na 113lub bardziej czytelny - JUMP_ABSOLUTE. Zmienia operand na 160- instrukcję, w której rozpoczyna się pętla for, w efekcie tworząc instrukcję GOTO na końcu programu.

Rozszerzony program drukuje liczby 0..7nieskończenie wiele razy bez przepełnienia stosu itp.

niebieski
źródło
6

PHP

Myślę, że jest to zgodne z zasadami punktu rozszerzenia; Nie jestem całkowicie jasny w punkcie 4. Jest bardzo podobny do odpowiedzi perla @ primo, więc myślę, że to się liczy.

Czysty

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

Rozszerzony

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

PHP pozwala zwiększać niektóre ciągi, takie jak:

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

Wszystkie te ciągi mają wartość 0, więc zapętla się praktycznie na zawsze (z wyjątkiem braku pamięci).

ToXik-jogurt
źródło
To w duchu konkurencji i bardzo interesujące. Właściwie nie było nic o rezygnacji z początkowego przypisania, więc jest to przypadek skrajny. W rzeczywistości oczekiwano, że nie ma punktu rozszerzenia między przypisaniem 0 a iteracjami. Ale nie zamierzam tego teraz odmawiać, ponieważ widzę kilka interesujących sposobów, opartych na tym i nie jest łatwo nadużywać.
Qwertiy,
2
@Qwertiy „więc to jest przypadek na krawędzi”. PHP w pigułce :)
ToXik-yogHurt
6

Perl

Wyczyść kod

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

Kod rozszerzony

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

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

Większość zmiennych Perla to tylko zmienne. Jednak język ma również tiefunkcję, która pozwala skutecznie podawać zmienne pobierające i ustawiające. W tym programie zmieniam główny pakiet (którego nazwa to łańcuch zerowy) w ekwiwalent klasy z języka obiektowego, jednocześnie mając przy tym program. To pozwala mi powiązać forlicznik pętli z samym programem. Wdrożenie TIESCALARpozwala tieodnieść sukces; zwracana wartość TIESCALARma być odniesieniem do dowolnego stanu wewnętrznego, który musimy utrzymywać powiązanego ze zmienną, ale ponieważ nie potrzebujemy żadnego, zwracamy puste odwołanie do tablicy jako symbol zastępczy. Następnie podajemy najprostsze możliwe implementacje metody pobierającej i ustawiającej; żadne z nich nic nie robi, więc próbuje to przypisać$xnie mają żadnego efektu, a próby jego odczytania zawsze powracają undef, czyli liczbowo mniej niż 8.


źródło
5

WinDbg

Czysty

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

Rozszerzony

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
}

Takie podejście tworzy alias dla <as |, więc gdy <napotkamy w kodzie, alias jest rozwijany do |i bitowo - lub jest wykonywany zamiast mniej niż. W WinDbg wszystkie niezerowe wartości są prawdziwe, więc anything | 8zawsze jest prawdziwe.

Uwaga: Nie .blockjest tak naprawdę potrzebny, jeśli aSi .forsą wprowadzane jako dwie różne linie, jak pokazano tutaj, jest wymagany tylko wtedy, gdy aSi .forznajdują się w tej samej linii.

mleko
źródło
5

Matematyka

Czysty

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

Rozszerzony

x /: (x = 0) := x = -Infinity;
For[x = 0, x < 8, ++x,]
alephalpha
źródło
5

Common Lisp

Wyczyść kod

(dotimes(i 8))

Rozszerzony

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

Makro o nazwie keyword:dotimesaka :dotimes(patrz 11.1.2.3 Pakiet KEYWORD ) jest zdefiniowane i rozwija się jako nieskończona pętla. Te defmacropowroty makro nazwa makro jest zdefiniowane, co może być doprowadzone shadowing-import. Tak więc ten nowydotimes symbole przesłaniają standardowy (który nie powinien być przedefiniowywany ani leksykalnie związany z innym makrem w programach przenośnych).

Rozszerzony (2)

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

Kiedy czytamy znak 8, zastępujemy go znakiem (loop). Oznacza to, że powyższe odczytuje jako (dotimes (i (loop)))i dlatego kod nigdy nie kończy obliczania górnej granicy. Wpływa to na wszystkie wystąpienia 8, nie tylko na jedno w pętli. Innymi słowy, 8 naprawdę oznacza nieskończoność. Jeśli jesteś ciekawy, gdy modyfikowalny jest tekst do odczytu jak wyżej, to znak 8 „kończy się” i odłącza się od innych obecnie czytanych liczb / symboli:

(list 6789)

... brzmi jak:

(list 67 (loop) 9)

Możesz uruchomić testy na Ideone: https://ideone.com/sR3AiU .

rdzeń rdzeniowy
źródło
4

Rubin

Czysty

Tego rodzaju pętla for nie jest zbyt często używana w Rubim, ale typowy samouczek powie ci, że jest to odpowiedni sposób:

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

Rozszerzony

Pętla for po prostu wywołuje (1..8).eachdany blok kodu, dlatego zmieniamy tę metodę:

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

for x in 1..8
  # Some code here
end
daniero
źródło
4

Haskell

Czysta wersja:

import Control.Monad (forM_)

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

Wersja rozszerzona:

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

Jest to dość proste, naprawdę: po prostu zdefiniować własny typ Ttak, że jego enumFromTowystąpienie jest nieskończony ciąg, a następnie użyć typu wywiązał tak że typ-adnotacją un-wartości 0i 8są traktowane jako typ T.

Kaktus
źródło
1
Fajny pomysł, aby zmienić domyślny typ przeciążonych literałów numerycznych Haskella.
nimi
3

///

W for/// nie ma wyraźnych pętli, ale można je zasymulować (mimo wszystko jest to zakończone).

Czysty:

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

Rozszerzony:

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

Co się dzieje?

Podczas, gdy pierwsza Program odlicza od 8 do 0, drugi z nich jest /0/0/zasada zastąpi 0przez 0aż do wieczności.

Cedric Reichenbach
źródło
Pomyślałem, że /0/1//1/2/.../7/8//8/8/8zamiast tego zrobisz coś takiego, jak liczyć.
Erik the Outgolfer,
3

JavaScript ES6

OK, oto wersja, która działa przy użyciu ES6 for ... konstrukcji pętli. Dam ci nawet czystą tablicę, abyśmy byli pewni, że nie ma śmiesznego interesu:

Czysty

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

Oczywiście nie powstrzymuje to nikogo przed bałaganem przy użyciu prototypu Array ...

Rozszerzony

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

Działa to poprzez nadpisanie domyślnego iteratora, aby nigdy się nie kończył, blokując wszystko w nieskończonej pętli. Kod nie ma nawet szansy uruchomić rzeczy w pętli.

Marcus Dirr
źródło
„zachowanie pętli powinno być takie samo w przypadku pustej pętli”
Qwertiy,
Cholera, tęskniłem za tym - muszę coś wymyślić.
Marcus Dirr
O ile mi wiadomo, nie da się zrobić wyzwania za pomocą pętli w stylu C dla Javascript, chyba że złamiesz regułę - albo mając coś w sobie (jak moje rozwiązanie), albo wstępnie masując pętlę deklaracja w twoim czystym kodzie (jak w przypadku Cedrica Reichenbacha).
Marcus Dirr
Właściwie istnieje kilka sposobów. Sposób ze zmienną globalną jest już opublikowany, ale jest jeszcze kilka, pozwalających varw pętli.
Qwertiy
Tak jak powiedziałem, o ile wiem. Po tym komentarzu zobaczyłem zmienną globalną i kopnąłem się.
Marcus Dirr
2

C ++

Wykorzystuje 2 punkty rozszerzenia:

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

Czysty program jest taki sam jak w opisie.

Karl Napf
źródło
Fajnie, ale można je „zoptymalizować” :) W C ++ jest kilka interesujących dodatków, które pozwalają uzyskać inną odpowiedź.
Qwertiy,
2

Brainfuck

Drukuję „0” dla każdej iteracji, aby ułatwić jej policzenie. Ale można wstawić dowolny kod bez zmiany sposobu działania pętli.

Czysty

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

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

Wypróbuj online

Wersja rozszerzona opiera się na wspólnej implementacji Brainfuck z 8-bitowymi komórkami. W tych implementacjach „przyrost” jest w rzeczywistości „przyrostem (mod 256)”. Tak więc, aby znaleźć pętlę, która będzie iterować dokładnie 8 razy w wersji czystej i nieskończonej w wersji rozszerzonej, możemy po prostu znaleźć rozwiązanie następującego systemu nierówności.

  • a + b * 8 (mod 256) == 0 (dla czystej wersji)
  • c + a + b * n (mod 256)> 0 dla wszystkich n (dla wersji rozszerzonej)
  • a> 0

W tym przypadku dopuszczamy a = 128, b = 16 i c = 1. Oczywiście 128 + 16 * 8 = 256 (i 256 (mod 256) = 0) i 128> 0, a ponieważ b jest parzyste, c + a + b * n jest nieparzyste dla każdego nieparzystego a + c, a zatem nigdy nie będzie parzystą wielokrotnością 256 w takich przypadkach. Dla uproszczenia wybieramy c = 1. Zatem jedyną potrzebną nam zmianą jest jedna+ na początku programu.

Rozszerzony

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

Wypróbuj online

Zostawiam OP, aby ustalić, czy ten wpis jest konkurencyjny. Brainfuck nie ma wyraźnej pętli for, ale forma pętli, której użyłem, jest tak bliska, jak to tylko możliwe. ++++++++jest również tak dosłowne, 8jak to tylko możliwe; Zawarłem sporo z nich.

Czysta wersja prawie na pewno stanowi typowy program napisany w tym języku, ponieważ nawet najkrótszy znany Brainfuck Hello World zależy od modułowej relacji powtarzalności do pracy.

Promień
źródło
2

Haskell

Czysty

import Control.Monad (forM_)

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

Rozszerzony

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

Zastępuje zwykły operator aplikacji funkcji operatorem, $który powtarza pętlę za każdym razem, gdy się kończy. Uruchomienie czystej wersji drukuje od 0 do 8, a następnie zatrzymuje się; wersja rozszerzona drukuje od 0 do 8, a następnie od 0 do 8 i tak dalej.

Trochę oszukuję, forM_ [0..8] $ \i -> print iniekoniecznie jest to „najczystszy” sposób na napisanie tej pętli w Haskell; wielu Haskellerów zmniejszyłoby ciało pętli, aby uzyskać, forM_ [0..8] printa wtedy nie można było $pominąć. W mojej obronie skopiowałem czysty kod z odpowiedzi Cactus , który nie potrzebował tej właściwości, więc przynajmniej jeden programista Haskell napisał ten kod bez motywacji do niepotrzebnego dodawania $!

Ben
źródło
1

C ++

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

Pozwala xocenić na 7. Nie działa w C, ponieważ wymaga wartości przy przypisywaniu i zwiększaniu.

Karl Napf
źródło
1

Nim

Wersja idiomatyczna, wykorzystująca countup :

Czysty

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

Rozszerzony

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

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

Prosta i bardzo podobna do odpowiedzi w języku Python, która redefiniujerange . Przedefiniowujemy countup, idiomatyczny sposób Nim iteracji z jednej int (włącznie) na drugą, aby dać 8s nieskończenie.

Bardziej interesująca wersja, wykorzystująca operator zasięgu ..:

Czysty

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

Rozszerzony

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

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

Bardzo podobne do poprzedniego rozwiązania, z tą różnicą, że redefiniujemy operator zakresu .., który normalnie dawałby tablicę [1, 2, 3, 4, 5, 6, 7, 8]iteratorowi wcześniej.

Miedź
źródło
1

GolfScript

Czysty

0{.8<}{)}while;

Rozszerzony

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

Przypisuje funkcję zwracającą n + 1 do zmiennej 8

jimmy23013
źródło
1

tcl

Normalna:

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

Rozszerzony:

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

Chodzi o to, aby przedefiniować incrpolecenie używane do zwiększania zmiennej i, tak aby nie zwiększać!

Można przetestować na: http://rextester.com/live/QSKZPQ49822

sergiol
źródło
1

Montaż x86_64

Czysty program:

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

Rodzaj pętli, jakiej używałby każdy programista asemblera, po której następowałaby syscall wyjścia, aby nie umożliwić dodawania jmp loop_startinstrukcji później.

Program rozszerzony:

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

Przepraszam również, jeśli źle, że czysty program nie ma punktu wejścia lub section .text

gęś121
źródło
Czy to nie zatrzyma się po przepełnieniu liczby całkowitej?
Qwertiy,
1
Och, może ... może. Ale to zajmie dużo czasu? Zapomniałem, że tak się może stać, będąc głównie programistą wysokiego poziomu
goose121
0

JavaScript

Czysty:

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

Rozszerzony:

window.Math = {PI: NaN};
for (var i = 0; !(i > Math.PI * 2.5); i++);
Cedric Reichenbach
źródło
Nie wydaje się być typową pętlą ...
Qwertiy
Tak, trochę naciągnąłem termin typowy ...: /
Cedric Reichenbach,
0

C ++

Czysty program

Ładna, normalna pętla, powtarzająca się od liczb od 0 do 7.

#include <iostream>

int main() {

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

}

Program rozszerzony

Preprocesor C ++ jest dość niebezpieczną funkcją ...

#include <iostream>
#define short bool

int main() {

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

}

Jedyny wiersz, który musieliśmy dodać, to #define short bool. To powoduje, iże logiczna zamiast krótkiej liczby całkowitej, więc operator inkrementacji ( i++) nie robi nic po iosiągnięciu 1. Dane wyjściowe wyglądają następująco:

0
1
1
1
1
1
...
FlipTack
źródło