Ini adalah tantangan di internet yang diminta oleh Palantir Technologies dalam wawancara mereka .
Sekelompok petani memiliki beberapa data ketinggian, dan kami akan membantu mereka memahami bagaimana curah hujan mengalir di atas tanah pertanian mereka. Kami akan mewakili tanah sebagai susunan ketinggian dua dimensi dan menggunakan model berikut, berdasarkan gagasan bahwa air mengalir menuruni bukit:
Jika empat sel tetangga sel semuanya memiliki ketinggian lebih tinggi, kami menyebut sel ini sebagai sink; air terkumpul di bak cuci. Jika tidak, air akan mengalir ke sel tetangga dengan ketinggian terendah. Jika sel bukan wastafel, Anda dapat menganggapnya memiliki tetangga terendah yang unik dan tetangga ini akan lebih rendah dari sel.
Sel-sel yang mengalir ke wastafel yang sama - secara langsung atau tidak langsung - dikatakan bagian dari cekungan yang sama.
Tantangan Anda adalah mempartisi peta menjadi baskom. Khususnya, mengingat peta ketinggian, kode Anda harus mempartisi peta menjadi cekungan dan menampilkan ukuran cekungan, dalam urutan menurun.
Asumsikan peta ketinggian adalah bujur sangkar. Input akan dimulai dengan garis dengan satu bilangan bulat, S, tinggi (dan lebar) peta. Baris S berikutnya masing-masing akan berisi baris peta, masing-masing dengan bilangan bulat S - ketinggian sel S di baris. Beberapa petani memiliki petak tanah kecil seperti contoh di bawah ini, sementara beberapa memiliki petak yang lebih besar. Namun, petani tidak akan memiliki sebidang tanah yang lebih besar dari S = 5000.
Kode Anda harus menampilkan daftar ukuran cekungan yang dipisahkan ruang, dalam urutan menurun. (Ruang tambahan diabaikan.)
Beberapa contoh di bawah ini.
Memasukkan:
3
1 5 2
2 4 7
3 6 9
Keluaran:
7 2
Cekungan, berlabel A dan B, adalah:
A A B
A A B
A A A
Memasukkan:
1
10
Keluaran:
1
Hanya ada satu baskom dalam kasus ini.
Memasukkan:
5
1 0 2 5 8
2 3 4 7 9
3 5 7 8 9
1 2 5 4 2
3 3 5 2 1
Keluaran:
11 7 7
Cekungan, berlabel A, B, dan C, adalah:
A A A A A
A A A A A
B B A C C
B B B C C
B B C C C
Memasukkan:
4
0 2 1 3
2 1 0 4
3 3 3 3
5 5 2 1
Keluaran:
7 5 4
Cekungan, berlabel A, B, dan C, adalah:
A A B B
A B B B
A B B C
A C C C
sumber
Jawaban:
Mathematica
Daftar ukuran cekungan bisa didapatkan
dimana
m
input data yang diberikan. Untuk menampilkan matriks seperti yang ada di pertanyaan satu dapat menggantikan// Reverse@Sort@Part[Tally[Flatten@#], All, 2] &
dengan/. {1 -> "A", 2 -> "B", 3 -> "C"} // MatrixForm
atau satu dapat menampilkannya sebagai gambar bukan menggunakan//ImageAdjust//Image
.sumber
JavaScript - 673
707730751e=[],g=[],h=[],m=[],q=[];function r(){a=s,b=t;function d(d,A){n=a+d,p=b+A;c>e[n][p]&&(u=!1,v>e[n][p]&&(v=e[n][p],w=n,k=p))}c=e[a][b],u=!0,v=c,w=a,k=b;0!=a&&d(-1,0);a!=l&&d(1,0);0!=b&&d(0,-1);b!=l&&d(0,1);g[a][b]=w;h[a][b]=k;return u}function x(a,b,d){function c(a,b,c,k){g[a+b][c+k]==a&&h[a+b][c+k]==c&&(d=x(a+b,c+k,d))}d++;0!=a&&c(a,-1,b,0);a!=l&&c(a,1,b,0);0!=b&&c(a,0,b,-1);b!=l&&c(a,0,b,1);return d}y=$EXEC('cat "'+$ARG[0]+'"').split("\n");l=y[0]-1;for(z=-1;z++<l;)e[z]=y[z+1].split(" "),g[z]=[],h[z]=[];for(s=-1;s++<l;)for(t=-1;t++<l;)r()&&m.push([s,t]);for(z=m.length-1;0<=z;--z)s=m[z][0],t=m[z][1],q.push(x(s,t,0));print(q.sort(function(a,b){return b-a}).join(" "));
Hasil tes (menggunakan Nashorn):
Mungkin akan ada masalah tumpukan untuk peta ukuran 5000 (tapi itu detail implementasi :).
Sumber unminified dalam semua itu adalah kesalahan:
Saya mendapat hasil minimalisasi yang lebih baik dengan memecah objek elemen menjadi array terpisah, mengglobalisasikan sedapat mungkin dan merangkul efek samping. NSFW.
Efek minimalisasi kode:
Saya bisa mencapai hampir 700 byte tanpa mengedit kode yang diperkecil jika saya bersedia untuk memodifikasi sumber aslinya. Tapi saya tidak melakukannya karena saya pikir membiarkannya apa adanya memberikan pandangan yang menarik dari titik awal.
sumber
var e=[],g=[],h=[],l,m=[],q=[]
menjadie=g=h=l=m=q=[]
. Anda mungkin dapat menyingkirkan penggunaanvar
kata kunci lainnya juga jika Anda tidak membayangi variabel global apa pun.Python: 276
306 365byteIni adalah usaha golf pertama saya. Saran sangat dihargai!
edit: impor dan file penutupan mengambil terlalu banyak karakter! Begitu juga menyimpan file dalam variabel dan pemahaman daftar bersarang.
sepenuhnya dikomentari (2130 byte ...)
sumber
open('a').read()
, saya pikir.JavaScript (ECMAScript 6) - 226 Karakter
Penjelasan
Versi Sebelumnya - 286 Karakter
Mengasumsikan bahwa input dalam variabel
S
;Penjelasan
Uji
Output:
[7, 2]
Output:
[11, 7, 7]
Output:
[5, 7, 4]
sumber
Julia, 315
Hanya fungsi rekursif yang menentukan apakah sel saat ini adalah wastafel atau menemukan saluran pembuangan, kemudian menyebutnya di setiap kumpulan indeks. Tidak repot untuk melakukan bagian input karena saya tidak akan menang, dan bagian itu tidak menyenangkan.
sumber
Haskell, 271
286Mungkin masih ada beberapa kode untuk golf di sini.
Penjelasan
Ide dasar: Untuk setiap sel (i, j) temukan sel terendah di "lingkungan". Ini memberikan grafik [ (i, j) → (mi, mj) ]. Jika sel adalah sel terendah, maka (i, j) == (mi, mj) .
Grafik ini dapat diulang: Untuk setiap a → b dalam grafik, gantikan dengan → → di mana b → c ada dalam grafik. Ketika iterasi ini menghasilkan tidak ada lagi perubahan, maka setiap sel dalam grafik menunjuk pada sel terendah yang akan mengalir.
Untuk golf ini, beberapa perubahan telah dibuat: Pertama, koordinat direpresentasikan sebagai daftar panjang 2, bukan pasangan. Kedua, begitu tetangga telah ditemukan, sel diwakili oleh indeks mereka ke dalam array linier sel, bukan koordinat 2D. Ketiga, karena ada sel n * n, setelah iterasi n * n, grafik harus stabil.
Tidak diajak
sumber
Ruby, 216
Ini pendekatan yang sedikit berbeda, hanya menggunakan "aliran" di setiap kotak sekali (kinerja tergantung apa kinerja Array :: index). Ia bergerak dari ketinggian tertinggi ke terendah, mengosongkan satu sel pada satu waktu ke tetangga terendah dan menandai sel dilakukan (dengan menambahkan 1 ke ketinggian) ketika selesai.
Berkomentar dan ditempatkan:
Changelog:
216 - cara yang lebih baik untuk membatalkan pilihan indeks di luar batas
221 - ternyata, "11" muncul sebelum "2" ... kembalikan
to_i
, tetapi hemat ruang padagets
es .224 - Lagi
s
pula, mengapa harus mendeklarasikan ? Daneach
=>map
229 - golf masif - sortir ketinggian terlebih dahulu
s
(dan dengan demikian jatuhkanwhile
klausa), gunakanmin_by
alih-alihsort_by{...}[0]
, jangan repotto_i
- repot untuk meninggikan, menggunakanflat_map
, dan mengecilkanselect{}
blok271 - memindahkan ukuran DAS ke array baru dan menggunakan sort_by
315 - pindah hasil ke array yang memberikan segala macam manfaat, dan mempersingkat daftar indeks tetangga. juga mendapatkan satu arang dalam indeks lambda.
355 - komit pertama
sumber
Python -
470 447 445 393 392 378 376 375 374369 byteSaya tidak bisa menahan diri!
Bukan solusi yang unggul, tapi saya senang membuatnya. Versi ini tidak menganggap input untuk disimpan di mana saja dan sebagai gantinya membacanya dari stdin. Kedalaman rekursi maksimum = jarak terpanjang dari satu titik ke titik tersebut.
Saya tidak punya waktu untuk menjelaskannya hari ini, tapi ini kode yang tidak disunat:Ini sebenarnya sangat berbeda dari kode aslinya. Saya membaca garis S dari stdin, membagi, memetakan ke int dan meratakan daftar untuk mendapatkan bidang yang rata. Lalu saya loop semua ubin (biarkan saya menyebutnya ubin) sekali. Fungsi aliran memeriksa ubin tetangga dan memilih yang dengan nilai terkecil. Jika lebih kecil dari nilai ubin saat ini, pindah ke sana dan ulangi. Jika tidak, ubin saat ini adalah wastafel dan baskom baru dibuat. Nilai pengembalian rekursi adalah id dari baskom.
sumber
JavaScript (ES6) 190
203Edit Sedikit lebih ES6ish (1 tahun kemudian ...)
Tentukan fungsi dengan baris input sebagai string, termasuk baris baru, kembalikan output sebagai string dengan trailing blank
sumber
Perl 6,
419404Baris baru ditambahkan untuk kejelasan. Anda dapat menghapusnya dengan aman.
Solusi lama:
Namun saya dikalahkan oleh solusi Python dan JavaScript.
sumber