Ada air di jendela saya

13

Skenarionya

Saya berkendara di sepanjang jalan dengan mobil saya dan hujan mulai turun. Tetesan hujan jatuh di jendela saya secara acak dan sekarang saya bertanya pada diri sendiri, di mana area basah terbesar yang terhubung?

Tugas

Untuk membuatnya lebih mudah, jendela itu terbagi dalam matriks 10 * 10 kotak. Tugas Anda adalah menemukan area tetesan air terhubung terbesar di jendela.

Memasukkan

Ada dua input yang mungkin, Anda dapat menggunakan Array 2 dimensi atau yang 1 dimensi. Anda dapat memilih antara input apa saja seperti stdin, dll ...
Contoh:

// 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]

Keluaran

Kode Anda harus memadamkan ukuran area terhubung terbesar dan koordinat x- dan y dari tetesan air yang termasuk dalam area ini dalam format
"Ukuran: Z Koordinat: (X1, Y1) (X2, Y2) .. "
Contoh untuk input sebelumnya:

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

Urutan Koordinat tidak masalah.

Aturan

  • Tetesan air terhubung, jika mereka saling menyentuh secara orthogonal
  • Koneksi diagonal tidak masuk hitungan
  • Mungkin ada banyak area dan kode Anda harus menemukan yang terbesar
  • Bidang kosong direpresentasikan sebagai "0" dan bidang basah sebagai "1"
  • Posting solusi Anda dengan penjelasan singkat dan output dari input sebelumnya
  • Kode terpendek dalam 7 hari ke depan akan menang
  • Jika ada dua area dengan ukuran yang sama, Anda dapat memilih satu

Pemenang: Ventero dengan 171 - Ruby

izlin
sumber
2
@ Doorknob mengeluh tentang kesalahan ketik? OP adalah orang Jerman.
edc65
1
@ Doorknob saya mengubahnya, terima kasih. Batas waktu hanya mengatakan, ketika saya akan menentukan pemenang tetapi Anda masih dapat memposting jawaban.
izlin
6
Saya akan mengatakan ini adalah duplikat dari codegolf.stackexchange.com/questions/32015/… .
Howard
1
@TeunPronk: OP berarti Poster Asli. Cari di Google :)
justhalf
2
Beberapa klarifikasi tentang metode input apa yang diizinkan, tepatnya, akan bagus.
Ventero

Jawaban:

3

Ruby, 171 karakter

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

Input melalui parameter baris perintah sebagai array satu dimensi.

Output untuk input sampel: Size: 6 Coordinates: (1,0) (1,1) (1,2) (1,3) (2,2) (2,1)

Jawaban ini menggunakan pendekatan pengisian banjir sederhana, membangun daftar koordinat untuk setiap kelompok curah hujan. Sebagian besar kode sebenarnya digunakan untuk memeriksa batas dan I / O.

Ventero
sumber
5

Python - 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

Input (Tempel sebelum kode):

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]

Terima kasih Calvin Hobbies untuk suntingan yang disarankan!

Vektor
sumber
Anda dapat menggunakan map(f,range(100))alih-alih [f(i)for i in range(100)]menyimpan 8 karakter. Saya juga percaya bahwa koordinat Anda (y, x) tidak (x, y).
Hobi Calvin
3

C # - 548 523 522 511 503 476

(di bawah 500 ... ya)

Saya yakin ada banyak ruang untuk perbaikan.

Cara saya memasukkan data adalah menginisialisasi array. Saya tidak memasukkan array itu ke dalam skor (jika Anda pikir ini curang, saya dapat mengubah kode, tetapi akan menambahkan kode yang relatif banyak karena C # tidak hebat dalam mem-parsing array)

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

Cobalah di http://ideone.com/UCVCPM

Catatan: Versi saat ini tidak berfungsi di ideone karena tidak suka using l=System.Collections... , jadi versi ideone sedikit usang (dan lebih lama)

Bagaimana itu bekerja

Ini pada dasarnya memeriksa apakah ada 1. Jika menemukan satu, ia menggunakan algoritma Flood Fill untuk mengganti semua yang berdekatan 1dengan 0dan menambahkan koordinat yang diganti ke daftar sementara. Setelah itu membandingkan daftar teratas ( m) ke daftar sementara ( t) dan diatur mke tjika tberisi lebih banyak elemen.

Christoph Böhmwalder
sumber
3

Mathematica - 180 byte

Fungsi ini membutuhkan array 2 dimensi.

Golf

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

Cantik

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

Contoh

{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

Ukuran: 6 Koordinat: {{1,2}, {2,2}, {2,3}, {3,2}, {3,3}, {4,2}}

Outputnya sedikit anomali. Mathematica mulai mengindeks pada 1 bukannya 0, dan digunakan {}untuk menunjukkan posisi. Tambahkan 2 byte ( -1) jika posisi harus diindeks 0. Tambahkan banyak byte jika harus digunakan ()alih-alih {}:(

Penjelasan

fadalah fungsi dari x. Ini didefinisikan csebagai transformasi x, di mana masing-masing (i, j) sekarang sama dengan bilangan bulat yang sesuai dengan komponen terhubung yang dimilikinya. Ini melibatkan pekerjaan utama:

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

masukkan deskripsi gambar di sini

Kemudian mhitung berapa banyak elemen dalam setiap komponen, urutkan berdasarkan angka itu, dan ambil hasil terakhir (artinya, dengan elemen terbanyak). Baris terakhir mencetak hitungan, dan posisi dalam cindeks terkandung dalam m.

mfvonh
sumber
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

Memasukkan

Dua dimensi dan rekatkan sebelum kode sebagai g, misalnya:

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

Tidak disatukan

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
sinar
sumber
2

Fungsi C # 374byte

Ini adalah versi modifikasi dari jawaban saya untuk Apakah Anda berada di ruangan terbesar? . Dibutuhkan array int satu dimensi, dan mengembalikan string sesuai gaya yang diperlukan. Ia bekerja dengan membangun set terpisah dari input (loop pertama), menghitung ukuran setiap set dan menemukan set terbesar (loop kedua) dan kemudian menambahkan sel dalam set ke string output (loop ketiga) yang kemudian dikembalikan .

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

Lebih sedikit golf (dan dengan kode tes):

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));
    }
}
VisualMelon
sumber
Ini membuat saya merasa tidak enak tentang solusi 476 bytes saya :( +1 untuk Anda, tuan.
Christoph Böhmwalder
1

JavaScript (EcmaScript 6) 183 189

Fungsi dengan input array dan nilai pengembalian string. Jika output nyata diperlukan (tidak jelas bagi saya) tambahkan 7 byte untuk '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)

Output Uji

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

Lebih mudah dibaca

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
)

Penjelasan

Dapatkan array dimensi tunggal dan parameter opsional dengan ukuran baris. Fungsi ini juga berfungsi dengan dimensi array yang berbeda, bahkan x! = Y.

Kode palsu:

 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.
edc65
sumber
1

JavaScript, 273

Function mengambil array dan mengembalikan string. Upaya pertama saya adalah ~ 500 karakter dan tidak menggunakan Flood Fill. Yang ini. Saya sedang mempelajari JavaScript sehingga saran apa pun akan dihargai.

Fungsi ini loop melalui array input dan untuk masing-masing 1 ditemukan mulai di sana dan mengubah semua terhubung ke 1s ke 0 menggunakan fungsi Fill. Saat melakukan hal itu ia mengingat gumpalan dengan paling 1s. Fungsi Fill mengubah posisi saat ini menjadi 0 dan kemudian memanggil dirinya sendiri pada posisi di atas, ke kanan, di bawah, dan ke kiri.

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

Tes di sini: http://goo.gl/9Hz5OH

Kode yang Dapat Dibaca

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);
        }
    }
}
JeffSB
sumber
1

Scala, 420

Hai, entri saya mengambil array 2d sebagai List[List[Int]], mengembalikan aString

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(" ")}\")

Penjelasan

Diberikan jendela sebagai List[List[Int]], pertama kita menemukan masing-masing "1" dan menyimpan koordinat dalam daftar. Selanjutnya kita ubah daftar itu menjadi aMap koordinat dari masing-masing "1" ke daftar koordinat setiap "1" yang berdekatan. Kemudian gunakan peta adjacency untuk secara transitif menghubungkan sub-gumpalan ke dalam gumpalan, dan akhirnya kami mengembalikan gumpalan terbesar (dan mengabaikan gumpalan duplikat karena urutan koordinat yang dikembalikan tidak masalah).

Lebih Mudah Dibaca

 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(" ")}""")

Kritik sangat dihargai.

Julian Peeters
sumber