Chương trình thêm tất cả các số tự nhiên và sản lượng -1/12 [đã đóng]


53

Như bạn có thể biết có một niềm vui toán học - thực tế là nếu bạn thêm tất cả các số tự nhiên, bạn sẽ có ... -1/12 (xem Wikipedia tại đây) .

Tất nhiên đây là kết quả rất kỳ lạ và không thể có được bằng cách chỉ thêm một số theo sau bởi một số khác, nhưng một số thủ thuật toán học đặc biệt.

Tuy nhiên, nhiệm vụ của bạn là viết một chương trình, có vẻ như nó cố gắng thêm tất cả các số tự nhiên, nhưng khi bạn chạy nó - nó sẽ trả về -1/12.

Trong mã giả, nó có thể trông như thế này:

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

Bạn có thể làm điều này theo bất kỳ cách nào bạn thích - bạn có thể khai thác một số lỗi tràn bộ đệm, chơi với các lỗi được ném trong khi một số biến trở nên quá lớn hoặc chỉ che giấu điều quan trọng dọc theo mã theo một cách thông minh. Điều kiện duy nhất là mã đó thoạt nhìn trông như thể nó cố gắng thêm tất cả các số tự nhiên và khi chạy, nó trả về -1/12 (ở bất kỳ định dạng nào, nó có thể là số thập phân, nhị phân, văn bản, nghệ thuật ascii bất cứ điều gì).

Mã tất nhiên có thể chứa nhiều hơn, so với hiển thị ở trên, nhưng nó phải đủ rõ ràng, để đánh lừa người đọc.

Đây là cuộc thi phổ biến - bỏ phiếu cho ý tưởng thông minh nhất!


2
Đã sửa các thẻ của bạn: nếu đó là cuộc thi phổ biến thì đó không thể là môn đánh gôn và chúng tôi có một thẻ ngầm cho các thử thách như "viết mã trông giống như x nhưng có y". Dù sao, đây là một thách thức khá tốt cho một người mới! :)
Martin Ender

2
@ m.buettner - cảm ơn vì đã chỉnh sửa thẻ, vâng, tôi mới ở đây, vì vậy tôi không biết tất cả các thẻ. Tôi sẽ cố gắng tuân theo các quy tắc!
Paweł Tokarz

3
Tại sao tất cả các câu trả lời cùng với câu hỏi chỉ bị bỏ qua? Downvoter: xin vui lòng để lại nhận xét.
arshajii

7
Dòng đầu tiên là không hoàn toàn đúng, tùy thuộc vào cách giải thích của bạn math.stackexchange.com/questions/39802/...
qwr

3
Tôi đang bỏ phiếu để đóng câu hỏi này dưới dạng ngoài chủ đề vì các thử thách ngầm không còn thuộc chủ đề trên trang web này. meta.codegolf.stackexchange.com/a/8326/20469
mèo

Câu trả lời:


38

C

Nên hoạt động trên các nền tảng có cả hai sizeof(float)sizeof(int)là 4 và tuân theo tiêu chuẩn dấu phẩy động của IEEE (tôi đoán vậy).

Phiên bản 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;
}

Đầu ra: -0.083

Giải trình:

Không phải là một câu trả lời rất thú vị, nhưng với những bình luận sai lệch.

Tổng từ 1 đến 79774 là 3181985425, có cùng biểu diễn nhị phân là -0,082638867199420928955078125 khi được hiểu là floatthay vì một unsigned int.

Lưu ý rằng !(abs<=0.001)được sử dụng thay vì abs>0.001để tránh thoát khỏi vòng lặp khi tổng đạt 2139135936 (NaN in float). (Cảm ơn @CodesInChaos đã đề xuất ý tưởng này thay vì isNaNkiểm tra độc lập .)

Đặc biệt cảm ơn @Geobits vì ý tưởng chấm dứt vòng lặp bằng cách so sánh tổng thay vì bộ đếm.

Chỉnh sửa: Phiên bản 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;
}

Đầu ra: -0.083333

Giải trình:

Sử dụng cùng một int-to- floatlừa, nhưng với sự --> "có xu hướng" nhà điều hành ở đây. Vì mỗi số nhỏ hơn vô hạn, vòng lặp sẽ không được thực hiện dù chỉ một lần.

Sau khi chuyển đổi thành floatnó được so sánh với intsố ma thuật (tức là -0.83333 được so sánh với 0xBDAAAAAB, hoặc 3182078635), tất nhiên là khác nhau.


3
tạo một #define INFINITY ở đầu và thay thế i <INFINITY
ojblass

2
Những cách thú vị để thoát khỏi vòng lặp nên được xem xét.
ojblass

Đối với những gì nó có giá trị, trong hex 79776137A0, đó là ((int) "\rz") << 4. Tuy nhiên, không chắc là nó hữu ích như thế nào
durron597

3
Bạn có thể định nghĩa một epsilon để thoát ra khỏi vòng lặp. Giải thích: "vì chúng tôi không thể chạy đến vô cùng, chúng tôi sẽ thoát ra khi nó hội tụ vào -1/12 trong phạm vi sai số dấu phẩy động" hoặc tương tự. Bạn sẽ phải kiểm tra giá trị float mỗi lần lặp, nhưng nó sẽ thoát khỏi giá trị 'vô hạn' kỳ lạ đó.
Geobits

1
Trong mã đầu tiên, bạn có thể sử dụng while(!(abs<delta))thay vì while(abs>delta)bỏ kiểm tra NaN.
CodeInChaos

20

Con trăn

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

Kết quả:

-0.0833333333333

Vậy bí quyết là gì?

Bí quyết là: đây là một tính toán hợp lệ.


18

Toán học

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

(Lưu ý: dán phần này vào sổ ghi chép Mathicala có thể sẽ tiết lộ những gì đang diễn ra.)


Có gì xảy ra ở đây là chúng ta đang đặt mặc định theo quy tắc của Sumlà quy tắc Dirichlet (mã hóa trong dòng đầu tiên - lưu ý rằng Mathematica cho phép literals unicode trong nguồn của nó), vì vậy dòng thứ hai, trong đó ra khỏi bối cảnh có vẻ như nó sẽ tạo ra vô cùng, kết thúc sản xuất giá trị thường xuyên -1/12.


3
Tôi khá chắc chắn rằng điều này là gian lận vì bạn đang bảo Mathicala sử dụng chính quy cần thiết để thực hiện tổng hợp.
Kyle Kanos

4
@KyleKanos Tại sao lại gian lận?
arshajii

2
Tôi biết đó không phải là mã golf, mà chỉ là một mẹo: bạn có thể cắt bốn ký tự và chỉ cần thêm trực tiếp 68+{0,37,46,37,31,36,40,33,48}, vì PlusListablethuộc tính. Cá nhân, tôi thấy điều này thành ngữ hơn.
David Zhang

3
@arshjii: đó là gian lận vì bạn phải che giấu sự thật rằng mã bị sai lệch. Sử dụng một gói gọi là 'chính quy hóa' hoàn toàn không che giấu điều này. -1 từ tôi.
Kyle Kanos

1
@arshajii: Điều đó che giấu nó nhiều hơn một chút và tôi đã bỏ qua nó.
Kyle Kanos

10

C

Định dạng độc đáo câu trả lời là -1/12, không 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;
}

Làm thế nào nó hoạt động?

Tổng tất cả các số lên tới 656618, ngoại trừ 386106. Điều này mang lại 215573541165.
Khi được hiểu là một chuỗi, trên một nền tảng endian nhỏ, bạn nhận được -1/12.


7

Brainfuck

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

Mã chỉ đánh giá 1 + 2 + 3 + ...

... cho đến khi i == 256và tràn xảy ra, giả sử kích thước ô 8 bit. Khi đó, itrở thành 0, vòng lặp chấm dứt và các ý kiến sau đây được thực thi.


Điều này không có ý nghĩa. Hầu hết các thông dịch viên cũng như thực tế là bạn tuyên bố nó đánh giá 1 + 2 + 3 + ...điều đó có nghĩa là 256 sẽ phải là hình tam giác i == 256như bạn cũng yêu cầu, nhưng 256 không phải là số tam giác. Ngoài ra, mã đầu ra của bạn ở -1/12đâu?
TimTech

@Timtech Vòng lặp không chấm dứt. Đó là bộ đếm tràn, không phải là tổng. Chỉ một vấn đề nhỏ: nó xuất ra 1/12thay vì -1/12(Hôm nay có vui không? + .- - .+ + .+ Hãy bỏ phiếu cho tôi .) Bốn cái .này là để xuất ra.
ace_HongKongInependence

@ace Nếu đó là bộ đếm, sẽ có hai tùy chọn: 1) Nếu các ô được bọc, thì sẽ không có tràn HOẶC 2) nếu các ô không bao bọc, thì tổng sẽ tràn qua trước khi bộ đếm gần hết 256.
TimTech

@ace Làm thế nào tôi có thể phạm sai lầm ngớ ngẩn đó? Tôi đã sửa nó, nhưng bây giờ nó có vẻ ít hơn.
johnchen902

1
@Timtech Các tế bào được bọc, vì vậy itrở thành số không khi nó đến 256(đó là những gì tôi muốn nói là tràn). Tại thời điểm này, vòng lặp bên ngoài chấm dứt và các dòng tiếp theo (có vẻ như là các bình luận) được thực thi, do đó đầu ra của -1/12.
johnchen902

6

Chỉ cần thêm một chút che giấu tốt hơn để rời khỏi vòng lặp để câu trả lời của ace.

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

Gợi ý không có tràn ...

Tôi chia cho 0 trước khi tôi tăng biến tôi khởi động trình xử lý ngoại lệ


Thêm một số ý kiến!
Navin

3
Anh ta chỉ tiếp tục tổng hợp cho đến khi tôi trở thành số 0 một lần nữa do tràn, tại thời điểm đó average=sum/i;đưa ra một SIGFPE, bị bắt bởi handler, in -1/12.
tomsmeding

không thêm ý kiến ​​chống lại tinh thần bị lép vế?
ojblass

1
@ojblass Phụ thuộc vào cách nhận xét ngầm. ;-)
Daniel Wagner

8
unsigned int sum=3182065200L; printf("%.3f\n",*(float*) &sum);là một sự cho đi mà một cái gì đó đang diễn ra ở đó, và thấy rằng nó trong bộ xử lý cho SIGFPE làm cho điều này trở nên quá rõ ràng đối với thị hiếu của tôi.
hvd

4

Perl 6

Điều này tính tổng bằng cách sử dụng hàm zeta. Tôi đã sử dụng [+] 1..*(tổng của tất cả các số từ 1 đến vô hạn), ngoại trừ việc chạy trong thời gian vô hạ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, tôi đã nghĩ đến việc đăng một bản tóm tắt đơn giản và tuyên bố rằng nó sẽ hoạt động, nhưng bạn phải đợi vô thời gian trước khi nó được in. Thật tốt khi thấy người khác cũng nghĩ như vậy.
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);
    }
}

Điều này thêm tất cả các số từ 0 đến giá trị tối đa, nhân với 12 và cũng thêm 1 vào cuối. Kết quả là 0, do đó tổng các số phải là (0 - 1) / 12.

Giải trình:

0xffffffff == -1, vòng lặp hoàn toàn không thực thi


3

Hồng ngọc

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)

Bản giới thiệu

Được rồi, ngữ nghĩa đầu ra và cú pháp ở đây có ý nghĩa rất nhỏ, nhưng có lẽ điều đó không rõ ràng trong nháy mắt.

Ngoài ra, lưu ý rằng trên thực tế, độc lập với Ruby Platform và Phiên bản. Nó phụ thuộc vào một số hằng số khác được định nghĩa như mong đợi.


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;

}

Để xử lý số tiền vô hạn (gần như) trong một khoảng thời gian hợp lý, hãy biên dịch với các tùy chọn sau cho một số tối ưu hóa trình biên dịch (bắt buộc):

$ gcc -trigraphs sum.c

Đầu ra mẫu:

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

1
Nếu bạn muốn biết làm thế nào điều này hoạt động, đọc tệp .S.
Joshua

8
Cờ trình biên dịch của bạn cung cấp mọi thứ đi ...
ace_HongKongInependence

3
Lỗ hổng tiêu chuẩn của người Viking không còn hài hước nữa - Trò ??/lừa bịp từ lâu đã không còn thông minh nữa. :(
doppelgreener

Cảm ơn bạn đã liên kết, điều đó giải thích rất nhiều. Có một liên kết đến Câu hỏi thường gặp ở bất cứ đâu, hoặc tôi phải tìm kiếm nó mỗi lần?

@tolos Bạn có thể yêu thích nó, hoặc đó là một trong những câu hỏi duy nhất trong thẻ meta [ faq ] hoặc tìm thấy nó qua Câu hỏi thường gặp của cộng đồng .
doppelgreener

3

Java

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

Về lý thuyết, điều này sẽ in true. Tuy nhiên, tôi nghĩ máy tính của tôi sẽ vỡ vụn trước khi chạy xong.


1
Tại sao nó phải prin đúng? Tại sao bạn mong đợi số tiền sẽ đạt -1/12?
Paweł Tokarz

@ PawełTokarz Tôi không phải là chuyên gia về Java nên tôi không thể chắc chắn, nhưng điều đáng chú ý là vì Java sử dụng phép chia số nguyên hoàn toàn -1/12bằng không. Vì vậy, tôi cho rằng đó là một số loại hành vi tràn làm cho vòng lặp kết thúc và trùng hợp sumtràn về không?
ace_HongKongInependence

Vâng, một tràn sẽ làm cho vòng lặp dừng lại khi nó đạt đến mức tối đa long. Vũ trụ có thể sẽ không còn tồn tại trước đó, nhưng đây chỉ là lý thuyết, phải không? Và vâng, 32 bit dưới cùng của sumtất cả sẽ bằng không - đó là lý do tại sao nó quan trọng đối sumvới một int, không phải là a long. Tất nhiên, như @ace đã nói, Java sử dụng phép chia số nguyên để đánh giá -1/12, vì vậy nó bằng không.
Dawood ibn Kareem

1
dài.MAX_VALUE là 9.223.372.036.854.775.807. Điều đó thật lớn lao, nhưng việc tăng thêm 1 triệu lần mỗi giây sẽ đưa bạn đến đó chỉ sau vài trăm nghìn năm. Bạn chỉ cần khoảng 4 tỷ gia số mỗi giây để hoàn thành trong vòng đời của con người. Ở đây, chúng ta không nói về thời gian "tận cùng của vũ trụ", trừ khi bạn biết điều gì đó mà bạn không chia sẻ với phần còn lại của chúng tôi.
user19057

1
@ user19057 Cảm ơn đã sửa. Tất nhiên bạn hoàn toàn đúng, mặc dù tôi rất muốn biết lý do tại sao bạn nghĩ vũ trụ sẽ tồn tại hơn 100 000 năm nữa. Trong mọi trường hợp, tôi sẽ không ngồi chờ đợi chương trình của tôi chạy xong. Có cỏ cho tôi xem đang phát triển.
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);
        }
    }
}

Làm thế nào nó hoạt động:

Java sử dụng mã hóa UTF-8 cho mọi thứ. Tôi sử dụng truеvới Cyrillic Ye ở cuối thay vì 'e' thông thường (nhờ @CodesInChaos) được static booleankhởi tạo false. Có import ȷava.math.BigDecimal;một dấu chấm j thay vì định nghĩa import java.math.BigDecimal; của tôi và đặt tên nhưng hai cách hack rõ ràng.ȷava.math.BigDecimalpublic static boolean truе = false;public String toString() { return "-1/12"; }

Ước gì tôi có thể đăng bài này như một spoiler nhưng tôi không thể tìm ra cách. Đây là phần còn lại của mã bị ẩn một cách lén lút.

// 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 có thể thấy rõ, nhưng sự khác biệt giữa ȷava và java quá nhỏ nên tôi đã phải đọc bình luận một vài lần để phát hiện ra dấu chấm này!
Paweł Tokarz

1
@OldCurmudgeon Tôi nghĩ rằng có một cái nhìn hoàn hảo cho e trong bảng chữ cái Cyrillic: Ye (Cyrillic)
CodeInChaos

1
Nếu tôi không nhầm, bạn gửi mã không đầy đủ. Nếu bạn nhập các gói không chuẩn, bạn cũng nên đăng mã của chúng.
ugoren

1
Cyryllic 'e' khá tuyệt để làm cho mọi thứ không thể đọc được. Hãy tưởng tượng: if (true! = True) {return true} other {return true}; : D
Paweł Tokarz

1
@Andrew G đúng!
Paweł Tokarz

2

Không có giải pháp Haskell, không thể chấp nhận!

Chúng tôi có thể sử dụng danh sách vô hạn của Haskell để có được câu trả lời chính xác!

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)

Giải pháp khá đơn giản khi bạn đưa mũi tên vào tài khoản ....

Vậy bí quyết là gì?

Không có phần mở rộng ngôn ngữ để xác định nhận xét dòng đơn


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

Theo tiêu chuẩn C, điều này rất có thể in ra Answer = -1/12vì sẽ có một tràn số nguyên được ký là hành vi không xác định. Tìm một trình biên dịch sẽ làm điều này được để lại như một bài tập cho người đọc.


mã này sẽ không bao giờ đạt đượcprintf
Bogdacutu

5
Tôi thích câu trả lời thường tạo ra đầu ra cần thiết, không chỉ là "cho phép".
Paŭlo Ebermann

2

Toán học

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

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

nhập mô tả hình ảnh ở đây


2
Bạn có phiền khi đưa ra lời giải thích về những gì đang xảy ra ở đây?
ace_HongKongInependence

Haha, khá buồn cười, và nó có thể là một tài liệu tốt để kiểm tra xem một người mới học Mathicala có hiểu cú pháp cơ bản hay không!
xzczd

1

Python 3.x

Kinda mới đây. Lời khuyên nào?

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 (Bản thảo 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 );

Làm thế nào nó hoạt động:

1:

Các ý kiến ​​mã là (không ngạc nhiên) tất cả những lời nói dối nhưng chúng là một sự phân tâm từ obfuscation chính.

2:

~ và ^ là các toán tử "bitwise not" và "bitwise xor". Kết quả là một được xác định lại thành -12.

3:

add được đặt thành hàm mũi tên ECMAScript 6 "(result, counter) => (result + counter, counter)" không thực hiện những gì các bình luận gợi ý - thay vào đó, nó chỉ trả về "bộ đếm" biểu thức cuối cùng và có hiệu quả một không-op.

4:

Có hai biến "kết quả" - một biến được viết bằng các ký tự ASCII thuần túy (trong phạm vi toàn cầu) và biến còn lại có Unicode "Cyrillic" (trong phạm vi của hàm ẩn danh được sử dụng để xác định thêm). "result = 1" đặt lại giá trị trong phạm vi toàn cầu và dòng thứ hai "result = (0 |! reѕult) / one;" cũng có phía bên trái đề cập đến biến "kết quả" trong phạm vi toàn cầu nhưng "giới thiệu" ở phía bên phải của biểu thức đề cập đến phạm vi của hàm và có giá trị 0 (thay vì giá trị mong đợi là 1 ) vì vậy giá trị của! reult / 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';
}

Nếu hai #defines bị loại bỏ, mã vẫn sẽ là mã C ++ hợp lệ và thực sự thử (nhưng tất nhiên không thành công) để tính tổng của tất cả các số nguyên.

Làm thế nào nó hoạt động:

Các chỉ thị tiền xử lý biến mã chính thành:

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

Ngoài việc khai báo một Ađối tượng, ba dòng đầu tiên chỉ là obfuscation. Dòng cuối cùng thực hiện tất cả các công việc sử dụng toán tử quá tải <<trên một Ađối tượng.

Đưa ra các áp phích giả mã, tôi không thể cưỡng lại để thêm cái này. Nó sử dụng cùng một ý tưởng cơ bản và nhỏ khác nhưng tôi không nghĩ nó thanh lịch.

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

Làm thế nào nó hoạt động:

Các #definethay đổi ý nghĩa của
while(true) {
để
while(test(counter)) {
Mở máy mà âm thầm tràn mỗi vòng của tổng trước khi tràn sẽ thêm 0x80000001 là kết quả. Do đó sau khi tăng b, b == kết quả khi b chẵn và (b + 0x80000000) == kết quả khi b là số lẻ. 1034594986 là biểu diễn số nguyên của số dấu phẩy động 1/12. Thêm 0x80000001 vào đó sẽ dẫn đến số nguyên gần với -1/12 và hàm kiểm tra sẽ trả về 0 (sai) và vòng lặp sẽ chấm dứt.

Và tại sao bạn không nên thử chạy nó:

Nếu bạn muốn xem các tác phẩm đó được cảnh báo: chức năng kiểm tra phải được gọi là 2 ^ 32 * 1034594986 lần trước khi kết thúc vòng lặp. (tức là không có trong cuộc đời của bạn). Nếu bạn muốn xác minh chức năng đó như đã nói, hãy sử dụng trình gỡ lỗi hoặc thay đổi chương trình để xem giá trị của kết quả và b ngay sau câu lệnh b ++. Khi hài lòng rằng chúng bằng nhau khi b thậm chí chỉ thay đổi giá trị ban đầu của b và bộ đếm thành 1034594986. Sau đó, chương trình sẽ xuất -0,08333 sau một thời gian.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.