コードゴルフ:カウント諸島


31

このstackoverflowの質問に触発されたシンプルなコンテスト:

衛星で撮影された表面の画像.が表示され*ます。画像はビットマップで、水は「」でマークされ、土地は「」でマークされています。隣接する ' *のグループは島を形成します。(2つの ' *'は、隣同士が水平、垂直、または斜めの場合に隣接しています)。あなたの仕事は、ビットマップの島の数を印刷することです。

シングル*もアイランドとしてカウントされます。

サンプル入力:

.........**
**......***
...........
...*.......
*........*.
*.........*

サンプル出力:

5

勝者は、コード内の最小バイト数のエントリです。


論理がわかりません。右上隅の5つの星は1つの島と見なされませんか?次に、例には4つの島があります。
-defhlt

画面は折り返されません。各コーナーに1つの島+ *孤島
-Claudiu

2
しかし、あなたの定義では、島は「*」文字のグループであり、複数を意味します。
アコライト

ああ公正な点。スタンドアロン*もまた島です。
クラウディ

回答:


30

Mathematica 188185170115130 46 48 48文字

説明

以前のバージョンでは、互いにチェス盤距離が1の位置のグラフを作成しました。 GraphComponentsその後、コンポーネントごとに1つの島の数を明らかにしました。

現在のバージョンではMorphologicalComponents、配列内の1のクラスター(1物理的に連続している領域)の検索と番号付けに使用します。グラフ化は不要であるため、これによりコードが大幅に節約されます。


コード

Max@MorphologicalComponents[#/.{"."->0,"*"->1}]&

Max@MorphologicalComponents[#/.{"."->0,"*"->1}]&[{{".", ".", ".", ".", ".", ".", ".", ".", ".", "*", "*"}, {"*", "*", ".", ".", ".", ".", ".", ".", "*", "*", "*"}, {".", ".", ".", ".", ".", ".", ".", ".", ".", ".", "."}, {".", ".", ".", "*", ".", ".", ".", ".", ".", ".", "."}, {"*", ".", ".", ".", ".", ".", ".", ".", ".", "*", "."}, {"*", ".", ".", ".", ".", ".", ".", ".", ".", ".", "*"}}]

5


使い方

データは配列として入力されます。Mathematicaでは、これはリストのリストです。

入力アレイにおいて、データが変換される1のと0置換することによっての

/.{"."->0,"*"->1}

where /.は、ReplaceAll置換規則が続く中置形式です。これは基本的に、配列を白黒画像に変換します。必要なのは、関数を適用することだけですImage

Image[{{".", ".", ".", ".", ".", ".", ".", ".", ".", "*", "*"}, {"*", "*", ".", ".", ".", ".", ".", ".", "*", "*", "*"}, {".", ".", ".", ".", ".", ".", ".", ".", ".", ".", "."}, {".", ".", ".", "*", ".", ".", ".", ".", ".", ".", "."}, {"*", ".", ".", ".", ".", ".", ".", ".", ".", "*", "."}, {"*", ".", ".", ".", ".", ".", ".", ".", ".", ".", "*"}} /. {"." -> 0, "*" -> 1}]

島々

白い四角は、値が1のセルに対応します。

以下の図は、このアプローチが使用するいくつかのステップを示しています。入力行列は含ま1さんと0さん。出力マトリックスは、各形態クラスターに番号を付けます。(MatrixForm2次元構造を強調するために、入力行列と出力行列の両方をラップしました。)

MorphologicalComponents1sを各セルのクラスター番号に対応する整数に置き換えます。

処理

Max 最大のクラスター番号を返します。


島の表示

Colorize 各島を一意に色付けします。

色付けする


V7に書かれたようので、これは動作していないMorphologicalComponents望んでいるImageが、それでもV9上で、これはすべきではありませんかMax@MorphologicalComponents[d/.{"."->0,"*"->1}]?つまり、最初に交換が行われますか? Max交換が行われる前に消えますか?
ミスターウィザード

V9があります。@ Mr.Wizardが正しいです。46文字が正しい数字です。
ムルタ

@ Mr.Wizard置換は、MorphologicalComponentsの適用前に実行されます。優先事項でなければなりません。
DavidC

こんにちは@DavidCarraher、私のポイントは "->"についてではありませんが、式が機能Max@MorphologicalComponents@d/.{"."->0,"*"->1}しないこと、意味がMax@MorphologicalComponents[d /. {"." -> 0, "*" -> 1}]あります。
ムルタ

9

Ruby 1.9(134 121 113 110)

stdinのマップまたはマップのファイル名を最初のコマンドライン引数として使用し、島の数をstdoutに出力します。基本的な再帰的な塗りつぶしを使用します。いつものように改善を歓迎します!

c=0
gets$!
c+=1while(f=->i{9.times{|o|$_[i]=?.;f[o]if$_[o=i+(o/3-1)*(~/$/+1)+o%3-1]==?*&&o>0}if i})[~/\*/]
p c

Davidの色付けと同様に、あなたはまた、変更して別の島を表示するために取得することができます$_[i]=?.$_[i]=c.to_sしてp cまでputs$_あなたにこのような何かを与えることになります、:

.........00
11......000
...........
...2.......
3........4.
3.........4

(少なくとも数字がなくなるまで!)

いくつかのテストケース:

.........**
**......***
...........
...*.......
*........*.
*.........*

5

......*..**....*
**...*..***....*
....*..........*
...*.*.........*
*........***....
*.....*...***...
*.....*...*....*
****..........**
*.........*.....

9

*

1

****
****
....
****

2

**********
*........*
*.******.*
*.*....*.*
*.*.**.*.*
*.*.**.*.*
*.*....*.*
*.******.*
*........*
**********

3


8
最後のテストが好きです。箱の中を考える!
ミスターリスター

1

C、169文字

stdinからマップを読み取ります。r(j)可能性があるように見えますが、再帰的なフラッドフィル機能を改善する運はありませんでした。

c,g,x,w;char m[9999];r(j){if(m[j]==42)m[j]=c,r(j+1),r(j+w-1),r(j+w),r(j+w+1),c+=j==g;}main(){while((m[x++]=g=getchar())+1)w=g<11*!w?x:w;for(;g++<x;)r(g);printf("%i",c);}

1

Python 2、 223 203バイト

20文字のスペースと不要な括弧を削り取ってくれたStep HenArnold Palmerに感謝します!

s=input()
c=[(s.index(l),i)for l in s for i,v in enumerate(l)if'*'==v]
n=[set([d for d in c if-2<d[0]-v[0]<2and-2<d[1]-v[1]<2])for v in c]
f=lambda x,p=0:p if x&n[p]else f(x,p+1)
print len(set(map(f,n)))

リスト内包表記を使用するとバイト数が減ると思いますが、大幅な改善はありませんでした。

ここで試してみてください。

私はn(隣人)リストの周りでそれをトリムしようとし続けていますが、成功していません。他の誰かがそのセクションのアイデアを持っているかもしれません。


PPCGへようこそ!ここだ217バイト、いくつかのスペースを除去することが。Pythonパーサーは本当に寛大です:P
スティーブン

必要以上の空白があります。間のスペースを削除(s.index(l),i)してforenumerate(l)if-v[0])<2andp=0:p、と、bool(x&n[p])else。また、を囲む2つのグループがあるため、printステートメントで必要以上の括弧がありますset。編集:StepHenによるビートは、モバイルで何かをするのは理想的ではありません。
アーノルドパーマー

@StepHenと私の提案を組み合わせた203バイトに加えて、条件を少し変更します。
アーノルドパーマー

助けてくれてありがとう!Pythonの寛大さは私を驚かせ続けます:)
溶媒和

0

Perl 5、100バイト

98バイトのコード+ -p0フラグ用の2バイト。

/.*/;$@="@+"-1;$~="(.?.?.{$@})?";(s/X$~\*/X$1X/s||s/\*$~X/X$1X/s)&&redo;s/\*/X/&&++$\&&redo}{$\|=0

オンラインでお試しください!

課題「How Many Holes?」に対する私の回答の適応(または単純化)。このコードがこの他の回答でどのように機能するかについての説明を見つけることができます(説明するのに少し時間がかかるので、説明全体を再入力しないことをお勧めします)。


0

Python 2、233バイト

他の回答と比較して長すぎます。この質問に対する私の回答のポート。
オンラインで試す

A=input()
c=0
X=len(A[0])-1
Y=len(A)-1
def C(T):
 x,y=T
 if A[y][x]<'.':A[y][x]='.';map(C,zip([x]*3+[min(x+1,X)]*3+[max(x-1,0)]*3,[y,min(y+1,Y),max(y-1,0)]*3))
while'*'in sum(A,[]):i=sum(A,[]).index('*');c+=1;C((i%-~X,i/-~X))
print c

0

JavaScript、158バイト

function f(s){w=s.search('\n');t=s.replace(RegExp('([*@])([^]{'+w+','+(w+2)+'})?(?!\\1)[*@]'),'@$2@');return t!=s?f(t):/\*/.test(s)?f(s.replace('*','@'))+1:0}

132バイトの非競合ES6回答(言語のポストデートチャレンジ):

f=s=>s!=(s=s.replace(RegExp(`([*@])([^]{${w=s.search`
`},${w+2}})?(?!\\1)[*@]`),`@$2@`))?f(s):/\*/.test(s)?f(s.replace(`*`,`@`))+1:0

いくつの穴への私の答えのポート(はい、私は時流に飛び乗っています、今私は他の2人が彼らの答えを移植するのを見ました)。


弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.