Saat Peluru bertabrakan

16

Tantangan ini didasarkan pada teka-teki yang saya baca di beberapa buku beberapa waktu lalu, yang saya temukan lagi di sini . Ini adalah tentang peluru yang ditembakkan dari senapan sekali per detik dengan kecepatan bervariasi yang bergerak dalam garis lurus selamanya. Ketika satu peluru mengenai yang lain, keduanya hancur sepenuhnya. (Jangan ragu untuk mengganti semua instance "peluru" dengan "rudal".)

Tugas

Diberi daftar kecepatan peluru dalam urutan menembak, tentukan apakah semua peluru dihancurkan.

Aturan

  • Input adalah daftar bilangan bulat non-negatif, dipisahkan oleh pembatas apa pun dan dengan satu karakter opsional sebelum dan sesudah. Ini adalah input yang valid: 1 2 3 4 5 6dan [1,2,3,4,5,6]. Pemrogram membuat pilihan.
  • Keluarkan nilai kebenaran jika setidaknya satu peluru bertahan selamanya dan nilai palsu sebaliknya.
  • Kecepatan peluru diberikan dalam satuan per detik.
  • Peluru bergerak secara simultan dan terus menerus.
  • Peluru dapat bertabrakan pada offset fraksional.
  • Beberapa peluru yang secara bersamaan mencapai posisi yang sama persis, apakah pada offset integral atau fraksional dari asal, semua saling bertabrakan.

Contohnya

Dalam diagram ini, Gperlihatkan pistol, >peluru, dan *saat peluru bertabrakan dan meledak.

Sejujurnya

Memasukkan: 0

        0123456789
Time 0 G>
     1 G>
     2 G>
   ...

Keluaran: 1


Memasukkan: 0 0 0

        0123456789
Time 0 G>
     1 G*
     2 G>
     3 G>
     4 G>
   ...

Keluaran: 1


Memasukkan: 1

        0123456789
Time 0 G>
     1 G >
     2 G  >
     3 G   >
   ...

Keluaran: 1


Memasukkan: 2 1

        0123456789
Time 0 G>
     1 G> >
     2 G >  >
     3 G  >   >
     4 G   >    >
   ...

Keluaran: 1


Memasukkan: 2 3 1

        0123456789
Time 0 G>
     1 G> >
     2 G>  >>
     3 G >    *
     4 G  >
     5 G   >
   ...

Keluaran: 1


Palsu

Memasukkan: 1 2 3 4 5 6

        Unit      1111111111
        01234567890123456789
Time 0 G>
     1 G>>
     2 G> *
     3 G>  >
     4 G>   > >
     5 G>    >  >>
     6 G      >   > *
     7 G            >  >
     8 G                  > >
     9 G                        >>
    10 G                              *
                  111111111122222222223
        0123456789012345678901234567890

Keluaran: 0


Memasukkan: 1 0 0 3

        Unit
        0123456789
Time 0 G>
     1 G>>
     2 G* >
     3 G>  >
     4 G   >>
     5 G     *

(Tabrakan kedua adalah pada waktu 4,5)
Output:0


Memasukkan: 2 1 2 3 6 5

        Unit      1111111111
        01234567890123456789
Time 0 G>
     1 G> >
     2 G>>  >
     3 G> *   >
     4 G>  >    >
     5 G>     *   >
     6 G     >      >
     7 G          >   >
     8 G               >>
     9 G                *
                  1111111111
        01234567890123456789

Keluaran: 0


Memasukkan: 2 3 6

        Unit
        0123456789
Time 0 G>
     1 G> >
     2 G>  >>
     3 G      *

Keluaran: 0

El'endia Starman
sumber
dapatkah saya meminta input dibatasi seperti 1<enter>2<enter>3...?
kucing
@sysreq: Itu mendorongnya, tapi saya akan membiarkannya.
El'endia Starman
Saya setuju dengan qunitopia - tantangan ini sangat sulit, tetapi saya sedang mengerjakan solusi ...
zmerch

Jawaban:

4

Python 2, 388 392 388 346 342 336 331 byte

z=k=input();l=len(k);v=range;u=v(l)
while l<z:
 r="";o=[r]*l;z=l
 for h in v(l):
    if r:o[h-1]=o[m]=r;m=h;r=""
    for j in v(h+1,l):
     p=k[h];q=k[j];t=u[j];n=(1.0*q*t-p*u[h])/(q-p)if q-p else""if p>0 else t
     if t<=n<r<()>o[j]>=n<=o[h]:r=n;m=j
 i=0;s=o and min(o)
 while i<l:
    if o[i]==s!="":del k[i],o[i],u[i];l-=1
    else:i+=1
print l

Ya Tuhan benda ini sangat besar, tapi saya percaya itu benar-benar berhasil. Setelah Anda melihat semua seluk beluknya, tantangan ini sangat sulit.

Saya tidak yakin apakah saya bisa menjelaskan cara kerjanya secara detail tanpa mengetik selama berjam-jam, jadi saya hanya akan memberikan ringkasan eksekutif.

Loop sementara utama utama adalah perulangan sampai daftar input tidak menyusut.

Nested for loop (dapatkah Anda percaya bahwa nested for loop sebenarnya adalah yang terpendek di sini?) Mengulangi setiap kecepatan peluru dan menggunakan numpy.rootsuntuk menghitung perhitungan pada waktu mana peluru akan bertabrakan dengan setiap peluru yang datang setelahnya. Di sini, ""digunakan untuk berarti infinity (tidak ada persimpangan). Kondisional tambahan harus disertakan untuk memastikan bahwa peluru yang berhenti ditandai bertabrakan pada saat mereka muncul daripada pada saat nol.

Untuk setiap nomor, kami melacak peluru mana yang akan terkena paling cepat, jika ada, dan kemudian odiperbarui dengan waktu tabrakan minimum untuk peluru yang terlibat.

Setelah pengulangan ganda ini berakhir, kami mengulangi daftar input dan menghapus setiap peluru yang akan bertabrakan pada minimum semua waktu tabrakan, jika ada. Ini memungkinkan kita untuk secara bersamaan menghapus sejumlah besar peluru jika semuanya bertabrakan pada saat yang sama.

Kemudian kami mengulangi seluruh proses pada sisa peluru, karena mereka mungkin bisa mendapatkan sekarang bahwa peluru yang mereka akan bertabrakan telah dihancurkan.

Segera setelah tidak ada peluru yang dihapus (ditunjukkan oleh daftar yang tidak menyusut), kami lolos dari loop sementara dan mencetak panjang daftar yang tersisa. Dengan demikian, program ini tidak hanya mencetak kebenaran jika peluru bertahan, itu sebenarnya mencetak dengan tepat jumlah peluru yang bertahan.

EDIT: Terima kasih khusus kepada feersum untuk membuat kasus pengujian untuk membantu saya menemukan bug.

EDIT 2: Menyelamatkan 42 byte dengan menyelesaikan persamaan linier dengan tangan alih-alih menggunakan numpy, dan membagi waktu mulai menjadi daftar terpisah dan merestrukturisasi suatu kondisi.

EDIT 3: Disimpan 4 byte dengan mengubah nama rentang

EDIT 4: Menyimpan 6 byte lebih banyak dengan mengganti spasi ganda dengan tab. Juga, feersum cukup baik untuk memberikan implementasinya menggunakan fraksi dan set untuk perbandingan. Saya telah membuatnya sedikit dan menghasilkan 331 byte, mengikat solusi saya.

EDIT 5: menyimpan 5 byte dengan menghapus inisialisasi yang tidak perlu dan menulis ulang suatu kondisi

kuintopia
sumber
Apakah Anda tidak menguji input contoh lagi? [1, 0, 0, 3] tidak berfungsi.
feersum
@feersum itu satu-satunya yang tidak saya uji, dangit. tapi tetap. DENGAN SEMUA UPAYA INI, SAYA LEBIH BAIK MENDAPAT UPVOTE. : P
quintopia
Masih tidak berfungsi. [1, 16, 18, 20, 30] harus mengembalikan 1.
feersum
OK sepertinya berfungsi sekarang, setidaknya sebagian besar waktu.
feersum