Kiểm tra phân chia thiếu kiên nhẫn


14

Nhiệm vụ của bạn là viết một chương trình hoặc hàm xác định xem một số có chia hết cho một số khác hay không. Điều hấp dẫn là nó sẽ đưa ra câu trả lời càng sớm càng tốt , ngay cả khi không phải tất cả các chữ số của số đã được đưa ra.

Chương trình của bạn sẽ lấy một số nguyên D 2 và sau đó là một chuỗi các chữ số làm đầu vào. Chúng đại diện cho các chữ số của một số nguyên N 1 khác, bắt đầu từ chữ số có nghĩa nhỏ nhất. Tại thời điểm đầu tiên mà N hoặc phải hay không được divisble bởi D , chương trình của bạn nên đầu ra câu trả lời thích hợp và thoát. Nếu sự kết thúc của đầu vào được đạt tới, nó nên đầu ra cho dù toàn bộ N chia hết cho D .

Dưới đây là danh sách các định dạng đầu vào có thể chấp nhận cho N (để lại nhận xét nếu bạn nghĩ rằng cái gì đó không được bao gồm nên được cho phép):

  • Đầu vào tiêu chuẩn : chữ số được đưa ra trên các dòng riêng biệt; cuối của đầu vào là EOF hoặc một giá trị đặc biệt; thoát có nghĩa là hàm trả về hoặc chương trình thoát.

  • Đầu vào tương tự : thông qua các tổ hợp phím hoặc mười nút đại diện cho mỗi chữ số; cuối của đầu vào là một giá trị đặc biệt; thoát có nghĩa là hàm trả về hoặc chương trình thoát.

  • Hàm với trạng thái toàn cục : được gọi lặp lại với các chữ số liên tiếp; cuối của đầu vào là một giá trị đặc biệt; thoát có nghĩa là hàm trả về giá trị khác null. Lưu ý rằng nếu bạn sử dụng trạng thái toàn cục, nó phải bị xóa sau khi giá trị được trả về hoặc đặt lại để chức năng hoạt động nhiều lần .

  • Hàm Curried : trả về một hàm khác sẽ được gọi với chữ số tiếp theo hoặc một giá trị; cuối của đầu vào là một giá trị đặc biệt hoặc gọi hàm không có đối số; thoát có nghĩa là hàm trả về một câu trả lời thay vì một hàm khác.

  • GUI nhắc hoặc tương tự : hiển thị nhiều lần; kết thúc đầu vào là "hủy" hoặc tương đương, hoặc một giá trị đặc biệt; thoát có nghĩa là nhắc nhở dừng xuất hiện.

  • Hàm lặp : đầu vào là một đối tượng hoặc hàm trạng thái trả về chữ số tiếp theo khi được gọi, kết thúc đầu vào là một ngoại lệ hoặc giá trị đặc biệt; thoát có nghĩa là iterator dừng được gọi.

Đầu vào cho D và đầu ra có thể thông qua bất kỳ phương pháp tiêu chuẩn chấp nhận được .

Các trường hợp thử nghiệm:

2;   6               => true
5;   6               => false
20;  0 3             => false
20;  0 4             => true
100; 1               => false
100; 0 0             => true
100; 0 2             => false
4;   2 4             => false
4;   2 5             => true
4;   2 [eof]         => false
4;   4 [eof]         => true
625; 5 5             => false
625; 5 7 2           => false
625; 5 7 3 6         => false
625; 5 7 3 4         => true
7;   9 3 4 [eof]     => false
7;   9 3 4 5 [eof]   => true
140; 0 3             => false
140; 0 4 5 [eof]     => false
140; 0 4 5 1 [eof]   => true
14;  4 5 1 4 [eof]   => false
14;  4 5 1 4 1 [eof] => true

Tôi nghĩ rằng chúng ta nên cho rằng một chữ số sẽ được đưa ra mỗi khi giải pháp của chúng tôi yêu cầu đầu vào, phải không? Và, nó phải là một chương trình đầy đủ, vì đây là cách khách quan để đảm bảo rằng đầu vào được đưa ra từng chữ số, không? (Thử thách cho biết "chương trình hoặc chức năng", hmm ...)
Erik the Outgolfer

1
@EriktheOutgolfer Định dạng đầu vào được giải thích chi tiết trong danh sách gạch đầu dòng trong câu hỏi.
Doorknob

1
Tôi chỉ nghĩ về việc những định dạng đó có thể khách quan như thế nào ... Tôi đoán tôi sẽ bỏ nitpicking và bắt đầu thực sự giải quyết điều này . :-)
Erik the Outgolfer

1
Có gì sai khi chỉ lấy một danh sách làm digitsđầu vào có giá trị đặc biệt cho EOF?
Jonathan Allan

1
@EriktheOutgolfer không nếu có giá trị EOF, trừ khi tôi hiểu nhầm điều gì đó. Ví dụ giả sử toàn bộ giá trị là 132 và số chia tiềm năng là 4 sau đó [][2]trở lại bất cứ điều gì khác ngoài falsehoặc true(bao gồm các chức năng riêng của mình vv ...) trong khi [2,3], [2,3,1][2,3,1,EOF]trở lại true. Nó tấn công tôi gần với tùy chọn nhà nước toàn cầu.
Jonathan Allan

Câu trả lời:


9

JavaScript (ES6), 70 byte

Định dạng đầu vào: Hàm cong

Hàm lấy ước số và trả về hàm lấy mỗi chữ số hoặc cho EOF. Hàm thứ hai trả về 0 (sai), 1 (đúng) hoặc chính nó (không trả lời).101

p=>(q='',g=(d,t=k=z=!~d||(q=d+q,p))=>k--?g(d,t-=(k+q)%p<1):t?t-z&&g:1)

Hãy thử trực tuyến!

Làm sao?

Cho một ước số và cổ tức q bao gồm n chữ số thập phân, chúng tôi tính biểu thức sau cho tất cả 0 k < p :pqn0k<p

(1)k×10n+q(modp)

Đối với mọi tồn tại và sao cho , dẫn đến:xpm10k<px= =mp+k

x×10n+q(modp)= =(mp+k)×10n+q(modp)= =(mp×10n(modp))+(k×10n+q(modp))(modp)= =0+(k×10n+q(modp))(modp)= =k×10n+q(modp)

Do đó, nếu bằng với tất cả , thì nó cũng sẽ bằng cho mọi và câu trả lời là đúng .0 0 k < p 0 k p(1)00k<p0kp

Vì lý do tương tự, nếu lớn hơn với tất cả , câu trả lời là sai .0 0 k < p(1)00k<p

Nếu kết quả của là hỗn hợp, chúng tôi chưa thể quyết định và cần thêm chữ số của hoặc thông báo EOF.q(1)q

Đã bình luận

p => (                       // p = divisor
  q = '',                    // q = dividend stored as a string, initially empty
  g = (                      // g() = curried function taking:
    d,                       //   d = next digit
    t =                      //   t = number of iterations yielding a non-zero value
    k =                      //   k = total number of iterations to process
    z =                      //   z = copy of k
      !~d ||                 //   if d == -1 (meaning EOF), use only 1 iteration
                             //   so that we simply test the current value of q
      (q = d + q, p)         //   otherwise, prepend d to q and use p iterations
  ) =>                       //
    k-- ?                    //   decrement k; if it was not equal to zero:
      g(                     //     do a recursive call to g():
        d,                   //       pass the current value of d (will be ignored anyway)
        t -= (k + q) % p < 1 //       test (k + q) % p and update t accordingly
      )                      //     end of recursive call
    :                        //   else:
      t ?                    //     if t is greater than 0:
        t - z && g           //       return 0 if t == z, or g otherwise
      :                      //     else:
        1                    //       return 1
)                            //

2

Hàng loạt, 177 169 byte

@set n=
@set g=1
:l
@set/ps=
@if %s%==- goto g
@set n=%s%%n%
@set/ae=%1/g,g*=2-e%%2,g*=1+4*!(e%%5),r=n%%g
@if %g% neq %1 if %r%==0 goto l
:g
@cmd/cset/a!(n%%%1)

Lấy dlàm tham số dòng lệnh và đọc các chữ số ntrên các dòng riêng biệt với -dấu EOF. Đầu ra 1cho số chia, 0nếu không. Giải trình:

@set n=

Khởi tạo nchuỗi trống.

@set g=1

ggcd(d, 10**len(n))

:l

Bắt đầu một vòng lặp đọc chữ số.

@set/ps=

Đọc chữ số tiếp theo.

@if %s%==- goto g

Dừng xử lý tại EOF.

@set n=%s%%n%

Chuẩn bị chữ số tiếp theo để n.

@set/ae=%1/g,g*=2-e%%2,g*=1+4*!(e%%5),r=n%%g

Cập nhật gngay mà len(n)đã tăng và tính toán n%g.

@if %g% neq %1 if %r%==0 goto l

Nếu rkhác không thì dchắc chắn không phân chia n, bởi vì g, một yếu tố của d, không. Nếu rbằng 0 thì chúng ta chỉ biết có dchia nnếu gbằng d, vì vậy nếu không, tiếp tục vòng lặp.

:g

Thoát khỏi vòng lặp đọc chữ số ở đây trên EOF.

@cmd/cset/a!(n%%%1)

Tính toán và ngầm định kết quả.

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.