Khi đạn va chạm


16

Thử thách này dựa trên một câu đố mà tôi đã đọc trong một số cuốn sách trước đây, mà tôi đã tìm thấy ở đây . Đó là về những viên đạn được bắn ra từ súng mỗi giây một lần với tốc độ khác nhau di chuyển theo đường thẳng mãi mãi. Khi một viên đạn trúng một viên đạn khác, cả hai đều bị phá hủy hoàn toàn. (Hãy thoải mái thay thế tất cả các trường hợp "viên đạn" bằng "tên lửa".)

Nhiệm vụ

Đưa ra một danh sách các tốc độ đạn theo thứ tự chúng được bắn vào, xác định xem tất cả các viên đạn có bị phá hủy hay không.

Những quy định

  • Đầu vào là danh sách các số nguyên không âm, được phân tách bằng bất kỳ dấu phân cách nào và với một ký tự tùy chọn trước và sau. Đây là những đầu vào hợp lệ: 1 2 3 4 5 6[1,2,3,4,5,6]. Các lập trình viên đưa ra lựa chọn.
  • Xuất ra một giá trị trung thực nếu ít nhất một viên đạn tồn tại mãi mãi và một giá trị giả khác.
  • Tốc độ đạn được tính theo đơn vị mỗi giây.
  • Đạn di chuyển đồng thời và liên tục.
  • Đạn có thể va chạm ở độ lệch phân đoạn.
  • Nhiều viên đạn đồng thời đạt đến cùng một vị trí, cho dù ở độ lệch tích phân hoặc phân số so với gốc, tất cả đều va chạm với nhau.

Ví dụ

Trong các sơ đồ này, Gđại diện cho súng, >đạn và *là thời điểm đạn va chạm và phát nổ.

Sự thật

Đầu vào: 0

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

Đầu ra: 1


Đầu vào: 0 0 0

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

Đầu ra: 1


Đầu vào: 1

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

Đầu ra: 1


Đầu vào: 2 1

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

Đầu ra: 1


Đầu vào: 2 3 1

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

Đầu ra: 1


Giả

Đầu vào: 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

Đầu ra: 0


Đầu vào: 1 0 0 3

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

(Va chạm thứ hai là tại thời điểm 4.5)
Đầu ra:0


Đầu vào: 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

Đầu ra: 0


Đầu vào: 2 3 6

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

Đầu ra: 0


Tôi có thể yêu cầu đầu vào được phân định như thế 1<enter>2<enter>3...nào?
con mèo

@sysreq: Đó là đẩy nó, nhưng tôi sẽ cho phép nó.
El'endia Starman

Tôi đồng ý với qunitopia - thử thách này thật khó khăn, nhưng tôi đang nghiên cứu một giải pháp ...
zmerch

Câu trả lời:


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

Chúa ơi điều này rất lớn, nhưng tôi tin rằng nó thực sự hoạt động. Một khi bạn thấy tất cả những điều phức tạp của nó, thử thách này thật khó khăn.

Tôi không chắc liệu tôi có thể giải thích cách thức hoạt động chi tiết mà không cần nhập hàng giờ không, vì vậy tôi sẽ chỉ đưa ra một bản tóm tắt điều hành.

Vòng lặp chính lớn đang lặp cho đến khi danh sách đầu vào không co lại.

Vòng lặp lồng nhau (bạn có thể tin rằng vòng lặp lồng nhau thực sự là vòng lặp ngắn nhất ở đây không?) Trên mỗi tốc độ đạn và sử dụng numpy.rootsđể tính toán thời điểm viên đạn sẽ va chạm với mỗi viên đạn đi sau. Ở đây, ""đang được sử dụng để có nghĩa là vô cùng (không có giao lộ). Một điều kiện bổ sung phải được đưa vào để đảm bảo rằng các viên đạn đã dừng được đánh dấu là va chạm vào thời điểm chúng xuất hiện thay vì tại thời điểm 0.

Đối với mỗi số chúng tôi theo dõi viên đạn nào sẽ bắn sớm nhất, nếu có, và sau đó ođược cập nhật với thời gian va chạm tối thiểu cho các viên đạn liên quan.

Sau khi vòng lặp kép này kết thúc, chúng tôi lặp lại danh sách đầu vào và xóa bất kỳ dấu đầu dòng nào sẽ va chạm ở mức tối thiểu của tất cả các lần va chạm, nếu có. Điều này cho phép chúng tôi đồng thời xóa số lượng lớn đạn nếu tất cả chúng xảy ra va chạm cùng một lúc.

Sau đó, chúng tôi lặp lại toàn bộ quá trình trên các viên đạn còn lại, vì giờ đây chúng có thể có được những viên đạn mà chúng sẽ va chạm đã bị phá hủy.

Ngay khi không có viên đạn nào bị xóa (được chỉ định bởi danh sách không bị thu hẹp), chúng tôi thoát khỏi vòng lặp while và in độ dài của danh sách còn lại. Do đó, chương trình này không chỉ in sự thật nếu đạn tồn tại, nó thực sự in chính xác số lượng đạn còn tồn tại.

EDIT: Cảm ơn đặc biệt đến frageum vì đã tạo ra các trường hợp thử nghiệm để giúp tôi tìm ra lỗi.

EDIT 2: Đã lưu 42 byte bằng cách giải phương trình tuyến tính bằng tay thay vì sử dụng numpy và tách thời gian bắt đầu thành một danh sách riêng và cấu trúc lại một điều kiện.

EDIT 3: Đã lưu 4 byte bằng cách đổi tên phạm vi

EDIT 4: Đã lưu thêm 6 byte bằng cách thay thế khoảng trắng kép bằng các tab. Ngoài ra, frageum cũng tốt bụng khi cung cấp cho anh ta cách sử dụng phân số và bộ để so sánh. Tôi đã đánh gôn nó một chút và nó đạt tới 331 byte, buộc giải pháp của tôi.

EDIT 5: đã lưu 5 byte bằng cách xóa một khởi tạo không cần thiết và viết lại một điều kiện


Bạn đã không kiểm tra các ví dụ đầu vào một lần nữa? [1, 0, 0, 3] không hoạt động.
frageum

@feersum đó là người duy nhất tôi không thử nghiệm, thật nguy hiểm. nhưng cố định. VỚI TẤT CẢ HIỆU QUẢ NÀY TÔI TỐT HƠN MỘT LỜI NÓI. : P
quintopia

Vẫn không hoạt động. [1, 16, 18, 20, 30] sẽ quay lại 1.
facerum

OK nó dường như làm việc bây giờ, hầu hết thời gian ít nhất.
frageum
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.