양말 서랍 시뮬레이션


16

배경

요일로 표시된 7 쌍의 양말 인 "평일 양말"컬렉션이 있습니다. 양말을 씻을 때 더미에 쌓여 옷장에 넣기 전에 올바른 쌍으로 정리해야합니다. 내 전략은 더미에서 한 번에 하나의 무작위 양말을 꺼내 서랍에 넣는 것입니다. 서랍에 맞는 양말 한 켤레가있을 때마다 양말을 묶어 옷장에 넣습니다. 당신의 임무는이 무작위 프로세스를 시뮬레이션하고 첫 번째 일치하는 쌍을 찾는 데 필요한 추첨 수를 반환하는 것입니다.

입력

입력 값은 정수 N ≥ 1 입니다. "일주일 일수"를 나타냅니다. 더미에 N 쌍의 양말이 있으며 각 쌍에는 고유 한 레이블이 있습니다. 필요한 경우 PRNG 시드를 입력으로 사용할 수도 있습니다.

산출

당신의 출력은 첫 번째 일치하는 쌍을 찾기 전에 내가 뽑아야하는 양말의 수입니다. 예를 들어 처음 두 양말이 이미 일치하는 쌍을 형성하면 출력은 2입니다.

물론 출력은 임의적이며 도면 순서에 따라 다릅니다. 양말을 그릴 때마다 선택이 균일하고 다른 모든 선택과 독립적이되도록 모든 도면 순서가 동일 하다고 가정 합니다.

예

하자 N = 3 우리는 총 6 개 양말, 라벨이 그래서, AABBCC을 . "양말 드로잉 프로토콜"의 가능한 실행은 다음과 같습니다.

       | Pile   | Drawer | Pairs
Begin  | AABBCC | -      | -
Draw B | AABCC  | B      | -
Draw C | AABC   | BC     | -
Draw B | AAC    | C      | BB
Draw A | AC     | AC     | BB
Draw A | C      | C      | AA BB
Draw C | -      | -      | AA BB CC

첫 번째 일치 쌍은 두 번째 B 를 그리고 난 후 세 번째 양말이 그려 졌으므로 올바른 출력이 3됩니다.

규칙과 득점

전체 프로그램 또는 함수를 작성할 수 있습니다. 가장 낮은 바이트 수가 이기고 표준 허점이 허용되지 않습니다. 입력 및 출력은 단항 (1 s)을 .

언어의 내장 RNG가 완벽하다고 가정 할 수 있습니다. 출력에 올바른 확률 분포가있는 한 실제로 양말 그리기 프로토콜을 시뮬레이션 할 필요는 없습니다.

"테스트 사례"

다음은 입력 N = 7에 대한 모든 출력의 대략적인 확률입니다 .

Output       2     3     4     5     6     7     8
Probability  0.077 0.154 0.210 0.224 0.186 0.112 0.037

솔루션을 테스트하기 위해, 예를 들어, 40,000 회 실행하여 출력 분포가 이에 가까운 지 확인할 수 있습니다.


25
실제 생활, 42 바이트Draw all socks. End up with an odd number.
— AdmBorkBork


따라서 n = 8은 1-> 7과 같지 않다가 다시 1입니까? 즉, 1 개의 레이블이 붙은 4 개의 양말
— Viktor Mellgren

@ViktorMellgren 아니요, 8 개의 고유 한 레이블이 있습니다.
— Zgarb

나는 동일한 양말로 가득 찬 서랍을 가지고 있으므로 그들을 분류 할 필요가 없습니다.
— JDługosz

답변:


9

젤리 , 8 바이트

ḤX€Ṛ<RTḢ

온라인으로 사용해보십시오! 또는 N = 7에 대한 분포를 확인하십시오 .

배경

n 을 쌍의 수로 하자 . 가 2N 개인 양말.

첫 번째 추첨의 경우 2n 양말 이 있으며 그 중 0 개 는 일치하는 쌍이됩니다. 따라서 성공 확률은 0 / 2n = 0입니다. 입니다.

첫 번째 무승부가 성공하지 못한 때문에, 거기에 2N - 1 개 더미에 양말과 1 일치하는 쌍을 초래 그들은. 따라서 성공 확률은 1 / (2n-1) 입니다.

경우 두 번째 무승부에 성공하지, 거기에 2N - 2 개 더미에 양말 이 일치하는 쌍을 초래 그들은. 따라서 성공 확률은 2 / (2n-2) 입니다.

일반적으로 첫 번째 k 추첨이 실패한 경우 더미에 2n-k 양말이 있으며 그중 2 개가 일치하는 쌍이됩니다. 따라서 성공 확률은 k / (2n-k)입니다. 입니다.

마지막으로, 첫 번째 n 추첨 중 어느 것도 성공하지 못한 경우, 더미에 2n-k 양말이 있으며 모두 일치하는 쌍이됩니다. 따라서 성공 확률은 n / (2n-n) = 1 입니다.

작동 원리

ḤX€Ṛ<RTḢ  Main link. Argument: n

Ḥ         Unhalve; yield 2n.
 X€       Map `random draw' over [1, ..., 2n], pseudo-randomly choosing an integer
          from [1, ..., k] for each k in [1, ..., 2n].
   Ṛ      Reverse the resulting array.
     R    Range; yield [1, ..., n].
    <     Perform vectorized comparison.
          Comparing k with the integer chosen from [1, ..., 2n - (k - 1)] yields 1
          with probability (k - 1) / (2n - (k - 1)), as desired.
          The latter half of elements of the left argument do not have a counter-
          part in the right argument, so they are left untouched and thus truthy.
      T   Truth; yield all indices of non-zero integers.
       Ḣ  Head; extract the first one.

8

젤리, 8 바이트

Rx2ẊĠṪ€Ṃ

온라인으로 사용해보십시오!

R    generate [1, 2, ..., n]
x2   duplicate every element (two socks of each pair)
Ẋ    shuffle the list, to represent the order in which socks are drawn
Ġ    group indices by value. this will produce a list of pairs of indices;
       each pair represents the point in time at which each of the corresponding
       socks were drawn
Ṫ€   take the last element of each pair. this returns an array of n integers
       which represent the points in time at which a matching sock was drawn
Ṃ    minimum, find the first point at which a matching sock was drawn

확인하려면 다음은 원하는 출력과 "셔플 목록"작업의 결과를 표시 하는 버전 입니다 (주문 양말이 어떤 순서로 그려 졌는지 확인).


5

파이썬, 66 바이트

from random import*
f=lambda n,k=1:k>randint(1,n*2)or-~f(n-.5,k+1)

Dennis는 사물을 재배치하여 5 바이트를 절약 할 수있는 영리한 방법을 생각했습니다.


4

MATL , 16 15 바이트

Q:"r@qGEy-/<?@.

온라인으로 사용해보십시오! 또는 N = 7의 경우 1000 개의 샘플에 대한 경험적 분포 를 관찰하십시오 (시간이 걸립니다).

이것은 직접 생성 확률 변수 의 확률 분포에 기초하여 결과를 나타내는. 하자 N은 양말 쌍의 수, 그리고하자 P ( K를 확률을 나타낸다) K 번째 무승부는 사실을 조건으로, 성공적으로 그 k는 -1 번째 무승부 성공적인 아니었다. 그런 다음 ( 여기 참조 ) :

  • p (1)은 분명히 0입니다. 단일 양말과 쌍을 가질 수 없습니다.
  • p (2)는 1 / (2 * N -1)이다. 두 번째 추첨에는 2 * N -1 남은 양말 중에서 선택할 수있는 우승 양말이 1 개 있습니다 .
  • p (3)은 2 / (2 * N- 2)이다. 세 번째 추첨에는 2 * N- 2 중에서 2 개의 우승 양말이 있습니다 . 두 번째 추첨 후 얻은 두 양말이 다르기 때문에 우승 양말의 수는 2입니다.
  • 일반적으로 동일한 추론에 의해 p ( k )는 ( k -1) / (2 * N - k +1)입니다.
  • 상기 식에 의해, p ( N 당신이 얻을 경우 +1)이 1입니다 N + 1 번째 당신이 다음 성공을 보장립니다.

따라서 코드는 최대 N +1 드로우 동안 반복됩니다 . 상기 K 개의 랜덤 변수가 확률 1 (같 생성 그릴 번째 K (2 * -1) / N - K 기타), 또는 0. 랜덤 변수가 1 (드로우 성공)과 동일 할 때마다 프로세스가 중지되고 현재 k 가 출력됩니다.

Q:      % Input N implicitly. Generate [1 2 ... N+1] (values of draw index, k)
"       % For each
  r     %   Random variable uniformly distributed on the interval (0,1)
  @q    %   Push iteration index, k-1
  GE    %   Push 2*N
  y     %   Duplicate: push k-1 again
  -     %   Subtract: gives 2*N-k+1
  /     %   Divide: gives (k-1)/(2*N-k+1)
  <     %   Push 1 if random value is less than (k-1)/(2*N-k+1), 0 otherwise
  ?     %   If we got a 1
    @   %     Push k
    .   %     Break loop
        %   End if implicitly
        % End loop implicitly
        % Display implicitly

1
당신과 나는 같은 생각을 가지고 있지만, 당신은 MATL을 알고 있습니다 :)
— Program man

3

MATL , 14 13 바이트

EZ@G\&=XRafX<

온라인으로 사용해보십시오! 또는 N = 7의 경우 4000 개의 샘플에 대한 경험적 분포 를 관찰하십시오 (시간이 걸립니다).

E      % Input N implicitly. Multiply by 2
Z@     % Random permutation of [1 2 ... 2*N]
G\     % Modulo N: random permutation of [0 0 1 1 ... N-1 N-1]
&=     % Compare all pairs for equality. Gives an N×N matrix
XR     % Upper triangular part excluding the diagonal
a      % True for each column if it contains at least one true entry
f      % Get indices of true values
X<     % Take minimum. Implicitly display

3

자바 스크립트, 77 73 바이트

n=>{p={};for(i=n;i--;p[i]=2);while(--p[n*Math.random()|0])i++;return i+2}

설명

var f = (n) => {
    var index;      // used first to initialize pile, then as counter
    var pile = {};  // sock pile

    // start with index = n
    // check that index > 0, then decrement
    // put 2 socks in pile at index
    for(index = n; index--; pile[index] = 2);
    // index is now -1, reuse for counter

    // pick random sock out of pile and decrement its count
    // continue loop if removed sock was not the last
    while(--pile[n * Math.random() | 0]) {
        index++;    // increment counter
    }
    // loop finishes before incrementing counter when first matching pair is removed
    // add 1 to counter to account for initial value of -1
    // add 1 to counter to account for drawing of first matching pair
    return index + 2;
};

당신은 네 개의 문자를 대체 저장할 수 있습니다 f=(n)=>와 n=>(당신이 할당을 유지하려는 경우, 또는 두 개의 일부를 유지 , 일부 삭제를 ).
— 구스타보 로드리게스

잘 잡았습니다. 고쳤습니다. 규칙에서 "전체 프로그램 또는 함수를 작성할 수 있습니다"를 읽을 때 이것이 필수라고 생각했습니다.
— kamoroso94

3
Meta에 대한 합의에 따라 이름에 바인딩되지 않은 명명되지 않은 함수는 기본적으로 허용됩니다.
— Zgarb

이것이 JavaSock이 아니어야합니까? (yes, lame)
— gcampbell


2

파이썬 3 142 105 104 바이트

1 바이트를 절약 한 Eʀɪᴋ ᴛʜᴇ Gᴏʟғᴇʀ 에 감사합니다 !

나의 첫 번째 답변 :

import random 
i=[x/2 for x in range(int(2*input()))]
d=[]
a=0
random.shuffle(i)
while 1:
 b=i.pop()
 if b in d:
  print(a)
  s
 d=d+[b]
 a+=1

나의 새로운 답변 :

from random import*
i=range(int(input()))*2
shuffle(i)
j=0
for x in i:
 if x in i[:j]:print(1+j)+s
 j+=1

둘 다 NameErroron으로 종료 됩니다 s.


2

R, 49

N=scan();which(duplicated(sample(rep(1:N,2))))[1]

R에서 이것을하는 더 좋은 방법이 있어야한다고 확신합니다! 더 똑똑한 일을 시도했지만 작동하지 않았습니다.

편집 : @bouncyball에 의해 기능이 필요하지 않으므로 개선되었습니다.


사용해야 function(N)합니까? 를 사용 N=scan();하면 2 바이트를 절약 할 수 있습니다
— bouncyball

1

파이썬 2, 101 바이트

from random import*
d=[]
p=range(input())*2
shuffle(p)
while list(set(d))==d:d+=p.pop(),
print len(d)

0

VBA, 61 바이트

Function K(D):While 2*D-K>K/Rnd:K=K+1:Wend:K=K+1:End Function

-이전의 경기 실패에 대한 양말 경기의 이동 확률을 모델링합니다. 평가 시점에서 K는 "손에 양말"이므로 추첨 번호가 하나 더 있습니다.


0

Pyth, 14 바이트

lhfnT{T._.S*2S

설명:

       ._        #Start with a list of all prefixes of
         .S      #a randomly shuffled
           *2S   #range from 1 to input (implicit), times 2.
  f              #filter this to only include elements where
   nT{T          #element is not equal to deduplicated self (i.e. it has duplicates)
lh               #print the length of the first element of that filtered list
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.