2017-01-10 6 views
3

質問がたくさんありますが、その中からランダムではないものを取得したいと思います。したがって、例えば5つの質問のために、もし私に質問すれば、私は再び始めます。私はusally新しい配列を作成した後、出力がルビーの配列のランダムでない反復要素を取得する

A? C? D? B? #all questions where asked once, so repeat

B? D? C? A? ...

+1

メモリにロードできない膨大な(または無限の)質問があると面白いです。それから、あなたの選択肢を十分にランダムにするために、数学の数学を使うことができます。例えば、 - *任意の** n **連続する数は、** n **のモジュロで素数のべき乗になり、**から** n ** - 1 *の数になります。 – ndn

+0

おっと、私は少し嘘をついた。素数は偶数であってはならない(別名2)。 – ndn

答えて

2

それがわずかに変更された考えとステファンのソリューション@に非常に近いです。

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"] 
+0

非常にエレガントで、例外的にうまく読みます! –

-1

のようなものでなければなりません

def askrandom 
questions = ["A?", "B?" , "C?" , "D?"] 

return #random question 
end 

方法(またはそのようなもの)に入れたいですランダム私は新しい配列に存在しない場合はランダムに値を追加します。
前回と同じ出力が得られた場合、追加したために出力が新しい配列になったことを意味します。
私の愚かな英語については申し訳ありません。質問の繰り返しを避けるために

+0

これは、運用コストを3倍増加させ、重複しているアレイでは失敗します。これは目標を達成する最悪の方法です。 – mudasobwa

2

、あなたはどこかに残っている質問を格納する必要があり、のは、インスタンス変数を使用してみましょう:

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 
+0

'@remaining_questions || = questionsではありません。shuffle'をコンストラクタなしで使うと、少しオーバーデザイナーになるのですか? – mudasobwa

+0

@mudasobwaは '[]'が真実であるため一度しか動かないでしょう – Stefan

+0

クラスを導入して以来、生涯は "新しい⇒尋ねる⇒滞在"に簡単に縮小するかもしれません。新しいアンケートが必要です。とにかく、それは範囲外の実装設計の問題です。 – mudasobwa

0

ピュア機能的アプローチ:

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 
+0

なぜこれがダウン表示されますか? – ndn

+0

@ndnの人々は、彼らが理解していない解決策をdownvoteする傾向があり、ルビーコミュニティはレール風の醜さに悪影響を及ぼします。 – mudasobwa

+0

@ndn私はコードを実行しましたが、出力は著者の期待どおりではありませんでした。それは、私が推測する理由かもしれません。 – fl00r

0
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?" 

これらの変更はどちらも私のオリジナルの回答より明らかに優れています。

+1

Mmm。私は、ここではグローバルな国家があまりにも多いと言います。私はラムダ/ファイバー/列挙子、またはいくつかのクラスに状態をラップすることによって、いくつかのカプセル化を追加します。副作用の1つは、メソッドをさまざまな入力で再利用する場合です: 'fire_away(q1); fire_away(q2) ' – fl00r

+0

私はこのような何かを意味するhttps://gist.github.com/fl00r/9ac83cc7e15f0e441f2bfa6ba37ff242 – fl00r

+0

@ fl00r、素晴らしい提案!以前はその技術を見ていなかった。私は編集します。 –

関連する問題