Chọn cây gậy dài nhất


13

Bạn là một người đam mê lập trình trẻ sống với 2 người bạn thân nhất của bạn. Mỗi tuần, một trong số các bạn phải làm tất cả các công việc trong nhà và bạn quyết định xem đó là lượt nào bằng cách chọn một cây gậy. Người nào chọn cây gậy ngắn nhất sẽ thua và làm tất cả các công việc.

Vì tất cả các bạn là lập trình viên và thích tạo ra các câu đố, bạn đã sửa đổi "Chọn cây gậy ngắn nhất" thành một câu đố trên máy tính.

Dưới đây là các quy tắc của câu đố.

  1. Bạn sẽ được cung cấp một ma trận 2D, trong đó mỗi cột đại diện cho một thanh.
  2. Trong mỗi cột, 1 đại diện cho một phần của thanh và 0 là khoảng trống
  3. Khi đi từ trên xuống dưới trong mỗi cột, ban đầu bạn có 0's và ngay sau khi bạn nhấn một 1, cây gậy đã bắt đầu và nghỉ ngơi của cột sẽ được lấp đầy với 1chỉ
  4. Bạn có thể viết chương trình của bạn để chọn một cột. Kích thước của thanh trong cột đó xác định người chiến thắng / người thua cuộc. Kích thước của thanh == số 1s trong cột đó.
  5. Tuy nhiên, chương trình đó chỉ có thể có độ phức tạp thời gian trường hợp xấu nhất tuyến tính.

Vì tất cả các bạn là lập trình viên, bạn sẽ biết liệu chương trình của người khác có đang giới hạn độ phức tạp thời gian hay không.

Công việc của bạn là:

  • Viết chương trình hoặc hàm chấp nhận đầu vào ở định dạng 2D hoặc mảng chuỗi.
  • Đầu vào có thể được lấy từ STDIN / prompt / console hoặc đối số chức năng.
  • Nếu bạn đang đọc đầu vào từ STDIN / prompt thì bạn có thể giả sử rằng việc đọc đầu vào và chuyển đổi nó thành một mảng mất 0 thời gian (mặc dù mã để làm như vậy phải có trong câu trả lời của bạn)
  • Xác định cột có thanh dài nhất trong đó.
  • Đầu ra có thể là giá trị trả về của hàm hoặc tới STDOUT / console / alert.
  • Chương trình / hàm phải có độ phức tạp thời gian trong trường hợp xấu nhất tuyến tính, O(m+n)trong đó mlà số lượng hàng và nsố cột.

Đầu vào có thể là một trong các định dạng sau:

Mảng 2D:

[ [0, 0, 0, 0],
  [1, 0, 0, 0],
  [1, 1, 0, 1],
  [1, 1, 1, 1] ]

Mảng của chuỗi:

[ "0000", "1000", "1101", "1111" ]

Đầu vào sẽ có các thuộc tính sau:

  • Kích thước của mảng là không xác định, giả sử một hình chữ nhật có kích thước bất kỳ
  • Trong bất kỳ cột nào, từ trên xuống, nếu bạn thấy 1, thì mọi thứ bên dưới sẽ là một
  • Các cột trống (tức là 0 độ dài) được cho phép.

Đây là một môn đánh gôn để mã ngắn nhất sẽ thắng ! *

Vui lòng giải thích mã của bạn hoặc cung cấp phiên bản chưa được chỉnh sửa (để xác minh độ phức tạp thời gian) cùng với định dạng đầu vào nào trong hai định dạng bạn mong đợi.

CẬP NHẬT Độ phức tạp thời gian tuyến tính ở đây có nghĩa là O (n + m) trong đó n là kích thước cột và m là kích thước hàng. (Dành cho những người không rõ ràng)

CẬP NHẬT 2 Điều này chắc chắn có thể được thực hiện trong thời gian tuyến tính. Và nếu bạn đang đăng một câu trả lời, vui lòng trì hoãn việc đăng logic / thuật toán trong một vài ngày để chiến đấu công bằng :)

CẬP NHẬT 3 Tôi sẽ xem qua tất cả các câu trả lời trong vài giờ để xác thực độ phức tạp của thời gian và chương trình :)


2
Tôi cho rằng điều này không thể được thực hiện trong O (n + m), vì mỗi ô có thể chứa giá trị quan trọng (tức là "1" đầu tiên của thanh / cột dài nhất). Vì vậy, bạn cần xem xét từng ô, mất O (n * m).
Falko

Có thể có cột trống?
Martin Ender

@Optimizer: Ồ, tôi hiểu rồi. Bạn đúng. :)
Falko

11
không thể được thực hiện trong O (n + m). Khi đầu vào đã được chuyển đổi thành định dạng cho phép truy cập ngẫu nhiên thì quá trình xử lý còn lại có thể là O (n + m), nhưng bạn yêu cầu viết chương trình và trong trường hợp xấu nhất là chỉ có 1trong đầu vào là ô cuối cùng nó là cần thiết để đọc toàn bộ đầu vào. Ngay cả khi thư viện tiêu chuẩn của một ngôn ngữ tạo ra quyền truy cập ngẫu nhiên vào stdin, trong các cảnh đó, nó sẽ đệm nó và do đó thời gian thực hiện là Omega (n * m).
Peter Taylor

2
Nếu bạn muốn cho phép mọi người " chỉ cần tạo một hàm chấp nhận một mảng ", câu hỏi không nên nói rằng họ phải viết chương trình. Và nếu bạn yêu cầu các giải pháp trong O (N ^ 0,5) trong đó N là kích thước của đầu vào, bạn không nên yêu cầu các giải pháp thời gian tuyến tính. Một giải pháp thời gian tuyến tính có thể đọc toàn bộ đầu vào.
Peter Taylor

Câu trả lời:


4

GolfScript, 45 ký tự

:^,:y;0:x{^y(=x=2%y*{y(:y;x\}{x):x}if^0=,<}do

Lấy đầu vào dưới dạng một chuỗi các chuỗi, trả về chỉ số (dựa trên 0) của cột cao nhất. Nó chạy trong các lần lặp O ( hàng + cột ) và mỗi lần lặp sẽ mất thời gian cơ bản không đổi (ít nhất là giả sử số học thời gian không đổi). Các hoạt động mảng / chuỗi duy nhất được thực hiện trong vòng lặp là tra cứu phần tử ( =) và lấy độ dài của chuỗi ( ,), cả hai đều mất thời gian không đổi trong GolfScript.

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

Giải trình:

Giống như hầu hết các giải pháp ở đây, mã này hoạt động bằng cách bắt đầu ở góc dưới bên trái của ma trận, đi lên hoặc phải tùy thuộc vào việc phần tử hiện tại của ma trận là 1 hay 0 và theo dõi cột nơi nó di chuyển lên cuối cùng .

Khi bắt đầu chương trình, tôi gán mảng đầu vào cho biến ^, độ dài của nó (tức là số lượng hàng) yvà 0 đến x. Giá trị 0 cũng được để lại trên ngăn xếp; trong vòng lặp sau, nó sẽ được thay thế bằng chỉ số của cột cao nhất.

Trong vòng lặp chính, ^y(=x=trích xuất xký tự -th của y-1hàng -th trong ^. Điều này thực sự trả về mã ASCII của ký tự, vì vậy 2%cần phải bỏ tất cả trừ bit cuối cùng. Trong trường hợp đặc biệt, nếu ybằng 0 (có thể xảy ra nếu cột cao nhất được tìm thấy cho đến tận hàng trên cùng), bit được tìm kiếm sẽ thực sự đến từ hàng cuối cùng trong ma trận (chỉ số -1), nhưng điều sau đây y*buộc nó về 0, do đó tạo ra một hàng tất cả các số ảo ở đầu ma trận một cách hiệu quả.

Sau ifđó, sau đó sẽ thực thi một trong hai khối mã trước nó, tùy thuộc vào việc bit tra cứu là khác không (đúng) hay không (sai). Nếu khác không, yđược giảm bởi một và giá trị hiện tại xthay thế chỉ số cột cao nhất trên ngăn xếp (với giá trị cũ tạm thời để lại trên đầu trang). Nếu bằng 0, xchỉ đơn giản là tăng thêm một (và tạm thời để lại trên ngăn xếp, trên đầu chỉ số cột cao nhất).

Cuối cùng, ^0=trích xuất hàng đầu tiên của ma trận, ,trả về độ dài của nó và <so sánh nó với chỉ số cột tạm thời để lại trên ngăn xếp (sẽ bằng xnếu nó chỉ tăng lên) Nếu chỉ số nhỏ hơn độ dài của hàng, vòng lặp lặp đi lặp lại.

Thi thiên Dựa trên thử nghiệm của tôi, có thể rút ngắn chương trình này bằng một ký tự bằng cách thay thế kiểm tra độ dài chuỗi ,<ở cuối vòng lặp bằng cách >cắt chuỗi ở chỉ mục đã cho và trả về phần cuối (sẽ trống và do đó sai, ở cuối vòng lặp). Tuy nhiên, trong khi cắt một chuỗi như thế dường như được triển khai như một hoạt động liên tục trong GolfScript (hay nói đúng hơn là trong Ruby, mà GolfScript chạy trên đầu trang), tôi không tìm thấy bất kỳ tài liệu chính thức nào nói như vậy. Để an toàn, tôi đã chọn tính năng dài hơn một chút, nhưng chắc chắn là phiên bản O (1) ở trên.


6

Ruby, 83 75 68 66 63 byte

f=->m{m[b=c=i=0].map{(c=i;b-=1)while(r=m[b-2])&&r[i]>0;i+=1};c}

Xác định hàm flấy dạng mảng 2D làm đầu vào.

Tôi đang bắt đầu ở phía dưới bên trái, theo dõi chiều dài thanh tối đa (thực tế, trừ đi) và cột tương ứng. Trong mỗi cột, nếu vẫn còn 1s trên độ dài thanh tối đa trước đó, tôi đi lên thanh đến cuối và nhớ chiều dài và cột tối đa mới. Điều đó có nghĩa là tôi đang lặp lại một lần dọc theo các cột và nhiều nhất là một lần dọc theo các hàng (cụ thể là tôi lặp lại theo chiều dài thanh tối đa), chính xác là như vậy O(m+n).


@Optimizer Tôi đã không thấy chỉnh sửa thứ hai của bạn cho đến sau khi tôi đăng nó, vì vậy dù sao nó cũng nằm trong lịch sử chỉnh sửa. Đó là lý do tại sao tôi chỉ đưa nó vào một spoiler cho những người muốn tự mình tìm ra nó.
Martin Ender

4

Trăn 2 - 71, 69, 73, 75 81

j=i=-1
M=input()
for m in M[0]:
 j+=1
 while-i<len(M)and M[i][j]:i-=1;J=j
print J

Đây có phải là để chạy trong Python 2 hoặc 3? Đầu vào được cho là trông như thế nào?
frageum

1
@feersum Python 2, mảng mảng.
Justin

@feersum: Quincunx nói đúng. Đầu vào là một mảng 2D của ints, như bạn đề xuất.
Falko

Sẽ không iđi ra khỏi giới hạn nếu một cây gậy chiếm cả một cột?
xnor

1
Xin lỗi, nhưng có vẻ như thay đổi jđể đếm từ 0phá vỡ điều kiện vòng lặp i*j.
xnor

2

C, 64 byte

Chỉnh sửa: Tôi đã học được rằng câu hỏi yêu cầu vị trí của cột dài nhất chứ không phải chiều dài của nó.

Dòng đầu tiên là mã đánh gôn và phần còn lại là lời gọi mẫu.

g(int m,int n,int**a,int*r){for(*r=n;n*m;a[m][n]?m--,*r=n:--n);}

/* usage:
    m = number of rows
    n = number of columns
    a = 1-based 2D array such that a[i][j] gives the value at the ith row and jth column
    r = address of return value 
    Returns (to r) the 1-indexed location of a column with the longest length, or 0 if n=0
    */

int main()
{
    int flat[4*4] = {1, 0, 0, 0,
                     1, 0, 0, 1,
                     1, 1, 0, 1,
                     1, 1, 1, 1};
    int*twoD[4] = {flat-1,flat+3,flat+7,flat+11};
    int ret;
    g(4,4,twoD-1,&ret);
    printf("%d", ret);
    return 0;
}

// old function which determines longest length (65 bytes)
f(int m,int n,int**a,int*r){for(*r=m;n*m;a[m][n]?m--:--n);*r-=m;}

Ấn tượng! Bạn có thể bỏ chữ ints trong chữ ký hàm bất kỳ hoặc không hoạt động do các con trỏ trong đó?
Martin Ender

1
Đầu vào chỉ nên chứa mảng. Bạn không thể nói với chương trình về kích thước của mảng.
Tối ưu hóa

Đợi đã, điều đó thực sự hoạt động? Điều này dường như đang trả lại độ dài của cây gậy dài nhất và không phải là vị trí của nó: ideone.com/YEzqzl
Martin Ender

2
@Optimizer về cơ bản là không thể trong C.
Martin Ender

Có thể, nhưng đó là câu hỏi :)
Trình tối ưu hóa

2

C #: 236 Chars

int p(int[,] a){int y=0,s=0,i=0,x;for(;++y<=a.GetUpperBound(0);)for(x=i;x<=a.GetUpperBound(1);){if(a[y,x++]==0)break;s=y;i++;}return s;}

vô dụng:

int p(int[,] a)
{
    int selectedRow=0;
    int maxLength=0;
    for(var y = 0; y<=a.GetUpperBound(0); y++)
        for(var x=maxLength; x<=a.GetUpperBound(1); x++)
        {
            if(a[y,x++]==0)
                break;
            selectedRow=y;
            maxLength++;
        }
    return selectedRow;
}

2

PHP 5,4 - 108 byte

(113 nếu bạn bao gồm <?php)

Định dạng đầu vào: Mảng sẽ được đọc dưới dạng chuỗi JSON.

php longest_stick.php "[[0, 0, 0, 0],[1, 0, 0, 0],[1, 1, 0, 1],[1, 1, 1, 1]]"

Khoảng trắng được thêm vào để dễ đọc - tất cả các dòng mới và khoảng trắng hàng đầu có thể được xóa.

<?php
$t=count($s=json_decode($argv[1]))-1;
foreach($s[0] as $k=>$_)
    while($s[$t][$k]) {
        $t--;
        $l = $k;
    }
echo $l?:0;

Phiên bản rút gọn:

<?php $t=count($s=json_decode($argv[1]))-1;foreach($s[0] as $k=>$_)while($s[$t][$k]){$t--;$l=$k;}echo $l?:0;

Loại ăn cắp thuật toán từ Martin ở đây, nhưng thật tuyệt khi chơi xung quanh với các ngôn ngữ không thường thấy ở đây XD


@ MartinBüttner Tôi đã "đánh cắp" thuật toán của bạn, vì vậy bây giờ nó phải là O (n + m). Tôi nghĩ nó đúng XD
Niet the Dark Tuyệt đối

Bạn có thể thay thế $s=json_decode($argv[1]);$t=count($s)-1;bằng $t=count($s=json_decode($argv[1]))-1;(-3 byte).
Hố đen

@Blackhole Thật vậy bạn có thể. Cảm ơn bạn!
Niet the Dark Tuyệt đối

@Blackhole Tôi nghĩ rằng sẽ phá vỡ chức năng. Nó sẽ thực hiện các bài tập ngay cả khi điều kiện không được đáp ứng.
Niet the Dark Tuyệt đối

@Blackhole Vẫn phá vỡ nó, tôi sợ XD $t--chỉ xảy ra nếu điều kiện được đáp ứng.
Niet the Dark Tuyệt đối

2

Rắn hổ mang - 98

def f(a)
    s,x,y=0,0,a.count-1
    while y+1and x<a[0].count
        while a[y][x],y,s=y-1,x
        x+=1
    print s

2

C ++ :: 78

Không giống như các giải pháp C khác, đây là toàn bộ chương trình. (không cần gọi, không cần cho hàm biết kích thước của mảng). Thật không may, điều này có nghĩa là nó dài hơn mainphải được sử dụng thay vì tên hàm ký tự đơn, tôi phải diễn giải đầu vào và sau đó đưa ra câu trả lời, trong đó giải pháp khác xử lý "nơi khác". Cũng là mã golf đầu tiên của tôi.
được biên dịch với g++ file.cpp -include iostream, chạy với ./a 000 010 110 111(ví dụ) == mảng chuỗi (tôi tin rằng điều này được cho phép trong thông số câu hỏi)

int c;main(int r,char**v){for(r--;r*v[r][c];v[r][c]-48?std::cout<<c,r--:++c);}

Phiên bản trên cho ra kết quả tốt nhất hiện tại cho đến nay trên mỗi lần lặp. Chữ số đầu ra cuối cùng là câu trả lời. Chuyển đổi từ xử lý từ dưới cùng bên trái thay vì dưới cùng bên phải và 0lập chỉ mục đã giảm giải pháp này 10 ký tự (!).
chuyển sang c ++ giảm việc gửi thêm một ký tự vì std::cout<<nó ngắn hơn putchar(-48)và nó cũng hỗ trợ rõ ràng hơn 9 thanh với đầu ra phù hợp (mặc dù có thể khó phân biệt từng đầu ra hơn)
Xóa trường trả lời và xuất ra một cách khác 6 ký tự. Bây giờ nó chỉ xuất ra hiện tại tốt nhất khi nó di chuyển lên mà cắt ra một số đầu ra ít nhất.
Toàn bộ tệp bây giờ chỉ có kích thước 78 byte - tiếp cận giải pháp chỉ có chức năng mà giải pháp khácCtrình sử dụng. (với rất nhiều mã bổ sung để hỗ trợ chức năng nói).

Như mô tả dưới đây đã hết hạn:

clà toàn cầu nên được khởi tạo với 0
rsố lượng đầu vào (hàng) +1 (tên chương trình)
vlà mảng chuỗi v[0]không hợp lệ (tên chương trình)
Vì nó là 0 được lập chỉ mục, rnằm ngoài giới hạn, vì vậy giảm dần.
Trong khi r!=0(chỉ vào chuỗi hợp lệ) và ký tự ctrong chuỗi không phải là dấu kết thúc null '\0'
nếu ký tự không '0'
đi lên một hàng ( r) và xuất cột ( c)
khác đi đến cột tiếp theo ( c)

xong

Tôi thậm chí có thể chơi golf này hơn nữa?

Mã Ungolfed (có đầu ra thêm):

#include <stdio.h>
#include <string.h>

int main(int argc, char* argv[])
{
  int rows = argc-1;
  int cols = strlen(argv[1]);
  int ans;

  printf("rows: %d, cols: %d\n",rows, cols);

  while((rows)&&cols)
  {
    if (argv[rows][cols-1]-'0')
    {
      printf("stick @%d,%d\n",cols,rows);
      ans = cols;
      rows--;
    }
    else
    {
      printf("no stick @%d,%d\n",cols,rows);
      cols--;
    }
  }
  printf("%d",ans);
}
Nó sử dụng độ dài của chuỗi để tìm ra số lượng cột và argc để tìm số lượng hàng. Bắt đầu ở góc dưới bên phải, nó tuân theo các quy tắc đơn giản sau: Nếu ô là một thanh, sau đó di chuyển lên, đặt câu trả lời cho cột hiện tại. Nếu ô không phải là một que, sau đó di chuyển sang trái. O (n + m): vì nó chỉ di chuyển lên và sang trái, nó chỉ có thể có số lần đọc tối đa n + m. Nó thoát sớm nếu nó rơi khỏi đỉnh hoặc bên trái của mảng.


1

OCaml - 144 ký tự

let s a=Array.(let rec f i j m=if i=0then m else if a.(i).(j)=0then if j=length a.(i)-1then m else f i(j+1)m else f(i-1)j j in f(length a-1)0 0)

Lấy int array arrayđầu vào làm đầu vào và bắt đầu từ bên dưới bên trái, di chuyển lên hoặc sang phải nếu nhìn thấy a 1hoặc a 0. Đếm cột bắt đầu từ 0.

Sử dụng

 s [| [| 0; 0; 0; 0 |]; [| 0; 0; 1; 0|]; [| 1; 0; 1; 0 |]; [| 1; 1; 1; 0 |]; [| 1; 1; 1; 1 |] |];;
 - : int = 2

Ung dung

let s a = Array.(
  let rec f i j m = (* m is the longest stick seen so far *)
    if i=0 then m (* A column is full: this is the longest possible stick and j=m anyway *)
    else if a.(i).(j)=0 then (* current column is shorter than a previously seen stick *)
      if j=length a.(i)-1 then m (* we have examined all columns, just return m *)
      else f i(j+1) m (* start examining next column *)
    else f (i-1) j j (* current column is longer than all the ones previously seen. Check how long the stick is *)
  in
  f (length a-1) 0 0)

0

T-SQL - 71 64

Lấy bảng A làm đầu vào

SELECT IDENTITY(INT, 1, 1) R, A INTO A
FROM (VALUES
 ('0000')
,('1000')
,('1101')
,('1111')
) AS A(A)

Và truy vấn là

SELECT TOP(1)CHARINDEX('1',A)FROM A WHERE A LIKE'%1%' ORDER BY R

SQLFiddle

Điều này trả về hàng đầu tiên từ bảng a được sắp xếp theo r trong đó có chuỗi 1 trong chuỗi a.

TOP(1) hạn chế kết quả cho hàng đầu tiên trả về.

CHARINDEX('1',A) trả về vị trí của 1 đầu tiên trong chuỗi hoặc 0 nếu không tìm thấy.

WHERE A LIKE'%1%' bộ lọc cho các hàng trong đó A chứa 1

ORDER BY R đảm bảo bảng được đọc từ trên xuống


Bạn có thể giải thích những gì đang xảy ra trong mã đó? : D Chưa có kinh nghiệm với T-SQL
Trình tối ưu hóa

Tôi hiểu rồi, vậy không phải bộ lọc trên mỗi hàng có hoạt động O (n * m) không? tức là không phức tạp thời gian tuyến tính.
Tối ưu hóa

Thật khó để nói. Công cụ SQL sẽ kiểm tra tất cả các hàng cho 1 trong cột. Nó sẽ chỉ trả lại hàng đầu tiên từ trên xuống đủ điều kiện. Vì vậy, trong tình huống này, nó quét toàn bộ bảng. Lọc các hàng có cột chứa 1. Sắp xếp kết quả trên cột nhận dạng và trả về kết quả đầu tiên.
MickyT

Nhìn vào nó như thế này: Sẽ thế nào nếu các hàng của bạn giống như "0000", "0000", "0000", "0001". Trong trường hợp này, nó sẽ phải đi đến hàng cuối cùng và cho đến ký tự cuối cùng của hàng để tìm ra sự hiện diện của 1
Trình tối ưu hóa

1
Vậy vâng, đó là O (m * n) rồi :)
Trình tối ưu hóa

0

Delphi 122 ký tự

Thở dài ... đó là một ngôn ngữ đồ sộ.

Cập nhật: phải thêm 6 ký tự trong việc thay đổi hàm trả về từ I thành số nguyên. Hàm vẫn được biên dịch khi chương trình thử nghiệm có "loại I = số nguyên;" tuyên bố còn lại từ một phiên bản trước đó của chương trình.

function S(A:array of string):integer;var n,c:integer;begin n:=0; repeat c:=Pos('1',A[n]);inc(n) until c>0; result:=c;end;

Bạn có đang thực hiện lệnh gọi Pos () trên mỗi hàng (trong trường hợp của bạn, chuỗi) của Mảng không?
Tối ưu hóa

@Optimiser Có, chương trình tìm kiếm từng chuỗi trong mảng (sử dụng 'inc (n)') cho đến khi tìm thấy '1'. '1' đầu tiên được tìm thấy sẽ là cao nhất (hoặc cao nhất bằng nhau) '1', do đó, vị trí của nó trong chuỗi (các chuỗi được 1-ndexed trong delphi) sẽ là vị trí của cột dài nhất. Thường xuyên thất bại nếu không có số 1 trong mảng, nhưng tôi tin rằng điều này sẽ bị hỏng đầu vào vì khi đó sẽ không có "thanh dài nhất" được tìm thấy.
Penguino

1
Vì vậy, trước hết, đây là một đầu vào hợp lệ "0000", "0010", "1111":, thứ hai, câu trả lời của bạn không đáp ứng yêu cầu phức tạp về thời gian tuyến tính
Trình tối ưu hóa

@Optimizer Có, đó sẽ là đầu vào hợp lệ và xác định chính xác thanh thứ 3. Nhưng tôi nhận ra sau khi thực hiện bài đăng mà tôi đã chuyển đổi chương trình N thứ tự hợp lệ đã sử dụng mảng, thành chương trình N ^ 2 không hợp lệ sử dụng chuỗi (theo đuổi mức giảm từ ~ 160 ký tự).
Penguino

0

sơ đồ - 236 ký tự

Thậm chí dài hơn phiên bản delphi ... có lẽ có một cách để làm điều này hiệu quả hơn nhiều với lược đồ. Và thậm chí tệ hơn - tôi chỉ nhận thấy đó là thứ tự m * n.

(define (s l) (cond ((eq? (cdr l) '()) (car l)) (else (map + (car l) (s (cdr l)))))) (define (u l) (define (t n p q l) (cond ((eq? l '()) p) ((< n (car l)) (t (car l) q (+ 1 q) (cdr l))) (else (t n p (+ 1 q) (cdr l))))) (t 0 0 1 (s l)))

l là danh sách có dạng '((0 0 0 0) (1 0 0 0) (1 1 0 1) (1 1 1 1)). Tôi nghĩ rằng đó là một đại diện hợp lý của đầu vào mảng 2D cho sơ đồ.

(sl) tính tổng các phần tử thứ n của mỗi danh sách phụ của danh sách danh sách các nuimbers, vì vậy (s '((0 0 0 0) (1 0 0 0) (1 1 0 1) (1 1 1 1))) sẽ trở lại (3 2 1 2).

(ul) trả về 'chỉ mục' của mục nhập lớn nhất của danh sách các số (sử dụng hàm trợ giúp t), vì vậy (u '(3 2 1 2)) sẽ trả về 1 (là phần tử lớn nhất' 3 trong danh sách ' (3 2 1 2) ở vị trí 1).


Tổng hợp tất cả các danh sách con là một hoạt động O (m * n).
Martin Ender

0

Vợt 70

Chơi gôn

(define(h m)(for/last([r m]#:final(memv 1 r))(length(takef r even?))))

Giả sử đầu vào là một mảng hai chiều, trong Vợt sẽ là một danh sách các danh sách:

(define m 
  '((0 0 0 0)
    (1 0 0 0)
    (1 1 0 1)
    (1 1 1 1)))

Ung dung:

(define (h m)
  ;; step through rows, stopping at the first that contains a 1
  (for/last ([r m] #:final (memv 1 r)) 
    (length (takef r even?)))) ; pop off the leading zeroes to get the column index

Trả về chỉ số cột với thanh dài nhất.


Vì vậy, về cơ bản, bạn đang đi qua từng cột và đếm số lượng 1?
Tối ưu hóa

Tôi thấy điểm của bạn. Thuật toán cập nhật.
Matthew Butterick

Điều này vẫn có độ phức tạp trong trường hợp xấu nhất là O (m * n) (đối với trường hợp không có 1trong ma trận, hoặc chỉ ở hàng dưới cùng).
Martin Ender

0

JavaScript, ES6, 76 ký tự

W=a=>(j=>{for(k=i=a.length-1;~i&~j;)a[i][j]?(k=j,i--):j--})(a[0].length-1)|k

Có mảng đầu vào mảng.


0

JavaScript ES6, 65 byte

Có cả hai định dạng đầu vào

f=(a,t)=>a.reduceRight((p,c)=>t+1?t:(x=c.indexOf(1,p))+1?x:t=p,0)

Giải thích:

Lặp đi lặp lại từ dưới lên trên. Sử dụng String.prototype.indexOf()hoặc Array.prototype.indexOf()tùy thuộc vào đầu vào trên mỗi giá trị. Tìm chỉ mục đầu tiên của mỗi hàng có 1 từ phần bù trước, nếu không tìm thấy thì nó đặt tbiến thành phần bù cuối cùng và không thực hiện indexOfcác cuộc gọi nữa .


indexOflàm việc tại một trong hai O(log n)hoặc O(n), vì vậy các thuật toán tổng thể sẽ không bao giờ có trongO(m + n)
Tối ưu hóa

@Optimizer Yeah nhận ra rằng đó là O (m * n) không suy nghĩ thẳng.
George Reith

@Optimizer Cập nhật thànhO(m+n)
George Reith
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.