เราจมหรือว่ายน้ำ?


40

ปัญหา

สถานการณ์วันโลกาวินาศอธิบายโดยสามตัวเลขในบรรทัดเดียวn, และm pการติดตามบรรทัดนั้นคือnบรรทัดที่มีmค่าต่อบรรทัด แต่ละค่าหมายถึงหน่วยน้ำทั้งหมดที่แต่ละเซลล์สามารถเก็บได้

pบรรทัดต่อไปนี้อธิบายสภาพอากาศสำหรับpวันถัดไป 1 หน่วยของฝนตกในเซลล์เดียวในแต่ละวัน หากปริมาณน้ำในเซลล์เกินจำนวนที่สามารถเก็บได้เซลล์นั้นจะท่วม หากเซลล์ที่อยู่ติดกันหลายแห่งทำงานได้เต็มประสิทธิภาพเซลล์เหล่านั้นจะถือว่าเป็นเซลล์เดียวที่แบ่งปันเพื่อนบ้านทั่วไป (คิดว่า Minesweeper เมื่อคุณคลิกที่กลุ่มว่าง)

  • เซลล์ตรงกลางเดียวมี 4 เพื่อนบ้าน
  • เซลล์กลางกำลังการผลิตสองตัวที่อยู่ติดกันทั้งหมดจะถือว่าเป็นหนึ่งเซลล์ที่มี 6 เพื่อนบ้าน
  • เซลล์มุมเดียวมีเพื่อนบ้าน 2 คน
  • ผนังเซลล์เดียวมี 3 เพื่อนบ้าน

เมื่อเซลล์ถูกน้ำท่วมเหตุการณ์น้ำท่วมจะเกิดขึ้น น้ำส่วนเกินทั้งหมดจะกระจายไปยังเพื่อนบ้านอย่างเท่าเทียมกัน หากนั่นเป็นสาเหตุทำให้เพื่อนบ้านหนึ่งคนหรือมากกว่าถูกน้ำท่วมเหตุการณ์น้ำท่วมอื่นก็เกิดขึ้น เรื่องนี้จะดำเนินต่อไปจนกว่าน้ำจะตกลงหรือเมืองน้ำท่วมอย่างสมบูรณ์

ตัวอย่างการป้อนข้อมูล

7 5 3
3 2 3 4 5
2 2 0 3 4
1 1 2 3 3
4 1 2 2
4 1 1 2 2
4 4 1 2 2
4 4 2 2 2
0 0
1 2
4 3

  • 0 0 หมายความว่าฝนตกในแถว 1, col 1
  • 1 2 หมายความว่าฝนตกในแถว 2, คอลัมน์ 3 (ซึ่งสามารถเก็บน้ำเป็นศูนย์และน้ำท่วมทันที!)

หลังจากpวันที่ฝนตกถ้าเมืองถูกน้ำท่วมอย่างสมบูรณ์ผลผลิตอ่างล้างจาน มิฉะนั้นการส่งออกว่ายน้ำ

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

การว่ายน้ำ

สมมติฐาน

  • ข้อมูลอาจถูกป้อนผ่าน stdin อ่านจาก "city.txt" หรือยอมรับว่าเป็นอาร์กิวเมนต์ ทั้งสามได้รับอนุญาตเพื่อไม่ให้เป็นโมฆะคำตอบใด ๆ ที่โพสต์แล้ว
  • ความจุน้ำจะเป็นจำนวนเต็มไม่เป็นลบ

นักศึกษาระดับปริญญาตรีมากกว่า 40 ทีม (จาก A&M, UT, LSU, Rice, Baylor และอื่น ๆ ) การแข่งขันในการประกวดเขียนโปรแกรมด้วยภาษาที่หลากหลายไม่สามารถแก้ปัญหานี้ได้ใน 5 ชั่วโมง ด้วยเหตุนี้ฉันจึงอดไม่ได้ที่จะพูดถึงว่ามีอะไรที่จับปริศนานี้ได้ทำให้แก้ปัญหาได้เล็กน้อย รหัสที่สั้นที่สุดยังคงชนะเพราะฉันมั่นใจว่ารหัสที่สั้นที่สุดจะแก้ปริศนาด้วย


มันเป็นnสายของmค่าหรือวิธีอื่น ๆ ? ตัวอย่างของคุณไม่ตรงกับข้อกำหนดที่เป็นลายลักษณ์อักษร
algorithmshark

@algorithmshark แก้ไขแล้ว
Rainbolt

13
ฉันไม่แน่ใจ แต่ดูเหมือนว่าคุณจะจมถ้าปริมาณฝนมากกว่าปริมาณฝนที่สี่เหลี่ยมจัตุรัสสามารถเก็บได้ มิฉะนั้นคุณจะลอย มันคืออะไร
Hosch250

2
@ hosch250 ทำลายความสนุก!
ฝนตก

1
"น้ำส่วนเกินกระจายไปยังเพื่อนบ้านอย่างสม่ำเสมอ" - มีแนวโน้มว่าจะเป็น 1 หน่วยของน้ำ มันจะกระจายเป็น0.25หน่วยเช่นไปยังเซลล์แต่ละเซลล์ที่อยู่ติดกัน
Neil Slater

คำตอบ:


16

Golfscript, 37 30ตัวอักษร

ใหม่และปรับปรุงต้องขอบคุณPeterTaylorสำหรับเคล็ดลับ:

~](\(@*\(@@<{+}*>"SwimSink"4/=

คำอธิบาย :

Code                     -                                            - Stack
~]                       - parse input into an array of integers      - []
(                        - pop first number and put on stack          - [] 7
\(                       - \ swaps top two, then pop first num again  - 7 [] 5
@                        - bring 3rd down from stack to front         - [] 5 7
*                        - mult. this is grid size                    - [] 35
\(@                      - bring next # out - the days of rain        - [] 3 35
@                        - bring array out                            - 3 35 []
<                        - take first 35 elements out of array.
                           this extracts just the capacities and 
                           consumes the rest                          - 3 []
{+}*                     - fold the array using plus - this sums the
                           entire thing                               - 3 86
<                        - greater-than comparison: 3 > 86?           - 0
"SwimSink"4/             - push a string and split it to groups of 4  - 0 ["Swim" "Sink"]

=                        - index into the array using the result of
                           the comparison. if rain > capacity, then
                           sink, else swim                            - "Swim"

จากนั้นโปรแกรมจะยุติการส่งออกสแต็ก


คำอธิบายรุ่นเก่า +:

[~](\(@*\(@{\(@\-}*\;0>"Sink""Swim"if

วิธีการเช่นเดียวกับForsเพียงแค่ Golfscripted =) น่าจะทำให้มีประสิทธิภาพมากขึ้น อินพุตจาก stdin

คำอธิบาย :

Code                     -                                            - Stack
[~]                      - parse input into an array of integers      - []
(                        - pop first number and put on stack          - [] 7
\(                       - \ swaps top two, then pop first num again  - 7 [] 5
@                        - bring 3rd down from stack to front         - [] 5 7
*                        - mult. this is grid size                    - [] 35
\(@                      - bring next # out - the days of rain        - [] 3 35
{                        - define a block which...
 \(@                     - brings next number out
 \-                      - swaps and subtracts 2nd down from top
}                                                                     - [] 3 35 {}
*                        - repeat that block 35 times. this ends up
                           pulling the capacities out one by one
                           and decrementing our number-of-days 
                           number by each one                         - [] -84 
\;                       - swap and kill the array to get rid of
                           unused input                               - -84
0>"Sink""Swim"if         - if the num > 0, evaluate to "Sink", 
                           otherwise to "Swim"                        - "Swim"

โปรแกรมจะสแต็กเอาต์พุตซึ่งเป็นคำตอบ


]จะไม่มีการจับคู่[จะรวบรวมทั้งสแต็กเป็นอาร์เรย์ดังนั้นการเริ่มต้น[~]สามารถทำให้ง่าย~]ขึ้น ในการรับgrid_sizeองค์ประกอบแรกของอาร์เรย์ให้ใช้<ดังนั้น<{+}*สามารถช่วยคุณประหยัดได้เล็กน้อยในการเพิ่มความจุทั้งหมด 0>"Sink""Swim"ifสามารถ0>"SinkSwim"4/=
Peter Taylor

@PeterTaylor: ขอบคุณสำหรับเคล็ดลับ! คุณแน่ใจเกี่ยวกับ~]? ฉันลองแล้วไม่ได้ผล แฮ็คสุดท้ายนั้นดีแม้ว่ามันจะต้องเป็น"SwimSink"- จะใช้มัน และสิ่งต่าง ๆ ที่ดูเหมือนจะมีแนวโน้มจะได้ทำงานต่อไป
Claudiu

ฉันมั่นใจ: นั่นเป็นเคล็ดลับมาตรฐานที่ฉันและคนอื่นใช้มานานหลายปี
Peter Taylor

@PeterTaylor: อืมแปลก ลองใช้ในล่ามที่ฉันลิงก์ไว้ - มันล้มเหลว ถ้าอย่างนั้นโอเคบางทีล่ามเว็บอาจไม่ได้มาตรฐาน แต่ฉันก็ลองด้วยruby golfscript.rbและมันยังไม่ทำงาน ... คุณสามารถตรวจสอบว่ามันใช้งานได้หรือไม่? ฉันได้รับข้อผิดพลาดเดียวกันทั้ง:undefined method '+' for nil:NilClass (NoMethodError)
Claudiu

1
เมื่อคุณแทรกสตริงตัวอักษรเพื่อทดแทนการขาด stdin คุณควรนำหน้าด้วยเครื่องหมายอัฒภาคเพื่อลบสตริงว่างที่มาจาก "stdin" โดยที่มันใช้งานได้ดี
Peter Taylor

20

C: 100 96 95 ตัวอักษร

n,m;main(p){scanf("%d%d%d",&n,&m,&p);for(n*=m;n--;scanf("%d",&m))p-=m;puts(p>0?"Sink":"Swim");}

ห้าชั่วโมง พาฉันไปห้านาที :)

Aragaer ขอขอบคุณสำหรับความเรียบง่าย! ฉันได้ แต่จัดเรียงการประกาศตัวแปรและข้อโต้แย้งหลักเห็นเป็นเสียงดังกราวโยนข้อผิดพลาดถ้าอาร์กิวเมนต์ที่สองหลักเป็นประเภทอื่น ๆ char **ที่ไม่ใช่


3
96 -p;main(n,m){for(scanf("%d%d%d",&n,&m,&p),n*=m;n--;scanf("%d",&m),p-=m);puts(p>0?"Sink":"Swim");}
aragaer

1
95 n,m;main(p){for(scanf("%d%d%d",&n,&m,&p),n*=m;n--;scanf("%d",&m))p-=m;puts(p>0?"Sink":"Swim");}- ฉันเคยเล่นด้วยความคิดn-=scanfแต่ไม่แน่ใจว่าโปรแกรมจะถูกต้องหลังจากนั้น ก่อนอื่นscanfสามารถย้ายไปที่ด้านหน้าforโดยไม่เปลี่ยนจำนวนตัวอักษร
aragaer

n-=scanf...จะไม่ทำงานเนื่องจากn-=1เป็นส่วนเพิ่มล่วงหน้าดังนั้นจะพลาดมุมตะวันออกเฉียงใต้ การเปลี่ยนแปลงอื่น ๆ นั้นยอดเยี่ยมมาก
Fors

7

Python 4 บรรทัด 175 ตัวอักษร

import sys 
F=sys.stdin
n,m,p=[int(a) for a in F.readline().split()]
print("sink") if p > sum([sum(int(x) for x in F.readline().split()) for a in range(n)]) else print("swim")

ฮ่า ๆ ๆ ฉันสงสัยว่าทั้ง 40 ทีมลงเอยด้วยการจับได้หรือไม่ ... หลังจากทำงานอย่างหนัก


10
ฉันเป็นหนึ่งใน 40+ ทีม เราได้รับการจับหลังจากล้มเหลว ทุกคนในหอประชุมต้องเผชิญพร้อมกัน ฉันคิดว่าบางทีฉันไม่ควรพูดถึงที่นี่ พวกคุณเร็วเกินไป!
Rainbolt

อุ๊ย! โดยวิธีการที่ฉันควรได้รับข้อมูลจาก stdin สำหรับคำถามประเภทนี้ - ฉันใหม่เพื่อการแลกเปลี่ยน :)
swalladge

ฉันกำลังจะแก้ไขคำถามของฉันเพื่อระบุระบุ STDIN แต่ฉันกลัวว่าจะทำให้คำตอบของคุณไม่ถูกต้อง ฉันได้อ่านปริศนาที่นี่มาประมาณเดือนและไม่ได้สังเกตว่าคนระบุ STDIN หรือไม่
Rainbolt

1
@swadadge ยินดีต้อนรับสู่ Codegolf! ผมขอแนะนำให้ทำพาดหัวพาดหัวโดย prepending #
TimWolla

2
คุณสามารถนำมันลงไปที่ 108 หากคุณใช้input()และmap():n,_,p=map(int,input().split());print(['sink','swim'][p>sum(sum(map(int,input().split()))for a in range(n))])
Blender

6

คุณลักษณะสองชั้น J (50 ถ่าน) และ K (40)

ปรากฎตามปกติทั้งสองมีโครงสร้างที่เหมือนกันแน่นอนในการแก้ปัญหาของพวกเขาดังนั้นพวกเขาทั้งสองที่นี่ K นั้นสั้นกว่าเยอะมากซึ่งน่าประหลาดใจมาก

>Sink`Swim{~(]<[:+/[+/@".@$+1!:1@#1:)/0 2{".1!:1]1

คำอธิบาย:

  • ".1!:1]1 - อ่านในบรรทัดแรกและแปลงเป็นจำนวนเต็ม
  • (...)/0 2{- นำรายการที่ดัชนี 0 และ 2 ( nและpตามลำดับ) และใช้เป็นอาร์กิวเมนต์ซ้ายและขวาไปที่คำกริยา(...)ตามลำดับ
  • +1!:1@#1:- อ่านในn+pบรรทัด
  • [+/@".@$- รับ ( $) nแถวแรก( [) ทิ้งส่วนที่เหลือแล้วแปลงเป็นจำนวนเต็ม ( ".) และหาผลรวมในแต่ละแถว ( +/)
  • ]<[:+/- pเพิ่มจำนวนเงินรวมกันแถวแล้วเปรียบเทียบค่านี้เพื่อโต้แย้งขวา เราผลิตจริงถ้าpน้อยกว่าผลรวม
  • >Sink`Swim{~- เลือกSwimว่าการเปรียบเทียบข้างต้นส่งผลให้เป็นจริงหรือSinkหากเป็นเท็จ

การใช้งาน:

   >Sink`Swim{~(]<[:+/[+/@".@$+1!:1@#1:)/0 2{".1!:1]1
7 5 3
3 2 3 4 5
2 0 3 3 4
1 1 2 3 3
4 1 2 2 2
4 1 1 2 2
4 4 1 2 2
4 4 2 2 2
0 0
1 2
4 3
Swim

และตอนนี้ K:

`Sink`Swim@{z<+//.:'x#0::'(x+z)#`}.. 0:`

อธิบาย:

  • . 0:` - อ่านในบรรทัดอินพุตและแปลงเป็นอาร์เรย์ของจำนวนเต็ม
  • {...}.- ใช้ตัวเลขทั้งสามนี้n m pเป็นอาร์กิวเมนต์ของx y zฟังก์ชันนี้
  • 0::'(x+z)#`- สร้างx+zสำเนาของหมายเลขอ้างอิงไฟล์อินพุต`แล้วอ่านเป็นบรรทัดสำหรับแต่ละไฟล์ ( 0::')
  • .:'x#- นำxไอเท็มแรกแล้วแปลงเป็นเวกเตอร์ของตัวเลข
  • z<+//- รวมเมทริกซ์ทั้งหมดเข้าด้วยกันแล้วทดสอบเพื่อดูว่ามันมีค่ามากกว่าzหรือไม่
  • `Sink`Swim@- ส่งคืนSinkหรือSwimตามว่าการทดสอบส่งคืนจริงหรือไม่

การใช้งาน:

  `Sink`Swim@{z<+//.:'x#0::'(x+z)#`}.. 0:`
7 5 3
3 2 3 4 5
2 2 0 3 4
1 1 2 3 3
4 1 2 2 2
4 1 1 2 2
4 4 1 2 2
4 4 2 2 2
0 0
1 2
4 3
`Swim

6

APL, 35

4↑'SwimSink'⌽⍨4×x[3]>+/{+/⎕}¨⍳1⌷x←⎕

ไม่แน่ใจว่าได้รับอนุญาตหรือไม่ แต่จะหยุดรับอินพุตหลังจาก "เมือง"

x←⎕นำเข้าและเก็บไว้ในตัวแปรx(ตัวเลขที่คั่นด้วยช่องว่างจะถูกตีความเป็นอาร์เรย์ตัวเลข)
1⌷แยกดัชนี 1 (อาร์เรย์ APL เป็นพื้นฐานเดียว)
สร้างอาร์เรย์จาก 1 ถึงอาร์กิวเมนต์ ( 1⌷x←⎕ในกรณีนี้)
¨การดำเนินการ "แผนที่"
{+/⎕}ใช้อาร์เรย์จาก ใส่และส่งคืนผลรวมผล
+/รวมของอาร์เรย์ที่สร้างโดยการดำเนินการแผนที่
4×x[3]>ทดสอบว่าผลรวม < x[3](ส่งคืน 1 หรือ 0) จากนั้นคูณ 4
'SwimSink'⌽⍨หมุนสตริง'SwimSink'ตามจำนวนนั้น
4↑ในที่สุดแยก 4 อักขระแรกของสตริง


ฉันคิดว่าส่วนเดียวที่สำคัญคือมันส่งคำตอบที่ถูกต้องสำหรับอินพุตที่กำหนด หากนี่เป็นเรื่องผิดปกติสำหรับ CodeGolf หวังว่าจะมีใครบางคนแจ้งให้เราทราบ
Rainbolt

เปลี่ยน⎕IO←0จากนั้นแทนที่4↑'SwimSink'⌽⍨4×ด้วย'Swim' 'Sink'⊃⍨, x[3]ด้วยx[2], และ1⌷xด้วย⊃xเพื่อบันทึกสองไบต์
อดัม

6

AWK, 70

n{for(;NF;NF--)s+=$NF;n--}NR==1{n=$1;p=$3}END{print p<s?"Swim":"Sink"}

นี่คือ imrovement โดย laindir ในการส่งของฉัน (86):

NR==1{h=$1;w=$2;r=$3;next}NR<=h{for(i=1;i<=w;++i)c+=$i}END{print(c>r?"Swim":"Sink")}

NR<=hควรเป็นNR<=h+1เช่นนั้นมิฉะนั้นคุณจะได้รับ Sink เท็จเนื่องจากขีดความสามารถบรรทัดสุดท้ายถูกข้ามไป สิ่งนี้สามารถย่อให้เหลือ 70 asn{for(;NF;NF--)s+=$NF;n--}NR==1{n=$1;p=$3}END{print p<s?"Swim":"Sink"}
laindir

1
@laindir ดีขอบคุณมากสำหรับการปรับปรุง! ฉันพบว่ามันสนุกมากที่ Awk เพิ่งมาถัดจาก APL, J และ K ซึ่งได้รับการปรับปรุงพันธุ์เพื่อเอาชนะทุกคนในการตีกอล์ฟ! :-)
user40989

@ user40989 ฉันไม่เข้าใจ Awk ดูเหมือนจะยาวกว่า J / K / APL ถึง 40-100% ถึงแม้ว่าพวกเขาจะไม่ได้เล่นกอล์ฟภาษา แต่เป็นภาษาโปรแกรมเชิงพาณิชย์
อดัม

5

CoffeeScript - 128 113

ฟังก์ชันที่รับสตริงเป็นอาร์กิวเมนต์เท่านั้น:

s=(l)->l=l.split /\n/;[n,m,p]=l[x=0].split /\s/;x+=c|0 for c in r.split /\s/ for r in l[1..n];`p>x?"Sink":"Swim"`

คุณสามารถลบการเยื้องและย้ายทุกอย่างในบรรทัดแรกคั่นด้วยเครื่องหมายอัฒภาค นอกจากนี้คุณยังเขียนแทน`p>x?"Sink":"Swim"` if p>x then"Sink"else"Swim"Parens สำหรับคำสั่งที่สามนั้นไม่จำเป็นเช่นกัน
Konrad Borowski

4

SED, 128

มันสนุกมากที่ได้เขียนsedเวอร์ชั่นนี้ มันมีมาสั้น ๆ ดังต่อไปนี้:

  • มันถือว่าเมืองมีมากกว่าสองคอลัมน์เพื่อให้จดจำสายฝนได้อย่างง่ายดาย

  • สมมติว่าความสามารถของแต่ละเมืองอยู่ในช่วง 0-9

นี่มันคือ:

1d
s/^. .$/R/
G
:a
s/[\n 0]//
/[2-9]/{s/^/C/
y/23456789/12345678/}
s/1/C/
s/0//
s/RC//
h
ta
${s/R//g
s/^Sink//
s/.*C$/Swim/
p}

โทรด้วย-nธง


3

SWI-Prolog 79

หากคุณไม่รังเกียจความจริงที่ว่าคำตอบนี้ใช้การป้อนข้อมูลด้วยการสืบค้นมากกว่าผ่านทาง stdin:

s(A,L):-append(A,B),sumlist(B,C),length(L,D),(D>C->E='Sink';E='Swim'),print(E).

คำตอบไม่ได้ตรวจสอบรูปแบบการป้อนข้อมูล แต่ฉันไม่คิดว่ามันเป็นปัญหาเนื่องจากการแข่งขันการเขียนโปรแกรมยังไม่ต้องการให้คุณทำเช่นนั้น

ตัวอย่างแบบสอบถาม (ใช้ตัวอย่างในคำถาม):

s([[3,2,3,4,5],
   [2,2,0,3,4],
   [1,1,2,3,3],
   [4,1,2,2,2],
   [4,1,1,2,2],
   [4,4,1,2,2],
   [4,4,2,2,2]],
  [(0,0),
   (1,2),
   (4,3)]).

1

Python - 152

import numpy
n, m, p = map(int,raw_input('').split())
print 'swim' if p<numpy.sum(numpy.matrix(';'.join([raw_input('') for i in range(n)]))) else 'sink'

1
คุณสามารถเริ่มต้นด้วยการลบช่องว่างออก หลังจาก,, ก่อนและหลัง', หลังจาก)
Ry-

1

สกาลา - 128

val a=readLine.split(' ')map(_.toInt);println(if((1 to a(0)map(x=>readLine.split(' ')map(_.toInt)sum)sum)>a(2))"swim"else"sink")

อาจเป็นไปได้ที่จะไม่ใส่วงเล็บบางอย่างหรือบางอย่าง แต่ Scala ไม่แน่นอนเกี่ยวกับเครื่องหมายวรรคตอนและรูปแบบที่ไม่มีจุดและ () vs {} และ whatnot


0

Javascript - 73 ตัวอักษร

for(i=c=0,a=s.split(/\s/);i++<a[0]*a[1];)c+=a[2+i]*1;c>a[2]?"Swim":"Sink"

ถือว่าเข้าเป็นในตัวแปรsและผลหรือSwimSink

ตัวอย่าง:

จากคำถามเดิม - ป้อนสิ่งนี้ลงในคอนโซลเบราว์เซอร์:

s="7 5 3\n3 2 3 4 5\n2 2 0 3 4\n1 1 2 3 3\n4 1 2 2 2\n4 1 1 2 2\n4 4 1 2 2\n4 4 2 2 2\n0 0\n1 2\n4 3";
for(i=c=0,a=s.split(/\s/);i++<a[0]*a[1];)c+=a[2+i]*1;c>a[2]?"Swim":"Sink"

ขาออก:

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