Mã hậu quả tăng dài nhất ngắn nhất


11

Thách thức là viết ra triển khai ngắn nhất để tìm ra sự gia tăng dài nhất .

Ví dụ : Gọi S là dãy 1 5 7 1 8 4 3 5 [độ dài của S = 8]

  • Chúng tôi có 1 chuỗi con có độ dài 0 [sẽ xem xét nó tăng]
  • 6 chuỗi con có độ dài 1 {1,5,7,8,4,3} [tất cả chúng được coi là tăng]
  • (7 * 8) / 2 chuỗi con có độ dài 2 [nhưng chúng tôi sẽ loại bỏ các bản sao], các tiểu mục tăng dần có màu đen mạnh.
    { 15,17 , 11, 18,14,13,57 , 51, 58 , 54,53,55,71, 78 , 74,73,75,84,83,85,43, 45,35 }

[lưu ý rằng chúng tôi chỉ quan tâm đến các chuỗi con tăng nghiêm ngặt]

[bạn không thể thay đổi thứ tự của các thành phần bên trong chuỗi, do đó không có chuỗi con [37] trong chuỗi ví dụ]

  • Chúng tôi đã tăng các chuỗi con có độ dài 4 là 1578, nhưng không có chuỗi con có độ dài 5, vì vậy chúng tôi xem xét độ dài của chuỗi con tăng dài nhất = 4.

Đầu vào :

a 1 a 2 ... a N (Trình tự)

tất cả các số là số nguyên dương nhỏ hơn 10 3
N <= 1000

Đầu ra :

Một số nguyên biểu thị độ dài của chuỗi con tăng dài nhất của chuỗi đầu vào.

sample input(1)
1 2 4 2 5
sample output(1)
4

sample input(2)
1 5 7 1 8 4 3 5
sample output(2)
4

Mã của bạn phải chạy kịp thời, vui lòng kiểm tra mã của bạn trong trường hợp này trước khi gửi nó ở đây (cũng là liên kết chứa giải pháp c ++ 11 290 byte của tôi)

Bạn có thể lấy đầu vào từ tệp / stdin hoặc làm tham số hàm và bạn có thể in đầu ra thành tệp / thiết bị xuất chuẩn hoặc chỉ trả về giá trị nếu bạn viết hàm

Bảng điểm

  1. Dennis CJam - 22
  2. isaacg Pyth - 26
  3. Howard GolfScript - 35
  4. người bán hàng tự hào Haskell - 56
  5. Ray Python 3 - 66
  6. histocrat Ruby - 67
  7. DLeh C # - 92
  8. Áo choàng YosemiteMark - 94
  9. faubiguy Python 3 - 113

1
"Chúng tôi có 1 chuỗi con có độ dài 0 [sẽ xem xét nó tăng lên]", về mặt kỹ thuật, bạn có vô số chuỗi con 0 độ dài :)
Cruncher

Trên thực tế, tôi phải thay đổi câu lệnh sao cho tất cả các "Bộ" phải xóa các bản sao, ví dụ: {1,5,7,1,8,4,3,5} phải là {1,5,7,8,4 , 3} và sau đó chúng ta có thể nói rằng có 1 chuỗi con 0 0 trong "Đặt". cảm ơn
Mostafa 36a2

1
Đối với các hàm, chúng ta nên đếm các byte của hàm ngoài ( function f(){...}) hay hàm bên trong (chỉ ...)? Nếu chúng ta đếm các chức năng bên ngoài, các chức năng ẩn danh có được phép không?
Dennis

Chúng tôi đếm chức năng bên ngoài và chức năng ẩn danh được cho phép, nhưng đừng bỏ lỡ việc cung cấp phiên bản có thể kiểm tra (phiên bản hoàn chỉnh với xử lý đầu vào / đầu ra)
Mostafa 36a2

Câu trả lời:


2

CJam, 22 byte

1e3,q~{_2$<$0=(t}/$0=z

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

Thí dụ

$ cjam subsequence.cjam <<< '[2 1]'; echo
1
$ cjam subsequence.cjam <<< '[1 9 2 4 3 5]'; echo
4

Chương trình in 57cho trường hợp thử nghiệm này sau 0,25 giây.

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

Tôi lấy ý tưởng chung từ câu trả lời của @ Ray .

1e3,    " Push the array [ 0 ... 999 ] (J).        ";
q~      " Read from STDIN and evaluate.            ";
{       " For each integer (I) of the input array: ";
  _2$<  " Push [ J[0] ... J[I - 1] ] (A).          ";
  $0=(  " Compute min(A) - 1.                      ";
  t     " Update J[I] with the value on the stack. ";
}/      "                                          ";
$0=     " Compute abs(min(J)).                     ";

5

Con trăn 3, 66

Lưu ý rằng tất cả các số nằm trong phạm vi [1, 999], chúng ta có thể sử dụng một mảng bđể duy trì độ dài chuỗi dài nhất kết thúc với mỗi số. b[x] = dcó nghĩa là chuỗi dài nhất kết thúc bằng xcó độ dài d. Đối với mỗi số từ đầu vào, chúng tôi cập nhật mảng bằng cách sử dụng b[x] = max(b[:x]) + 1và sau đó chúng tôi đã hoàn thành công việc bằng cách thực hiện max(b)cuối cùng.

Độ phức tạp thời gian là Trên) O (mn) , trong đó mluôn là 1000 và nlà số phần tử đầu vào.

def f(a):
 b=[0]*1000
 for x in a:b[x]=max(b[:x])+1
 return max(b)

Wow, có vẻ như đã vô dụng :) Bạn có thể kiểm tra nó bằng cách sử dụng stdin / stdout bằng cách thêm một dòng:

print(f(map(int,input().split())))

for x in a: max(b)trông khá nhiều O (n ^ 2).
Howard

@Howard Đó là O(1000 n)1000 và là một hằng số. Bạn cũng có thể nghĩ nó như O(m n).
Ray

3
Với lập luận như vậy, toàn bộ cuộc thảo luận là vô ích vì trên đầu vào hạn chế, độ phức tạp luôn luôn O(1);-)
Howard

@ Làm thế nào tôi đến từ thế giới ACM-ICPC và đây là một quy ước ở đó. Bạn có thể nghĩ nó là O (mn). Nó vẫn khác với O (n ^ 2). Dù sao, thời gian chi phí sẽ ít hơn thời gian khởi động phiên dịch viên nên tôi nghĩ nó đủ nhanh.
Ray

Thuật toán ngắn ấn tượng! Tôi chỉ có thể phát hiện một ký tự (ít nhất là khi chuyển sang Python 2): Bạn có thể in kết quả. printngắn hơn return.
Falko

3

Con trăn - 113

a=[]
for i in map(int,input().split()):
 if not a or i>a[-1]:a+=[i]
 z=0
 while a[z]<i:z+=1
 a[z]=i
print(len(a))

Giải pháp được chấp nhận. Mã của bạn đã được thử nghiệm ở đâyđây .
Mostafa 36a2

@ Mostafa36a2 Từ "được chấp nhận" có nghĩa khác trên trang web này. Tôi nghĩ những gì bạn có nghĩa là "chấp nhận được".
Ray

Xin lỗi, vâng, ý tôi là chấp nhận được, quá sớm để chọn Người được chấp nhận.
Mostafa 36a2

Với dòng a+=[i]*(a==[]or i>a[-1]);z=0và in len(a)(không có dấu ngoặc), bạn có thể lưu 4 ký tự.
Falko

3

Bình thường , 26 29 33 39

J*]0^T3Fkyw=@JkheS:J0k)eSJ

Giải pháp của cảng @ ray. Vượt qua các bài kiểm tra chính thức. Bây giờ sử dụng đầu vào STDIN được phân tách bằng dấu cách, không phải chức năng gọi.

Chạy như sau:

./pyth.py -c "J*]0^T3Fkyw=@JkheS:J0k)eSJ" <<< "1 5 7 2 8 4 3 5"
4

Giải trình:

J*]0^T3                 J = [0]*10^3
Fkyw                    For k in space_sep(input()):
=@Jk                    J[k]=
heS:J0k                 max(J[0:k])+1
)                       end for
eSJ                     max(J)

Thời gian không giới hạn:

Bình thường , 18

L?eS,ytbhyf>Thbbb0

Lưu ý kỹ thuật: Tôi nhận thấy một lỗi trong trình biên dịch Pyth của tôi khi viết golf này. Lđã không làm việc. Đó là lý do tại sao có một cam kết gần đây với kho git ở trên.


mã của bạn không chạy kịp thời cho một trường hợp có danh sách lớn (giả sử 100 phần tử)
Mostafa 36a2

3
@ Mostafa36a2 Nếu bạn muốn yêu cầu thời gian chạy, vui lòng nói như vậy trong câu hỏi và thêm một hoặc hai trường hợp thử nghiệm. Nếu đó chỉ là một nhận xét, thì tôi đồng ý, nó khá chậm.
isaacg

Xin lỗi nhưng tôi đã đề cập rằng đó không phải là thời gian chạy mà ít nhất là [cách thức kịp thời], không có vấn đề gì nếu mã mất 10-20 phút hoặc thậm chí một giờ, nhưng các giải pháp O (2 ^ n) sẽ không bao giờ cho kết quả trong suốt cuộc sống lâu dài của chúng tôi.
Mostafa 36a2

@ Mostafa36a2 Có nó, tôi chỉ nhận thấy dòng đó. Tôi sẽ làm việc để cải thiện.
isaacg

1
Xin lỗi tôi thấy bản cập nhật bây giờ, xin vui lòng thử trường hợp này và cho tôi biết nếu nó hoạt động.
Mostafa 36a2

3

Clojure, 94 ký tự

Sử dụng phương pháp cập nhật kết quả của @ Ray trong một vectơ 1000 mục:

(defn g[s](apply max(reduce #(assoc % %2(inc(apply max(take %2 %))))(into[](repeat 1e3 0))s)))

Mỗi yêu cầu, với câu lệnh in (sẽ in câu trả lời và trả về nil). Đầu vào phải là một vectơ (g [1 2 3]) hoặc danh sách (g '(1 2 3)):

(defn g[s](prn(apply max(reduce #(assoc % %2(inc(apply max(take %2 %))))(into[](repeat 1e3 0))s))))

bạn có thể thêm câu lệnh in để làm cho nó có thể kiểm tra được không? Nó sẽ không được tính vào điểm số.
Mostafa 36a2

1
Cập nhật. Tôi đã chạy nó trên cả hai ví dụ lớn của bạn và nhận được 58 và 57 như mong đợi.
YosemiteMark

Tôi nghĩ bạn vẫn cần gọi hàm: p, nhưng nếu bạn đã thử nó thì thế là đủ.
Mostafa 36a2

3

Haskell, 58 57 56 ký tự

(x:s)%v|v>x=x:s%v|0<1=v:s
_%v=[v]
l s=length$foldl(%)[]s

Điều này sử dụng một thuật toán tôi đã thấy một lần trên internet, nhưng tôi không thể tìm thấy nó. Phải mất một lượng thời gian không thể nhận thấy trên trường hợp thử nghiệm đã cho trên máy tính của tôi với GHCi (có thể sẽ còn nhanh hơn nếu được biên dịch).


Thuật toán mà bạn đề cập giống như thuật toán được sử dụng bởi @faubiguy.
Ray

@Ray bạn đúng
tự hào

2

GolfScript, 35 ký tự

~]]){1${~2$<*)}%1+$-1>[\+]+}/$-1=0=

Một triển khai hoạt động như một chương trình hoàn chỉnh với đầu vào trên STDIN (không có số độ dài cho trước). Việc thực hiện là hợp lý nhanh chóng, ngay cả đối với đầu vào dài hơn (thử ở đây ).

Ví dụ:

> 1 5 7 1 8 4 3 5
4

> 5 1 9 9 1 5
2

1
@ MartinBüttner Mất khoảng 5 giây cho 1000 số trên máy tính của tôi. Giả sử $là O (n log n) thuật toán là O (n ^ 2 log n).
Howard

vui lòng thử đầu vào trong liên kết này
Mostafa 36a2

@ Mostafa36a2 Tôi đã làm rồi (xem bình luận trước). Sau 5 giây, nó trả về 58.
Howard

đây là một số khác, nó sẽ trả về 57, vì vậy nếu mã của bạn đã trả về 57 thì nó được chấp nhận :) Xin chúc mừng
Mostafa 36a2

@ Mostafa36a2 Ah, bây giờ tôi thấy đó là hai trường hợp thử nghiệm riêng biệt. Có, liên kết thứ hai của bạn trả về 57 cũng như giải pháp của tôi cho đầu vào này.
Howard

2

Ruby, 67

s=Hash.new{|s,a|f,*r=a
s[a]=f ?[1+s[r.select{|x|x>f}],s[r]].max: 0}

Điều này chạy trong 30 giây trên đầu vào lớn, điều đó có được tính là một cách kịp thời không? : p

Đó là đệ quy vũ phu, nhưng với một số ghi nhớ.


1
Vâng, đây là một cách kịp thời :)
Mostafa 36a2

2

C #, 172 92 ký tự

Không có gì đặc biệt, nhưng tôi đã làm điều đó vì vậy tôi nghĩ rằng tôi cũng có thể gửi nó.

int a(int[] j){int c=2,m=2,i=1;for(;++i<j.Length;){c=j[i]>j[i-1]?c+1:2;m=c>m?c:m;}return m;}

Cảm ơn Armin và Bob vì những cải tiến của họ!


1
bạn có thể thay đổi tham số của mình thành int [] và sau đó bạn sẽ có ít ký tự hơn vì bạn sẽ không cần truyền chuỗi thành int
Armin

2
Các không gian xung quanh =>là không cần thiết. Bạn cũng có thể di chuyển i=0khai báo bên ngoài forvòng lặp, đến int c=2,m=2,i=0;for(;. Bạn cũng có thể thả niềng răng quanh forcơ thể, vì bạn chỉ có một tuyên bố duy nhất trong đó.
Bob

c++;if(c>m)m=c;có thể m=c++>m?m:c;, và bạn có thể một lần nữa thả niềng răng xung quanh đó.
Bob

1
Trên thực tế, bạn cũng có thể loại bỏ if(i>0)kiểm tra bằng cách forbắt đầu vòng lặp ở mức 1. Bạn có thể rút ngắn hơn nữa int c=2,m=2,i=0;for(;i<j.Length;i++)if(i>0)đề xuất trước đó int c=2,m=2,i=0;for(;i++<j.Length;). Toàn bộ phần đó có thể được chuyển đổi thành int c=2,m=2,i=0;for(;i++<j.Length;){c=j[i]>j[i-1]?c+1:2;m=c>m?m:c;}(sử dụng một ternary khác để thay thế phần còn lại cuối cùng if- quy tắc ngón tay cái là ngắn hơn nếu ifcơ thể bạn chỉ đơn giản là một nhiệm vụ.
Bob

2
Xin lỗi - lỗi đánh máy trong bình luận trước đây của tôi, m=c>m?m:cnên được m=c>m?c:m. Và nếu bạn thêm vào đề xuất của @ Armin, bạn sẽ nhận được 92 byte, gần như giảm một nửa kích thước! int a(int[] j){int c=2,m=2,i=0;for(;i++<j.Length;){c=j[i]>j[i-1]?c+1:2;m=c>m?c:m;}return m;}
Bob

2

J , 19 byte

[:#]`I.`[} ::,~/@|.

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

Chạy trong O (n log n) , sử dụng một loại kiên nhẫn được sửa đổi vì chỉ cần độ dài, không phải là thứ tự thực tế, là cần thiết.

Giải trình

[:#]`I.`[} ::,~/@|.  Input: array
                 |.  Reverse
               /     Reduce right-to-left
     I.                Find the index to insert while keeping it sorted
                       (uses binary search)
         }             Amend the current search array at that index with the next value
           ::          If error (when the index is not found)
             ,           Append the value at the end
 #                   Length of that array

1

Bash + coreutils, 131 byte

Giải pháp này thất bại khủng khiếp về yêu cầu cách thức kịp thời và thậm chí không đặc biệt ngắn, nhưng tôi thích rằng loại điều này ít nhất là về mặt lý thuyết có thể có trong kịch bản shell, vì vậy dù sao tôi cũng sẽ đăng. Điều này chạy với độ phức tạp thời gian gây ra vĩnh cửu của O (2 ^ n).

s=${1//,/,:\},\{}
a=`eval echo "{$s,:}"`
for s in $a;{
b="$(tr , \\n<<<$s|grep -v :)"
sort -nC<<<"$b"&&wc -w<<<$b
}|sort -nr|sed 1q

Đầu vào là một danh sách được phân tách bằng dấu phẩy được truyền dưới dạng một đối số dòng lệnh:

$ time ./slisc.sh 1,5,7,1,8,4,3,5
4

real    0m1.240s
user    0m0.518s
sys 0m0.689s
$ 

Mở rộng cú đúp được sử dụng để xây dựng danh sách tất cả các chuỗi con có thể.

  • Dòng đầu tiên thay thế dấu phẩy bằng ,:},{, tạo ra một chuỗi như1,:},{5,:},{7,:},{1,:},{8,:},{4,:},{3,:},{5
  • Dòng thứ hai hoàn thành chuỗi này với dấu ngoặc nhọn, dấu phẩy và dấu chấm phẩy để cung cấp cho chuỗi này {1,:},{5,:},{7,:},{1,:},{8,:},{4,:},{3,:},{5,:}. Đây là một bản mở rộng bash brace hợp lệ, khi evaled với một echodanh sách phân tách không gian này1,5,7,1,8,4,3,5 1,5,7,1,8,4,3,: 1,5,7,1,8,4,:,5 1,5,7,1,8,4,:,: ...
  • theo mặc định, bash chia tách các chuỗi với khoảng trắng, vì vậy chúng tôi lặp qua từng phần tử của danh sách này:
    • dấu phẩy được thay thế bằng dòng mới, sau đó các dòng chứa dấu hai chấm được loại bỏ, đưa ra danh sách phân tách dòng mới cho mỗi lần tiếp theo có thể
    • sau đó chúng tôi sort -Csẽ kiểm tra thứ tự tăng dần và nếu có, hãy sử dụng wc -wđể in độ dài của danh sách
  • danh sách kết quả của độ dài danh sách được sắp xếp theo chiều ngược lại và giá trị đầu tiên được in để đưa ra độ dài tiếp theo tăng dài nhất.

1

Stax , 21 byte

ë/NS7Γ╥╚┌{1╤╒¬è¶²╢╦┌☼

Chạy và gỡ lỗi nó

Điều này có hai trường hợp thử nghiệm, một trong số đó là trường hợp 1000 phần tử. Nó chạy một trong 24 giây trên máy của tôi. Nó sử dụng phương pháp lập trình động cổ điển cho loại vấn đề này.


0

J 34

Lưu ý rằng tôi đọc đầu vào tiêu chuẩn là tốt.

>./;+/@:*&.>(<*>.)/\&.><\.".1!:1]3

Không đọc đầu vào tiêu chuẩn, thịt là 26 ký tự.

>./;+/@:*&.>(<*>.)/\&.><\.

Chỉ cần nhận thấy tôi chạy chậm cho đầu vào lớn, oh tốt.



0

C # (.NET Core) , 155 byte

Đã sử dụng một mảng để tính toán chuỗi tăng dài nhất kết thúc tại mỗi vị trí trong mảng đầu vào (lập trình động), sau đó trả về giá trị lớn nhất. Ví dụ, mảng được tính toán cho đầu vào [1,5,7,1,8,4,3,5]sẽ là [1,2,3,1,4,2,2,3]và giá trị lớn nhất 4được trả về.

int b(int[]x){int l=x.Length,r=1,i=0,j,c;var a=new int[l];a[0]=1;while(++i<l)for(j=0;j<i;j++){c=x[j]<x[i]?a[j]+1:1;a[i]=a[i]<c?c:a[i];r=r<c?c:r;}return r;}

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


0

Ngôn ngữ Wolfram (Mathicala) , 38 byte

Length@LongestOrderedSequence[#,Less]&

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

Tất nhiên có một Mathicala tích hợp sẵn để tìm các chuỗi được đặt hàng dài nhất. Tên của nó rất dài: nó chiếm hơn một nửa giải pháp và tôi sẽ không ngạc nhiên nếu có ai đó chơi golf giải pháp này.

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.