모든 자연수를 더하고 -1/12를 산출하는 프로그램 [닫힘]


53

아시다시피, 모든 자연수를 더하면 -1/12로 끝나는 수학적인 재미있는 사실이 있습니다 (Wikipedia 참조) .

물론 이것은 매우 이상한 결과이며 하나의 숫자 다음에 다른 숫자를 추가하여 얻을 수는 없지만 특별한 수학적 트릭을 얻을 수는 없습니다.

그러나 당신의 임무는 모든 자연수를 더하려고 시도 하는 것처럼 보이는 프로그램을 작성하는 것이지만 실행할 때 -1/12를 반환합니다.

의사 코드에서는 다음과 같이 보일 수 있습니다.

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

원하는 방식으로이 작업을 수행 할 수 있습니다. 버퍼 오버플로를 이용하거나 일부 변수가 너무 커지는 동안 발생하는 오류를 재생하거나 코드를 따라 중요한 것을 숨기 게 할 수 있습니다. 유일한 조건은 코드가 처음에 모든 자연수를 추가하려고 시도하는 것처럼 보이고 실행하면 -1/12를 반환합니다 (어떤 형식이든 십진수, 이진, 텍스트, ASCII 아트 등).

물론 코드는 위에 표시된 것보다 훨씬 많은 것을 포함 할 수 있지만 독자를 속일 수있을 정도로 명확해야합니다.

이것은 가장 인기있는 아이디어입니다-가장 영리한 아이디어에 투표하십시오!


2
태그를 수정했습니다. 인기 경쟁 인 경우 코드 골프가 될 수 없으며 "x처럼 보이지만 y는 수행하는 코드 작성"과 같은 문제에 대한 언더 태그가 있습니다. 어쨌든, 이것은 새로운 이민자에게는 꽤 어려운 도전입니다! :)
Martin Ender 2013 년

2
@ m.buettner-태그를 편집 해 주셔서 감사합니다. 예, 여기 새로 왔으므로 모든 태그를 인식하지 못합니다. 규칙을 따르도록 노력하겠습니다!
Paweł Tokarz

3
질문과 함께 모든 답변이 왜 하향 조정 되었습니까? Downvoter : 의견을 남겨주세요.
arshajii

7
첫 번째 줄은 해석에 따라 완전히 사실이 아닙니다 math.stackexchange.com/questions/39802/…
qwr

3
나는이 문제를 주제로 다루지 않기로 결심했다. 왜냐하면이 사이트에서 미숙 한 도전은 더 이상 주제가 아니기 때문이다. meta.codegolf.stackexchange.com/a/8326/20469
cat

답변:


38

플랫폼에서 작동 곳 모두해야 sizeof(float)하고 sizeof(int)(4)이며, IEEE 부동 소수점 표준 (내 생각)을 따른다.

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

산출: -0.083

설명:

매우 흥미로운 답변은 아니지만 오해의 소지가 있습니다.

1에서 79774까지의 합은 3181985425이며 . float대신 해석 될 때 -0.082638867199420928955078125와 동일한 이진 표현을 갖 습니다 unsigned int.

즉 주 !(abs<=0.001)대신 사용 abs>0.001합 2,139,135,936 (NaN이에 도달 할 때 루프를 종료 피하기 위해 float). (독립적 인 isNaN검사 대신이 아이디어를 제안 해 주신 @CodesInChaos에게 감사합니다 .)

카운터 대신 합계를 비교하여 루프를 종료한다는 아이디어에 대해 @Geobits에게 감사드립니다.

편집 : 버전 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;
}

산출: -0.083333

설명:

같은 사용 intDi의 float트릭을하지만,이와 --> 연산자 "경향" 여기. 모든 숫자가 무한대보다 작기 때문에 루프는 한 번도 실행되지 않습니다. 그것으로

변환 한 후 마법 번호 float와 비교됩니다 int(즉 -0.83333은 0xBDAAAAAB또는 3182078635 와 비교됩니다 ). 물론 다릅니다.


3
상단에 #DEFINE 무한대을하고 <INFINITY를 내가 대체
ojblass

2
루프를 벗어나는 흥미로운 방법을 고려해야합니다.
ojblass

그것은 가치가 무엇 육각의 것은 79776이다 137A0((int) "\rz") << 4. 그것이 얼마나 유용한 지 잘 모르겠습니다
durron597

3
루프에서 벗어나도록 엡실론을 정의 할 수 있습니다. 설명 : "무한대로 실행할 수 없기 때문에 부동 소수점 마진 내에서 -1/12에 수렴되면 나옵니다"또는 유사합니다. 반복 할 때마다 float 값을 확인해야하지만 그 이상한 '무한대'값을 제거합니다.
Geobits

1
첫 번째 코드 에서는 NaN 검사를 삭제하는 while(!(abs<delta))대신 사용할 수 있습니다 while(abs>delta).
코드 InChaos

20

파이썬

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

결과:

-0.0833333333333

그래서 트릭은 무엇입니까?

요령은 유효한 계산입니다.


18

매스 매 티카

\: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

(참고 : 이것을 Mathematica 노트북에 붙여 넣으면 진행 상황이 드러날 것입니다.)


여기서 일어나는 것은 기본 정규화SumDirichlet 정규화로 설정한다는 것입니다 (첫 번째 줄로 인코딩 됨-Mathematica는 소스에서 유니 코드 리터럴을 허용합니다), 따라서 두 번째 줄은 문맥에서 생성되는 것처럼 보입니다 무한대는 정규화 된 값을 생성합니다 -1/12.


3
Mathematica에 합계를 만드는 데 필요한 정규화를 사용하도록 지시했기 때문에 이것이 부정 행위라고 확신합니다.
Kyle Kanos

4
@KyleKanos 왜 부정 행위입니까?
arshajii

2
나는 골프를 코딩 아니에요 알고 있지만, 단지 팁 : 당신은 추가 단지 바로 네 개의 문자를 절감 할 수 68+{0,37,46,37,31,36,40,33,48}있기 때문에, PlusListable속성을. 개인적으로, 나는 이것을 더 관용적이라고 생각합니다.
David Zhang

3
@arshjii : 코드가 잘못되었다는 사실 을 숨겨야 하기 때문에 부정 행위 입니다. 'regularization'이라는 패키지를 사용해도 이것을 숨기지 않습니다. 나에게서 -1.
Kyle Kanos

1
@arshajii : 그것은 그것을 조금 더 숨기고 나는 그것을 억압하지 않았습니다.
Kyle Kanos

10

대답의 형식을 -1/12아닌 으로 정돈합니다 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;
}

어떻게 작동합니까?

386106을 제외하고 최대 656618까지의 모든 수를 합산합니다. 215573541165를 제공
합니다. 작은 엔디안 플랫폼에서는 문자열로 해석하면 -1/12가됩니다.


7

Brainfuck

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

코드는 1 + 2 + 3 + ...을 평가합니다.

... i == 2568 비트 셀 크기를 가정 할 때까지 및 오버 플로우가 발생했습니다. 이 i되면 0,는 루프가 종료되고 다음 주석 이 실행됩니다.


말이되지 않습니다. 대부분의 통역사들은 당신이 그것을 평가한다고 주장한다는 사실뿐만 아니라 랩핑도 1 + 2 + 3 + ...256이 i == 256당신이 주장하는 것처럼 삼각형이어야 함을 의미 하지만 256은 삼각형 숫자가 아닙니다. 또한 코드는 어디에 출력 -1/12됩니까?
Timtech

@Timtech 루프가 종료됩니다. 합계가 아니라 오버플로 된 카운터입니다. 그냥 하나의 작은 문제 : 그것은 출력하는 1/12대신에 -1/12(오늘 해피 +? .- - .+ + .+ 날 투표하세요 .)이 네 가지가 .출력됩니다.
ace_HongKongIndependence

세포가 래핑 경우 1), 다음 오버 플로우가 없을 것이다 : 그것은 카운터가 있었다면 @ace, 두 가지 옵션이있을 것 또는 세포를 포장하지 않는 경우 카운터가도에 이르렀 던 전에 2), 그 합이 방법을 오버 플로우 것이다 256.
Timtech

@ace 어리석은 실수는 어떻게합니까? 나는 그것을 고쳤지만 지금은 덜 유쾌한 것처럼 보인다.
johnchen902

1
@Timtech Cells는 줄 바꿈되므로 i도착하면 0이됩니다 256(오버플로가 의미 한 것입니다). 이 시점에서 외부 루프가 종료되고 다음과 같은 행 (주석처럼 보임)이 실행 -1/12됩니다.
johnchen902

6

루프를 에이스의 대답으로 남겨 두는 약간의 난독 화를 추가하는 것입니다.

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

힌트 오버플로가 없습니다 ...

나는 예외 처리기를 시작하는 변수를 증가시키기 전에 0으로 나눕니다.


의견을 추가하십시오!
Navin

3
그는 오버플로로 인해 다시 0이 될 때까지 계속 합산합니다.이 시점에서 -1/12를 인쇄 average=sum/i;하여 SIGFPE를 handler잡습니다.
tomsmeding

미숙 한 정신에 대해 의견을 추가하지 않습니까?
ojblass 12

1
@ojblass 의견의 수위에 달려 있습니다. ;-)
Daniel Wagner

8
unsigned int sum=3182065200L; printf("%.3f\n",*(float*) &sum);SIGFPE의 핸들러에 있음을 알면 이것이 내 취향에 너무 명백합니다.
hvd

4

펄 6

zeta 함수를 사용하여 합계를 계산합니다. [+] 1..*무한 시간에 실행되는 것을 제외하고는 (1과 무한대 사이의 모든 숫자의 합계)를 사용했을 것입니다.

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: "/";

하하, 나는 간단한 요약을 게시하고 그것이 효과가 있다고 주장하려고 생각했지만 인쇄하기 전에 무한한 시간을 기다려야합니다. 다른 사람도 그렇게 생각하는 것이 반갑습니다.
Kyle Kanos

4

자바

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

그러면 0부터 최대 값까지의 모든 숫자에 12를 곱한 값이 추가되고 끝에 1이 추가됩니다. 결과는 0이므로 숫자의 합은 (0-1) / 12 여야합니다.

설명:

0xffffffff == -1, 루프가 전혀 실행되지 않습니다


3

루비

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)

데모

좋아, 여기서 출력 의미론과 구문은 거의 의미가 없지만 어쩌면 눈에 띄지 않을 수도 있습니다.

또한 이것은 실제로 Ruby 플랫폼 및 버전과 무관합니다. 예상대로 정의되는 다른 상수에 따라 다릅니다.


3

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

}

합리적인 시간에 (거의) 무한한 합계를 처리하려면 일부 컴파일러 최적화를 위해 다음 옵션을 사용하여 컴파일하십시오 (필수).

$ gcc -trigraphs sum.c

샘플 출력 :

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

1
이것이 어떻게 작동하는지 알고 싶다면 .S 파일을 읽으십시오.
Joshua

8
귀하의 컴파일러 플래그는 모든 것을 제공합니다.
ace_HongKongIndependence

3
더 이상 재미 있지 않은 표준“루프 홀”??/3 단계 트릭은 오랫동안 영리 해지지 않았습니다. :(
doppelgreener

많은 설명이있는 링크에 감사드립니다. 어디서나 FAQ에 대한 링크가 있습니까, 아니면 매번 FAQ를 검색해야합니까?

@tolos 마음에 들거나 [ faq ] 메타 태그 아래에있는 유일한 질문 중 하나 이거나 커뮤니티 FAQ에서 찾을 수 있습니다 .
doppelgreener

3

자바

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

이론적으로 이것은 인쇄 true됩니다. 그러나 컴퓨터가 작동을 마치기 전에 먼지가 쌓일 것이라고 생각합니다.


1
왜 그렇습니까? 합계가 -1/12에 도달 할 것으로 예상되는 이유는 무엇입니까?
Paweł Tokarz

@ PawełTokarz Java 전문가가 아니므로 확실히 알 수는 없지만 Java는 정수 나누기를 사용하기 때문에 완전히 -1/120입니다. 그래서 루프를 끝내고 우연히 sum0으로 오버플로 하는 오버플로 동작이라고 생각 합니까?
ace_HongKongIndependence 0시 32 분에서

예, 오버플로는 루프가 최대에 도달하면 루프를 중지시킵니다 long. 그때까지 우주는 더 이상 존재하지 않을 것입니다. 그러나 이것은 단지 이론적 인 것입니까? 그리고 맞습니다. 32 비트의 하위 32 개 sum는 모두 0 입니다. 따라서 a가 아닌 sum이어야합니다 . 물론 @ace가 말했듯이 Java는 정수 나누기를 사용하여 평가 하므로 0입니다. intlong-1/12
Dawood ibn Kareem

1
long.MAX_VALUE는 9,223,372,036,854,775,807입니다. 그것은 크지 만 초 당 백만 번 증가하면 단 몇 십만 년 안에 당신을 얻을 수 있습니다. 인간의 삶에서 끝내려면 초당 약 40 억 증분 만 있으면됩니다. 우리가 다른 사람들과 공유하고 있지 않은 것을 알지 않는 한, "우주 끝"타임 스케일을 말하는 것은 아닙니다.
user19057

1
@ user19057 수정 해 주셔서 감사합니다. 물론 우주가 10 만 년 이상 지속될 것이라고 생각하는 이유를 알고 싶습니다. 어쨌든, 나는 프로그램이 끝날 때까지 기다리지 않을 것입니다. 성장하는 것을 볼 잔디가 있습니다.
다우드 이븐 카림

3

자바

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

작동 방식 :

Java는 모든 것에 UTF-8 코딩을 사용합니다. 끝에 초기화 된 일반적인 'e'(@ CodesInChaos 덕분에) 대신 Cyrillic Yetruе 와 함께 사용 합니다 . 있다 로모그래퍼 점이없는 J 대신 내 를 정의 하고 이름 만이 명백한 해킹에.static booleanfalseimport ȷava.math.BigDecimal;import java.math.BigDecimal;ȷava.math.BigDecimalpublic static boolean truе = false;public String toString() { return "-1/12"; }

나는 이것을 스포일러로 게시 할 수는 있지만 어떻게 해결할 수는 없기를 바랍니다. 숨어있는 나머지 코드는 다음과 같습니다.

// 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는 분명히 보이지만 ȷava와 java의 차이는 너무 작아서이 점을 발견하기 위해 몇 번 주석을 읽어야했습니다!
Paweł Tokarz

1
@OldCurmudgeon 나는을위한 완벽한 닮은 있다고 생각 전자 키릴 알파벳 : 예 (키릴)
CodesInChaos

1
내가 실수하지 않으면 불완전한 코드를 게시합니다. 비표준 패키지를 가져 오는 경우 해당 코드도 게시해야합니다.
ugoren

1
고리 형 'e'는 물건을 읽을 수 없게 만드는 데 매우 시원합니다. 상상해보십시오. if (true! = true) {return true} else {return true}; : D
Paweł Tokarz

1
@Andrew G 사실!
Paweł Tokarz

2

허용되지 않는 Haskell 솔루션이 없습니다!

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)

화살표를 고려할 때 해결책은 매우 간단합니다 ....

그래서 트릭은 무엇입니까?

한 줄 주석을 정의하기위한 언어 확장이 없습니다.


2

#include <stdio.h>

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

C 표준에 따르면, Answer = -1/12정의되지 않은 동작 인 부호있는 정수 오버플로가 있기 때문에 매우 잘 인쇄 될 수 있습니다. 이를 수행 할 컴파일러를 찾는 것은 독자에게 연습으로 남습니다.


이 코드는 결코 도달하지 않을 것입니다printf
Bogdacutu

5
나는 단지 "허용"이 아니라 필요한 출력을 생성하는 답변을 선호한다.
Paŭlo Ebermann

2

매스 매 티카

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

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

여기에 이미지 설명을 입력하십시오


2
여기서 무슨 일이 일어나고 있는지 설명해 주시겠습니까?
ace_HongKongIndependence

하하, 꽤 재밌고, Mathematica 초보자가 기본 구문을 이해 했는지 여부를 테스트하기에 좋은 자료가 될 수 있습니다 !
xzczd

1

파이썬 3.x

여기에 새로운 것이 있습니다. 팁이 있습니까?

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

자바 스크립트 (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 );

작동 방식 :

1:

코드 주석은 (놀랍게도) 모두 거짓말이지만 주요 난독 화에서 산만합니다.

2 :

~와 ^는 "비트 단위"및 "비트 단위 xor"연산자입니다. 하나는 -12로 재정의됩니다.

삼:

add는 ECMAScript 6 화살표 기능 "(result, counter) => (result + counter, counter)"로 설정됩니다. 이는 주석에서 제안한대로하지 않습니다. 대신 마지막 표현식 "counter"만 리턴하고 효과적으로 노업.

4 :

두 개의 "결과"변수가 있습니다. 하나는 순수한 ASCII 문자 (글로벌 범위)로 작성되고 다른 하나는 유니 코드 키릴 문자 "ѕ"(추가를 정의하는 데 사용되는 익명 함수의 범위 내)가 있습니다. "result = 1"은 전역 범위 내 값을 재설정하고 "result = (0 |! reѕult) / one;"; 또한 전역 범위에서 "result"변수를 참조하는 왼쪽이 있지만 표현식의 오른쪽에서 "reѕult"는 함수 범위를 나타내며 예상 값이 1이 아닌 0입니다. ) 따라서! reѕult / one = -1/12의 값입니다.


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

#define개가 제거되면 코드는 여전히 유효한 C ++ 코드이며 실제로 모든 정수의 합계를 계산하려고 시도합니다 (물론 실패합니다).

작동 방식 :

전 처리기 지시문은 메인 코드를 다음과 같이 바꿉니다. 객체

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

를 선언하는 것 외에도 A처음 세 줄은 난독 화입니다. 마지막 줄은 객체 에서 오버로드 된 연산자 <<를 사용하여 모든 작업 을 수행 A합니다.

포스터 의사 코드가 주어지면 이것을 추가하는 것에 저항 할 수 없었습니다. 동일한 기본 아이디어와 다른 작은 아이디어를 사용하지만 우아하다고 생각하지 않습니다.

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

작동 방식 :

#define변화의 의미
while(true) {

while(test(counter)) {
자동으로 결과에 0x80000001을 추가합니다 오버 플로우하기 전에 요약의 각 라운드를 오버 플로우 시스템에. 따라서 b가 증가한 후에는 b가 짝수 일 때 b == 결과이고 b가 홀수 일 때 (b + 0x80000000) == 결과입니다. 1034594986은 부동 소수점 숫자 1/12의 정수 표현입니다. 0x80000001을 추가하면 -1/12에 가까운 정수가되고 테스트 함수는 0 (거짓)을 반환하고 루프가 종료됩니다.

그리고 왜 당신이 그것을 실행하려고하지 않아야합니다 :

작업이 경고되는지 확인하려면 루프를 종료하기 전에 테스트 기능을 2 ^ 32 * 1034594986 번 호출해야합니다. (즉, 평생이 아닌). 함수가 지시 한대로 작동하는지 확인하려면 디버거를 사용하거나 프로그램을 변경하여 b ++ 문 바로 뒤에 결과 값과 b를 표시하십시오. b가 b 일 때도 동일하다고 생각되면 b와 카운터의 초기 값을 1034594986으로 변경하십시오. 프로그램은 얼마 후 -0.08333을 출력해야합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.