N Cửa, K Khỉ


13

Có N cửa và K khỉ. Ban đầu, tất cả các cửa đều đóng.

Vòng 1: Con khỉ thứ 1 ghé thăm mọi cánh cửa và bật cửa (nếu cánh cửa được đóng lại, nó sẽ được mở ra; nếu nó mở, nó sẽ bị đóng lại).

Vòng 2 : Con khỉ đầu tiên ghé thăm mọi cánh cửa và bật cửa. Sau đó, con khỉ thứ 2 ghé thăm mỗi cánh cửa thứ 2 và bật cửa.

. . .

. . .

Vòng k: Con khỉ thứ 1 ghé thăm mọi cánh cửa và bật cửa. . . . . . . . . . Con khỉ thứ k ghé thăm mọi cánh cửa thứ k và bật cửa.

Đầu vào: NK (cách nhau bởi một khoảng trắng)

Đầu ra: Số cửa được mở, mỗi số được phân tách bằng một khoảng trắng.

Ví dụ :

Đầu vào: 3 3

Đầu ra: 1 2

Các ràng buộc :

0 <N <101

0 <= K <= N

Lưu ý :

  • Giả sử cửa N được đánh số từ 1 đến N và khỉ K được đánh số từ 1 đến K

  • Người nào có mã ngắn nhất sẽ thắng. Ngoài ra, hiển thị đầu ra cho N = 23, K = 21


lấy cảm hứng từ câu đố này ?
làm lạnh toán học

Tôi chỉ có một câu hỏi, nếu N = K, mọi cửa số nguyên tố đều mở, phải không?
Fabinout

@Fabinout không n=k=3xuất ra 1 2nên bạn sai ... và 5 đầu ra 1 2 4có một mẫu nhưng rất ít rõ ràng.
làm lạnh toán học

@Fabinout nó tuân theo một kiểu số Fibonacci rất kỳ lạ, toán học trừu tượng rất tiên tiến của nó.
làm lạnh toán học

@tryingToGetProgrammingSt dán bạn đúng, ký ức của tôi cho tôi biết câu trả lời là danh sách các số nguyên tố, khi đó là danh sách các số vuông.
Fabinout

Câu trả lời:


14

APL, 32 28 26

{(2|+/(⍳⍺)∘.{+/0=⍺|⍨⍳⍵}⍳⍵)/⍳⍺}/⎕

⎕:
      23 21
 1 2 4 8 9 16 18 23 

Giải thích

  • {+/0=⍺|⍨⍳⍵}là một hàm trả về số lần cửa (đối số bên trái) được bật trên vòng (đối số bên phải), bằng với số lượng các yếu tố của đó là ≤ :

    • ⍳⍵ Tạo mảng số từ 1 đến

    • ⍺|⍨Tính mô-đun cho mỗi mục của mảng đó

    • 0= Thay đổi thành 1 trong đó có 0 và 0 cho mọi thứ khác

    • +/ Tính tổng mảng kết quả

  • Hàm ngoài:

    • (⍳⍺), ⍳⍵Tạo mảng từ 1 đến N và 1 đến K

    • ∘.{...}Đối với mỗi cặp phần tử của hai mảng, áp dụng hàm. Điều này đưa ra một ma trận số lần được bật, mỗi hàng đại diện cho một cánh cửa và mỗi cột đại diện cho một vòng.

    • +/Tính tổng các cột. Điều này đưa ra một loạt số lần mỗi cánh cửa được bật trên tất cả các vòng.

    • 2|Mô-đun 2, vì vậy nếu một cánh cửa đang mở, đó là 1; nếu nó đóng, nó là 0.

    • (...)/⍳⍺ Cuối cùng, tạo một mảng từ 1 đến N và chỉ chọn những mảng có 1 trong mảng ở bước trước.

  • /⎕ Cuối cùng, chèn chức năng giữa các số từ đầu vào.


BIÊN TẬP

{(2|+⌿0=(,↑⍳¨⍳⍵)∘.|⍳⍺)/⍳⍺}/⎕
  • ,↑⍳¨⍳⍵Tạo tất cả "khỉ" (Nếu K = 4, thì đây là 1 0 0 0 1 2 0 0 1 2 3 0 1 2 3 4)

    • ⍳⍵Mảng từ 1 đến (K)

    • ⍳¨ Đối với mỗi trong số đó, tạo mảng từ 1 đến số đó

    • ,↑Chuyển đổi mảng lồng nhau thành một ma trận ( ) và sau đó làm sáng tỏ thành một mảng đơn giản ( ,)

  • (,↑⍳¨⍳⍵)∘.|⍳⍺Đối với mỗi số từ 1 đến (N), hãy sửa đổi nó với mỗi con khỉ.

  • 0=Thay đổi thành 1 trong đó có 0 và 0 cho mọi thứ khác. Điều này đưa ra một ma trận của các toggles: Hàng là mỗi con khỉ trên mỗi vòng, các cột là cửa ra vào; 1 có nghĩa là chuyển đổi, 0 có nghĩa là không chuyển đổi.

  • +⌿ Tính tổng các hàng để có được một số lần mỗi cửa được bật

Các phần khác không được thay đổi


BIÊN TẬP

{(≠⌿0=(,↑⍳¨⍳⍵)∘.|⍳⍺)/⍳⍺}/⎕

Sử dụng XOR less ( ≠⌿) thay vì sum và mod 2 ( 2|+⌿)


APL có được thiết kế cho kịch bản golf không? ;-)
celtschk

@celtschk Vâng, một phần, theo một cách nào đó. Nó được thiết kế để thể hiện các thuật toán chính xác.
kẻ lừa đảo người lái xe

Tại sao bạn sử dụng giảm dfn {}/thay vì chỉ lấy N và K làm đối số cho dfn?
Adám

@ Adám Bởi vì 1) đây là quá khứ của tôi; 2) câu hỏi này có trước "tiêu chuẩn hóa chương trình hoặc chức năng" và I / O; 3) OP đặc biệt nói "cách nhau bởi một khoảng trống"
TwiNight

Đủ công bằng, nhưng ít nhất bạn có thể lưu một byte bằngi←⍳⍺
Adám

4

GolfScript, 33 ký tự

~:k;),1>{0\{1$)%!k@-&^}+k,/}," "*

Nếu các cửa được đánh số bắt đầu bằng 0, nó sẽ lưu 3 ký tự.

Ví dụ ( trực tuyến ):

> 3 3
1 2

> 23 21
1 2 4 8 9 16 18 23

3

Toán học, 104 ký tự

{n,k}=FromDigits/@StringSplit@InputString[];Select[Range@n,OddQ@DivisorSum[#,If[#>k,0,k+1-#]&]&]~Row~" "

Thí dụ:

Trong [1]: = {n, k} = FromDigits / @ StringSplit @ InputString []; Chọn [Range @ n, OddQ @ DivisorSum [#, If [#> k, 0, k + 1 - #] &] & ] ~ Hàng ~ ""

? 23 21

Hết [1] = 1 2 4 8 9 16 18 23


1
Bạn có thể loại bỏ 15 ký tự khác để phân tích cú pháp đầu vào bằng cách giả sử một luồng đầu vào, ví dụ : {n,k}=%~Read~{Number,Number}.
Marcks Thomas

3

Ruby, 88

Dựa trên câu trả lời của @ manatwork.

gets;~/ /
$><<(1..$`.to_i).select{|d|(1..k=$'.to_i).count{|m|d%m<1&&(k-m+1)%2>0}%2>0}*$&

Những quả cầu tinh ranh luôn phá vỡ cú pháp nổi bật!


Xin lỗi, nhưng 90 ký tự ( phiên bản 2 ) và 86 ký tự ( phiên bản 3 ) dường như có lỗi: một số mới, 22, xuất hiện trong kết quả của họ.
thao tác

@manatwork cuộc gọi tốt, tôi nghĩ rằng tôi đã sửa nó bây giờ với chi phí của hai nhân vật. Tôi cảm thấy như countbit đó có thể được cải thiện hơn nữa, tôi ước ruby ​​có một #sumphương thức được xây dựng cho những thứ như thế:>
Paul Prestidge

Ồ Thực sự ấn tượng.
manatwork

3

Con trăn 3 97 84

Nếu một con khỉ xuất hiện trong một số vòng chẵn, điều đó không thay đổi chút nào. Nếu một con khỉ xuất hiện trong một số lần chẵn, điều đó giống như trong một vòng chính xác.

Do đó, một số con khỉ có thể bị bỏ lại, và những con khác chỉ cần chuyển cửa một lần.

N,K=map(int,input().split())
r=set()
while K>0:r^=set(range(K,N+1,K));K-=2
print(*r)

Đầu ra cho 23 21:

1 2 4 8 9 16 18 23

Sử dụng thông minh các hoạt động thiết lập! Tôi nghĩ rằng bạn có thể rút ngắn range(2-K%2,K+1,2)tới range(K,0,-2).
xnor

Hoặc tốt hơn nữa, thay thế forvòng lặp bằng một whilevòng lặp:while K>0:r^=set(range(K,N+1,K));K-=2
xnor

@xnor: cảm ơn, thật tuyệt!
Phục hồi Monica

2

R - 74

x=scan(n=2);cat(which(colSums((!sapply(1:x[1],`%%`,1:x[2]))*x[2]:1)%%2>0))

Mô phỏng:

> x=scan(n=2);cat(which(colSums((!sapply(1:x[1],`%%`,1:x[2]))*x[2]:1)%%2>0))
1: 23 21
Read 2 items
1 2 4 8 9 16 18 23

2

javascript 148 127

function e(n,k){b=array(n);d=[];function a(c){for(i=0;i<n;i+=c)b[i]=!b[i];c<k&&a(c+1)}a(1);for(i in b)b[i]&&d.push(i);return d}

đây là một phiên bản (bit nhỏ) có thể đọc được:

function e(n, k) {     //define N and K
     b = array(n); //declare all doors as closed
     d = [];     //create array later used to print results

     function a(c) {   //(recursive) function that does all the work
         for (i = 0; i < n; i += c)  //increment by c until you reach N and...
              b[i] = !b[i];  //toggle said doors
         c < k && a(c + 1)  //until you reach k, repeat with a new C (next monkey)
     }
     a(1); //start up A

     for (i in b) b[i] && d.push(i); //convert doors to a list of numbers
     return d //NO, i refuse to explain this....
}   //closes function to avoid annoying errors

DEMO fiddle

tôi nên lưu ý rằng nó bắt đầu đếm từ 0 (về mặt kỹ thuật là lỗi do lỗi một)


Bạn có thể xóa dòng thứ 3 nếu thay đổi dòng thứ 2 thành b=Array(n);Điều này sẽ khởi tạo mảng của bạn dưới dạng n chiều dài không xác định. ! không xác định là đúng, vì vậy con khỉ đầu tiên sẽ biến tất cả thành dấu vết.
path411

@ path411 cảm ơn bạn rất nhiều! Tôi ngạc nhiên tôi quên cách làm việc khai báo mảng "thích hợp"! bạn có thể cảm thấy thoải mái+1
làm lạnh toán học

Hấp dẫn. Có vẻ như bạn là người duy nhất tôi từng thấy cho đến nay dường như nhận được câu trả lời tương tự như của tôi cho N = 23, K = 21. Sự khác biệt duy nhất là vấn đề
ngoài lề

Tìm ra những gì sai với tôi, và điều này có cùng một vấn đề. Đối với mỗi vòng, bạn chỉ gửi một con khỉ qua tất cả các cửa. Tuy nhiên, theo thông số kỹ thuật của thử thách, cần có những con khỉ $ i chạy qua mỗi vòng - trong đó $ i là số vòng bạn đang tham gia.
Iszi

2

JavaScript, 153

(function(g){o=[],f=g[0];for(;i<g[1];i++)for(n=0;n<=i;n++)for(_=n;_<f;_+=n+1)o[_]=!o[_];for(;f--;)o[f]&&(l=f+1+s+l);alert(l)})(prompt().split(i=l=s=' '))

Đầu ra cho N = 23, K = 21:

1 2 4 8 9 16 18 23  

Đã thử nghiệm trong Chrome, nhưng không sử dụng bất kỳ tính năng ECMAScript mới nào nên sẽ hoạt động trong mọi trình duyệt!

Tôi biết tôi sẽ không bao giờ giành chiến thắng trước các mục khác và @tryingToGetProgrammingStrainght đã gửi một mục trong JavaScript, nhưng tôi không nhận được kết quả tương tự cho N = 23, K = 21 vì mọi người khác đều nhận được điều đó nên tôi nghĩ tôi Tôi muốn có một phiên bản của riêng tôi.

Chỉnh sửa : nguồn chú thích (khi xem lại cái này, tôi phát hiện ra các địa điểm để lưu thêm 3 ký tự, vì vậy nó có thể được cải thiện vẫn còn ...)

(function(g) {
    // initialise variables, set f to N
    o = [], f = g[0];

    // round counter
    // since ++' ' == 1 we can use the same variable set in args
    for (; i < g[1]; i++)
        // monkey counter, needs to be reset each round
        for (n = 0 ; n <= i; n++)
            // iterate to N and flip each Kth door
            for (_ = n; _ < f; _ += n + 1)
                // flip the bits (as undef is falsy, we don't need to initialise)
                // o[_] = !~~o[_]|0; // flips undef to 1
                o[_] = !o[_]; // but booleans are fine
    // decrement f to 0, so we don't need an additional counter
    for (;f--;)
        // build string in reverse order
        o[f] && (l = f + 1 + s + l); // l = (f + 1) + ' ' + l
    alert(l)
    // return l // use with test
// get input from user and store ' ' in variable for use later
})(prompt().split(i = l = s = ' '))
// })('23 21'.split(i = l = s = ' ')) // lazy...

// == '1 2 4 8 9 16 18 23  '; // test

làm tốt lắm! nếu bạn cũng sẽ cung cấp một phiên bản có thể đọc và nhận xét, tôi có thể sẽ+1
làm lạnh toán học

Trả lời cập nhật! Vì tôi không thể nhận xét về câu trả lời của bạn, để thêm vào nhận xét của @ path411, bạn có thể đặt b = [] và các chỉ mục trống vẫn chưa được xác định và điều đó giúp bạn tiết kiệm thêm 6 ký tự!
Dom Hastings

tôi đã làm điều đó rồi ....
làm lạnh toán học

1

Ruby - 65 ký tự

(1..n).each{|d|
t=0
(1..k).each{|m|t+=n-m+1 if d%m==0}
p d if t%2>0}

n = 23, k = 21 # => 1 2 4 8 9 16 18 23 

Đây là phép tính, trong mã giả:

  • Gọi s (d) là số lần cửa d được chạm sau k vòng.
  • s (d) = tổng (m = 1..m = k) (d% m == 0? (n-m + 1): 0)
  • cửa d mở sau k vòng nếu s (d)% 2 = 1 (hoặc> 0)

Nếu bạn không tin rằng biểu thức cho s (d) là chính xác, hãy nhìn nó theo cách này:

  • Gọi s (d, r) là số lần cửa d được chạm sau vòng r.
  • s (d, k) - s (d, k-1) = tổng (m = 1, .., m = k) (d% m == 0? 1: 0)
  • s (d, k-1) - s (d, k-2) = tổng (m = 1, .., m = (k-1)) (d% m == 0? 1: 0)
  • ...
  • s (d, 2) - s (d, 1) = d% 2 == 0? 1: 0
  • s (d, 1) = 1
  • tổng cả hai vế để có được biểu thức trên cho s (d), bằng s (d, k)

Rất súc tích! Nơi làm nkđến từ đâu? Và đầu ra dường như được phân tách bằng các dòng mới hơn là khoảng trắng.
Paul Prestidge

1

PowerShell: 132

Mã đánh gôn:

$n,$k=(read-host)-split' ';0|sv($d=1..$n);1..$k|%{1..$_|%{$m=$_;$d|?{!($_%$m)}|%{sv $_ (!(gv $_ -Va))}}};($d|?{(gv $_ -Va)})-join' '

Un-Golfed, Mã nhận xét:

# Get number of doors and monkeys from user as space-delimited string.
# Store number of doors as $n, number of monkeys as $k.
$n,$k=(read-host)-split' ';

# Store a list of doors in $d.
# Create each door as a variable set to zero.
0|sv($d=1..$n);

# Begin a loop for each round.
1..$k|%{

    # Begin a loop for each monkey in the current round.
    1..$_|%{

        # Store the current monkey's ID in $m.
        $m=$_;

        # Select only the doors which are evenly divisible by $m.
        # Pass the doors to a loop.
        $d|?{!($_%$m)}|%{

            # Toggle the selected doors.
            sv $_ (!(gv $_ -Va))
        }
    }
};

# Select the currently open doors.
# Output them as a space-delimited string.
($d|?{(gv $_ -Va)})-join' '

# Variables cleanup - don't include in golfed code.
$d|%{rv $_};rv n;rv d;rv k;rv m;

# NOTE TO SELF - Output for N=23 K=21 should be:
# 1 2 4 8 9 16 18 23

Ồ, tôi thấy vấn đề của tôi là gì. Tôi đã hiểu nhầm câu hỏi - đây không phải là vấn đề 100 Lockers. Đó là, đưa lên một notch! Điều này sẽ đòi hỏi một chút công việc hơn ...
Iszi

1
Ngọt! Việc sửa nó để đáp ứng các yêu cầu thách thức đúng cách chỉ thu được 6 ký tự cuối cùng.
Iszi

0

Powershell, 66 byte

Dựa trên câu trả lời của Cary Swoveland .

param($n,$k)1..$n|?{$d=$_
(1..$k|?{($n-$_+1)*!($d%$_)%2}).Count%2}

Kịch bản thử nghiệm:

$f = {

param($n,$k)1..$n|?{$d=$_
(1..$k|?{($n-$_+1)*!($d%$_)%2}).Count%2}

}

@(
    ,(3, 3   , 1,2)
    ,(23, 21 , 1, 2, 4, 8, 9, 16, 18, 23)
) | % {
    $n,$k,$expected = $_
    $result = &$f $n $k
    "$("$result"-eq"$expected"): $result"
}

Đầu ra:

True: 1 2
True: 1 2 4 8 9 16 18 23
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.