세 가지 입력에 대한 요세푸스 문제


22

이 사이트 에이 질문과 유사한 질문이 있지만, 나는 약간의 왜곡을가했습니다.

서클 n 의 인원 수 , 각 단계에서 계산 된 k 번째 사람 및 생존 한 q 번째 사람의 세 가지 입력이 있습니다 . 서클의 사람들은 1부터 n 까지 번호가 매겨집니다 .

예를 들어, 20 명으로 구성된 서클에서 20 번째 생존자는 첫 번째 제거 된 사람이고 19 번째 생존자는 두 번째 제거 된 사람입니다. 일반적으로, 요세푸스의 문제가 결정하는 것입니다 마지막으로 여기라고 사람이 제거 된 첫번째 생존자.

그 3 개 개의 입력과 함께의 수를 반환, 가장 짧은 프로그램이나 기능을 쓰기 Q 살아 남기 위해 번째 사람.

명확성에 문제가 있으면 알려주세요.

몇 가지 예 :

>>> josephus(20, 3, 9)
4
>>> josephus(4, 3, 1)
1
>>> josephus(100, 9, 12)
46

편집 : 모든 입력이 유효하다고 가정합니다. 즉, 아무도 0 또는 음수를 요구하지 않으며 5 명 서클에서 20 번째 생존자를 요구하지 않습니다 (즉, 1 ≤ q ≤ n).

편집 : 12 월 2 일 시작 UTC + 7 자정에 답변을 수락합니다.


1
질문에 솔루션을 포함시키는 대신 답변으로 자신의 솔루션을 게시하십시오.
손잡이

알았다. 죄송합니다
Sherlock9

1
명확히하기 위해 q=1이것이 연결된 요세푸스 질문과 정확히 동일 하다면 ?
AdmBorkBork

@TimmyD 정확히
Sherlock9

답변:


5

Pyth, 16 바이트

eu.<PGvzh-QvwShQ

온라인으로 사용해보십시오 : 데모 또는 테스트 스위트

입력 형식은입니다 k<newline>n<newline>q.

설명:

eu.<PGvzh-QvwShQ   implicit: z = first input line (string)
                             Q = second input line (integer)
              hQ   Q + 1
             S     the range [1, 2, ..., Q+1]
 u      h-Qvw      apply the following statement (Q-input()+1) times to G=^
    PG                remove the last number of G
  .<  vz              and rotate eval(z) to the left
e                  print the last number of the resulting list  

7

피에트, 280 273 codels

여기에 이미지 설명을 입력하십시오

편집 : 나는 이것을 더 아래로 골라 내었고, 나는 그것을 더 아래로 내릴 수 있다고 생각하지만, 앞으로 나올 것입니다. 지금은 그것이 작동하는 것이 기쁘고 왼쪽 하단에 서명 할 공간이있어서 기쁩니다. 더 많은 코덱을 저장 해야하는 두 가지 아이디어는 a) 끝 명령을 변경하려면 pop, push 1, add, out num(pop n, 출력 r + 1) b) 왼쪽 하단 모서리에서 다시 복제하여 루프에서 나중에 스택 조작으로 코덱을 저장하는 것입니다.

위의 그림은 코덱 당 8 픽셀의 코드입니다. 일반적으로 파이썬 답변과 동일한 알고리즘이지만 k , q , n 순서의 입력이 있습니다. 실제로, 많은 스택 조작이 있습니다. 이미지를 열고 코드를 실행하여 여기에서 시도해 볼 수 있습니다 .

설명

솔루션의 단계별 풀기입니다.

in num    get k
dup       Stack: k k
push 1
subtract  Stack: k k-1
in num    get q
dup       Stack: k k-1 q q
dup       Stack: k k-1 q q q
push 4
push 2
roll      Stack: k q q k-1 q
mod       Stack: k q q r
in num    get n
# note: the loop will return to the following codel
dup       Stack: k q q r n n
push 4
push 3
roll      Stack: k q r n n q
greater   1 or 0
pointer   Here the loop begins. If q>n, the pointer moves clockwise.
          Else, it points straight ahead

LOOP:     Stack: k i r n (i=q at the start of the loop)
push 4
push 2
roll      Stack: r n k i
push 1
add       Stack: r n k i=i+1
push 2
push 1
roll      Stack: r n i k
dup       Stack: r n i k k
push 5
push 4
roll      Stack: n i k k r
add       Stack: n i k m=r+k
push 3
push 2
roll      Stack: n k m i
dup       Stack: n k m i i
push 3
# here it turns the corner
push 1
roll      Stack: n k i m i
mod       Stack: n k i r=m%i
push 4
# here it turns the corner and avoids the black codels
push 1
roll      Stack: r n k i
dup       Stack: r n k i i
push 5
push 3
roll      Stack: k i i r n
dup       Stack: k i i r n n
# and we meet up with the dark green codel once more
push 4
push 3
roll      Stack: k i r n n i
greater   Stack: k i r n (0 or 1)
pointer   if else again

# else    Stack: k i r n
push 2    
push 1
roll      Stack: k i n r
# and turn the corner
push 1
add       Stack: k i n r+1
out num   print r+1
# turn the corner into the end pattern (the shape with the black edges)
END

빈 공간을 세지 않습니까? Piet의 점수를 매기는 방법에 대한 메타 게시물이 있습니까? 아마도 있어야 할 것입니다.
Sparr

@Sparr, 나는 빈 공간을 세고 있습니다. 그것은 21 코덱 x 13 코덱 이미지이므로 점수는 273 코덱입니다.
Sherlock9

아, 나는 잘못 계산했다. 죄송합니다.
Sparr

4

CJam, 22 20 19 바이트

q~_,@a@*{m<)\}%\~=)

입력을로 읽습니다 q k n. CJam 통역사 에서 온라인으로 사용해보십시오 .

작동 원리

q~                   Read and evaluate all input. This pushes q, k, and n.
  _,                 Push A := [0 ... n-1].
    @a               Rotate on top of the stack and wrap it in an array.
      @*             Rotate the original n on top and repeat [k] n times.
        {    }%      For each of the n k's:
         m<            Rotate A k units to the left.
           )\          Pop the last element and swap it with A.
               \~    Swap the resulting array with q and apply bitwise NOT.
                 =)  Select the corresponding element and add 1 to it.

3

골프 스크립트, 58 56 55 35 31 30 바이트

3 개의 입력이 이미 스택에 있다고 가정하면 n , k , q 순서로

~1$(1$%3$),@),-{\2$+\%}%\)])\;

이 솔루션은 최종 답변 이외의 모든 것을 제거해야한다고 가정합니다.

작동 원리

자세한 내용 j(n,k,q)은 Python 3 솔루션을 참조하십시오 .

~                                   Read the inputs n, k, q
 1$(                                Duplicate k, decrement
    1$                              Duplicate q
      %                             (k-1)%q
       3$),                         Create array [0..n+1]
           @),                      Create array [0..q+1]
              -                     Subtract the second array from the first,
                                        leaving only [q+1..n+1]
               {      }%            Map the following statement onto [q+1..n+1].
                                        The numbers from this array will be denoted i.
                \                   Swap i and r
                 2$+                Duplicate k, add to r
                    \               Swap r and i
                     %              r mod i
                        \)          Swap the leftover array from map with r, increment
                          ]         Put the whole stack into an array
                           )        Remove the last member of the array, r
                            \;      Pop the array, leaving only the result

편집 1 : @Doorknob의 제안 사용 (모든 입력을 배열로 가져 오기 위해 + 추가)

전에,

\.(2$2$*1$4$%-{.5$3$*>!}{~)2$*1$/~)}while 4$3$*\-)\;\;\;\;

편집 2 : 위키의 규칙에 따라 ~를 추가하고 코드를 줄였습니다. 감사합니다 @Dennis

전에,

[\.(2$2$*1$4$%-{.5$3$*>!}{~)2$*1$/~)}while 4$3$*\-)]+)\;

편집 3 : 더 짧은 알고리즘을 구현했습니다.

전에,

~\.(2$2$*1$4$%-{.5$3$*>!}{~)2$*1$/~)}while 4$3$*\-)]-1=

편집 4 : 내가 사용할 수 있다는 것을 알았습니다.% 지도로 .

전에,

~1$(1$%{1$4$<}{\)\2$+1$%}while)])\;

편집 5 : 사소한 편집. 변경 2$@만드는 [0..q-1]하고 3$하는 2$검색 할k . 물린 저장

전에,

~1$(1$%3$),2$),-{\3$+\%}%\)])\;

1
\;\;\;\;])\;(배열로 포장, 오른쪽 ununcons, 스왑 및 팝) 으로 대체 할 수 있습니다 .
손잡이

명확성을 위해 @Dennis 코드를 편집했습니다.
Sherlock9

좋아 @ 데니스. ~를 추가하고 프로그램과 기능 만 허용하도록 질문을 편집했습니다. 다른 제안이 있습니까?
Sherlock9

아냐 :)
Dennis

2

자바 스크립트 (ES6), 56 바이트

(n,k,q)=>{r=(k-1)%q;for(i=q;i<n;r=(r+k)%++i);return r+1}

언 골프

기본적으로 @ Sherlock9 의 Python 답변에 대한 JavaScript 적응 .

(n,k,q)=>{
  r=(k-1)%q;
  for(i=q;i<n;r=(r+k)%++i);
  return r+1
}

테스트

n = <input type="number" id="N" value="100" /><br />
k = <input type="number" id="K" value="9" /><br />
q = <input type="number" id="Q" value="12" /><br />
<button onclick="result.innerHTML=(

(n,k,q)=>{r=(k-1)%q;for(i=q;i<n;r=(r+k)%++i);return r+1}

)(+N.value,+K.value,+Q.value)">Go</button><br />
<pre id="result"></pre>


나는 당신의 ungolfed 버전을 ungolfed라고 부르지 않을 것입니다 : P
Fund Monica의 소송

1

수학, 50 바이트

<<Combinatorica`
Tr@Position[Josephus@##2,1+#2-#]&

익명의 기능. 순서대로 입력을 q,n,k받습니다.


1

C, 81 73 바이트

@ user81655 기반으로내 파이썬 답변의 Javascript 구현을 .

편집 : 제거 i

int j(int n,int k,int q){int r=(k-1)%q;for(;q<n;r=(r+k)%++q);return r+1;}

테스트

#include <stdio.h>
int j(int n,int k,int q){int r=(k-1)%q;for(;q<n;r=(r+k)%++q);return r+1;}
int main()
{
    printf("%d\n", j(20,3,9));
    return 0;
}

일부 C 버전에서는 int매개 변수 이름 앞에를 삭제할 수 있습니다 .
기금 모니카의 소송

1

파이썬 3, 72 66 62 바이트

62 바이트의 동적 프로그래밍 기능. Wikipedia의 알고리즘에서 채택되었습니다 . 해당 페이지에서 q = 1 (즉, i = 1, r = 0) 일 때이 알고리즘을 직접 구현 했었지만 지금은이 알고리즘이 제거 된 것을 알 수 있습니다.

편집 1 : 내가 제거i 4 바이트를 절약하기 위해 했습니다. 설명은 변경되지 않습니다.

편집 2 : 바이트 수의 잘못된 계산. 나는 \r\nEOL 에 사용 하고 있었고 3 바이트가 추가되었을 때 알지 못했습니다. 이에 따라 바이트 수를 줄였습니다.

def j(n,k,q):
 r=(k-1)%q
 while q<n:q+=1;r=(r+k)%q
 return r+1

작동 원리

def j(n,k,q):
 i=q;r=(k-1)%q              We start with the smallest possible circle to have a q-th
                                survivor, a circle of q people.
 while i<n:i+=1;            Iterate from q to n
                r=(r+k)%i   Every time you add people to the circle, r increases by k, 
                                modulo the current size of the circle i.
 return r+1                 Return the result.

내 코드를 설명해야한다는 것을 상기시켜 준 @Dennis에게 감사의 말을 전한다. 확실치 않은 사항이 있으면 알려주십시오.

편집하다:

전에,

Graham, Knuth 및 Patashnik 가 콘크리트 수학 에서 채택한 반복 함수입니다 . 이 알고리즘은 더 길지만 큰 n 및 작은 k에 대해 더 빠릅니다 .

def t(n,k,q):
 m=k-1;z=q*k-m%q
 while z<=n*m:z=-(-z*k//m)
 return n*k-z+1

1
복사하여 붙여 넣을 때 잘라내는 것 같습니다 +. 교수형이 있습니다.
xnor

1

PHP, 71 바이트

@ Sherlock9의 답변을 기반으로합니다. 알고리즘에 대한 Python 답변을 참조하십시오.

function a($n,$k,$q){for($r=($k-1)%$q;$q<$n;$r=($r+$k)%++$q);echo$r+1;}

또는 알고리즘이없는 원래의 순진한 접근법이 있습니다. 이것은 사람들을 찾은 것을 표시하기 위해 배열을 사용합니다.

91 바이트

function a($n,$k,$q){for($r=--$i;$q<=$n;++$i%$k||$c[$r]=$q++)while($c[$r=++$r%$n]);echo$r;}

1

하스켈, 48 47 43 바이트

(n!k)q=1+foldl(mod.(k+))(mod(k-1)q)[q+1..n]

두 개의 입력이있는 Josephus 함수 의 Rosetta 코드 페이지 에서 Haskell 알고리즘을 기반으로합니다 . 골프 제안을 환영합니다.

편집 : 내 덕분에 nimi pointfree 버전을 제안을 통해 최초의 알고리즘을 골프에 대한 도움말, 나를 수 있도록함으로써 두 번째 알고리즘을 골프에 대한 도움말은 알고 until키워드가 존재한다.

(n#k)q|m<-k-1=1+n*k-until(>n*m)(\z-> -div(-z*k)m)(q*k-mod m q)

Python 의 마지막 에 Graham, Knuth 및 Patashnik의 Concrete Mathematics에서 채택한 알고리즘 버전 . 이 알고리즘은 62 바이트로 길고 첫 번째만큼 많이 다운되지는 않았지만 크고 n작은 것이 빠릅니다.k .

언 골프 드 :

첫 번째 알고리즘

jos_g num step q = 1 + foldl (\x -> mod (x + step) ) (mod (step-1) q) [q+1..num]

두 번째 알고리즘

jos_gkp num step q
    -- ceiling throws a type-related fit with ceiling(z*k/(k-1))
    -- better to use - div (-z * k) (k - 1)
    | m <- step-1 = 1 + num*step - until (>num*m)(\z-> -div (-z*k) m) (q*step - mod m q) 

새로운 언어를 배우기 위해이 질문을 선택하셨습니까? 답변의 6/10이 당신입니다 : P
Mego

@ Mego 나는 채팅에서 이것을 언급했다 : DI는 어쨌든 게시해야하는지 물었고 그들은 계속 말했다. 또한 그렇습니다. 친구들이 저의 "Hello, World!"라고 말했습니다. 새로운 언어를 위해 : D
Sherlock9

나는 이것이 나쁜 것이라고 말하지 않습니다. 난 그냥 즐겁게, 그게 다야.
Mego

@ Sherlock9 : untilPython 버전의 두 번째 알고리즘을 약간 더 직접 변환하는 데 사용할 수 있습니다 (n#k)q|m<-k-1=1+n*k-until(>n*m)(\z-> -div(-z*k)m)(q*k-mod m q).
nimi

@nimi : DI는 신의 축복을 빕니다 foldl. 당신의 도움을 주셔서 감사합니다!
Sherlock9

1

GML (GameMaker Language), 88 바이트

@ user81655 님의 답변을 바탕으로

r=argument0
k=argument1
q=argument2
r=(k-1)mod q;for(i=q;i<n;r=(r+k)mod ++i){}return r+1

1

젤리 , 14 13 바이트

Rµṙ⁴ṖµL>⁵µ¿⁴ị

TryItOnline!

방법?

Rµṙ⁴ṖµL>⁵µ¿⁴ị - Main link: n, k, q
 µ            - monadic chain separation
R             - range(n): [1,2,3,...,n] - the circle of people
     µ   µ¿   - while
      L       -     length
       >      -     greater than
        ⁵     -     5th program argument (3rd input), i.e. q
  ṙ           -         rotate left by
   ⁴          -         4th program argument (2nd input) i.e. k
    Ṗ         -         pop - remove the rightmost person
            ị - get index
           ⁴  - 4th program argument (2nd input), i.e. k

0

루비, 53 48 바이트

람다.

->n,k,q{r=(k-1)%q;(q+=1;r=(r+k)%q)while q<n;r+1}

작동 원리

def j(n,k,q)
  r=(k-1)%q   # r starts at j[q,k,q]
  while q<n
    q+=1
    r=(r+k)%q # Every time you add people to the circle, r increases by k, 
              # modulo the current size of the circle q.
  end
  r+1         # Return the result.
end
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.