N 문, K 원숭이


14

N 문과 K 원숭이가 있습니다. 처음에는 모든 문이 닫힙니다.

1 라운드 : 첫 번째 원숭이가 모든 문을 방문하고 문을 토글합니다 (문이 닫히면 문이 열리고 열리면 닫힙니다).

라운드 2 : 첫 번째 원숭이가 모든 문을 방문하고 문을 토글합니다. 그런 다음 두 번째 원숭이는 두 번째 문마다 방문하여 문을 토글합니다.

. . .

. . .

k 라운드 : 첫 번째 원숭이가 모든 문을 방문하고 문을 토글합니다. . . . . . . . . . k 번째 원숭이는 모든 k 번째 문을 방문하여 문을 토글합니다.

입력 : NK (단일 공백으로 구분)

출력 : 문 번호가 열려 있으며 각각 단일 공간으로 구분됩니다.

:

입력 : 3 3

출력 : 1 2

제약 사항 :

0 <N <101

0 <= K <= N

참고 :

  • N 문은 1부터 N까지, K 원숭이는 1부터 K까지라고 가정합니다.

  • 가장 짧은 코드를 가진 사람이 승리합니다. 또한 N = 23, K = 21에 대한 디스플레이 출력



N = K 인 경우 모든 소수 문이 열려 있습니까?
Fabinout

@ Fabinout n=k=31 2잘못 출력 하지 않을 것입니다 ... 5 출력 1 2 4에는 패턴이 있지만 그보다 덜 분명합니다.
Math chiller

@ Fabinout 그것은 피보나치 숫자 세트의 매우 이상한 유형, 매우 진보 된 추상 수학을 따릅니다.
Math chiller

@tryingToGetProgramming 당신이 옳은대로, 내 기억은 대답이 소수의 목록 일 때 소수의 목록이라고 대답했습니다.
Fabinout

답변:


14

APL, 32 28 26

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

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

설명

  • {+/0=⍺|⍨⍳⍵}(왼쪽 인수)이 라운드 (오른쪽 인수)로 전환 된 횟수를 반환하는 함수입니다. 이 계수의 수는 ≤입니다 .

    • ⍳⍵ 1에서 1까지의 숫자 형 배열 생성

    • ⍺|⍨해당 배열의 모든 항목마다 계수 계산

    • 0= 0이있는 1로 변경하고 다른 모든 것에는 0으로 변경하십시오.

    • +/ 결과 배열 합

  • 외부 기능 :

    • (⍳⍺), ⍳⍵1에서 N, 1에서 K까지 배열 생성

    • ∘.{...}두 배열의 모든 요소 쌍에 대해 함수를 적용하십시오. 이것은 토글 된 횟수의 행렬을 제공하며, 각 행은 문을 나타내고 각 열은 라운드를 나타냅니다.

    • +/열을 합산하십시오. 이것은 각 문이 모든 라운드에서 토글되는 횟수의 배열을 제공합니다.

    • 2|모듈러스 2이므로 문이 열려 있으면 1입니다. 닫혀 있으면 0입니다.

    • (...)/⍳⍺ 마지막으로 1에서 N까지 배열을 생성하고 이전 단계에서 배열에 1이있는 배열 만 선택하십시오.

  • /⎕ 마지막으로 입력 숫자 사이에 함수를 삽입하십시오.


편집하다

{(2|+⌿0=(,↑⍳¨⍳⍵)∘.|⍳⍺)/⍳⍺}/⎕
  • ,↑⍳¨⍳⍵모든 "원숭이"를 생성하십시오 (K = 4 인 경우 1 0 0 0 1 2 0 0 1 2 3 0 1 2 3 4)

    • ⍳⍵1에서 (K) 까지 배열

    • ⍳¨ 각각에 대해 1에서 해당 숫자까지 배열을 생성하십시오.

    • ,↑중첩 배열을 행렬 ( ) 로 변환 한 다음 간단한 배열 ( ,) 로 분해

  • (,↑⍳¨⍳⍵)∘.|⍳⍺1에서 (N) 까지의 각 숫자 에 대해 각 원숭이로 수정하십시오.

  • 0=0이있는 1로 변경하고 다른 것은 0으로 변경하십시오. 이것은 토글 매트릭스를 제공합니다. 행은 각 라운드마다 원숭이이고, 열은 문입니다. 1은 토글을 의미하고 0은 토글이 없음을 의미합니다.

  • +⌿ 각 문이 토글 된 횟수의 배열을 얻기 위해 행을 합산

다른 부분은 변경되지 않습니다


편집하다

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

≠⌿sum 대신 mod 2 ( 2|+⌿) 대신 XOR reduce ( )를 사용하십시오.


APL은 골프 스크립트 용으로 설계 되었습니까? ;-)
celtschk 2018 년

@celtschk 그렇습니다. 알고리즘을 간결하게 표현하도록 설계되었습니다.
luser droog

{}/N과 K를 dfn의 인수로 사용하는 대신 dfn 축소를 사용 합니까?
Adám

@ Adám 1) 이것은 과거입니다. 2)이 질문은 "프로그램 또는 기능"및 I / O 표준화보다 우선합니다. 3) OP는 구체적으로 "단일 공간으로
분리됨

충분히 i←⍳⍺
공평

4

GolfScript, 33 자

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

문이 0부터 시작하여 번호가 매겨지면 3자를 저장합니다.

예 ( 온라인 ) :

> 3 3
1 2

> 23 21
1 2 4 8 9 16 18 23

3

매스 매 티카, 104 자

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

예:

In [1] : = {n, k} = FromDigits / @ StringSplit @ InputString []; 선택 [Range @ n, OddQ @ DivisorSum [#, If [#> k, 0, k + 1-#] &] & ] ~ 행 ~ ""

? 23 21

아웃 [1] = 12 8 9 16 18 23


1
입력 스트림을 가정하여 입력을 구문 분석하는 데 15자를 추가로 사용할 수 있습니다 (예 :) {n,k}=%~Read~{Number,Number}.
Marcks Thomas

3

루비, 88

@manatwork의 답변을 기반으로합니다.

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

이러한 닷지 글로벌은 항상 구문 강조를 중단합니다!


죄송합니다. 90 자 ( 개정 2 )와 86 자 ( 개정 3 )는 버그가있는 것 같습니다. 22 개가 새로운 결과로 나타났습니다.
manatwork

@manatwork good call, 나는 지금 두 글자의 비용으로 그것을 고쳤다 고 생각한다. 나는 그 count비트가 더 향상 될 수 있다고 생각합니다. 루비가 다음 #sum과 같은 것들을 위해 내장 된 방법을 원했습니다 :>
Paul Prestidge

와! 정말 감동했습니다.
manatwork

3

파이썬 3, 97 84

원숭이가 짝수의 라운드에 나타나면 아무런 변화가 없습니다. 원숭이가 짝수 번 나타나는 경우 정확히 한 라운드와 동일합니다.

따라서 일부 원숭이를 제외하고 다른 원숭이는 문을 한 번만 전환하면됩니다.

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

에 대한 출력 23 21:

1 2 4 8 9 16 18 23

세트 작업의 영리한 사용! 나는 당신이 단축 될 수 있습니다 생각 range(2-K%2,K+1,2)range(K,0,-2).
xnor

또는 for루프를 루프로 교체하십시오 while.while K>0:r^=set(range(K,N+1,K));K-=2
xnor

@ xnor : 고마워요!
복원 Monica Monica

2

제 74 화

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

시뮬레이션:

> 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

스크립트 (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}

다음은 (작은 비트) 읽을 수있는 버전입니다.

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

데모 바이올린

나는 0부터 계산하기 시작한다는 것을 명심해야한다 (기술적으로는 한 번에 하나의 오류)


두 번째 줄을 b=Array(n);This로 변경하면 세 번째 줄을 제거 할 수 있습니다. 이는 배열을 n 길이로 정의되지 않은 채로 초기화합니다. ! undefined는 true이므로 첫 번째 원숭이 패스가 모두 true로 바뀝니다.
path411

@ path411 감사합니다! 나는 "적절한"배열 선언이 어떻게 작동하는지 잊어 버렸다는 것에 놀랐다! 당신은 자유롭게 느낄 수 있습니다+1
Math chiller

흥미 롭군 지금까지 본 것 중 하나는 N = 23, K = 21에 대한 것과 비슷한 답변을 얻는 것으로 보입니다. 유일한 차이점은 0을 포함하고 23을 제외하는 비
독점

내 문제가 무엇인지 알아 내면 같은 문제가 있습니다. 각 라운드마다, 당신은 모든 문을 통해 하나의 원숭이를 보내고 있습니다. 그러나 챌린지 사양에 따라 각 라운드마다 $ i 원숭이가 있어야합니다. 여기서 $ i는 현재 라운드 수입니다.
Iszi

2

자바 스크립트, 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=' '))

N = 23, K = 21에 대한 출력 :

1 2 4 8 9 16 18 23  

Chrome에서 테스트되었지만 멋진 새로운 ECMAScript 기능을 사용하지 않으므로 모든 브라우저에서 작동합니다!

나는 다른 항목에 대해 결코 이길 수 없다는 것을 알고 있으며 @tryingToGetProgrammingStrainght는 이미 JavaScript로 항목을 제출했지만 다른 모든 사람들과 함께 N = 23, K = 21에 대해 동일한 결과를 얻지 못했기 때문에 생각했습니다. 내 자신의 버전으로 이동합니다.

편집 : 주석이 달린 소스 (이 부분을 다시 살펴보면 다른 3자를 저장할 장소를 발견 했으므로 여전히 향상 될 수 있습니다 ...)

(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

잘 했어! 당신은 또한 아마 것 읽을 수 및 주석 버전을 제공 할 경우+1
수학 냉각기

답변이 업데이트되었습니다! 귀하의 답변에 대해서는 언급 할 수 없으므로 @ path411의 의견에 추가하기 위해 b = []를 설정할 수 있으며 빈 색인은 여전히 ​​정의되지 않았으므로 다른 6 문자가 절약됩니다!
Dom Hastings

나는 이미 그것을 ....
수학 냉각기

1

루비-65 자

(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 

다음은 의사 코드의 계산입니다.

  • s (d)를 k 라운드 후 문 d가 터치 된 횟수로 둡니다.
  • s (d) = 합 (m = 1..m = k) (d % m == 0? (n-m + 1) : 0)
  • s (d) % 2 = 1 (또는> 0) 인 경우 k 라운드 후 문 d가 열립니다.

s (d)에 대한 표현식이 올바른지 확신 할 수 없으면 다음과 같이보십시오.

  • s (d, r)은 r 라운드 후 문 d에 닿은 횟수가되도록합니다.
  • s (d, k)-s (d, k-1) = 합 (m = 1, .., m = k) (d % m == 0? 1 : 0)
  • s (d, k-1)-s (d, k-2) = 합 (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
  • s (d, k)와 동일한 s (d)에 대한 위의 표현식을 구하려면 양변을 합산하십시오.

매우 간결합니다! 어디에서 수행 n하고 k있지만, 출신? 그리고 출력은 공백이 아닌 줄 바꿈으로 분리 된 것으로 보입니다.
Paul Prestidge

1

PowerShell : 132

골프 코드 :

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

언 골프, 주석 처리 된 코드 :

# 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

아, 내 문제가 무엇인지 알 수 있습니다. 나는 질문을 오해했다-이것은 100 Lockers 문제 가 아니다 . 그것은 한 단계 올라 갔다! 이 ... 조금 더 많은 작업이 필요합니다
Iszi

1
단! 챌린지 요구 사항을 제대로 충족하도록 수정하면 결국 6 자만 얻을 수있었습니다.
Iszi

0

파워 쉘, 66 바이트

Cary Swoveland의 답변을 기반으로 합니다.

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

테스트 스크립트 :

$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"
}

산출:

True: 1 2
True: 1 2 4 8 9 16 18 23
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.