รหัส - กอล์ฟ: Count Islands


31

การประกวดอย่างง่ายซึ่งได้รับแรงบันดาลใจจากคำถาม stackoverflow นี้ :

คุณจะได้รับภาพพื้นผิวที่ถ่ายโดยดาวเทียมภาพเป็นบิตแมปที่น้ำถูกทำเครื่องหมายด้วย ' .' และที่ดินถูกทำเครื่องหมายด้วย ' *' กลุ่มที่อยู่ติดกัน*เป็นเกาะ (สอง ' *' อยู่ติดกันหากพวกเขาเป็นเพื่อนบ้านแนวนอนแนวตั้งหรือแนวทแยง) งานของคุณคือการพิมพ์จำนวนเกาะในบิตแมป

หนึ่ง*ยังนับเป็นเกาะ

ตัวอย่างอินพุต:

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

ตัวอย่างผลลัพธ์:

5

ผู้ชนะคือรายการที่มีจำนวนไบต์น้อยที่สุดในรหัส


ฉันไม่เข้าใจตรรกะ ไม่ใช่ 5 ดาวที่มุมขวาบนถือว่าเป็นเกาะเดียวใช่ไหม ตัวอย่างของคุณมี 4 เกาะ
defhlt

หน้าจอไม่ห่อ หนึ่งเกาะในแต่ละมุม + *เกาะโดดเดี่ยว
Claudiu

2
แต่ตามคำจำกัดความของคุณเกาะคือกลุ่มของอักขระ '*' ซึ่งมีความหมายมากกว่าหนึ่งตัว
acolyte

โอ้จุดยุติธรรม สแตนด์อะโลน*ยังเป็นเกาะ
Claudiu

คำตอบ:


30

Mathematica 188 185 170 115 130 46 48 ตัวอักษร

คำอธิบาย

ในรุ่นก่อนหน้านี้ฉันได้ทำกราฟตำแหน่งที่มีระยะกระดานหมากรุกเท่ากับ 1 จากแต่ละตำแหน่ง GraphComponentsจากนั้นเปิดเผยจำนวนเกาะหนึ่งแห่งต่อองค์ประกอบ

รุ่นปัจจุบันใช้MorphologicalComponentsในการค้นหาและจัดกลุ่มจำนวนของกลุ่มที่อยู่ในอาร์เรย์ - ภูมิภาคที่1มีต่อเนื่องทางกายภาพ เนื่องจากการสร้างกราฟไม่จำเป็นจึงส่งผลให้เกิดการใช้โค้ดอย่างประหยัด


รหัส

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

ตัวอย่าง

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

5


มันทำงานอย่างไร

ข้อมูลที่ป้อนเข้าเป็นอาร์เรย์ ใน Mathematica นี่คือรายการของรายการ

ในอาร์เรย์อินพุตข้อมูลจะถูกแปลงเป็น1's และ0' s โดยการแทนที่

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

โดยที่/.เป็นรูปแบบมัดReplaceAllตามด้วยกฎการแทนที่ นี่เป็นการแปลงอาเรย์เป็นภาพขาวดำ สิ่งที่เราต้องทำคือใช้ฟังก์ชั่น, Image.

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

islands

สี่เหลี่ยมสีขาวตรงกับเซลล์ที่มีค่า 1

ภาพด้านล่างแสดงขั้นตอนที่ใช้ เมทริกซ์การป้อนข้อมูลมีเพียง1'และ0' s เมทริกซ์เอาต์พุตจะเลเบลแต่ละคลัสเตอร์ที่มีตัวเลข (ฉันหุ้มทั้งเมทริกซ์อินพุตและเอาต์พุตMatrixFormเพื่อเน้นโครงสร้างสองมิติของมัน)

MorphologicalComponentsแทนที่1s ด้วยเลขจำนวนเต็มที่สอดคล้องกับหมายเลขคลัสเตอร์ของแต่ละเซลล์

processing

Max ส่งคืนหมายเลขคลัสเตอร์ที่ใหญ่ที่สุด


การแสดงหมู่เกาะ

Colorize จะระบายสีเกาะแต่ละเกาะโดยเฉพาะ

colorize


มันไม่ทำงานตามที่เขียนไว้ใน v7 เพราะMorphologicalComponentsต้องการImageแต่แม้ใน v9 นี้ไม่ควรMax@MorphologicalComponents[d/.{"."->0,"*"->1}]? นั่นคือการแทนที่ทำได้ก่อน? Maxจะหายไปก่อนที่การแทนที่จะเสร็จสิ้นหรือไม่
Mr.Wizard

ฉันมี V9, @ Mr.Wizard ถูกต้อง 46 ตัวอักษรเป็นตัวเลขที่ถูกต้อง
Murta

@ Mr.Wizard การเปลี่ยนจะดำเนินการก่อนที่จะใช้ MorphologicalComponents จะต้องเป็นสิ่งที่สำคัญกว่า
DavidC

สวัสดี @DavidCarraher จุดของฉันไม่เกี่ยวกับ "->" แต่การแสดงออกMax@MorphologicalComponents@d/.{"."->0,"*"->1}ไม่ทำงานสิ่งที่สมเหตุสมผลคือMax@MorphologicalComponents[d /. {"." -> 0, "*" -> 1}]อะไรดังนั้นคุณมีตัวละครอีกหนึ่งตัว
Murta

9

ทับทิม 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

คล้ายกับ Colorize เดวิดคุณยังสามารถได้รับมันในการแสดงหมู่เกาะที่แตกต่างกันโดยการเปลี่ยน$_[i]=?.ไป$_[i]=c.to_sและp cเพื่อputs$_ที่จะให้คุณบางอย่างเช่นนี้

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

(อย่างน้อยก็จนกว่าตัวเลขจะหมด!)

กรณีทดสอบบางส่วน:

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

5

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

9

*

1

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

2

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

3


8
ฉันชอบการทดสอบครั้งสุดท้าย กำลังคิดอยู่ข้างในกล่อง!
นาย Lister

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 ไบต์

ขอบคุณStep HenและArnold Palmerสำหรับการกำจัดช่องว่าง 20 ตัวและวงเล็บที่ไม่จำเป็น!

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 ไบต์โดยการลบช่องว่างบางส่วน Parser Python นั้นอ่อนโยนจริงๆ: P
Stephen

คุณมีพื้นที่ว่างมากกว่าที่จำเป็น ลบช่องว่างระหว่าง(s.index(l),i)และfor, enumerate(l)และif, -v[0])<2และand, p=0:และpและและbool(x&n[p]) elseคุณยังมีวงเล็บเกินความจำเป็นในงบการพิมพ์ของคุณเพราะคุณมี 2 setกลุ่มโดยรอบ แก้ไข: Beat by StepHen สาเหตุที่ทำสิ่งต่างๆบนมือถือไม่เหมาะ
Arnold Palmer

203 bytesรวม @ StepHen's และคำแนะนำของฉันรวมทั้งการเปลี่ยนแปลงเงื่อนไขเล็กน้อย
Arnold Palmer

ขอบคุณทั้งคู่สำหรับความช่วยเหลือ! ความกรุณาของ Python ทำให้ฉันประหลาดใจ
:)

0

Perl 5 , 100 ไบต์

รหัส 98 ไบต์ + 2 ไบต์สำหรับ-p0แฟล็ก

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

ลองออนไลน์!

การปรับตัว (หรือค่อนข้างง่ายขึ้น) ของคำตอบของฉันต่อความท้าทายมีกี่หลุม? . คุณสามารถหาคำอธิบายว่ารหัสนี้ทำงานอย่างไรกับคำตอบอื่น ๆ นี้ (มันค่อนข้างยาวที่จะอธิบายดังนั้นฉันไม่ต้องการพิมพ์คำอธิบายทั้งหมดซ้ำอีกครั้ง)


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}

คำตอบที่ไม่ใช่การคอมไพล์ ES6 (ความท้าทายทางภาษาลงวันที่) สำหรับ 132 ไบต์:

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

พอร์ตของคำตอบของฉันไปกี่หลุม (ใช่ฉันกระโดดขึ้นไปบน bandwagon ตอนนี้ฉันเห็นคนอื่นอีกสองคนตอบคำถามแล้ว)


โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.