Lập trình năng lượng: O (1 ^ N), O (N ^ 1), O (2 ^ N), O (N ^ 2) tất cả trong một


65

Viết chương trình (hoặc hàm) thể hiện bốn độ phức tạp thời gian O lớn phổ biến tùy thuộc vào cách nó được chạy. Trong bất kỳ hình thức nào, nó có một số nguyên dương N mà bạn có thể giả sử là ít hơn 2 31 .

  1. Khi chương trình được chạy ở dạng ban đầu, nó sẽ có độ phức tạp không đổi . Đó là, độ phức tạp phải là Θ (1) hoặc tương đương, Θ (1 ^ N) .

  2. Khi chương trình được đảo ngược và chạy nó sẽ có độ phức tạp tuyến tính . Nghĩa là, độ phức tạp phải là Θ (N) hoặc, tương đương, Θ (N ^ 1) .
    (Điều này có ý nghĩa vì N^1được 1^Nđảo ngược.)

  3. Khi chương trình được tăng lên gấp đôi , tức là nối với chính nó, và chạy nó nên có phức tạp, đặc biệt là 2 N . Đó là, độ phức tạp phải là Θ (2 ^ N) .
    (Điều này có ý nghĩa vì 2in 2^Nlà gấp đôi 1in 1^N.)

  4. Khi chương trình được nhân đôi đảo ngược và chạy, nó sẽ có độ phức tạp đa thức , cụ thể là N 2 . Đó là, độ phức tạp phải là Θ (N ^ 2) .
    (Điều này có ý nghĩa vì N^2được 2^Nđảo ngược.)

Bốn trường hợp này là những trường hợp duy nhất bạn cần xử lý.

Lưu ý rằng để chính xác, tôi đang sử dụng ký hiệu theta () lớn thay vì chữ O lớn vì thời gian chạy của các chương trình của bạn phải được giới hạn ở cả trên và dưới bởi độ phức tạp bắt buộc. Nếu không, chỉ cần viết một hàm trong O (1) sẽ thỏa mãn cả bốn điểm. Nó không quá quan trọng để hiểu sắc thái ở đây. Chủ yếu, nếu chương trình của bạn đang thực hiện các hoạt động k * f (N) cho một số k không đổi thì có khả năng là trong (f (N)).

Thí dụ

Nếu chương trình ban đầu là

ABCDE

sau đó chạy nó sẽ mất thời gian liên tục. Đó là, cho dù đầu vào N là 1 hoặc 2147483647 (2 31 -1) hoặc bất kỳ giá trị nào ở giữa, nó sẽ chấm dứt trong khoảng thời gian gần như nhau.

Phiên bản đảo ngược của chương trình

EDCBA

nên mất thời gian tuyến tính theo N. Đó là thời gian cần thiết để chấm dứt tỷ lệ xấp xỉ với N. Vì vậy, N = 1 mất ít thời gian nhất và N = 2147483647 mất nhiều thời gian nhất.

Phiên bản nhân đôi của chương trình

ABCDEABCDE

nên mất hai-to-the-N lần về N. Đó là, thời gian cần thiết để chấm dứt nên xấp xỉ tỉ lệ với 2 N . Vì vậy, nếu N = 1 chấm dứt trong khoảng một giây, N = 60 sẽ mất nhiều thời gian hơn tuổi của vũ trụ để chấm dứt. (Không, bạn không phải kiểm tra nó.)

Phiên bản nhân đôi và đảo ngược của chương trình

EDCBAEDCBA

nên mất thời gian bình phương về mặt N. Đó là, thời gian cần thiết để chấm dứt nên tỷ lệ thuận với N * N. Vì vậy, nếu N = 1 chấm dứt trong khoảng một giây, N = 60 sẽ mất khoảng một giờ để chấm dứt.

Chi tiết

  • Bạn cần thể hiện hoặc lập luận rằng các chương trình của bạn đang chạy trong sự phức tạp mà bạn nói chúng là. Đưa ra một số dữ liệu thời gian là một ý tưởng tốt nhưng cũng cố gắng giải thích tại sao về mặt lý thuyết sự phức tạp là chính xác.

  • Thật tốt nếu trong thực tế thời gian các chương trình của bạn không đại diện hoàn hảo cho sự phức tạp của chúng (hoặc thậm chí là xác định). ví dụ: đầu vào N + 1 đôi khi có thể chạy nhanh hơn N.

  • Môi trường bạn đang chạy chương trình của bạn vấn đề. Bạn có thể đưa ra các giả định cơ bản về cách các ngôn ngữ phổ biến không bao giờ cố tình lãng phí thời gian trong các thuật toán, nhưng, ví dụ, nếu bạn biết phiên bản cụ thể của Java thực hiện sắp xếp bong bóng thay vì thuật toán sắp xếp nhanh hơn , thì bạn nên tính đến điều đó nếu bạn thực hiện bất kỳ sắp xếp nào .

  • Đối với tất cả các phức tạp ở đây giả sử chúng ta đang nói về các tình huống xấu nhất , không phải trường hợp tốt nhất hoặc trường hợp trung bình.

  • Độ phức tạp không gian của các chương trình không quan trọng, chỉ có độ phức tạp thời gian.

  • Các chương trình có thể xuất ra bất cứ điều gì. Nó chỉ là vấn đề mà họ lấy số nguyên dương N và có độ phức tạp thời gian chính xác.

  • Bình luận và các chương trình multiline được cho phép. (Bạn có thể cho rằng \r\nđảo ngược là \r\nđể tương thích với Windows.)

Nhắc nhở Big O

Từ nhanh nhất đến chậm nhất O(1), O(N), O(N^2), O(2^N)(thứ tự 1, 2, 4, 3 ở trên).

Điều khoản chậm hơn luôn chiếm ưu thế, ví dụ O(2^N + N^2 + N) = O(2^N).

O(k*f(N)) = O(f(N))cho hằng số k. Vì vậy O(2) = O(30) = O(1)O(2*N) = O(0.1*N) = O(N).

Ghi nhớ O(N^2) != O(N^3)O(2^N) != O(3^N).

Bảng cheat O gọn gàng.

Chấm điểm

Đây là mã golf bình thường. Chương trình gốc ngắn nhất (thời gian không đổi một) tính bằng byte thắng.


Câu hỏi tuyệt vời! Điểm nhỏ: chúng tôi không phải chỉ định trường hợp xấu nhất / trường hợp tốt nhất / trường hợp trung bình, bởi vì đầu vào duy nhất được tính là kích thước N là số N (mà BTW không phải là khái niệm thông thường về kích thước đầu vào: đó sẽ là coi đầu vào N là kích thước log N). Vì vậy, chỉ có một trường hợp cho mỗi N, đồng thời là trường hợp tốt nhất, tồi tệ nhất và trung bình.
ShreevatsaR

5
Có vẻ như bạn đã đi chệch khỏi các định nghĩa thông thường về độ phức tạp. Chúng tôi luôn xác định độ phức tạp thời gian của một thuật toán là một hàm có kích thước của đầu vào của nó . Trong trường hợp đầu vào là một số, kích thước của đầu vào là logarit cơ sở 2 của số đó. Vì vậy, chương trình n = input(); for i in xrange(n): passcó độ phức tạp theo cấp số nhân, bởi vì nó thực 2 ** khiện các bước, k = log_2(n)kích thước đầu vào ở đâu. Bạn nên làm rõ liệu đây là trường hợp, vì nó thay đổi đáng kể các yêu cầu.
wchargein

Câu trả lời:


36

Python 3 , 102 byte

try:l=eval(input());k=1#)]0[*k**l(tnirp
except:k=2#2=k:tpecxe
print(k**l*[0])#1=k;))(tupni(lave=l:yrt

Hãy thử trực tuyến!

Đây là của O (1 ^ n), vì đây là những gì chương trình làm:

  • đánh giá đầu vào
  • tạo mảng [0]
  • in nó

Đảo ngược:


try:l=eval(input());k=1#)]0[*l**k(tnirp
except:k=2#2=k:tpecxe
print(l**k*[0])#1=k;))(tupni(lave=l:yrt

Hãy thử trực tuyến!

Đây là của O (n ^ 1), vì đây là những gì chương trình làm:

  • đánh giá đầu vào
  • tạo mảng [0] * đầu vào (0 lặp lại nhiều lần như đầu vào)
  • in nó

Nhân đôi:

try:l=eval(input());k=1#)]0[*k**l(tnirp
except:k=2#2=k:tpecxe
print(k**l*[0])#1=k;))(tupni(lave=l:yrt
try:l=eval(input());k=1#)]0[*k**l(tnirp
except:k=2#2=k:tpecxe
print(k**l*[0])#1=k;))(tupni(lave=l:yrt

Hãy thử trực tuyến!

Đây là của O (2 ^ n), vì đây là những gì chương trình làm:

  • đánh giá đầu vào
  • tạo mảng [0]
  • in nó
  • cố gắng đánh giá đầu vào
  • Thất bại
  • tạo mảng [0] * (đầu vào 2 ^) (0 lặp lại nhiều lần như đầu vào 2 ^)
  • in nó

Nhân đôi và đảo ngược:


try:l=eval(input());k=1#)]0[*l**k(tnirp
except:k=2#2=k:tpecxe
print(l**k*[0])#1=k;))(tupni(lave=l:yrt
try:l=eval(input());k=1#)]0[*l**k(tnirp
except:k=2#2=k:tpecxe
print(l**k*[0])#1=k;))(tupni(lave=l:yrt

Hãy thử trực tuyến!

Đây là của O (n ^ 2), vì đây là những gì chương trình làm:

  • đánh giá đầu vào
  • tạo mảng [0] * đầu vào (0 lặp lại nhiều lần như đầu vào)
  • in nó
  • cố gắng đánh giá đầu vào
  • Thất bại
  • tạo mảng [0] * (đầu vào ^ 2) (0 lặp lại nhiều lần so với bình phương đầu vào)
  • in nó

Tại sao nó không treo chờ tương tác của người dùng khi có nhiều cuộc gọi đến input()?
Jonathan Allan

1
Đó là một lỗ hổng mà "kết thúc truyền" được truyền vào cuối truyền?
Rò rỉ Nun

1
Bạn có thể giải thích nó được không?
Brain Guider

1
Re: đối số "cuối tập tin", bạn đang nhìn mọi thứ ngược lại. Khi bạn đang sử dụng thiết bị đầu cuối, yêu cầu treo đầu vào vì có gì đó được kết nối với thiết bị đầu cuối; ctrl-D có thể được gửi để gửi rõ ràng không có đầu vào. Nếu đầu vào được kết nối với một tệp trống (như TIO sẽ làm nếu bạn để trống hộp đầu vào) hoặc nếu nó được kết nối với một tệp nơi tất cả các đầu vào đã được đọc, thì không cần yêu cầu đầu vào làm bất cứ điều gì; nó đã biết không có đầu vào. Trên UNIX / Linux, "cuối tệp" và "không có đầu vào khả dụng" không thể phân biệt được trên các tệp thông thường.

3
Đối với trường hợp đầu tiên, klà đầu vào và llà một, vì vậy bạn vẫn đang tính toán 1**k, phải không? Điều này sẽ mất O(log(k))thời gian, mặc dù thực tế rằng bạn và tôi và mọi người đều biết trước rằng đó là một?
Richard Rast

18

Perl 5, 82 73 71 + 1 (cờ -n) = 72 byte

Tôi chắc chắn rằng tôi có thể chơi golf này (rất nhiều) nhiều hơn, nhưng đó là giờ đi ngủ, tôi đã dành đủ thời gian để gỡ lỗi, và tôi tự hào về những gì tôi có cho đến nay.

#x$=_$;
$x.=q;#say for(1..2**$_)#)_$..1(rof _$=+x$;;
eval $x;$x=~s/#//;

Bản thân chương trình không sử dụng đầu vào và chỉ đánh giá một chuỗi bắt đầu bằng một nhận xét và sau đó thực hiện thay thế một chuỗi, vì vậy điều này rõ ràng là trong thời gian không đổi. Về cơ bản, nó tương đương với:

$x="#";
eval $x;
$x=~s/#//;

Nhân đôi:

#x$=_$;
$x.=q;#say for(1..2**$_)#)_$..1(rof _$=+x$;;
eval $x;$x=~s/#//;
#x$=_$;
$x.=q;#say for(1..2**$_)#)_$..1(rof _$=+x$;;
eval $x;$x=~s/#//;

Bit thực sự mất thời gian theo cấp số nhân là eval thứ hai: nó đánh giá lệnh say for(1..2**$_), liệt kê tất cả các số từ 1 đến 2 ^ N, rõ ràng mất thời gian theo cấp số nhân.

Đảo ngược:

;//#/s~=x$;x$ lave
;;$x+=$_ for(1..$_)#)_$**2..1(rof yas#;q=.x$
;$_=$x#

Điều này (ngây thơ) tính tổng của đầu vào, rõ ràng mất thời gian tuyến tính (vì mỗi lần thêm là trong thời gian không đổi). Mã thực sự được chạy tương đương với:

$x+=$_ for(1..$_);
$_=$x;

Dòng cuối cùng chỉ để khi các lệnh này được lặp lại, nó sẽ mất thời gian bậc hai.

Đảo ngược và nhân đôi:

;//#/s~=x$;x$ lave
;;$x+=$_ for(1..$_)#)_$**2..1(rof yas#;q=.x$
;$_=$x#
;//#/s~=x$;x$ lave
;;$x+=$_ for(1..$_)#)_$**2..1(rof yas#;q=.x$
;$_=$x#

Điều này bây giờ lấy tổng của đầu vào (và thêm nó vào tổng của đầu vào, nhưng bất cứ điều gì). Vì nó không N^2bổ sung thứ tự , điều này mất thời gian bậc hai. Về cơ bản nó tương đương với:

$x=0;
$x+=$_ for(1..$_);
$_=$x;
$x+=$_ for(1..$_);
$_=$x;

Dòng thứ hai tìm thấy tổng của đầu vào, thực hiện Nbổ sung, trong khi dòng thứ tư thực hiện summation(N)bổ sung, đó là O(N^2).


Tuyệt quá! Làm điều đó trong một ngôn ngữ chính sẽ khó khăn! Điều này có upvote của tôi!
Arjun

Làm tốt lắm, cái này khá đẹp. Bạn có thể có nghĩa là $x.=q;##say...thay vì $x.=q;#say...mặc dù (với hai #thay vì 1). (Điều đó sẽ giải thích tại sao bạn đếm được 76 byte thay vì 75). Ngoài ra, bạn nên đếm -ncờ trong bytecount của bạn, vì chương trình của bạn không làm được gì nhiều nếu không có nó.
Dada

@Dada Tôi vô tình hoán đổi evalcác s///lệnh và. Nếu bạn làm evalđầu tiên bạn chỉ cần một #. Nắm bắt tốt!
Chris

@Chris Đúng, nó hoạt động thực sự. Bạn có thể bỏ qua sản phẩm cuối cùng #: $x=~s/#//;đảo ngược ;//#/s~=x$, trong bối cảnh của bạn không làm gì cả, như với hàng đầu #. (Tôi chưa kiểm tra nó mặc dù). Bất kể, có +1!
Dada

@Dada Bắt đẹp một lần nữa!
Chris

17

Trên thực tế , 20 byte

";(1╖╜ⁿr"ƒ"rⁿ@╜╖1(;"

Hãy thử trực tuyến!

Đầu vào: 5

Đầu ra:

rⁿ@╜╖1(;
[0]
5

Đảo ngược:

";(1╖╜@ⁿr"ƒ"rⁿ╜╖1(;"

Hãy thử trực tuyến!

Đầu ra:

rⁿ╜╖1(;
[0, 1, 2, 3, 4]
5

Nhân đôi:

";(1╖╜ⁿr"ƒ"rⁿ@╜╖1(;"";(1╖╜ⁿr"ƒ"rⁿ@╜╖1(;"

Hãy thử trực tuyến!

Đầu ra:

rⁿ@╜╖1(;
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31]
rⁿ@╜╖1(;
rⁿ@╜╖1(;
[0]

Nhân đôi và đảo ngược:

";(1╖╜@ⁿr"ƒ"rⁿ╜╖1(;"";(1╖╜@ⁿr"ƒ"rⁿ╜╖1(;"

Hãy thử trực tuyến!

Đầu ra:

rⁿ╜╖1(;
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24]
rⁿ╜╖1(;
rⁿ╜╖1(;
[0, 1, 2, 3, 4]

Ý chính

Thực tế là một ngôn ngữ dựa trên ngăn xếp.

  • abclà một chương trình có độ phức tạp O (1 n ) và gấp đôi của nó có độ phức tạp O (2 n ).
  • deflà một chương trình có độ phức tạp O (n 1 ) và gấp đôi của nó có độ phức tạp O (n 2 ).

Sau đó, trình của tôi là "abc"ƒ"fed", nơi ƒđược đánh giá. Bằng cách đó, "fed"sẽ không được đánh giá.

Tạo chương trình cá nhân

Mã giả của thành phần đầu tiên ;(1╖╜ⁿr:

register += 1 # register is default 0
print(range(register**input))

Mã giả của thành phần thứ hai ;(1╖╜ⁿ@r:

register += 1 # register is default 0
print(range(input**register))

Tôi không bao giờ nghĩ rằng điều này sẽ thậm chí có thể! Làm tốt lắm, thưa ngài! +1
Arjun

@Arjun Cảm ơn bạn đã đánh giá cao của bạn.
Nữ tu bị rò rỉ

Điều này là tuyệt vời và thực sự tăng đến thách thức bằng cách không sử dụng bình luận IMO. Tuyệt vời!
ShreevatsaR

1
Chà, điều này thực sự có ý kiến ​​... các chuỗi không được đánh giá và là NOP ...
Leaky Nun

4

Thạch , 20 byte

Một phần lấy cảm hứng từ giải pháp Thực tế của Leaky Nun .

Các dòng mới hàng đầu và trailing là đáng kể.

Bình thường:


⁵Ŀ⁵
R
R²
2*R
‘
⁵Ŀ⁵

Hãy thử trực tuyến!

Đầu vào: 5

Đầu ra:

610

Đảo ngược:


⁵Ŀ⁵
‘
R*2
²R
R
⁵Ŀ⁵

Hãy thử trực tuyến!

Đầu vào: 5

Đầu ra:

[1, 2, 3, 4, 5]10

Nhân đôi


⁵Ŀ⁵
R
R²
2*R
‘
⁵Ŀ⁵

⁵Ŀ⁵
R
R²
2*R
‘
⁵Ŀ⁵

Hãy thử trực tuyến!

Đầu vào: 5

Đầu ra:

[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32]10

Nhân đôi và đảo ngược


⁵Ŀ⁵
‘
R*2
²R
R
⁵Ŀ⁵

⁵Ŀ⁵
‘
R*2
²R
R
⁵Ŀ⁵

Hãy thử trực tuyến!

Đầu vào: 5

Đầu ra:

[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25]10

Giải trình

Chìa khóa ở đây là Ŀ, có nghĩa là "gọi liên kết tại chỉ số n là một đơn nguyên." Các liên kết được lập chỉ mục từ trên xuống dưới bắt đầu từ 1, không bao gồm liên kết chính (liên kết dưới cùng nhiều nhất). Ŀcũng là mô-đun, vì vậy nếu bạn cố gắng gọi liên kết số 7 trên 5 liên kết, bạn sẽ thực sự gọi liên kết 2.

Liên kết được gọi trong chương trình này luôn là liên kết ở chỉ số 10 ( ) cho dù đó là phiên bản nào của chương trình. Tuy nhiên, liên kết nào ở chỉ số 10 phụ thuộc vào phiên bản.

Cái xuất hiện sau mỗi Ŀcái ở đó để nó không bị vỡ khi đảo ngược. Chương trình sẽ báo lỗi tại thời điểm phân tích nếu không có số trước đó Ŀ. Có một sau nó là một nilad ra khỏi vị trí, mà chỉ đi thẳng đến đầu ra.

Phiên bản gốc gọi liên kết , tính toán n + 1.

Phiên bản đảo ngược gọi liên kết R, tạo ra phạm vi 1 .. n.

Phiên bản nhân đôi gọi liên kết 2*R, tính toán 2 n và tạo ra phạm vi 1 .. 2 n .

Phiên bản nhân đôi và đảo ngược gọi liên kết ²R, tính toán n 2 và tạo ra phạm vi 1 .. n 2 .


4

Befunge-98 , 50 byte

Bình thường

\+]#:\-1vk  !:;#
@k!:-1 .: ;#]#$ <;
[*:>@ 
&$< ^&;

Đây là chương trình đơn giản nhất trong số 4 - các lệnh duy nhất được thực hiện như sau:

\+]
  !
  : @
&$< ^&;

Chương trình này thực hiện một số nội dung không phù hợp trước khi nhấn lệnh "rẽ phải" ( ]) và một mũi tên. Sau đó, nó nhấn 2 lệnh "lấy đầu vào". Vì chỉ có 1 số trong đầu vào và do cách TIO xử lý &s, chương trình sẽ thoát sau 60 giây. Nếu có 2 đầu vào (và vì tôi có thể không thêm byte), IP sẽ chuyển sang chức năng "chương trình kết thúc".

Hãy thử trực tuyến!

Đảo ngược

;&^ <$&
 @>:*[
;< $#]#; :. 1-:!k@
#;:!  kv1-\:#]+\

Cái này phức tạp hơn một chút. các lệnh có liên quan như sau:

;&^  $
  >:*[
;< $#]#; :. 1-:!k@
  :

tương đương với

;&^                   Takes input and sends the IP up. the ; is a no-op
  :                   Duplicates the input.
  >:*[                Duplicates and multiplies, so that the stack is [N, N^2
     $                Drops the top of the stack, so that the top is N
     ]#;              Turns right, into the loop
         :.           Prints, because we have space and it's nice to do
            1-        Subtracts 1 from N
              :!k@    If (N=0), end the program. This is repeated until N=0
;< $#]#;              This bit is skipped on a loop because of the ;s, which comment out things

Phần quan trọng ở đây là :. 1-:!k@bit. Điều này hữu ích vì miễn là chúng ta đẩy độ phức tạp chính xác lên ngăn xếp trước khi thực hiện ở độ phức tạp thời gian thấp hơn, chúng ta có thể có được độ phức tạp mong muốn. Điều này sẽ được sử dụng trong 2 chương trình còn lại theo cách này.

Hãy thử trực tuyến!

Nhân đôi

\+]#:\-1vk  !:;#
@k!:-1 .: ;#]#$ <;
[*:>@ 
&$< ^&;\+]#:\-1vk  !:;#
@k!:-1 .: ;#]#$ <;
[*:>@ 
&$< ^&;

Và lệnh liên quan là:

\+]
  !
  :
&$< ^&;\+]#:\-1vk  !:;#
@k!:-1 .: ;#]#$ <;

Chương trình này đi vào 2 vòng. Đầu tiên, nó đi theo cùng một đường dẫn như chương trình bình thường, đẩy 1 và N lên ngăn xếp, nhưng thay vì quấn quanh đến giây &, IP lại nhảy qua một bình luận thành một vòng lặp đẩy 2^N:

        vk!:    If N is 0, go to the next loop.
      -1        Subtract 1 from N
 +  :\          Pulls the 1 up to the top of the stack and doubles it
  ]#            A no-op
\               Pulls N-1 to the top again

Các bit khác trên dòng 4 được bỏ qua bằng ;s

Sau khi (2 ^ N) được đẩy lên ngăn xếp, chúng tôi di chuyển xuống một dòng vào vòng in nói trên. Do vòng lặp đầu tiên, độ phức tạp thời gian là (N + 2 ^ N), nhưng điều đó giảm xuống (2 ^ N).

Hãy thử trực tuyến!

Nhân đôi và đảo ngược

;&^ <$&
 @>:*[
;< $#]#; :. 1-:!k@
#;:!  kv1-\:#]+\;&^ <$&
 @>:*[
;< $#]#; :. 1-:!k@
#;:!  kv1-\:#]+\

Các lệnh liên quan:

;&^

;< $#]#; :. 1-:!k@

 @>:*[

  :

Hàm này gần như giống hệt với chương trình đảo ngược, nhưng N^2không bị bật ra khỏi ngăn xếp, bởi vì dòng đầu tiên của bản sao thứ hai của chương trình được nối vào dòng cuối cùng của dòng thứ nhất, nghĩa là lệnh drop ( $) không bao giờ được thực thi , vì vậy chúng tôi đi vào vòng lặp in với N^2trên cùng của ngăn xếp.

Hãy thử trực tuyến!

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.