Có nước trên cửa sổ của tôi


13

Kịch bản

Tôi lái xe dọc theo một con đường với chiếc xe của tôi và trời bắt đầu mưa. Những hạt mưa rơi ngẫu nhiên trên cửa sổ của tôi và bây giờ tôi tự hỏi, khu vực ẩm ướt được kết nối lớn nhất ở đâu?

Nhiệm vụ

Để dễ dàng hơn, cửa sổ được chia theo ma trận 10 * 10 ô vuông. Công việc của bạn là tìm khu vực thả nước được kết nối lớn nhất trên cửa sổ.

Đầu vào

Có hai đầu vào khả dĩ, bạn có thể sử dụng Mảng 2 chiều hoặc Mảng 1 chiều. Bạn có thể chọn giữa bất kỳ đầu vào nào như stdin, v.v ...
Ví dụ:

// 2-dimensional:
[[0,1,0,0,0,0,1,0,0,0],
 [0,1,1,0,0,0,0,1,1,0],
 [0,1,1,0,0,0,0,1,0,0],
 [0,1,0,0,0,0,0,0,0,0],
 [0,0,0,0,0,0,0,0,1,0],
 [0,0,0,1,1,0,0,0,1,0],
 [0,0,0,1,1,0,0,0,1,0],
 [0,0,0,0,0,1,1,0,1,0],
 [0,0,0,0,0,1,1,0,1,0],
 [0,0,0,0,0,0,0,0,0,0]]

// 1-dimensional
[0,1,0,0,0,0,1,0,0,0,
 0,1,1,0,0,0,0,1,1,0,
 0,1,1,0,0,0,0,1,0,0,
 0,1,0,0,0,0,0,0,0,0,
 0,0,0,0,0,0,0,0,1,0,
 0,0,0,1,1,0,0,0,1,0,
 0,0,0,1,1,0,0,0,1,0,
 0,0,0,0,0,1,1,0,1,0,
 0,0,0,0,0,1,1,0,1,0,
 0,0,0,0,0,0,0,0,0,0]

Đầu ra

Mã của bạn phải đưa ra kích thước của khu vực được kết nối lớn nhất và tọa độ x và y của các hình mờ thuộc khu vực này theo định dạng
"Kích thước: Z Tọa độ: (X1, Y1) (X2, Y2) .. . "
Ví dụ cho đầu vào trước:

Size: 6 Coordinates: (1,0) (1,1) (2,1) (1,2) (2,2) (1,3)

Thứ tự của các tọa độ không quan trọng.

Quy tắc

  • Waterdrops được kết nối, nếu chúng chạm vào nhau trực giao
  • Kết nối đường chéo không được tính
  • Có thể có nhiều khu vực và mã của bạn phải tìm ra khu vực lớn nhất
  • Trường trống được biểu thị là "0" và trường ướt là "1"
  • Đăng giải pháp của bạn với một lời giải thích ngắn và đầu ra của đầu vào trước đó
  • Mã ngắn nhất trong vòng 7 ngày tới sẽ giành chiến thắng
  • Nếu có hai khu vực có cùng kích thước, bạn có thể chọn một khu vực

Người chiến thắng: Ventero với 171 - Ruby


2
@Doorknob phàn nàn về một lỗi đánh máy? OP là người Đức.
edc65

1
@Doorknob Tôi đã thay đổi nó, cảm ơn bạn. Giới hạn thời gian chỉ nói, khi tôi sẽ xác định người chiến thắng nhưng bạn vẫn có thể đăng câu trả lời.
izlin

6
Tôi muốn nói rằng đây là bản sao của codegolf.stackexchange.com/questions/32015/iêu .
Howard

1
@TeunPronk: OP có nghĩa là Poster gốc. Tra cứu nó trong Google :)
cần

2
Một số làm rõ về phương thức nhập liệu được cho phép, chính xác, sẽ là tuyệt vời.
Ventero

Câu trả lời:


3

Ruby, 171 ký tự

r=eval *$*
u=(0..99).map(&v=->p{-~p*r[p]>0?" (#{r[p]=0;u=p%c=10},#{p/c})"+v[p+c]+v[p-c]+v[u>0?p-1:p]+v[u<9?p+1:p]:""}).max_by &:size
puts"Size: #{u.size/6} Coordinates:"+u

Nhập thông qua tham số dòng lệnh dưới dạng mảng một chiều.

Đầu ra cho đầu vào mẫu: Size: 6 Coordinates: (1,0) (1,1) (1,2) (1,3) (2,2) (2,1)

Câu trả lời này sử dụng cách tiếp cận lấp đầy lũ đơn giản, xây dựng danh sách tọa độ cho từng cụm hạt mưa. Hầu hết các mã thực sự được sử dụng để kiểm tra giới hạn và I / O.


5

Con trăn - 192

a=10;g+=[0]*a
def f(k):
 if g[k]:g[k]=0;return" (%d,%d)"%(k/a,k%a)+f(k+a)+f(k-a)+f(k+(k%a<9))+f(k-(k%a>0))
 return''
m=max(map(f,range(100)),key=len)
print"Size: "+`len(m)/6`+" Coordinates:"+m

Đầu vào (Dán trước mã):

g=[0,1,0,0,0,0,1,0,0,0,0,1,1,0,0,0,0,1,1,0,0,1,1,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1,1,0,0,0,1,0,0,0,0,1,1,0,0,0,1,0,0,0,0,0,0,1,1,0,1,0,0,0,0,0,0,1,1,0,1,0,0,0,0,0,0,0,0,0,0,0]

Cảm ơn Sở thích của Calvin cho các chỉnh sửa được đề xuất!


Bạn có thể sử dụng map(f,range(100))thay vì [f(i)for i in range(100)]để lưu 8 ký tự. Ngoài ra tôi tin rằng tọa độ của bạn là (y, x) chứ không phải (x, y).
Sở thích của Calvin

3

C # - 548 523 522 511 503 476

(dưới 500 ... vâng)

Tôi chắc chắn có rất nhiều chỗ để cải thiện.

Cách tôi nhập dữ liệu là khởi tạo một mảng. Tôi đã không bao gồm mảng đó trong điểm số (nếu bạn nghĩ rằng điều này là gian lận, tôi có thể thay đổi mã, nhưng nó sẽ thêm mã tương đối vì C # không tuyệt vời trong việc phân tích cú pháp mảng)

using o=System.Console;using l=System.Collections.Generic.List<int[]>;class P{
static int[,] a ={{0,1,0,0,0,0,1,0,0,0},{0,1,1,0,0,0,0,1,1,0},{0,1,1,0,0,0,0,1,0,0},{0,1,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,1,0},{0,0,0,1,1,0,0,0,1,0},{0,0,0,1,1,0,0,0,1,0},{0,0,0,0,0,1,1,0,1,0},{0,0,0,0,0,1,1,0,1,0},{0,0,0,0,0,0,0,0,0,0}};
static int w=10,h=w,x=0,y;static l t=new l(),m=new l();static void f(int r,int c){if(a[r,c]==1){a[r,c]=0;if(r<h)f(c,r+1);if(r>0)f(c,r-1);if(c<w)f(c+1,r);if(c>0)f(c-1,r);t.Add(new[]{c,r});}}static void Main(){for(;++x<w;)for(y=0;++y<h;){if(a[x,y]==1)f(x,y);if(t.Count>m.Count)m=t.FindAll(r=>true);t.Clear();}o.Write("Size: "+m.Count+" Coordinates: ");m.ForEach(c=>o.Write("({0},{1}) ",c[0],c[1]));}}

Kiểm tra nó tại http://ideone.com/UCVCPM

Lưu ý: Phiên bản hiện tại không hoạt động ở chế độ ideone vì không thích using l=System.Collections... , vì vậy phiên bản ideone hơi lỗi thời (và dài hơn)

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

Về cơ bản nó kiểm tra nếu có a 1. Nếu nó tìm thấy một, nó sử dụng các thuật toán Fill lũ để thay thế tất cả các liền kề 1's với 0và cho biết thêm các tọa độ thay thế vào một danh sách tạm thời. Sau đó, nó so sánh danh sách hàng đầu ( m) với danh sách tạm thời ( t) và đặt mthành tnếu tchứa nhiều phần tử hơn.


3

Toán học - 180 byte

Hàm này có một mảng 2 chiều.

Chơi gôn

f@x_:=(c=MorphologicalComponents[x,CornerNeighbors->False];m=Last@SortBy[ComponentMeasurements[c,"Count"],Last];Print["Size: ",Last@m," Coordinates: ",Reverse/@Position[c,m[[1]]]])

Đẹp

f@x_ := (
   c = MorphologicalComponents[x, CornerNeighbors -> False];
   m = Last@SortBy[ComponentMeasurements[c, "Count"], Last];
   Print["Size: ", Last@m, " Coordinates: ", Reverse/@Position[c, m[[1]]]]
   );

Thí dụ

{0,1,0,0,0,0,1,0,0,0,0,1,1,0,0,0,0,1,1,0,0,1,1,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1,1,0,0,0,1,0,0,0,0,1,1,0,0,0,1,0,0,0,0,0,0,1,1,0,1,0,0,0,0,0,0,1,1,0,1,0,0,0,0,0,0,0,0,0,0,0};
w=Partition[%,10];
f@w

Kích thước: 6 Tọa độ: {{1,2}, {2,2}, {2,3}, {3,2}, {3,3}, {4.2}}

Đầu ra hơi bất thường. Mathematica bắt đầu lập chỉ mục ở mức 1 thay vì 0 và sử dụng {}để chỉ vị trí. Thêm 2 byte ( -1) nếu các vị trí cần được lập chỉ mục 0. Thêm nhiều byte nếu họ cần sử dụng ()thay vì {}:(

Giải trình

flà một chức năng của x. Nó định nghĩa clà một phép biến đổi x, trong đó mỗi (i, j) bây giờ bằng một số nguyên tương ứng với thành phần được kết nối mà nó thuộc về. Nó liên quan đến công việc chính:

MorphologicalComponents[w, CornerNeighbors -> False] // Colorize

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

Sau đó mtính toán có bao nhiêu phần tử trong mỗi thành phần, sắp xếp chúng theo số đó và lấy kết quả cuối cùng (có nghĩa là, với hầu hết các phần tử). Dòng cuối cùng in số đếm và các vị trí trong cchỉ mục chứa trong m.


2

Haskell, 246

r=[0..9]
q=[(i,j)|i<-r,j<-r]
t v p@(i,j)|elem p v||notElem p q||g!!j!!i==0=v|1<2=foldr(\(k,l)v->t v(i+k,j+l))(p:v)$zip[-1,0,1,0][0,-1,0,1]
(?)=map
a=t[]?q;(b,c)=maximum$zip(length?a)a
main=putStrLn.unwords$["Size:",show b,"Coordinates:"]++show?c

Đầu vào

Hai chiều và dán trước mã như g, ví dụ:

g = [[0, 1, 1, ......, 0], [......], ....]

Ung dung

field = [
 [0,1,0,0,0,0,1,0,0,0],
 [0,1,1,0,0,0,0,1,1,0],
 [0,1,1,0,0,0,0,1,0,0],
 [0,1,0,0,0,0,0,0,0,0],
 [0,0,0,0,0,0,0,0,1,0],
 [0,0,0,1,1,0,0,0,1,0],
 [0,0,0,1,1,0,0,0,1,0],
 [0,0,0,0,0,1,1,0,1,0],
 [0,0,0,0,0,1,1,0,1,0],
 [0,0,0,0,0,0,0,0,0,0]
 ]
range = [0..9]
positions = [(i, j) | i <- range, j <- range]
directions = zip [-1, 0, 1, 0] [0, -1, 0, 1]
traverse visited pos@(i, j)
  | pos `elem` visited || pos `notElem` positions || field!!j!!i == 0 = visited
  | otherwise = foldr folder (pos:visited) directions
  where folder = (\(di, dj) visited -> traverse visited (i + di, j + dj))
blocks = map (traverse []) positions
(maxCount, maxBlock) = maximum $ zip (map length blocks) blocks
main = putStrLn.unwords $ ["Size:", show maxCount, "Coordinates:"] ++ map show maxBlock

2

Hàm C # 374byte

Đây là phiên bản sửa đổi nhiều trong câu trả lời của tôi cho Bạn có ở trong phòng lớn nhất không? . Nó nhận một mảng ints một chiều và trả về một chuỗi theo kiểu yêu cầu. Nó hoạt động bằng cách xây dựng các tập hợp tách rời khỏi đầu vào (vòng đầu tiên), kiểm tra kích thước của từng bộ và tìm tập lớn nhất (vòng thứ hai) và sau đó nối bất kỳ ô nào trong tập đó vào chuỗi đầu ra (vòng thứ ba) sau đó được trả về .

static string F(int[]g){int s=10,e=0,d=s*s,a=0,b=d+1;int[]t=new int[b],r=new int[b];t[d]=d;System.Func<int,int>T=null,k=v=>t[T(v)]=t[v]<d?a:d;T=v=>t[v]!=v?T(t[v]):v;for(;a<d;a++)if(g[a]>0){e=t[a]=a;if(a>s)k(a-s);if(a%s>0)k(a-1);}else t[a]=d;for(;a-->0;)e=r[e]<++r[b=T(a)]&&b<d?b:e;var p="Size: "+r[e]+" Coordinates:";for(;d-->1;)p+=T(d)==e?" ("+d%s+","+d/s+")":"";return p;}

Ít chơi gôn hơn (và có mã kiểm tra):

class P
{
    static int[] z = {0,1,0,0,0,0,1,0,0,0,0,1,1,0,0,0,0,1,1,0,0,1,1,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1,1,0,0,0,1,0,0,0,0,1,1,0,0,0,1,0,0,0,0,0,0,1,1,0,1,0,0,0,0,0,0,1,1,0,1,0,0,0,0,0,0,0,0,0,0,0};

    static string F(int[]g)
    {
        int s=10,e=0,d=s*s,a=0,b=d+1;

        int[]t=new int[b],r=new int[b];
        t[d]=d;
        System.Func<int,int>T=null,k=v=>t[T(v)]=t[v]<d?a:d;
        T=v=>t[v]!=v?T(t[v]):v;

        for(;a<d;a++)
            if(g[a]>0)
            {
                e=t[a]=a;
                if(a>s)k(a-s);
                if(a%s>0)k(a-1);
            }
            else
                t[a]=d;
        for(;a-->0;)
            e=r[e]<++r[b=T(a)]&&b<d?b:e;

        var p="Size: "+r[e]+" Coordinates:";
        for(;d-->1;)
            p+=T(d)==e?" ("+d%s+","+d/s+")":"";

        return p;
    }

    static void Main()
    {
        System.Console.WriteLine(F(z));
    }
}

Điều này khiến tôi cảm thấy tồi tệ về giải pháp 476 byte của mình :( +1 cho bạn, thưa ông.
Christoph Böhmwalder

1

JavaScript (EcmaScript 6) 183 189

Một hàm với đầu vào mảng và giá trị trả về chuỗi. Nếu đầu ra thực sự là cần thiết (không rõ ràng với tôi), hãy thêm 7 byte cho 'alert ()'.

W=(a,n=10,x=0)=>(F=p=>a[p]|0&&(a[p]=0,o+=' ('+p%n+','+(p/n|0)+')',1+F(p-n)+F(p+n)+F(p-(p%n>0))+F(p+((p+1)%n>0))),a.map((e,p)=>(t=F(p,o=''))>x&&(x=t,k=o)),'Size: '+x+' Coordinates:'+k)

Kiểm tra đầu ra

Size: 6 Coordinates: (1,0) (1,1) (1,2) (1,3) (2,2) (2,1)

Dễ đọc hơn

W=(a,n=10,x=0)=>
(
  F=p=>
    a[p]|0&&(  
      a[p]=0,o+=' ('+p%n+','+(p/n|0)+')',
      1+F(p-n)+F(p+n)+F(p-(p%n>0))+F(p+((p+1)%n>0)) // modulo takes care of not overflowing out of a row
    ),
  a.map((e,p)=>(t=F(p,o=''))>x&&(x=t,k=o)), 
  'Size: '+x+' Coordinates:'+k
)

Giải trình

Nhận một mảng kích thước duy nhất và một tham số tùy chọn với kích thước của một hàng. Hàm này cũng hoạt động với các kích thước mảng khác nhau, thậm chí x! = Y.

Mã giả:

 For each element, 
   try to fill. 
   During the fill operation build a string with the coordiinates. 
   Remember the longest fill and the corresponding string and 
 output that at the end.

1

JavaScript, 273

Hàm lấy mảng và trả về chuỗi. Nỗ lực đầu tiên của tôi là ~ 500 ký tự và không sử dụng Flood Fill. Cái này nào. Tôi đang học JavaScript nên mọi đề xuất đều được đánh giá cao.

Hàm này lặp qua mảng đầu vào và với mỗi 1 được tìm thấy, nó bắt đầu từ đó và thay đổi tất cả được kết nối thành 1s thành 0 bằng cách sử dụng hàm Fill. Trong khi làm như vậy, nó nhớ các blob với nhiều nhất 1s. Hàm Fill thay đổi vị trí hiện tại thành 0 và sau đó gọi chính nó ở vị trí trên, bên phải, bên dưới và bên trái.

function G(m){var B="",b=0;for(var p=0;p<m.length;p++)if(m[p]){var T="",t=0;
Z(p);if(t>b){b=t;B=T;}}return"Size: "+b+" Coordinates:"+B;function Z(p){if(m[p])
{m[p]=0;t++;T+=" ("+p%10+","+Math.floor(p/10)+")";if(p>9)Z(p-10);if(p%10)Z(p-
1);if(p<90)Z(p+10);if(p%10!=9)Z(p+1);}}}

Kiểm tra tại đây: http://goo.gl/9Hz5OH

Mã có thể đọc được

var map = [0, 1, 0, 0, 0, 0, 1, 0, 0, 0,
           ...
           0, 0, 0, 0, 0, 0, 0, 0, 0, 0];

function F(map) {

    var bestBlob = "", bestLen=0;
    for (var p = 0; p < map.length; p++)
        if (map[p]) {
            var thisBlob = "", thisLen=0;
            Fill(p);
            if (thisLen > bestLen){
                bestLen=thisLen ; bestBlob = thisBlob;
            }
        }
    return "Size: " + bestLen + " Coordinates:" + bestBlob;

    function Fill(p) {
        if (map[p]) {
            map[p] = 0; thisLen++;
            thisBlob += " (" + p % 10 + "," + Math.floor(p / 10) + ")";
            if (p > 9) Fill(p - 10);
            if (p % 10) Fill(p - 1);
            if (p < 90) Fill(p + 10);
            if (p % 10 != 9) Fill(p + 1);
        }
    }
}

1

Scala, 420

Xin chào, mục nhập của tôi lấy mảng 2d làm a List[List[Int]], trả vềString

val o=for{(r, y)<-w.zipWithIndex;(v,x)<-r.zipWithIndex;if(v == 1)}yield(x,y);val a=o.flatMap(c=>o.collect{case(x,y)if{(x==c._1+1||x==c._1-1)&&y==c._2^(y==c._2+1||y==c._2-1)&&x==c._1}=>c->(x,y)}).groupBy(_._1).map(n => (n._1->n._2.map(t=>t._2)));val b=a.values.flatMap(v=>v.map(c=>a(c)++v));val l=b.collect{case x if (x.length==b.map(_.length).max)=>x}.head;println(s\"Size: ${l.length} Coordinates: ${l.mkString(" ")}\")

Giải trình

Đưa ra một cửa sổ là một List[List[Int]], đầu tiên chúng ta tìm thấy mỗi "1" và lưu tọa độ trong một danh sách. Tiếp theo, chúng ta biến danh sách đó thành một Maptọa độ của mỗi "1" thành một danh sách tọa độ của mỗi "1" liền kề. Sau đó, sử dụng bản đồ kề để liên kết các đốm phụ thành các đốm màu và cuối cùng chúng ta trả lại các đốm lớn nhất (và bỏ qua các đốm trùng lặp vì thứ tự các tọa độ được trả về không quan trọng).

Dễ đọc hơn

 val w = {
  List(//0,1,2,3,4,5,6,7,8,9
    List(0,1,0,0,0,0,1,0,0,0), //0
    List(0,1,1,0,0,0,0,1,1,0), //1
    List(0,1,1,0,0,0,0,1,0,0), //2
    List(0,1,0,0,0,0,0,0,0,0), //3
    List(0,0,0,0,0,0,0,0,1,0), //4
    List(0,0,0,1,1,0,0,0,1,0), //5
    List(0,0,0,1,1,0,0,0,1,0), //6
    List(0,0,0,0,0,1,1,0,1,0), //7
    List(0,0,0,0,0,1,1,0,1,0), //8
    List(0,0,0,0,0,0,0,0,0,0)) //9
}

case class Coord(x: Int, y: Int)

val ones: List[Coord] = for{
  (row, y)   <- w.zipWithIndex
  (value, x) <- row.zipWithIndex
  if (value == 1)        
} yield Coord(x,y)

val adjacencyMap: Map[Coord, List[Coord]] = ones.flatMap(keyCoord => ones.collect{
case Coord(adjacentX, adjacentY) if {
    (adjacentX == keyCoord.x + 1 || adjacentX == keyCoord.x - 1) && adjacentY == keyCoord.y ^ 
    (adjacentY == keyCoord.y + 1 || adjacentY == keyCoord.y - 1) && adjacentX == keyCoord.x
  }  => keyCoord->Coord(adjacentX,adjacentY)
}).groupBy(_._1).map(n => (n._1->n._2.map(t=>t._2) ))

val blobs: Iterable[List[Coord]] = adjacencyMap.values.flatMap(v => v.map(coord => adjacencyMap(coord)++v))

val largestBlob: List[Coord] = blobs.collect{case x if (x.length == blobs.map(b=> b.length).max) => x}.head

println(s"""Size: ${largestBlob.length} Coordinates: ${largestBlob.collect{case Coord(x,y) => (x,y)}.mkString(" ")}""")

Phê bình được đánh giá rất cao.

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.