AWK를 사용하여 무작위 순서로 숫자 1-6을 만듭니다.

AWK를 사용하여 무작위 순서로 숫자 1-6을 만듭니다.

저는 AWK를 사용하여 1~6 사이의 값을 생성하는데, 이 값은 무작위 순서로 표시되어야 합니다. 올바른 숫자 범위를 생성하는 논리를 정리했지만 중복 숫자가 출력되는 것을 방지하기 위해 배열로 읽는 데 어려움을 겪고 있습니다. 현재 내 코드에는 다음이 있습니다.

BEGIN{
FS=""
}{
for (i=1; i<=6; ++i) {
v=(int (rand()*6)+1   
print v }

현재 6개의 숫자를 출력하고 있지만 2, 2, 6, 1, 4, 2의 중복이 표시됩니다. 1, 4, 2, 5, 6, 3과 같은 출력이 필요합니다.

내 AWK 프로그램의 배열 측면에 대해 도움을 줄 수 있는 사람이 있나요?

매우 감사합니다

답변1

awk최소한 대부분의 Unix 시스템에서는 다음을 사용해야 합니다.

$ seq 6 | shuf
5
2
3
4
1
6

또는 @StéphaneChazelas가 댓글에서 언급한 것처럼요 shuf -i 1-6.

정말로 awk를 사용하고 싶다면 awk를 사용하는 방법이 있습니다.크누스 셔플:

$ cat tst.awk
function shuf(arr,      i, j, n, tmp) {
    n = length(arr)
    for (i=n; i>1; i--) {
        j = int( 1 + rand()*i )
        tmp = arr[i]
        arr[i] = arr[j]
        arr[j] = tmp
    }
}

BEGIN {
    srand()
    for (i=1; i<=n; i++) { arr[i] = i }
    shuf(arr)
    for (i=1; i<=n; i++) { print arr[i] }
}

$ awk -v n=6 -f tst.awk
3
1
5
4
6
2

필요한 값으로 배열을 채운 다음 배열의 각 인덱스에 저장된 값을 임의로 선택한 다른 인덱스에 저장된 값으로 바꾼 다음 배열을 인쇄합니다.

위의 함수 는 shuf()배열의 단일 패스에서 작동합니다.

답변2

그냥 네가 원하는 것 같아셔플 재생1에서 6 사이의 숫자입니다.

대부분의 구현에는 "무작위" 순서 지정 옵션이 sort있습니다 -R(이 옵션은 표준이 아닙니다). 대부분의 쉘에는 범위 내에서 문자열 또는 숫자의 조합을 생성하기 위한 "중괄호 확장"이 있습니다(중괄호 확장은 표준이 아닙니다).

$ printf '%s\n' {1..6} | sort -R
6
2
3
4
5
1

답변3

6가지 항목(숫자 1~6 포함)을 배열하는 방법에는 720가지(= 6!(6 계승) = 1 × 2 × 3 × 4 × 5 × 6) 가지가 있습니다. 따라서 한 가지 방법은 1에서 6 사이의 난수를 생성하는 것입니다! (실제로는 0에서 6!−1 사이) 이를 해당 순열에 매핑합니다.

BEGIN {
        n = 6
        srand()
        # Compute n! (n factorial) and create an array of numbers.
        f = 1
        for (i = 1; i <= n; i++) {
                f *= i;
                nums[i] = i;
        }
        # Get random number between 0 and n!-1.
        r = int(rand()*f)
        # Deconstruct it.
        for (i = n; i > 0; i--) {
                remainder = r % i + 1
                print nums[remainder]
                # Remove it from the array.
                for (j = remainder; j < n; j++) nums[j] = nums[j+1]
                r = int(r/i)
        }
}

이것은 잘 확장되지 않습니다.

  • 내 awk 버전은 22를 계산할 수 있습니다! 하지만 23을 계산할 수는 없습니다!
  • 알고리즘은 O(N2 ). 즉, 큰 값을 처리하는 경우N,  N=6000은 백만 배 더 오래 걸립니다N=6.

이점:

  • rand()한 번만 호출되기 때문에 비용이 매우 많이 드는 가상의 세계에서 위의 내용을 사용하고 싶을 수도 있습니다 rand().
  • 이 알고리즘은 동일한 숫자 시퀀스 번호를 반복적으로 쉽게 생성할 수 있습니다( r임의 값이 아닌 알려진 값으로 설정하여).

관련 정보