Apakah Kita Tenggelam atau Berenang?

40

Masalah

Skenario kiamat digambarkan oleh tiga angka pada satu baris, n, m, dan p. Mengikuti garis itu adalah ngaris dengan mnilai per baris. Setiap nilai mewakili total unit air yang dapat ditahan oleh setiap sel.

Baris berikut pmenjelaskan cuaca untuk phari-hari berikutnya . 1 unit hujan jatuh di satu sel setiap hari. Jika jumlah air dalam sel melebihi jumlah yang bisa dipegangnya, sel itu akan banjir. Jika beberapa sel yang berdekatan berada pada kapasitas penuh, mereka diperlakukan sebagai satu sel yang berbagi tetangga yang sama (pikirkan Minesweeper ketika Anda mengklik pada sekelompok kosong).

  • Sel tengah tunggal memiliki 4 tetangga
  • Dua sel tengah yang berdekatan dan berkapasitas penuh diperlakukan sebagai satu sel yang memiliki 6 tetangga
  • Sel sudut tunggal memiliki 2 tetangga
  • Satu sel dinding memiliki 3 tetangga

Ketika sel banjir, peristiwa banjir terjadi. Semua kelebihan air didistribusikan secara merata ke tetangganya. Jika itu menyebabkan satu atau lebih tetangga banjir, maka peristiwa banjir lainnya terjadi. Ini berlanjut sampai air telah mengendap, atau kota telah sepenuhnya banjir.

Contoh Input

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 berarti hujan di baris 1, kolom 1
  • 1 2 berarti hujan di baris 2, kolom 3 (yang dapat menampung nol air dan segera banjir!)

Setelah pberhari-hari hujan, jika kota benar-benar banjir, keluaran Sink . Jika tidak, hasilkan Swim .

Contoh Output

Berenang

Asumsi

  • Masukan dapat diberikan melalui stdin, baca dari "city.txt", atau diterima sebagai argumen. Ketiganya diizinkan agar tidak membatalkan jawaban yang sudah diposting.
  • Kapasitas air adalah bilangan bulat non-negatif.

40+ tim mahasiswa sarjana (dari A&M, UT, LSU, Rice, Baylor, dll.) Yang bersaing dalam kontes pemrograman dengan berbagai bahasa yang tersedia tidak dapat menyelesaikan masalah ini dalam 5 jam. Karena itu, saya tidak dapat membantu tetapi menyebutkan bahwa ada masalah dengan teka-teki ini yang membuat solusinya sepele. Kode terpendek masih menang, karena saya sangat yakin bahwa kode terpendek juga akan memecahkan teka-teki.

Rainbolt
sumber
Apakah itu ngaris mnilai atau sebaliknya? Contoh Anda tidak sesuai dengan spesifikasi tertulis.
algorithmshark
@algorithmshark Dikoreksi
Rainbolt
13
Saya tidak yakin, tetapi bagi saya tampaknya Anda tenggelam jika jumlah hujan lebih besar dari jumlah hujan yang dapat ditahan oleh semua kotak; jika tidak, Anda melayang. Apakah ini?
Hosch250
2
@ hosch250 Memanjakan kesenangan!
Rainbolt
1
"Kelebihan air didistribusikan secara merata ke tetangganya." - itu kemungkinan adalah 1 unit air. Apakah itu didistribusikan sebagai 0.25unit misalnya untuk setiap sel yang berdekatan (dengan asumsi sel banjir tengah tunggal)?
Neil Slater

Jawaban:

16

Golfscript, 37 30 karakter

Baru dan lebih baik, terima kasih kepada PeterTaylor untuk tips:

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

Penjelasan :

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"

Program kemudian berakhir, mengeluarkan tumpukan.


Versi lama + penjelasan:

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

Pendekatan yang sama seperti Fors , just Golfscripted =). Kemungkinan bisa dibuat lebih efisien. Masukan dari stdin.

Penjelasan :

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"

Program kemudian mengeluarkan tumpukan, yang hanya jawabannya.

Claudiu
sumber
]tanpa pencocokan [akan mengumpulkan seluruh tumpukan ke dalam array, sehingga inisial [~]dapat disederhanakan ~]. Untuk mendapatkan grid_sizeelemen pertama dari sebuah array, gunakan <, jadi <{+}*hampir pasti bisa menghemat sedikit untuk menambah kapasitas total. 0>"Sink""Swim"ifdapat0>"SinkSwim"4/=
Peter Taylor
@PeterTaylor: Terima kasih atas tipsnya! Anda yakin tentang itu ~]? Saya mencobanya dan sepertinya tidak berhasil. Retas terakhir bagus meskipun harus "SwimSink"- akan menggunakannya. dan hal array juga tampaknya menjanjikan, akan mulai bekerja pada itu.
Claudiu
Saya yakin: itu tipuan standar yang saya dan orang lain telah gunakan selama bertahun-tahun.
Peter Taylor
@PeterTaylor: Hmm aneh. Cobalah di penerjemah yang ditautkan dengan saya - gagal. Kemudian - ok, mungkin penerjemah web tidak standar. Tetapi saya juga mencoba ruby golfscript.rbdan itu masih tidak berhasil ... dapatkah Anda memverifikasi bahwa itu berhasil pada Anda? Saya mendapatkan kesalahan yang sama pada keduanya:undefined method '+' for nil:NilClass (NoMethodError)
Claudiu
1
Ketika Anda memasukkan string literal untuk menggantikan kekurangan stdin, Anda harus mengawalinya dengan titik koma untuk menghapus string kosong yang sebenarnya berasal "dari stdin". Dengan itu berfungsi dengan baik
Peter Taylor
20

C: 100 96 95 karakter

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

Lima jam? Butuh waktu lima menit. :)

Aragaer, terima kasih atas penyederhanaannya! Namun saya mengatur ulang deklarasi variabel dan argumen ke utama, mengingat Dentang melempar kesalahan jika argumen kedua ke utama adalah dari jenis lain selain char **.

Untuk S
sumber
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");}. Saya juga bermain dengan ide n-=scanf, tetapi tidak yakin apakah program akan benar setelah itu. Pertama scanfdapat dipindahkan ke depan fortanpa mengubah jumlah karakter.
aragaer
n-=scanf...tidak akan bekerja, karena n-=1pada dasarnya adalah kenaikan sebelum, sehingga akan kehilangan sudut tenggara. Perubahan lainnya sangat bagus.
Fors
7

Python, 4 baris, 175 karakter

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, saya ingin tahu apakah 40+ tim akhirnya menemukan tangkapan ... setelah menyelesaikannya dengan keras.

menelan
sumber
10
Saya berada di salah satu dari 40+ tim. Kami DIBERIKAN tangkapan setelah gagal. Semua orang di auditorium facepalmed secara bersamaan. Saya pikir mungkin saya seharusnya tidak menyebutkannya di sini. Kalian terlalu cepat!
Rainbolt
Aduh! Ngomong-ngomong, haruskah saya mendapatkan input dari stdin untuk pertanyaan-pertanyaan semacam ini? - Saya baru di stackexchange. :)
swalladge
Saya akan mengedit pertanyaan saya untuk mengatakan tentukan STDIN, tetapi saya khawatir itu akan membatalkan jawaban Anda. Saya telah membaca teka-teki di sini selama sekitar satu bulan, dan belum benar-benar memperhatikan apakah orang-orang menentukan STDIN atau tidak.
Rainbolt
1
@swalladge Selamat datang di Codegolf! Saya sarankan menjadikan headline sebagai headline dengan menambahkan a #.
TimWolla
2
Anda dapat menurunkannya menjadi 108 jika Anda menggunakan input()dan map():n,_,p=map(int,input().split());print(['sink','swim'][p>sum(sum(map(int,input().split()))for a in range(n))])
Blender
6

Fitur ganda J (50 char) dan K (40)

Ternyata, seperti biasa, keduanya memiliki struktur yang sama persis dalam solusi mereka, jadi mereka berdua ada di sini. K jauh lebih pendek, yang merupakan kejutan yang menyenangkan.

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

Penjelasan:

  • ".1!:1]1 - Baca di baris pertama, dan konversikan ke bilangan bulat.
  • (...)/0 2{- Ambil item pada indeks 0 dan 2 ( ndan pmasing - masing), dan gunakan masing - masing sebagai argumen kiri dan kanan pada kata kerja (...).
  • +1!:1@#1:- Baca n+psejalan.
  • [+/@".@$- Ambil ( $) nbaris pertama ( [), buang sisanya, lalu konversikan ke integer ( ".) dan jumlahkan pada setiap baris ( +/).
  • ]<[:+/- Tambahkan bersama jumlah baris, lalu bandingkan nilai ini dengan argumen yang tepat p,. Kami menghasilkan benar jika pkurang dari jumlah.
  • >Sink`Swim{~- Pilih Swimjika perbandingan di atas menghasilkan true, atau Sinkjika false.

Pemakaian:

   >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

Dan sekarang K:

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

Dijelaskan:

  • . 0:` - Baca di jalur input, dan konversi ke array bilangan bulat.
  • {...}.- Gunakan tiga angka ini n m psebagai argumen x y zuntuk fungsi ini.
  • 0::'(x+z)#`- Buat x+zsalinan pegangan file input `, dan kemudian baca dalam satu baris untuk masing-masingnya ( 0::')
  • .:'x#- Ambil xitem pertama , dan konversi masing-masing ke vektor angka.
  • z<+//- Jumlah seluruh matriks bersama-sama, dan kemudian tes untuk melihat apakah itu lebih besar dari z.
  • `Sink`Swim@- Kembali Sinkatau Swimsesuai dengan apakah tes tersebut kembali benar.

Pemakaian:

  `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
algoritme hiu
sumber
6

APL, 35

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

Tidak yakin apakah diizinkan tetapi berhenti menerima input setelah "kota"

x←⎕Mengambil input dan menyimpannya dalam variabel x(angka-angka terbatas-ruang ditafsirkan sebagai array numerik)
1⌷Ekstrak indeks 1 (array APL berbasis satu)
Hasilkan array dari 1 hingga argumen ( 1⌷x←⎕dalam hal ini)
¨"Peta" operasi
{+/⎕}Ambil array dari masukan dan kembalikan jumlah
+/Jumlah array yang dihasilkan oleh operasi peta
4×x[3]>Uji jika jumlah < x[3](mengembalikan 1 atau 0), kemudian gandakan 4
'SwimSink'⌽⍨Putar string 'SwimSink'dengan jumlah itu
4↑Akhirnya, ekstrak 4 karakter pertama dari string

TwiNight
sumber
Saya pikir satu-satunya bagian yang penting adalah menghasilkan jawaban yang benar untuk setiap input yang diberikan. Jika ini tidak biasa bagi CodeGolf, mudah-mudahan seseorang akan memberi tahu saya.
Rainbolt
Ubah ⎕IO←0, lalu ganti 4↑'SwimSink'⌽⍨4×dengan 'Swim' 'Sink'⊃⍨, x[3]dengan x[2], dan 1⌷xdengan ⊃xuntuk menyimpan dua 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"}

Ini adalah perbaikan oleh yang laindir pada kiriman saya (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")}
pengguna40989
sumber
NR<=hseharusnya NR<=h+1, jika tidak, Anda akan mendapatkan Sink palsu karena baris terakhir kapasitas dilewati. Ini juga dapat disingkat menjadi 70 sebagain{for(;NF;NF--)s+=$NF;n--}NR==1{n=$1;p=$3}END{print p<s?"Swim":"Sink"}
laindir
1
@laindir Baiklah, terima kasih banyak atas peningkatannya! Saya merasa sangat menyenangkan, bahwa Awk hanya datang di sebelah APL, J dan K, yang dikembangbiakkan untuk mengalahkan semua orang di golf kode! :-)
user40989
@ user40989 Saya tidak mengerti. Awk tampaknya 40-100% lebih lama dari J / K / APL, meskipun mereka bukan bahasa golf, melainkan (berasal dari) bahasa pemrograman komersial.
Adám
5

CoffeeScript - 128 113

Fungsi yang menggunakan string sebagai satu-satunya argumen:

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"`
TimWolla
sumber
Anda dapat menghapus lekukan, dan memindahkan semuanya pada baris pertama dipisahkan oleh titik koma. Anda juga menulis `p>x?"Sink":"Swim"`bukan if p>x then"Sink"else"Swim". Parens untuk pernyataan ketiga juga tidak diperlukan.
Konrad Borowski
4

SED, 128

Sangat menyenangkan untuk menulis sedversi ini. Ini memiliki kedatangan singkat berikut:

  • Diasumsikan kota memiliki lebih dari dua kolom, untuk dengan mudah mengenali garis hujan.

  • Diasumsikan bahwa kapasitas masing-masing kota berada pada kisaran 0-9.

Ini dia:

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}

Panggil dengan -nbendera.

pengguna40989
sumber
3

SWI-Prolog 79

Jika Anda tidak keberatan dengan kenyataan bahwa jawaban ini membutuhkan input dari kueri, bukan melalui stdin:

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

Jawabannya tidak memvalidasi format input, tapi saya rasa itu bukan masalah, karena kontes pemrograman juga tidak mengharuskan Anda melakukannya.

Permintaan sampel (menggunakan contoh dalam pertanyaan):

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)]).
n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳
sumber
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'
pengguna1159256
sumber
1
Anda bisa mulai dengan mengeluarkan spasi. Setelah ,, sebelum dan sesudah ', setelah )...
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")

Mungkin saja untuk menghilangkan beberapa tanda kurung atau sesuatu, tetapi Scala benar-benar berubah-ubah tentang tanda baca dan gaya bebas-titik dan () vs {} dan yang lainnya.

Joe K.
sumber
0

Javascript - 73 Karakter

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

Mengasumsikan input dalam variabel sdan output Swimatau Sink.

Contoh:

Dari pertanyaan awal - memasukkan ini ke konsol browser:

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"

Output:

Swim
MT0
sumber