Chúng ta chìm hay bơi?


40

Vấn đề

Một kịch bản ngày tận thế được mô tả bởi ba con số trên một dòng duy nhất, n, m, và p. Theo sau dòng đó là ncác dòng có mgiá trị trên mỗi dòng. Mỗi giá trị đại diện cho tổng đơn vị nước mà mỗi tế bào có thể giữ.

Các pdòng sau mô tả thời tiết cho những pngày tiếp theo . 1 đơn vị mưa rơi vào một tế bào mỗi ngày. Nếu lượng nước trong một tế bào vượt quá lượng nước có thể chứa, thì tế bào đó sẽ tràn vào. Nếu nhiều ô liền kề hoạt động hết công suất, chúng được coi là một ô chia sẻ hàng xóm chung (nghĩ Minesweeper khi bạn nhấp vào một nhóm khoảng trống).

  • Một ô giữa có 4 hàng xóm
  • Hai ô trung bình đầy đủ, liền kề được coi là một ô có 6 ô lân cận
  • Một ô góc duy nhất có 2 hàng xóm
  • Một ô tường đơn có 3 hàng xóm

Khi một tế bào lũ lụt, một sự kiện lũ lụt xảy ra. Tất cả nước thừa được phân phối đều cho các nước láng giềng. Nếu điều đó làm cho một hoặc nhiều hàng xóm bị lũ lụt, thì một sự kiện lũ lụt khác sẽ xảy ra. Điều này tiếp tục cho đến khi nước đã ổn định, hoặc thành phố đã bị ngập hoàn toàn.

Ví dụ đầu vào

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

  • 0 0 có nghĩa là trời mưa ở hàng 1, col 1
  • 1 2 có nghĩa là trời mưa ở hàng 2, col 3 (có thể giữ nước bằng 0 và lũ lụt ngay lập tức!)

Sau những pngày mưa, nếu thành phố bị ngập hoàn toàn, đầu ra chìm . Nếu không, đầu ra Bơi .

Ví dụ đầu ra

Bơi

Giả định

  • Đầu vào có thể được cung cấp thông qua stdin, đọc từ "city.txt" hoặc được chấp nhận làm đối số. Cả ba đều được cho phép để không làm mất hiệu lực bất kỳ câu trả lời đã được đăng.
  • Dung lượng nước sẽ là số nguyên không âm.

Hơn 40 đội sinh viên đại học (từ A & M, UT, LSU, Rice, Baylor, v.v.) cạnh tranh trong một cuộc thi lập trình với nhiều ngôn ngữ có sẵn không thể giải quyết vấn đề này trong 5 giờ. Do đó, tôi không thể không đề cập đến việc có một câu đố về câu đố này khiến cho lời giải trở nên tầm thường. Mã ngắn nhất vẫn thắng, vì tôi tin chắc rằng mã ngắn nhất cũng sẽ giải được câu đố.


Đây có phải là ndòng mgiá trị hay ngược lại? Ví dụ của bạn không phù hợp với đặc điểm kỹ thuật bằng văn bản.
thuật toán

@alerskymshark Đã sửa
Rainbolt

13
Tôi không chắc, nhưng dường như với tôi rằng bạn chìm nếu lượng mưa lớn hơn tổng lượng mưa mà tất cả các ô vuông có thể giữ được; Nếu không thì bạn nổi. Có phải đây không?
Hosch250

2
@ hosch250 Làm hỏng cuộc vui!
Rainbolt

1
"Lượng nước dư thừa được phân phối đều cho các nước láng giềng." - đó có khả năng là 1 đơn vị nước. Nó có phân phối như 0.25các đơn vị ví dụ cho mỗi ô liền kề (giả sử một ô bị ngập giữa) không?
Neil Slater

Câu trả lời:


16

Golf, 37 30 ký tự

Mới và được cải thiện, nhờ PeterTaylor cho lời khuyên:

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

Giải thích :

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"

Chương trình sau đó chấm dứt, xuất ra ngăn xếp.


Phiên bản cũ + giải thích:

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

Cách tiếp cận tương tự như Fors , chỉ cần Golfscripted =). Có thể có thể được thực hiện hiệu quả hơn. Đầu vào là từ stdin.

Giải thích :

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"

Chương trình sau đó xuất ra ngăn xếp, đó chỉ là câu trả lời.


]không có kết quả khớp [sẽ thu thập toàn bộ ngăn xếp thành một mảng, vì vậy ban đầu [~]có thể được đơn giản hóa ~]. Để có được các grid_sizephần tử đầu tiên của một mảng, hãy sử dụng <, do đó <{+}*gần như chắc chắn có thể giúp bạn tiết kiệm một chút khi thêm tổng dung lượng. 0>"Sink""Swim"ifcó thể0>"SinkSwim"4/=
Peter Taylor

@PeterTaylor: Cảm ơn những lời khuyên! Bạn có chắc chắn về ~]? Tôi đã thử nó và nó dường như không hoạt động. Bản hack cuối cùng là tốt mặc dù nó phải "SwimSink"- sẽ sử dụng nó. và điều mảng cũng có vẻ hứa hẹn, sẽ làm việc trên đó.
Claudiu

Tôi chắc chắn: đó là một mẹo tiêu chuẩn mà tôi và những người khác đã sử dụng trong nhiều năm.
Peter Taylor

@PeterTaylor: Hmm lạ. Hãy thử nó trong trình thông dịch mà tôi liên kết đến - nó thất bại. Sau đó - ok có thể trình thông dịch web là không chuẩn. Nhưng tôi cũng đã thử ruby golfscript.rbvà nó vẫn không hoạt động ... bạn có thể xác minh rằng nó hoạt động được không? Tôi nhận được cùng một lỗi trên cả hai:undefined method '+' for nil:NilClass (NoMethodError)
Claudiu

1
Khi bạn chèn một chuỗi ký tự để thay thế cho việc thiếu stdin, bạn nên đặt trước nó bằng một dấu chấm phẩy để loại bỏ chuỗi trống thực sự xuất phát từ "stdin". Với nó hoạt động tốt
Peter Taylor

20

C: 100 96 95 ký tự

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

Năm giờ? Mất tôi năm phút. :)

Aragaer, cảm ơn bạn đã đơn giản hóa! Tuy nhiên, tôi đã sắp xếp lại các khai báo và đối số biến thành chính, xem như Clang đưa ra lỗi nếu đối số thứ hai thành chính là bất kỳ loại nào khác ngoài 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");}. Tôi cũng đã chơi với ý tưởng về n-=scanf, nhưng không chắc chương trình sẽ chính xác sau đó. Đầu tiên scanfcó thể được chuyển đến phía trước formà không thay đổi số lượng nhân vật.
aragaer

n-=scanf...sẽ không hoạt động, vì n-=1về cơ bản là một sự gia tăng trước, vì vậy nó sẽ bỏ lỡ góc đông nam. Sự thay đổi khác là tuyệt vời.
Dành cho

7

Python, 4 dòng, 175 ký tự

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

Lol, tôi tự hỏi nếu 40+ đội kết thúc việc tìm ra ... sau khi làm việc đó một cách khó khăn.


10
Tôi đã ở trong một trong số hơn 40 đội. Chúng tôi đã GIVEN bắt sau khi thất bại. Mọi người trong khán phòng cùng một lúc. Tôi nghĩ có lẽ tôi không nên đề cập đến nó ở đây. Các bạn đã quá nhanh!
Rainbolt

Ôi! Nhân tiện, tôi có nên lấy đầu vào từ stdin cho những loại câu hỏi này không? - Tôi mới đến stackexchange. :)
swalladge

Tôi sẽ chỉnh sửa câu hỏi của mình để chỉ định STDIN, nhưng tôi sợ rằng nó sẽ làm mất hiệu lực câu trả lời của bạn. Tôi đã đọc các câu đố ở đây khoảng một tháng và không thực sự chú ý nếu mọi người chỉ định STDIN hay không.
Rainbolt

1
@swalladge Chào mừng bạn đến với Codegolf! Tôi khuyên bạn nên đặt tiêu đề thành tiêu đề bằng cách đăng ký trước #.
TimWolla

2
Bạn có thể hạ nó xuống 108 nếu bạn sử dụng 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

Tính năng nhân đôi J (50 char) và K (40)

Hóa ra, như thường lệ, hai người này có cùng cấu trúc trong các giải pháp của họ, vì vậy cả hai đều ở đây. K là ngắn hơn rất nhiều, mặc dù, đó là một bất ngờ thú vị.

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

Giải trình:

  • ".1!:1]1 - Đọc trong dòng đầu tiên, và chuyển đổi sang số nguyên.
  • (...)/0 2{- Lấy các mục ở chỉ số 0 và 2 ( nptương ứng) và sử dụng chúng làm đối số bên trái và bên phải cho động từ (...), tương ứng.
  • +1!:1@#1:- Đọc theo n+pdòng.
  • [+/@".@$- Lấy ( $) các nhàng đầu tiên ( [), loại bỏ phần còn lại, sau đó chuyển đổi thành số nguyên ( ".) và tính tổng trên mỗi hàng ( +/).
  • ]<[:+/- Cộng các tổng hàng lại với nhau, rồi so sánh giá trị này với đối số đúng , p. Chúng tôi sản xuất đúng nếu pít hơn tổng.
  • >Sink`Swim{~- Chọn Swimnếu kết quả trên cho kết quả đúng hoặc Sinksai.

Sử dụng:

   >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

Và bây giờ là K:

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

Giải thích:

  • . 0:` - Đọc trong một dòng đầu vào, và chuyển đổi thành một mảng các số nguyên.
  • {...}.- Sử dụng ba số này n m plàm đối số x y zcho hàm này.
  • 0::'(x+z)#`- Tạo x+zbản sao của xử lý tệp đầu vào `, sau đó đọc trong một dòng cho mỗi trong số chúng ( 0::').
  • .:'x#- Lấy các xmục đầu tiên , và chuyển đổi từng mục thành một vectơ số.
  • z<+//- Tính tổng toàn bộ ma trận với nhau, rồi kiểm tra xem nó có lớn hơn không z.
  • `Sink`Swim@- Trả lại Sinkhoặc Swimtheo thử nghiệm trả về đúng sự thật.

Sử dụng:

  `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←⎕

Không chắc chắn nếu được phép nhưng nó dừng chấp nhận đầu vào sau "thành phố"

x←⎕Đưa đầu vào và lưu trữ nó trong biến x(các số được phân tách bằng dấu cách được hiểu là một mảng số)
1⌷Trích xuất chỉ mục 1 (mảng APL là một dựa trên)
Tạo một mảng từ 1 đến đối số ( 1⌷x←⎕trong trường hợp này)
¨Hoạt động "Bản đồ"
{+/⎕}Lấy mảng từ nhập và trả về tổng
+/Sum mảng được tạo bởi hoạt động bản đồ
4×x[3]>Kiểm tra nếu tổng < x[3](trả về 1 hoặc 0), sau đó nhân 4
'SwimSink'⌽⍨Xoay chuỗi 'SwimSink'với số tiền đó
4↑Cuối cùng, trích xuất 4 ký tự đầu tiên của chuỗi


Tôi nghĩ phần duy nhất quan trọng là nó đưa ra câu trả lời đúng cho bất kỳ đầu vào nào. Nếu điều này là bất thường đối với CodeGolf, hy vọng ai đó sẽ cho tôi biết.
Rainbolt

Thay đổi ⎕IO←0, sau đó thay thế 4↑'SwimSink'⌽⍨4×với 'Swim' 'Sink'⊃⍨, x[3]với x[2], và 1⌷xvới ⊃xlưu hai byte.
Adám

6

AWK, 70

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

Đây là một sự phê chuẩn của laindir trong bài nộp của tôi (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<=hnên NR<=h+1, nếu không, bạn sẽ nhận được các bồn rửa giả vì dòng năng lực cuối cùng bị bỏ qua. Điều này cũng có thể được rút ngắn xuống còn 70 nhưn{for(;NF;NF--)s+=$NF;n--}NR==1{n=$1;p=$3}END{print p<s?"Swim":"Sink"}
laindir

1
@laindir Vâng, cảm ơn bạn rất nhiều vì sự cải thiện! Tôi thấy điều đó thật thú vị, rằng Awk chỉ đến bên cạnh APL, J và K, được tạo ra để đánh bại mọi người chơi golf! :-)
dùng40989

@ user40989 Tôi không hiểu. Awk dường như dài hơn 40 - 100% so với J / K / APL, mặc dù chúng không phải là ngôn ngữ chơi gôn, mà là (xuất phát từ) ngôn ngữ lập trình thương mại.
Adám

5

Cà phê - 128 113

Hàm lấy chuỗi làm đối số duy nhất:

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"`

Bạn có thể xóa vết lõm và di chuyển mọi thứ trên dòng đầu tiên được phân tách bằng dấu chấm phẩy. Bạn cũng viết `p>x?"Sink":"Swim"`thay if p>x then"Sink"else"Swim". Parens cho tuyên bố thứ ba cũng không cần thiết.
Konrad Borowski

4

SED, 128

Thật vui khi viết một sedphiên bản này. Nó có các truyện ngắn sau:

  • Nó giả định thành phố có nhiều hơn hai cột, để dễ dàng nhận ra những dòng mưa.

  • Nó giả định rằng sức chứa của mỗi thành phố nằm trong khoảng 0-9.

Đây là:

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}

Gọi với -ncờ.


3

SWI-Prolog 79

Nếu bạn không bận tâm thực tế là câu trả lời này lấy đầu vào bằng truy vấn, thay vì thông qua stdin:

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

Câu trả lời không xác thực định dạng đầu vào, nhưng tôi không nghĩ đó là vấn đề, vì cuộc thi lập trình cũng không yêu cầu bạn phải làm như vậy.

Truy vấn mẫu (sử dụng ví dụ trong câu hỏi):

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

Con trăn - 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
Bạn có thể bắt đầu bằng cách lấy ra một số khoảng trắng. Sau khi ,, trước và sau ', sau khi )...
Ry-

1

Scala - 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")

Có thể có thể bỏ qua một số dấu ngoặc đơn hoặc một cái gì đó nhưng Scala thực sự hay thay đổi về dấu câu và kiểu không có điểm và () so với {} và không có gì.


0

Javascript - 73 ký tự

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

Giả sử đầu vào là trong biến svà đầu ra Swimhoặc Sink.

Thí dụ:

Từ câu hỏi ban đầu - nhập câu hỏi này vào bảng điều khiển trình duyệt:

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"

Đầu ra:

Swim
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.