Tüm doğal sayıları toplayan ve -1 / 12 sonuç veren program [kapalı]


53

Bildiğiniz gibi matematiksel bir eğlence var - tüm doğal sayıları eklerseniz ... -1/12 (Wikipedia'da buraya bakınız) .

Elbette bu çok garip bir sonuçtur ve sadece bir sayı diğerini takip ederek elde edilemez, fakat bazı özel matematiksel numaralar elde edilebilir.

Ancak, sizin göreviniz, tüm doğal sayıları eklemeyi deneyen gibi görünen bir program yazmaktır , ancak çalıştırdığınızda - -1/12 döndürür.

Sahte kodda şöyle görünebilir:

result  = 0;
counter = 1;
while(true) {
  result  += counter;
  counter ++;
}
println(result);

Bunu istediğiniz şekilde yapabilirsiniz - bazı değişkenler çok büyürken arabellek taşmasından faydalanabilir, atılan hatalarla oynayabilir veya kod boyunca önemli olan şeyi akıllıca gizleyebilirsiniz. Tek koşul, kodun ilk önce tüm doğal sayıları eklemeye çalışıyormuş gibi görünmesi ve çalıştırıldığında -1 / 12 döndürmesidir (herhangi bir biçimde, ondalık, ikili, metin, ascii sanat, her neyse).

Kod elbette yukarıda gösterilenden çok daha fazlasını içerebilir, ancak okuyucuyu kandırabilecek kadar açık olması gerekir.

Bu popülerlik yarışması - en zekice fikre oy verin!


2
Etiketleriniz düzeltildi: popülerlik yarışması ise kod golf olamaz, ve "x'e benzeyen ancak y'ye benzeyen kod yaz" gibi zorluklar için düşük bir etiketimiz var. Neyse, bu yeni başlayanlar için oldukça iyi bir meydan okuma! :)
Martin Ender

2
@ m.buettner - etiketleri düzenlediğiniz için teşekkürler, evet, burada yeniyim, bu yüzden tüm etiketlerin farkında değilim. Kuralları takip etmeye çalışacağım!
Paweł Tokarz

3
Neden soruyla birlikte tüm cevaplar reddedildi? Downvoter: Lütfen bir yorum bırakın.
arshajii

7
İlk satır, yorumunuza bağlı olarak tamamen doğru değildir math.stackexchange.com/questions/39802/…
qwr

3
Bu soruyu konu dışı olarak kapatmak için oy veriyorum, çünkü bu konudaki aşikar zorluklar artık konu dışı. meta.codegolf.stackexchange.com/a/8326/20469
kedi

Yanıtlar:


38

C

Platformlarda çalışmak nereye hem Should sizeof(float)ve sizeof(int)4'ü IEEE kayan nokta standart (sanırım) izler.

Versiyon 1:

#define toFloat(x) (*(float*)&x)
#define ABS(x)     (x<0 ? (-x) : x)
#include <stdio.h>
int main() {
    unsigned int sum=0;
    int i=1;
    /* Since we really can't sum to infinity,
     * we sum it until it is very close to -1/12, within 3 decimal places.
     * Need to convert sum to float since -1/12 is not int                 */
    while(!(ABS(toFloat(sum) + 1./12) <= 0.001)) {
        sum+=i;
        i++;
    }
    printf("%.3f\n", toFloat(sum));
    return 0;
}

Çıktı: -0.083

Açıklama:

Çok ilginç bir cevap değil, yanıltıcı yorumlarla.

79774, 1'den toplamı olarak tefsir edildiği zaman, -0.082638867199420928955078125 aynı ikili gösterimi yer alır 3181985425, bir floatyerine arasında unsigned int. Toplam 2139135936 (NaN inç ) değerine ulaştığında, döngüyü bırakmaktan kaçınmak yerine kullanıldığını

unutmayın . (Bu kontrolü bağımsız kontrol yerine önerdiğiniz için @CodesInChaos'a teşekkürler .)!(abs<=0.001)abs>0.001floatisNaN

@Geobits'e, sayaç yerine toplamı karşılaştırarak döngüyü sonlandırma fikri için özel teşekkürler.

Düzenleme: Sürüm 2

#include <stdio.h>
const float inf = 1./0.;
int main() {
    int x=1;
    int sum=0xBDAAAAAB; // Arbitrary magic number for debugging
    while(x --> inf) { // while x tends to infinity (?)
        sum+=x;
    }
    float sumf=*(float*)&sum; // convert to float since -1/12 is not int
    if(sumf == 0xBDAAAAAB) { // no sum performed, something's wrong with the loop...
        fprintf(stderr, "sum is unchanged\n");
        return -1;
    }
    printf("%f\n", sumf);
    return 0;
}

Çıktı: -0.083333

Açıklama:

Aynı intşeyi kullanır float, ancak burada --> "eğilim" operatörüyle . Her sayı sonsuzluktan daha küçük olduğundan, döngü bir kez bile yürütülmez.

Dönüştürdükten sonra float, intsihirli sayıyla (yani -0.83333 ile karşılaştırılır 0xBDAAAAABveya 3182078635) karşılaştırılır, hangisi farklıdır.


3
üstte #define INFINITY yapın ve i <INFINITY
ojblass

2
Döngüden çıkmanın ilginç yolları düşünülmelidir.
ojblass

Değeri 79776için 137A0, hex cinsinden , hangisi olduğu ((int) "\rz") << 4. Ne kadar yararlı olduğundan emin değilim, ancak
durron597

3
Döngüden kopmak için bir epsilon tanımlayabilirsiniz. Açıklama: "sonsuza dek koşamayacağımız için, -1/12 'de kayan nokta marjı sınırları içinde birleştiğinde kopacağız" veya benzeri. Her yinelemede float değerini kontrol etmeniz gerekecek, ancak bu 'sonsuz' değerden kurtulacak.
Geobits

1
İlk kodda , NaN kontrolünü bırakmak while(!(abs<delta))yerine kullanabilirsiniz while(abs>delta).
CodesInChaos

20

piton

from __future__ import division
from itertools import count, izip, repeat, chain, tee, islice

def flatten(iterable):
  "Flatten one level of nesting."
  return chain.from_iterable(iterable)

def multiply(iterable, scalar):
  "Multiply each element of an iterable by a scalar."
  for e in iterable:
    yield e * scalar

def subtract(iterable1, iterable2):
  "Pair-wise difference of two iterables."
  for e, f in izip(iterable1, iterable2):
    yield e - f

def add(iterable1, iterable2):
  "Pair-wise sum of two iterables."
  for e, f in izip(iterable1, iterable2):
    yield e + f

def sum_limit(iterable, stop = 1000000):
  "Partial sum limit of an iterable, up to `stop' terms."
  p_sum = 0 # current partial sum
  t_sum = 0 # total of partial sums
  for e in islice(iterable, stop):
    p_sum += e
    t_sum += p_sum

  # return average of partial sums
  return t_sum / stop

# All natural numbers
n = count(1)

# The same range multiplied by 4
n4 = multiply(count(1), 4)

# Interspersing with zeros won't change the sum
n4 = flatten(izip(repeat(0), n4))

# Subtracting 4n - n results in 3n
n3 = subtract(n4, n)

# Make two clones of this range
n3a, n3b = tee(n3)

# Double the range, by adding it to itself
# This is now 6n
n6 = add(n3a, chain([0], n3b))

# Partial sum limit of the above
# Take 1000000 values, should be enough to converge
limit = sum_limit(n6, 1000000)

# Divide by 6 to get the sum limit of n
print limit / 6

Sonuç:

-0.0833333333333

Peki püf noktası nedir?

İşin püf noktası: bu geçerli bir hesaplama.


18

Mathematica

\:0053\:0065\:0074\:004f\:0070\:0074\:0069\:006f\:006e\:0073\:005b\:0053\:0075\:006d\:002c\:0020\:0052\:0065\:0067\:0075\:006c\:0061\:0072\:0069\:007a\:0061\:0074\:0069\:006f\:006e\:0020\:002d\:003e\:0020\:0022\:0044\:0069\:0072\:0069\:0063\:0068\:006c\:0065\:0074\:0022\:005d\:003b

Sum[n, {n, 1, Infinity}]
-1/12

(Not: Bunu bir Mathematica defterine yapıştırmak büyük olasılıkla neler olduğunu ortaya çıkarır.)


Burada olan şudur: Dirichlet normalizasyonu için varsayılan düzenlemeyi ( Sumilk satırda kodlanmıştır - Mathematica'nın kaynağında unicode değişmezlere izin verdiğine dikkat edin), yani bağlamdan çıkmış gibi görünen ikinci satır sonsuzluk, düzenli değer üreterek sona erer -1/12.


3
Bunun aldatmaya başladığından eminim çünkü Mathematica'ya toplamı yapmak için gereken düzenlemeyi kullanmasını söylüyorsunuz.
Kyle Kanos,

4
@KyleKanos Neden bu aldatma?
arshajii

2
Kod golf olmadığını biliyorum, ama sadece bir ipucu: bu özelliği 68+{0,37,46,37,31,36,40,33,48}olduğundan Plus, dört karakter kesebilir ve doğrudan ekleyebilirsiniz Listable. Şahsen ben bunu daha aptalca buluyorum.
David Zhang

3
@ arshjii: Hile yapıyor çünkü kodun yanıltıcı olduğu gerçeğini gizlemeniz gerekiyor . 'Düzenleme' adlı bir paket kullanmak bunu gizlemez. Benden -1.
Kyle Kanos

1
@ arshajii: Bu biraz daha gizler & Ben reddettim.
Kyle Kanos

10

C

Yanıtı güzel biçimde -1/12değil, biçimlendirir 0.8333.

#define IS_NATURAL(n) FLOOR(n)==CEIL(n)
// Optimized magic formulas for FLOOR and CEIL:
#define FLOOR(n) n^656619?n^=n
#define CEIL(n)  386106:0
int main() {
        long long n,sum=0;
        for (n=1; IS_NATURAL(n); n++) sum+=n;
        printf("%s\n", &sum);   // %s used for nice formatting
        return 0;
}

Nasıl çalışır?

386106 hariç, 656618'e kadar olan tüm sayıları toplar. Bu, 215573541165'i verir
.


7

brainfuck

+ [ [->+>+<<] > [-<+>] <+ ]
--------------------------------------------------------------------------------
Evaluate $\sum_{i=1}^\infty i$
--------------------------------------------------------------------------------
Memory Layout:
i > copy of i > sum
--------------------------------------------------------------------------------
Happy today? ---.+++ +.- -.+ +.+
Please vote me up.
--------------------------------------------------------------------------------

Kod sadece 1 + 2 + 3 + değerlendiriyor ...

... i == 2568 bit hücre büyüklüğü varsayılarak, taşma gerçekleşene kadar . Bunun üzerine iolur 0döngü sona erer ve, yorumlar infaz şunlar.


Bu hiçbir anlam ifade etmiyor. Tercümanların çoğu, değerlendirdiğini iddia ettiğiniz gerçeğini sararken, bu 1 + 2 + 3 + ..., 256'nın i == 256sizin de iddia ettiğiniz gibi üçgen olması gerektiği anlamına gelir , ancak 256, üçgen bir sayı değildir. Ayrıca, kodun nereden çıktı -1/12?
Timtech

@Timtech Döngü sona eriyor. Taşan sayaç, toplam değil. Sadece küçük bir problem: bunun 1/12yerine çıktılar -1/12(Bugün mutlu musun? + .- - .+ + .+ Lütfen oy verin .) Bu dördü çıktı .için.
ace_HongKongIndependence

@ ace Sayaç olsaydı, iki seçenek olurdu: 1) Hücreler sarılırsa, o zaman taşma olmaz VEYA 2) hücreler sarılmazsa, o zaman toplam yakın sayılmadan önce taşardı 256.
Timtech

@ Bu aptal hatayı nasıl yapabilirim? Düzeltdim, ama şimdi daha az önemsiz görünüyor.
johnchen902

1
@Timtech Hücreleri sarma yapar, böylece iulaştığında sıfıra gelir 256(taşma ile kastettiğim buydu). Bu noktadan sonra dış döngü sonlanır ve izleyen satırlar (yorumlara benzeyen) yürütülür, dolayısıyla çıktısı alınır -1/12.
johnchen902

6

Sadece döngüyü as'ın cevabına bırakarak biraz daha iyi bir şaşırtmaca ekleyerek.

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

void handler(int trapId)
{
  unsigned int sum=3182065200L;
  printf("%.3f\n",*(float*) &sum);
  exit(0);
}

int main (void)
{
    unsigned int sum=0;
    int i=0;
    float average = 0.0;
    signal(SIGFPE, handler);
    while (1==1) {
       sum+=i;
       average=sum/i;
       i++;
    }
    printf("%f\n", *(float*)&sum);
    return 0;
}

İpucu taşma yok ...

İstisna işleyicisini başlatan değişken değişkenini artırmadan önce 0'a bölüyorum


Bazı yorumlar ekleyin!
Navin

3
O taşma nedeniyle tekrar sıfır oluncaya kadar toplamaya devam ediyor, bu noktada -1 / 12 baskı yaparak average=sum/i;yakalanan bir SIGFPE handlerveriyor.
05

aldatma ruhuna karşı yorum eklemek değil mi?
ojblass

1
@ojblass Yorumların ne kadar yetersiz olduğuna bağlı. ;-)
Daniel Wagner

8
unsigned int sum=3182065200L; printf("%.3f\n",*(float*) &sum);orada bir şeyler oluyor ve SIGFPE işleyicisinde olduğunu görmek benim zevklerim için çok açık bir şey.
14:00

4

Perl 6

Bu, zeta işlevini kullanarak toplamı hesaplar. Kullanmış olurdu [+] 1..*o sonsuz zaman içinde çalışır dışında (1 ile sonsuzluk arasındaki tüm sayıların toplamını).

use v6;

# Factorial function.
sub postfix:<!>($number) {
    return [*] 1 .. $number;
}

# Infinite list of bernoulli numbers, needed for zeta function.
my @bernoulli := gather {
    my @values;
    for ^Inf -> $position {
        @values = FatRat.new(1, $position + 1), -> $previous {
            my $elements = @values.elems;
            $elements * (@values.shift - $previous);
        } ... { not @values.elems };
        take @values[*-1] if @values[*-1];
    }
}

# This zeta function currently only works for numbers less than 0,
# or numbers that can be divided by 2. If you try using something else,
# the compiler will complain. I'm too lazy to implement other cases of
# zeta function right now.
#
# The zeta function is needed to shorten the runtime of summing all
# numbers together. While in Perl 6, [+] 1..* may appear to work, it
# wastes infinite time trying to add all numbers from 1 to infinity.
# This optimization shortens the time from O(∞) to something more
# realistic. After all, we want to see a result.

multi zeta(Int $value where * < 0) {
    return @bernoulli[1 - $value] / (1 - $value);
}

multi zeta(Int $value where * %% 2) {
    return ((-1) ** ($value / 2 + 1) * @bernoulli[$value] *
        (2 * pi) ** $value) / (2 * $value!);
}

# 1 + 2 + 3 + ... = (-zeta -1)
#
# Reference: Lepowsky, J. (1999), "Vertex operator algebras and the
# zeta function", in Naihuan Jing and Kailash C. Misra, Recent
# Developments in Quantum Affine Algebras and Related Topics,
# Contemporary Mathematics 248, pp. 327–340, arXiv:math/9909178
say (-zeta -1).nude.join: "/";

Haha, basit bir özet göndermeyi ve çalışacağını iddia etmeyi düşünüyordum, ancak yazdırılmadan önce sonsuz bir süre beklemeniz gerekecek. Başka birinin de böyle düşündüğünü görmek güzel.
Kyle Kanos

4

Java

public class Add {
    public static void main(final String... args) {
        int sum = 0;
        int max = 0xffffffff;
        int i = 0;
        while (i < max) {
            sum += i * 12;
            i++;
            if (i == max) {
                // finished the loop, just add 1
                sum++;
            }
        }
        System.out.println(sum);
    }
}

Bu, 0'dan en büyük değere kadar olan tüm sayıları 12 ile çarparak ekler ve sonunda 1 değerini de ekler. Sonuç 0'dır, bu nedenle sayıların toplamı (0 - 1) / 12 olmalıdır.

Açıklama:

0xffffffff == -1, döngü hiç çalışmıyor


3

Yakut

print "Using Ruby #$RUBY_PLATFORM-.#$RUBY_VERSION#$."

BUFF_SIZE = 3
STREAM = STDOUT.to_i

if STREAM.<<(BUFF_SIZE).display{:error}
  abort "Cannot write to stream"
end

i = 0
sum = 0

until STREAM.|(BUFF_SIZE).display{:eof}
  sum += i
  i += 1
end

STREAM.<<(sum)

gösteri

Tamam, buradaki sözde çıktı semantiği ve sözdizimi çok az anlam ifade ediyor, ama belki de bu sıradan bir bakışta belli değil.

Ayrıca, bunun aslında Ruby Platform ve Version'den bağımsız olduğunu unutmayın. Beklendiği gibi tanımlanan diğer bazı sabitlere bağlı.


3

C

#include "stdio.h"

// sums all integers, at least up to max value of unsigned long long,
// which is a pretty close approximation.
int main()
{

    double sum = 0.0;
    double stop_value = -0.08333333333;
    unsigned long long count = 0;

    while(1)
    {
        sum = sum + (double)count++;

        // know what the stop_value in hex is?!??/
        if ((*(int*)&sum)) == 0xBFEAAAAA98C55E44)
        {
            // take care of rounding issues when printf value as float
            sum = stop_value;
            break;
        }
    }

    printf("sum: %f\n", sum);

    return 0;

}

(Neredeyse) sonsuz toplamı makul bir süre içinde ele almak için, bazı derleyici optimizasyonları için aşağıdaki seçeneklerle derleyin (gerekli):

$ gcc -trigraphs sum.c

Örnek çıktı:

$ ./a.out
$ sum: -0.83333
$

1
Bunun nasıl çalıştığını bilmek istiyorsanız, .S dosyasını okuyun.
Joshua,

8
Derleyici bayrağınız her şeyi verir ...
ace_HongKongIndependence

3
Artık komik olmayan standart “boşluklar” - ??/Trigraph numarası, uzun zamandır akıllı olmayı bıraktı. :(
doppelgreener

Bağlantı için teşekkür ederim, bu çok açıklıyor. Herhangi bir yerde SSS bağlantısı var mı, yoksa her seferinde mi aramam gerekiyor?

@tolos Favori olabilir veya [ faq ] meta etiketi altındaki tek sorulardan biridir veya Topluluk SSS bölümünden bulabilirsiniz .
doppelgreener

3

Java

int sum = 0;
long addend = 0L;
while (++addend > 0){
    sum += addend;
}
System.out.println(sum == -1/12);

Teorik olarak, bu yazdıracak true. Ancak, bilgisayarım çalışmayı bitirmeden önce toza çarpacağını düşünüyorum.


1
Neden doğru basmalı? Toplamın -1 / 12'ye ulaşmasını neden bekliyorsunuz?
Paweł Tokarz

@ PawełTokarz Bir Java uzmanı değilim, bu yüzden kesin olarak söyleyemem, ancak Java'nın tamsayı bölmesini kullanması -1/12kesinlikle sıfır olduğu için dikkat çekicidir . Dolayısıyla, döngünün bitmesine ve rastlantısal sumolarak sıfıra taşan bir çeşit taşma davranışı olduğunu farz ediyorum ?
ace_HongKongIndependence

Evet, bir taşma, döngünün maksimum seviyeye geldiğinde durmasını sağlar long. Evren muhtemelen o zamana kadar var olmayacak, ama bu sadece teorik değil mi? Ve evet, en alttaki 32 bitin sumhepsi sıfır olacaktır - bu yüzden sumbir intolmamak önemlidir long. Tabii ki, @ace'ın dediği gibi, Java değerlendirmek için tamsayıyı kullanır -1/12, bu yüzden sıfırdır.
Dawood ibn Kareem

1
long.MAX_VALUE, 9,223,372,036,854,775,807'dir. Bu büyük, ancak saniyede yalnızca 1 milyon kez artırmak, sizi birkaç yüz bin yıl içinde oraya götürür. İnsan ömründe bitmek için saniyede yalnızca 4 milyar artışa ihtiyacınız olacak. Geri kalan bizimle paylaşmadığınız bir şey bilmiyorsanız, burada, "evrenin sonu" zaman çizelgelerinden bahsetmiyoruz.
user19057

1
@ user19057 Düzeltme için teşekkürler. Tabii ki oldukça haklısınız, ancak evrenin neden 100 000 yıldan daha uzun süre dayanacağını düşündüğünüzü bilmek isterim. Her durumda, programımın çalışmasını bitirmesini bekleyerek oturup durmayacağım. Büyümeyi izlemem için çim var.
Dawood ibn Kareem

3

Java

import ȷava.math.BigDecimal;
import static ȷava.math.BigDecimal.ONE;
import static ȷava.math.BigDecimal.ZERO;
import static ȷava.math.BigDecimal.truе;

public class Test {

    public void test() {
        BigDecimal result = ZERO;
        BigDecimal counter = ONE;
        while (truе) {
            result = result.add(counter);
            counter = counter.add(ONE);
        }
        System.out.println(result);
    }

    public static void main(String args[]) {
        try {
            new Test().test();
        } catch (Throwable t) {
            t.printStackTrace(System.err);
        }
    }
}

Nasıl çalışır:

Java, her şey için UTF-8 kodlamasını kullanır. Kullandığım truеbir ile Kiril Ye yerine zamanki 'e' (@CodesInChaos sayesinde) ucundaki static booleanbaşlatıldığı için false. Orada import ȷava.math.BigDecimal;bir ile dotless j yerine import java.math.BigDecimal; Benim ȷava.math.BigDecimaltanımlayıp public static boolean truе = false;ve public String toString() { return "-1/12"; }isim ama iki bariz kesmek için.

Keşke bunu bir spoiler olarak gönderebilseydim ama nasıl yapabileceğimi çözemiyorum. İşte gizlice gizlenmiş olan kodun geri kalanı.

// Note that the ȷ in `ȷava` below is NOT a real j.
package ȷava.math;

public class BigDecimal {

    // true is actually false! Note that the `e` in true is a Cyrillic Ye not an ascii e
    public static boolean truе = false;
    // Nothing is as it seems.
    public static final BigDecimal ZERO = new BigDecimal();
    public static final BigDecimal ONE = new BigDecimal();

    @Override
    public String toString() {
        return "-1/12";
    }

    public BigDecimal add(BigDecimal b) {
        // Do nothing.
        return this;
    }
}

Ŧrue / true açıkça görülebilir, ancak andava ve java arasındaki fark çok küçük. Bu noktayı bulmak için yorumu birkaç kez okumak zorunda kaldım!
Paweł Tokarz

1
@OldCurmudgeon için mükemmel bir görünüm olduğunu düşünüyorum Kiril alfabesinde e : Ye (Kiril)
CodesInChaos

1
Yanılmıyorsam, eksik kod gönderirsiniz. Standart olmayan paketleri alırsanız, kodlarını da göndermelisiniz.
ugoren

1
Cyryllic 'e' olayları okunamaz hale getirmek için oldukça havalı. Hayal edin: if (true! = True) {return true} else {return true}; : D
Paweł Tokarz

1
@Andrew G doğru!
Paweł Tokarz

2

Haskell çözümü yok, kabul edilemez!

Kesin bir cevap elde etmek için Haskell'in sonsuz listelerini kullanabiliriz!

Haskell:

import Data.Bits
import Data.Char
import Data.Ratio
import Data.Tuple
import Control.Applicative
import Control.Arrow

{-# LANGUAGE SingleLineComment "$" #-}

main = print . showAnswer ( sum [1,2..] )
     $ prints "Summation of Natural Numbers"

showAnswer _ = id

prints = uncurry (%) . first negate
       . uncurry quotRem . flip
       ( (***) <$> id <*> id     )
       ( second negate twinPrime )
       <$> (+) . flip shiftR 2
       . ord . head
       where twinPrime = (5,7)

Okları hesaba katarsanız, çözüm oldukça açıktır ....

Peki püf noktası nedir?

Tek satırlı bir yorum tanımlayacak dil uzantısı yok


2

C

#include <stdio.h>

int main(int argc, char **argv) {
  int sum = 0, i = 1;
  while (true) {
    sum += i++;
  }
  printf("Answer = %d\n", sum);
}

C standardına göre Answer = -1/12, tanımlanamayan davranış olan imzalı bir tamsayı taşması olacağından , bu çok iyi bir çıktı olabilir . Bunu yapacak bir derleyici bulmak, okuyucunun alıştırması olarak bırakılmıştır.


bu kod asla ulaşmayacakprintf
Bogdacutu

5
Sadece "izin ver" yerine genellikle istenen çıktıyı üreten cevapları tercih ederim.
Paŭlo Ebermann

2

Mathematica

I I/Row[{##}]&@@

 (
  result = 0;
  counter = 1;
  while (true); {
   counter++,
   result += counter}
  )

görüntü tanımını buraya girin


2
Burada neler olup bittiğiyle ilgili bir açıklama yapar mısınız?
ace_HongKongIndependence

Haha, oldukça komik ve bir Mathematica acemisinin temel sözdizimini anlayıp anlamadığını test etmek iyi bir materyal olabilir !
xzczd

1

Python 3.x

Burada biraz yeni. Herhangi bir ipucu?

import sys
from string import digits as infinity

#function to add two numbers
def add(num1, num2):
    return num1 + num2


#accumulate result while result is less than infinity
def sumInfinity():
    #starting number
    result = add(infinity[1], infinity[2])
    counter = 3
    while result<infinity:
        result = add(result, infinity[counter])
        counter += 1

    return result

#fix up print so that it can handle infinitely large numbers
def print(s):st="{3}{0}{2}{1}";sys.stdout.write(st.format(infinity[1],s,"/","-"))

print(sumInfinity())

1

JavaScript (ECMAScript 6)

result  = 0;
counter = 1;
one     = 1;

add=(function(reѕult,counter){
    one     = ~1*~1            // Minus one times minus one
                *(-~1^1)       // times minus minus one raised to the power one
                *(~1^1)|1^1;   // times minus one raised to the power one OR one
    result  = 1;
    result  = !reѕult/one; // Reset result to zero.
    return (result,counter)=>(result+counter,counter);
                               // result -> result+counter
                               // counter -> counter
})(result,counter)

while( counter < 1e6 )
{
    add( result, counter );
    counter++;
}
console.log( result );

Nasıl çalışır:

1:

Kod yorumları (şaşırtıcı olmayan bir şekilde) tüm yalanlardır, ancak ana şaşırtmacanın dikkatini dağıtır.

2:

~ ve ^, "bitwise değil" ve "bitwise xor" işleçleridir. Birinde -12 ile yeniden tanımlandı.

3:

add, ECMAScript 6 ok işlevine "(sonuç, sayaç) => (sonuç + sayaç, sayaç)" olarak ayarlanmıştır; hayır op.

4:

İki "sonuç" değişkeni vardır - bunlardan biri saf ASCII karakterleriyle (genel kapsamda) yazılırken diğeri ise bir Unicode Kiril "ѕ" (ekleme tanımlamak için kullanılan adsız işlev kapsamında) içerir. "result = 1", global kapsamdaki ve ikinci satırdaki değeri sıfırlar "result = (0 |! reѕult) / one;" ayrıca, global kapsamdaki "sonuç" değişkenine atıfta bulunan sol tarafa sahiptir, ancak ifadenin sağ tarafındaki "yeniden sonuç", işlevin kapsamına atıfta bulunur ve 0 değerine (beklenen değer yerine 1 değerine sahiptir) ) bu yüzden! reѕult / one = -1/12 değeri.


1

C ++

#include <iostream>
#include <limits>

#define long A
#define for(a)

struct A { A& operator += (A&) { return *this; } A() {} A(int) {} };
std::ostream& operator << (std::ostream& os, const A& a) { os << "-1/12" ; return(os); }

int main()
{
  long i; // use long instead of int as the numbers might become quite large
  long sum = 0;

  for(i = 0; i < std::numeric_limits<double>::infinity(); i++)
    sum += i;

  std::cout << sum << '\n';
}

Eğer iki #define ler silinirse, kod hala geçerli bir C ++ kodu olacak ve gerçekte tüm tam sayıların toplamını hesaplamaya çalışacaktır (ancak elbette başarısız).

Nasıl çalışır:

Önişlemci direktifleri ana kodu şöyle sıralar:

A i;
A sum = 0;
sum += i;
std::cout << sum << '\n';

Bir Anesneyi açıklamaktan başka, ilk üç satır sadece şaşırtmacadır. Son satır, tüm işi <<bir Anesnede aşırı yüklenmiş operatörü kullanarak yapar .

Posterlerin sözde kodu göz önüne alındığında, bunu eklemek için direnemedim. Aynı temel ve başka küçük bir fikri kullanıyor ama bunun o kadar zarif olduğunu sanmıyorum.

#include <iostream>

// defines and functions to make the code suggestion work

#define true test(counter)

uint32_t result;
uint32_t counter;

int test(uint32_t& a)
{
  static uint32_t b = 0;
  return a == 0xffffffff ? a++, ++b > 1034594986 ? 0 : 1 : 1;
}

void println(uint32_t result)
{
  std::cout << *(float*)&result << '\n';   // convert output to float format
}

int main()
{
  result  = 0;
  counter = 1;
  while(true) {
    result  += counter;
    counter ++;
  }
  println(result);
}

Nasıl çalışır:

#defineDeğişiklikler anlamı
while(true) {
için
while(test(counter)) {
sessizce sonuçlanması 0x80000001 katacak bir taşma önce toplamı her turda taşabilir makinelerde. Bu nedenle, b artışından sonra, b == b, b eşit olduğunda ve (b + 0x80000000) == b. 1034594986, 1/12 kayan nokta sayısının tamsayı gösterimidir. Buna 0x80000001 eklenmesi, -1 / 12'ye yakın bir tamsayıyla sonuçlanır ve test işlevi 0 (false) döndürür ve döngü sona erer.

Ve neden onu çalıştırmayı denememelisin:

İşlerin uyarıldığını görmek istiyorsanız: döngüyü sonlandırmadan önce test işlevinin 2 ^ 32 * 1034594986 kez çağrılması gerekir. (yani yaşamınız boyunca değil). Bu fonksiyonun söyleneni yaptığını doğrulamak istiyorsanız, bir hata ayıklayıcı kullanın veya sonucun değerini görmek için programı ve b'yi b ++ ifadesinden hemen sonra değiştirin. B eşit olduğunda eşit olduklarından emin olduklarında, b'nin ilk değerini bile değiştirir ve bunun karşılığını 1034594986 olarak değiştirir.

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.