C#: atestat și pregătire ONTI

C#: quiz cu amestecare reproductibilă și identități stabile

Amestecă întrebările unui quiz C# fără să pierzi răspunsurile corecte. Folosește Fisher–Yates și o sămânță fixă pentru teste care pot fi reproduse.

Amestecarea întrebărilor nu trebuie să rupă asocierea cu răspunsurile. Fiecare Question păstrează ID-ul, textul și răspunsul corect în același obiect. Algoritmul schimbă pozițiile obiectelor, fără să amestece separat textele și cheile. Pentru teste folosim aceeași sămânță a generatorului pseudoaleator.

Cum lucrezi cu exemplul

Programul complet folosește C# 7.3 și API-uri disponibile în .NET Framework 4.8. Deschide Lesson.csproj din arhivă sau creează un proiect Console App (.NET Framework 4.8) și înlocuiește Program.cs. Datele de demonstrație sunt incluse în cod.

Descarcă sursele și instrucțiunile.

Ideea și pașii de implementare

Fisher–Yates parcurge lista de la sfârșit spre început. La pasul i alege j între zero și i inclusiv și schimbă cele două elemente. Random.Next(i+1) are capătul din dreapta exclus, deci produce exact intervalul dorit. Lista este copiată înainte de amestecare pentru a păstra ordinea originală.

O sămânță fixă ajută reproducerea în același mediu de execuție. Nu promitem aceeași secvență Random pentru orice versiune de runtime. Testul robust verifică proprietățile: toate ID-urile apar o singură dată, perechile întrebare-răspuns rămân intacte și două rulări în același mediu, cu aceeași sămânță, coincid.

Exemplu și rezultat așteptat

Setul are întrebările cu ID-urile 10, 20 și 30. După amestecare, sortarea ID-urilor trebuie să dea tot 10, 20, 30. Pentru ID 20, răspunsul rămâne 3 indiferent de poziția nouă. Programul nu fixează o permutare particulară în rezultatul așteptat; afișează trei confirmări de proprietăți.

Schemă pentru lecția 44: Question: ID + text + cheie; Fisher–Yates: schimbă obiecte; ID 20 își păstrează cheia 3; Permutare, fără pierderi.Question: ID + text + cheie → Fisher–Yates: schimbă obiecte → ID 20 își păstrează cheia 3 → Permutare, fără pierderi.Mărește schema ↗

Codul complet

using System;
using System.Collections.Generic;
using System.Linq;
using System.IO;
using System.Globalization;
using System.Xml.Linq;
using System.Data;
class Question {public int Id;public string Text;public int Answer;}
class Program {
    static List<Question> Shuffle(List<Question> source,int seed) {
        var result=new List<Question>(source);var random=new Random(seed);
        for(int i=result.Count-1;i>0;i--) {int j=random.Next(i+1);var temp=result[i];result[i]=result[j];result[j]=temp;}
        return result;
    }
    static void Main() {
        var source=new List<Question> {new Question {Id=10,Text="2+3",Answer=5},
            new Question {Id=20,Text="Length [4,7,9]",Answer=3},new Question {Id=30,Text="4*2",Answer=8}};
        var a=Shuffle(source,42);var b=Shuffle(source,42);
        Console.WriteLine(a.Select(x=>x.Id).OrderBy(x=>x).SequenceEqual(new[]{10,20,30}));
        Console.WriteLine(a.Single(x=>x.Id==20).Answer==3);
        Console.WriteLine(a.Select(x=>x.Id).SequenceEqual(b.Select(x=>x.Id)));
    }
}

Rezultatul programului:

True
True
True

Greșeli și limite

Nu sorta cu un comparator aleator: comparatorul nu mai respectă un contract coerent. Nu construi un Random nou pentru fiecare schimb. Nu amesteca lista în timpul răspunsului utilizatorului. Salvează ordinea sesiunii dacă vrei să poți reconstrui ulterior parcursul exact.

Exersează

Testează lista goală, un singur element și zece întrebări. Verifică unicitatea ID-urilor înainte de începerea sesiunii. Integrează funcția în miniaplicația quiz și păstrează obiectul curent, nu o cheie dintr-un vector neamestecat. Explică de ce schimbarea poziției nu trebuie să schimbe corectitudinea răspunsului.

Continuă parcursul

Parcursul complet de 50 de lecții

Bazele C#

Lecția precedentă: C#: proiect catalog cu note și raport calculat

Lecția următoare: C#: proiect labirint cu BFS și drum desenat.

Referință: documentația Microsoft.

Întrebări frecvente

De ce amestec obiecte complete?

Pentru a păstra împreună identitatea, textul și răspunsul corect.

Next(i+1) poate întoarce i?

Da. Limita superioară este exclusă, deci valorile sunt de la zero la i.

Sămânța fixă garantează aceeași ordine pe orice runtime?

Nu este o promisiune universală. Testează proprietățile și fixează mediul când ai nevoie de reproducere exactă.

Un pas mai departe

Autentifică-te pentru a păstra progresul în cont.

Exersează cu o problemă →