challenge 重複無し乱数

整数nを渡すと1 ~ n までの整数を重複しないようランダムに出力する関数「bingo」を作ってください。

このお題はraynstardさんの投稿を元にしています。ご投稿ありがとうございました。 投稿の内容には表示のしかたも含まれていたのですが、 このお題では「重複しない1~nまでの乱数をどうやって作るか」という点に集中することにして、 結果の整形は続編としてこの後のお題で出すことにします。 サンプル入出力は下のようになります。

>>> bingo(10)
[10, 7, 8, 4, 5, 2, 3, 1, 6, 9]
>>> bingo(3)
[2, 3, 1]
>>> bingo(3)
[2, 3, 1]
>>> bingo(3)
[3, 1, 2]
>>> bingo(10)
[7, 3, 8, 6, 4, 10, 9, 2, 1, 5]

Posted feedbacks - Batchfile

バッチで書いてみました。27行目の行末に半角空白が 1つあるので注意してください。

環境変数%RANDOM%は 0~32767の範囲で乱数を返します。乱数値の一桁目( 0~9)だけを採用
し、要素数 nで除算すると剰余は 0~n-1のいずれかの値になります。その値を擬似配列の
インデックスとして利用するため、値に 1を加えて補正しています。シャッフルに偏りが
生じるとは思いますが、これが考えつく限界でした。

  e.g.
    C:\>bingo 10
    [ 10, 4, 9, 3, 1, 8, 7, 6, 2, 5 ]

    C:\>bingo 3
    [ 2, 1, 3 ]

    C:\>bingo 3
    [ 2, 3, 1 ]

    C:\>bingo 3
    [ 2, 1, 3 ]

    C:\>bingo 10
    [ 1, 7, 10, 5, 6, 4, 8, 2, 9, 3 ]

遅延環境変数展開と環境変数%RANDOM%を利用しているので、Windows NTでは動作しません。
Windows XPで動作を確認。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
:: bingo.bat
@echo off
  setlocal enabledelayedexpansion
    set i=0
    set j=0
    set t=
    set v=0

    echo %1|findstr /r "[^0-9]" >NUL 2>&1
    if %ERRORLEVEL% equ 0 (echo %0 [NUMBER] & goto :EOF)

    :: 擬似配列を生成
    for /l %%i in (1,1,%1) do set v_%%i=%%i

    :: 値をシャッフル
    set i=1
    :loop
      set /a j=%RANDOM:~-1%%%%1+1
      set v=!v_%i%!
      set v_%i%=!v_%j%!
      set v_%j%=%v%
      set /a i+=1
    if %i% lss %1 goto loop

    for /l %%i in (1,1,%1) do (
      set t=!t!!v_%%i!
      if %%i lss %1 set t=!t!, 
    )
  endlocal & echo [ %t% ]
goto :EOF

Index

Feed

Other

Link

Pathtraq

loading...