Selamat mendapatkan 10.000 reputasi!

19

Setelah @ MartinBüttner mencapai tepat 10.000 reputasi , kami sekarang memiliki tiga baris penuh pengguna 10 ribu di halaman pengguna ! Sekarang, karena kita semua programmer di sini, kami lebih suka mengotomatisasi sesuatu daripada melakukannya secara manual. Tantangan Anda adalah menulis sebuah program untuk memberi selamat secara otomatis kepada 10k pengguna baru.

Spesifikasi

Memasukkan

Input akan berupa ngaris angka yang dipisahkan ruang. (Jika Anda mau, Anda juga dapat mengambil daftar tunggal angka-angka yang dipisahkan spasi, jika itu membuat kode Anda lebih pendek.) Misalnya:

10 20 30 40 50
15 25 35 45 55
20 30 40 50 60

Atau:

10 20 30 40 50,15 25 35 45 55,20 30 40 50 60

Setiap daftar angka mewakili daftar nilai reputasi pengguna dalam satu hari.

Keluaran

Outputnya akan menjadi jumlah nbaris yang sama (atau daftar yang dipisahkan koma dengan panjang yang sama). Setiap item baris / daftar adalah:

  • :D jika ada pengguna yang reputasinya baru>> 10.000.
    • Berpisah beberapa ruang :Djika ada beberapa pengguna yang memenuhi atau melewati hitungan 10.000 rep. Misalnya, :D :D :Duntuk 3 pengguna 10k baru.
  • :( dan kemudian hentikan output lebih lanjut jika inputnya ambigu atau tidak mungkin (lebih lanjut tentang ini di bagian selanjutnya).
  • tidak ada jika kedua kondisi ini tidak benar.

Kemenduaan

Mungkin saja inputnya ambigu. Untuk keperluan tantangan ini, kami menganggap bahwa:

  • Batas reputasi adalah 200 per hari, mengabaikan hadiah dan hadiah dan sejenisnya demi tantangan.
  • Pengguna tidak boleh kehilangan reputasi (sekali lagi untuk kesederhanaan dan untuk tantangan).

Input dianggap ambigu ketika tidak mungkin untuk menentukan nilai reputasi mana yang sesuai dengan pengguna yang mana. Misalnya, dalam input 10 20,30 40, Anda tidak bisa memastikan apakah pengguna 10-rep menjadi pengguna 30-rep atau 40-rep.

Input dianggap mustahil ketika pengguna dari satu hari tidak mungkin menjadi pengguna dari hari berikutnya. Misalnya, dalam input 10 20,310 320, situasi ini jelas tidak mungkin karena pengguna tidak dapat memperoleh 300 reputasi dalam sehari. Pengguna kehilangan reputasi juga tidak mungkin.

Kasus tepi

  • Nilai reputasi awal dapat dimulai dari apa saja (yaitu pengguna dapat mulai dengan 1337 reputasi).
  • Tidak ada output untuk item baris / daftar pertama.
  • Masukan akan selalu valid secara sintaksis, artinya nilai reputasi akan selalu bilangan bulat positif, akan selalu ada jumlah nilai reputasi yang sama per baris / daftar item, dll.
  • Nilai-nilai reputasi tidak diurutkan; mereka mungkin dalam urutan apa pun.

Uji kasus

Input: 9900,10000
Keluaran::D

Input: 9900 9950 9910,10100 9950 9910,10300 10150 10110
Keluaran::D,:D :D

Input: 10 20 30,42 10 20,10 242 20,442 42 10,0 0 0,442 42 10
Keluaran:,,,:(

Input: 10 20,15 25,15 25
Keluaran:,,

Input: 9999 9998 9997,10000 9998 9997,10000 10000 9997,10300 10000 10000
Keluaran::D,:D,:(

Input: 100,90,80,70
Keluaran::(

Input: 10000 10000 10000 9999,10000 10000 10000 10000,10010 10020 10030 10040
Keluaran::D,:(

Input: 9999 9998 9997 9996,10196 10197 10198 10199,10399 10199 10197 10196
Keluaran::D :D :D :D,

Gagang pintu
sumber
@ MartinBüttner Ah, tidak memperhatikan itu. Diperbaiki
Gagang Pintu
Langkah pertama dalam contoh itu juga ambigu.
Martin Ender
1
Sedangkan contoh 4 tidak ambigu.
Martin Ender
(i.e. a user can start with 1337 reputation).Saya menyukai ini karena itu adalah perwakilan saya ... selamat 5 menit yang lalu sampai seseorang mengangkat salah satu jawaban saya xD
Teun Pronk
Contoh 5, langkah 2 juga ambigu (pengguna 10k yang mana?). Hal yang sama berlaku untuk contoh 7 (kecuali jika Anda menambahkan beberapa aturan yang membedakan pengguna dengan rep yang sama tidak relevan, tetapi lalu bagaimana Anda tahu pengguna mana yang pada hari pertama, jika ia terikat dengan orang lain di kemudian hari?)
Martin Ender

Jawaban:

12

Ruby, 209 byte

Sunting: Saya beralih ke Ruby yang memperpendek sekitar 30%. Lihat riwayat edit untuk versi Mathematica asli. Saya kira penghematan utama datang dari Ruby permutationtidak mengabaikan posisi beralih dari elemen yang identik (yang saya harus menipu Mathematica ke).

Ini menggunakan format yang dipisahkan oleh baris baru.

gets.split('
').map{|s|s.split.map &:to_i}.each_cons(2){|a,b|a.permutation.map{|q|q.zip(b).map{|x,y|y-x}}.reject{|d|d.any?{|x|x<0||x>200}}.size!=1?abort(':('):(puts':D '*(a.count{|d|d<1e4}-b.count{|d|d<1e4}))}

Intinya adalah ini:

  • Dapatkan semua pasangan hari berturut-turut.
  • Dapatkan semua permutasi dari hari sebelumnya, dan kurangi masing-masing dari hari ini.
  • Parit semua hasil yang mengandung perbedaan yang negatif atau lebih besar 200.
  • Jika jumlah permutasi yang tersisa bukan 1, hasilkan :(.
  • Kalau tidak, output sebanyak :Dada pengguna 10k baru.
  • Pada akhirnya, drop semua hari setelah yang pertama :(.

Lebih sedikit golf:

gets.split("\n").map{|s|
  s.split.map &:to_i
}.each_cons(2){|a,b|
  a.permutation.map{|q|
    q.zip(b).map{|x,y|
      y-x
    }
  }.reject{|d|
    d.any?{|x|
      x<0||x>200
    }
  }.size!=1 ? abort(':(') : (puts ':D '*(a.count{|d|d<1e4}-b.count{|d|d<1e4}))
}

Saya pikir itu adalah satu rantai enumerator yang cantik. :)

PS: Apakah aneh kalau saya yang pertama memberikan jawaban untuk ini?

Martin Ender
sumber
8
Saya tidak berpikir itu aneh. Sesuatu memberi tahu saya bahwa Anda memiliki keunggulan bidang asal;)
Calvin Hobbies
Jadi ini akan gagal beberapa contoh dalam pertanyaan, kan?
Cruncher
@Cruncher Ini akan gagal yang menurut saya salah menurut spec (seperti yang saya sebutkan di komentar). Jika Doorknob memutuskan untuk mengubah spec alih-alih memperbaiki contoh, saya kira saya harus mengerjakan ulang ini.
Martin Ender
@ MartinBüttner Itulah yang saya kira. Hanya mengkonfirmasi :)
Cruncher
6

Haskell, 254 249 244 232 228

import Data.List
t=m(9999<)
p(a:b:r)=(a,b,r)%(filter(all(`elem`[0..200]))$nub$m(zipWith(-)b)$permutations a)
p _=""
(a,b,r)%(_:[])=(concat$m(const":D ")$t b\\t a)++'\n':p(b:r)
_%_=":("
m=map
main=interact$p.m(m read.words).lines

Penjelasan kecil: Algoritma ini sangat mirip dengan yang digunakan oleh MartinBüttner, kecuali nubyang saya habiskan. Perhatikan bahwa perbedaan daftar digunakan untuk bekerja di luar berapa banyak lagi reputasi nilai-nilai 10000 atau lebih besar pada hari n + 1 dibandingkan dengan hari n: t b\\t a.

Saya juga setuju dengan Martin Büttner tentang interpretasi spesifikasi dan bahwa beberapa contoh di atas salah, bahkan sampai-sampai contoh # 2 salah (seharusnya :().

TheSpanishInquisition
sumber
Bukankah seharusnya kamu alias map?
haskeller bangga
1
Itu benar (tabungan 2 bytes), tapi lain 10 bytes bisa diselamatkan dengan membuat zinfiks dan mengganti replicate (length l) xdengan map (const x) l. Bukankah Haskell fantastis?
TheSpanishInquisition
pastilah itu. Golf yang bagus! Pada catatan itu, Karena aplikasi fungsi memiliki prioritas tertinggi, Anda harus dapat mempersingkat (t b)\\(t a)untuk t b\\t a, golf keluar 4 byte lagi.
haskeller bangga
Akan lebih baik jika ada beberapa kode untuk menemukan tempat-tempat di mana kode dapat dipersingkat secara otomatis ... Tampaknya agak besar dari suatu proyek.
haskeller bangga
Anda benar @proudhaskeller, paretheses itu tidak perlu. Terima kasih.
TheSpanishInquisition