내 창문에 물이있다


13

시나리오

나는 내 차와 함께 도로를 따라 운전하며 비가 내리기 시작합니다. 빗방울이 무작위로 내 창문에 떨어지고 있으며 지금 가장 큰 젖은 지역은 어디입니까?

작업

보다 쉽게하기 위해 창은 10 * 10 정사각형의 매트릭스로 분할됩니다. 당신의 임무는 창문에서 가장 큰 연결된 물방울 지역을 찾는 것입니다.

입력

두 가지 가능한 입력이 있습니다. 2 차원 배열 또는 1 차원 배열을 사용할 수 있습니다. 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의 ​​Ventero-Ruby


2
@Doorknob이 오타에 대해 불평합니까? OP는 독일어입니다.
edc65

1
@Doorknob 나는 그것을 변경했습니다, 감사합니다. 시간 제한은 내가 승자를 결정할 때만 답변을 게시 할 수 있다고 말합니다.
izlin

6
나는 이것이 codegolf.stackexchange.com/questions/32015/…복제품 이라고 말하고 싶습니다 .
Howard

1
@TunPronk : OP는 원본 포스터를 의미합니다. 구글에서 찾아보십시오 :)
justhalf

2
어떤 입력 방법이 허용되는지 정확히 설명하면 좋을 것입니다.
Ventero

답변:


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

명령 행 매개 변수를 통해 1 차원 배열로 입력하십시오.

샘플 입력에 대한 출력 : Size: 6 Coordinates: (1,0) (1,1) (1,2) (1,3) (2,2) (2,1)

이 답변은 간단한 플러드 필 접근법을 사용하여 각 빗방울 클러스터에 대한 좌표 목록을 작성합니다. 대부분의 코드는 실제로 범위 검사 및 I / O에 사용됩니다.


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]

제안 된 수정 사항에 대해 Calvin 's Hobbies에게 감사드립니다!


map(f,range(100))대신 [f(i)for i in range(100)]8자를 저장할 수 있습니다 . 또한 좌표가 (x, y)가 아닌 (y, x)라고 생각합니다.
Calvin 's Hobbies

3

C 번호 - 548 523 522 511 503 476

(500 이하 ... 네)

개선의 여지 가 많이 있다고 확신 합니다.

데이터를 입력 한 방식은 배열을 초기화하는 것이 었습니다. 나는 그 배열을 점수에 포함시키지 않았다.

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이 마음에 들지 않기 때문에 ideone에서 작동하지 않으므로 using l=System.Collections...ideone 버전이 약간 오래되었습니다 (그리고 더 길다)

작동 원리

기본적으로가 있는지 확인합니다 1. 이 하나를 발견하면, 모든 인접한 대체 할 홍수 채우기 알고리즘을 사용 1하여의를 0임시 목록에 교체 된 좌표를 추가합니다. 그런 다음 최상위 목록 ( m)을 임시 목록 ( t)과 비교하고 더 많은 요소 가 포함 된 경우로 설정 m합니다 .tt


3

Mathematica-180 바이트

이 함수는 2 차원 배열을 사용합니다.

골프

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는 0 대신 1부터 색인을 생성하고 {}위치를 나타내는 데 사용 합니다. -1위치를 0으로 색인화해야하는 경우 2 바이트 ( )를 추가하십시오 . 그들이 ()대신 사용해야 하는 경우 많은 바이트를 추가하십시오 {}:(

설명

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예를 들어 다음 과 같이 코드 앞에 2 차원을 붙여 넣습니다 .

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 바이트 기능

이것은 당신이 가장 큰 방에 있습니까? . int의 1 차원 배열을 취하고 필요한 스타일로 문자열을 리턴합니다. 입력 (첫 번째 루프)에서 분리 된 세트를 작성하고 각 세트의 크기를 계산하고 가장 큰 세트 (두 번째 루프)를 찾은 다음 해당 세트의 셀을 출력 문자열 (세 번째 루프)에 추가하여 반환됩니다 .

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, 좋은 선생님 바이트에 대해 나를 기분 나빴다.
크리스토프 Böhmwalder에게

1

자바 스크립트 (EcmaScript 6) 183 189

배열 입력 및 문자열 반환 값이있는 함수입니다. 실제 출력이 필요한 경우 (나에게 명확하지 않음) 'alert ()'에 7 바이트를 추가하십시오.

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

자바 스크립트, 273

함수는 배열을 받아서 문자열을 반환합니다. 첫 번째 시도는 ~ 500 자였으며 플러드 필을 사용하지 않았습니다. 이거에요 JavaScript를 배우고 있으므로 제안을 부탁드립니다.

이 함수는 입력 배열을 반복하며 1 개 발견 될 때마다 시작되고 Fill 함수를 사용하여 1로 연결된 모든 항목을 0으로 변경합니다. 그렇게하는 동안 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

안녕하세요, 제 항목은 같은 2 차원 배열을 List[List[Int]]하는을 반환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(" ")}\")

설명

창을로 지정하면 List[List[Int]]먼저 각 "1"을 찾아 좌표를 목록에 저장합니다. 다음으로 우리는 그리스트를 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(" ")}""")

비판은 대단히 높이 평가됩니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.