На моєму вікні є вода


13

Сценарій

Я їду по дорозі зі своїм автомобілем, і починає дощ. Краплі дощу падають на моє вікно випадковим чином, і тепер я запитую себе, де найбільша з’єднана волога зона?

Завдання

Для того, щоб було простіше, вікно ділиться на матрицю розміром 10 * 10 квадратів. Ваше завдання - знайти найбільшу підключену зону краплі води на вікні.

Вхідні дані

Можливі два входи, ви можете використовувати двовимірний масив або одновимірний. Ви можете вибрати між будь-якими входами, такими як stdin тощо.
Приклад:

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

Вихідні дані

У вашому коді має бути розміщено розмір найбільшої пов'язаної ділянки та x- і y-координати крапель, які належать до цієї області у форматі
"Розмір: Z Координати: (X1, Y1) (X2, Y2). . "
Приклад попереднього введення:

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

Порядок координат не має значення.

Правила

  • Водяники пов'язані між собою, якщо вони торкаються один одного ортогонально
  • Діагональні з'єднання не враховуються
  • Областей може бути багато, і ваш код повинен знайти найбільшу
  • Порожнє поле представлене як "0", а мокре поле - як "1"
  • Опублікуйте своє рішення з коротким поясненням та результатом попереднього введення
  • Найкоротший код протягом наступних 7 днів виграє
  • Якщо є дві області однакового розміру, ви можете вибрати одну

Переможець: Вентеро з 171 - Рубі


2
@Doorknob скаржиться на помилку друку? OP - німецька.
edc65

1
@Doorknob Я змінив це, дякую. Час обмежує лише те, коли я визначу переможця, але ви все ще можете розмістити відповіді.
izlin

6
Я б сказав, що це дублікат codegolf.stackexchange.com/questions/32015/… .
Говард

1
@TeunPronk: OP означає оригінальний плакат. Подивіться це в Google :)
justhalf

2
Деякі роз'яснення, які саме способи введення дозволені, було б чудово.
Вентеро

Відповіді:


3

Рубі, 171 персонаж

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

Введіть через параметр командного рядка як одновимірний масив.

Вихідні дані для вибірки: Size: 6 Coordinates: (1,0) (1,1) (1,2) (1,3) (2,2) (2,1)

У цій відповіді використовується простий підхід для заливки, будуючи список координат для кожного кластеру краплі дощу. Більшість кодів фактично використовується для перевірки меж і вводу / виводу.


5

Пітон - 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

Введення (Вставити перед кодом):

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]

Дякую хобі Кальвіна за запропоновані зміни!


Ви можете використовувати map(f,range(100))замість, [f(i)for i in range(100)]щоб зберегти 8 символів. Також я вважаю, що ваші координати (y, x) не (x, y).
Захоплення Кальвіна

3

C # - 548 523 522 511 503 476

(до 500 ... так)

Я впевнений, що є багато можливостей для вдосконалення.

Те, як я ввів дані, було ініціалізувати масив. Я не включив цей масив в рахунок (якщо ви думаєте, що це обман, я можу змінити код, але він додасть відносно багато коду, оскільки C # не чудово підходить для розбору масивів)

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

Перевірте це на http://ideone.com/UCVCPM

Примітка: Поточна версія не працює в ideone, тому що вона не подобається using l=System.Collections..., тому версія ideone трохи застаріла (і довше)

Як це працює

В основному він перевіряє, чи є 1. Якщо він знаходить, він використовує алгоритм заливки , щоб замінити всі суміжні 1«з з 0і додає змінення координати до тимчасового списку. Потім він порівнює верхній список ( m) для тимчасового списку ( t) і наборів mдля tякщо tмістить більше елементів.


3

Mathematica - 180 байт

Ця функція займає двовимірний масив.

Гольф

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

Досить

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

Приклад

{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

Розмір: 6 Координати: {{1,2}, {2,2}, {2,3}, {3,2}, {3,3}, {4,2}}

Вихід трохи аномальний. Mathematica починає індексувати 1, а не 0, і використовує {}для позначення позиції. Додайте 2 байти ( -1), якщо позиції потрібно 0-індексувати. Додайте багато байтів, якщо їх потрібно використовувати ()замість {}:(

Пояснення

fє функцією x. Він визначається cяк перетворення x, де кожне (i, j) тепер дорівнює цілому числу, відповідно до того, до якого зв'язаного компонента належить. Він передбачає основну роботу:

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

введіть тут опис зображення

Потім mобчислює кількість елементів у кожному компоненті, сортує їх за цим числом і бере останній результат (мається на увазі, з найбільшою кількістю елементів). Останній рядок друкує підрахунок та позиції в cіндексі, що містяться в m.


2

Хаскелл, 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

Вхідні дані

Два параметри та вставити перед кодом g, наприклад:

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

Безумовно

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

C # 374байтова функція

Це сильно модифікована версія моєї відповіді на те, чи ти в найбільшій кімнаті? . Він займає одновимірний масив ints і повертає рядок у потрібному стилі. Він працює, будуючи роз'єднані набори з вхідного (першого циклу), підраховуючи розмір кожного набору і знаходячи найбільший набір (другий цикл), а потім додаючи будь-які комірки в цьому наборі до вихідного рядка (третьої петлі), який потім повертається .

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

Менш гольф (і з тестовим кодом):

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

Мені це погано в моєму рішенні 476 байт :( +1 для вас, добрий сер.
Крістоф Бьомвальдер

1

JavaScript (EcmaScript 6) 183 189

Функція з введенням масиву та зворотним значенням рядка. Якщо потрібен реальний вихід (мені не зрозуміло), додайте 7 байтів для "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)

Тестовий вихід

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

Більш читабельний

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
)

Пояснення

Отримайте одномірний масив та необов'язковий параметр з розміром рядка. Функція також працює з різними розмірами масиву, навіть x! = Y.

Псевдокод:

 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

Функція займає масив і повертає рядок. Моєю першою спробою було ~ 500 символів, і я не використовував Fill Fill. Цей робить. Я вивчаю JavaScript, тому будь-які пропозиції будуть вдячні.

Ця функція проходить через вхідний масив, і для кожного знайденого 1 він починається там і змінює всі підключені до 1s на 0 за допомогою функції Fill. При цьому він запам'ятовує крапку з найбільшою 1-ю. Функція Fill змінює поточну позицію на 0, а потім викликає позицію вгорі, праворуч, знизу та зліва.

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

Тест тут: http://goo.gl/9Hz5OH

Читаний код

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

Скала, 420

Привіт, мій запис приймає 2d масив як a List[List[Int]], повертає 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(" ")}\")

Пояснення

Давши вікно як List[List[Int]], спочатку ми знаходимо кожне "1" і зберігаємо координати у списку. Далі перетворюємо цей список на a Mapкоординати кожного "1", щоб перелічити координати кожного суміжного "1". Потім використовуйте карту примикання, щоб транзитивно пов’язати підблоки в краплі, і нарешті ми повернемо найбільшу крапку (і ігнорування повторюваних крапок, оскільки порядок повернених координат не має значення).

Більш читабельний

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

Критика дуже цінується.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.