質問がたくさんありますが、その中からランダムではないものを取得したいと思います。したがって、例えば5つの質問のために、もし私に質問すれば、私は再び始めます。私はusally新しい配列を作成した後、出力がルビーの配列のランダムでない反復要素を取得する
A? C? D? B? #all questions where asked once, so repeat
B? D? C? A? ...
質問がたくさんありますが、その中からランダムではないものを取得したいと思います。したがって、例えば5つの質問のために、もし私に質問すれば、私は再び始めます。私はusally新しい配列を作成した後、出力がルビーの配列のランダムでない反復要素を取得する
A? C? D? B? #all questions where asked once, so repeat
B? D? C? A? ...
それがわずかに変更された考えとステファンのソリューション@に非常に近いです。
class Questions
def initialize(array_of_questions)
@questions = array_of_questions
@nums ||= get_nums
end
def get_nums
([email protected]).to_a.shuffle
end
def get_num
@nums.pop or (@nums = get_nums).pop
end
def pick
@questions[get_num]
end
end
questions = Questions.new(["A", "B", "C", "D"])
10.times.map{ questions.pick }
#=> ["B", "D", "C", "A", "C", "A", "B", "D", "A", "B"]
非常にエレガントで、例外的にうまく読みます! –
のようなものでなければなりません
def askrandom
questions = ["A?", "B?" , "C?" , "D?"]
return #random question
end
方法(またはそのようなもの)に入れたいですランダム私は新しい配列に存在しない場合はランダムに値を追加します。
前回と同じ出力が得られた場合、追加したために出力が新しい配列になったことを意味します。
私の愚かな英語については申し訳ありません。質問の繰り返しを避けるために
これは、運用コストを3倍増加させ、重複しているアレイでは失敗します。これは目標を達成する最悪の方法です。 – mudasobwa
、あなたはどこかに残っている質問を格納する必要があり、のは、インスタンス変数を使用してみましょう:
def initialize
@remaining_questions = []
end
とのは、独自の方法に疑問を抽出してみましょう:
def questions
["A?", "B?" , "C?" , "D?"]
end
@remaining_questions
が空の場合は、シャッフルコピーquestions
で初期化します。その後、あなたは、単に最初の項目を削除(およびリターン):
def ask_random
@remaining_questions = questions.shuffle if @remaining_questions.empty?
@remaining_questions.shift
end
ピュア機能的アプローチ:
def ask(question)
question.tap { |q| puts "Asking question #{q}" }
end
def askrandom(asked = [], remaining = ["A?", "B?" , "C?" , "D?"].shuffle)
return asked if remaining.empty?
askrandom(asked << ask(remaining.pop), remaining)
end
def fire_away(questions)
@n = (@n || -1) + 1
@order = [*0...questions.size].shuffle if @n % questions.size == 0
questions[@order.shift]
end
q = ["A?", "B?" , "C?" , "D?"]
fire_away q #=> "D?"
fire_away q #=> "A?"
fire_away q #=> "C?"
fire_away q #=> "B?"
fire_away q #=> "B?"
fire_away q #=> "C?"
fire_away q #=> "A?"
fire_away q #=> "D?"
fire_away q #=> "A?"
fire_away q #=> "C?"
fire_away q #=> "B?"
fire_away q #=> "D?"
またfl00r @
def reset_questions
@n = nil
end
が提案された方法を必要とするかもしれfire_away
が定義されているクラス内に表示されているインスタンス変数の必要性を回避(および避けるために、次の方法reset_questions
の必要性):
もう1つの方法は、別のクラスを作成します(これは@ fl00rの答えに非常に近い)。
class Questions
def initialize(*questions)
@questions = questions
@n = -1
end
def next_question
@n += 1
@order = [*[email protected]].shuffle if @n % @questions.size == 0
@questions[@order.shift]
end
end
q = Questions.new("A?", "B?" , "C?" , "D?")
q.next_question #=> "C?"
q.next_question #=> "A?"
q.next_question #=> "D?"
q.next_question #=> "B?"
q.next_question #=> "B?"
これらの変更はどちらも私のオリジナルの回答より明らかに優れています。
Mmm。私は、ここではグローバルな国家があまりにも多いと言います。私はラムダ/ファイバー/列挙子、またはいくつかのクラスに状態をラップすることによって、いくつかのカプセル化を追加します。副作用の1つは、メソッドをさまざまな入力で再利用する場合です: 'fire_away(q1); fire_away(q2) ' – fl00r
私はこのような何かを意味するhttps://gist.github.com/fl00r/9ac83cc7e15f0e441f2bfa6ba37ff242 – fl00r
@ fl00r、素晴らしい提案!以前はその技術を見ていなかった。私は編集します。 –
メモリにロードできない膨大な(または無限の)質問があると面白いです。それから、あなたの選択肢を十分にランダムにするために、数学の数学を使うことができます。例えば、 - *任意の** n **連続する数は、** n **のモジュロで素数のべき乗になり、**から** n ** - 1 *の数になります。 – ndn
おっと、私は少し嘘をついた。素数は偶数であってはならない(別名2)。 – ndn