Random getallen met checkbox

Status
Niet open voor verdere reacties.

rambomambo

Gebruiker
Lid geworden
9 dec 2012
Berichten
163
Ik heb 2 checkboxen 1 voor sommen en 1 voor producten.

Nu dit werkt perfect maar nu wil ik dat er bij de producten een uitkomst mag zijn niet hoger dan 100 maar dit lukt niet met
antwoord = rand.next(100)
ook zou ik willen dat ik de beide checkboxen aanvink dat ik random oefeningen krijg met soms een + en soms een maal

private void genereersom()
{



int max = 10;

tbRandom.Clear();
Random rand = new Random();
int randomgetal1 = rand.Next(0,100);
int randomgetal2 = rand.Next(0, 100);


if (cbSom.IsChecked == true)
{

Antwoord = randomgetal1 + randomgetal2;
test = "+";
}
else if (cbProduct.IsChecked == true)
{




Antwoord = randomgetal1 * randomgetal2;

test = "*";
}




lblplusofmaal.Content = string.Format("{0}" + test + "{1} =", randomgetal1, randomgetal2);
 
Als je niet wil dat de som groter is dan 100, kun je het volgende doen:

Algemene som: x + y = z

Men neme een willekeurig getal z kleiner dan 100, dat wordt je uitkomst.
Vervolgens neem je een willekeurig getal x binnen het interval [0;z].
Nu kun je het getal y uitrekenen, namelijk y = z - x.

Hetzelfde kun je doen met andere rekenkundige bewerkingen.

En kun je je code tussen codetags zetten zodat het leesbaarder wordt?
 
Je kunt gewoon wat meer checks toevoegen om dit te krijgen.

Eerst kijken of beide checks zijn aangevinkt, dan random. Anders aan de hand van een van de checks

En als je een max uitkomst wilt kun je eenvoudig aan de hand van de eerste random de tweede aanmaken.

Zoals voor de:

int x = rnd.Next(0, 100);
int y = rnd.Next(0, 100 - x);


Uiteindelijk kun je dit alles fijn in een class stoppen zodat je in je programma niet steeds de checks hoeft te doen, maar ik weet niet precies hoever je bent met het ontdekken van C#.




edit: reactie vooraf en achteraf redelijk tegelijk, nu kun je er in iedergeval vast wel wat van maken :P
 
Laatst bewerkt:
+ variant is makkelijk te doen.

int randomgetal2 = rand.Next(0, (100-randomgetal1));

* wordt een stuk moeilijker.
1 * 100 = 100
2 * 50 = 100
3 * 33 = 99
4 * 25 = 100
5 * 20 = 100
6* 16 = 96
7 * 14 = 98
8 * 12 = 96
9 * 11 = 99
10 * 10 = 100
etc.
Wat ik hier mee aan wil geven dat je daar maar 10 mogelijkheden heb.

List<int> keer = new list<int>;
list.add -- optie 1 tot 10
list.add(100)
list.add2(50)

int randomgetal1 = random(0,10);
int randomgetal2 = list[randomgetal1 -1 ];

succes

Wat je ook zou kunenn doen random getal 1 en random getal2 kunnen draaien. Maar uit eindelijk heb je nog steed 20 mogelijkheden

leuke is int randomgetal1 = random(0,20);
if(randomgetal1 > 10) randomgetal1 =- 10
randomgetal2 = keer[randomgetal1 -1]

Leuke toevoeging
 
Laatst bewerkt:
@csshunter: Dat dacht ik ook. Vandaar ook mijn opmerking "Hetzelfde kun je doen met andere rekenkundige bewerkingen."

Alleen ik zit nu te denken - aangezien dit is om sommen te genereren om te oefenen (toch?) - dat het niet handig is als er geen mooie getallen uitkomen.
Er moet dus nog een soort check inkomen.

Klopt dat, TS?

[edit]@csshunter: Waarom is je post verwijderd?[/edit]
 
Laatst bewerkt:
ja de bedoeling is dus om willekeurige oefeningen te krijgen.

Bv 2*50 = 100 ,5*5 = 25
maar dan wel dat de uitkomst niet hoger dan 100mag vallen.
en ook dat ik beide checkboxen aanvink dat ik soms een som en soms een product moet oplossen. De computer kiest dus of het een optelling of een vermenigvuldiging word.
 
Allereerst een kans van 1 op 2 of het een vermenigvuldiging of een optelling wordt wordt (dit kun je uitbreiden).
De optelling is hiervoor uitgebreid beschreven door Bloodshed en mij. Voor de vermenigvuldiging moet je het anders aanpakken (omdat je anders kommagetallen krijgt).

Dit kun je doen met de modulo-operator.
while (z % x = 0) ...
 
Van c#.net heb ik geen snars verstand, maar kan je voor de vermenigvuldiging (analoog aan de optelling) niet met:


int randomgetal1 = rand.Next(1,10);
int randomgetal2 = rand.Next(0,100/randomgetal1);



een heel eind komen?


  • randomgetal1 mag dan geen 0 zijn, want delen door nul ... ;)
  • Om het moeilijker te maken kan je het minimum van randomgetal2 ook op 10 zetten, dan wordt het tweede getal minstens 10. Anders komen er veel sommetjes bij in de gedaante van: 2*2=?

[edit]Ah, verse waar intussen![/edit]
@JoZ1: ik dacht even dat ik ernaast zat in mijn 1e reactie, dus nog even nagedacht. ;)
 
Laatst bewerkt:
ja wat je ziet staan is dus randomgetal1 mijn getal1 en randomgetal 2 is mijn 2de random getal tussen haakjes 1,100 wil zeggen dat mijn
getallen niet kleiner dan 1 en niet groter dan 100 mogen zijn.

Ik heb al veel geleerd over C# maar het zijn nog een paar kleinig heden die ik zou willen oplossen lol
 
Laatst bewerkt door een moderator:
K bedankt ik ga het morgen eens testen.
 
Laatst bewerkt door een moderator:
Misschien domme vraag, maar maakt het "int" type van beide variabelen er niet vanzelf mooie hele getallen van?
Dan zou er geen modulo (of, in javascript-termen, mathRound of mathFloor) aan te pas hoeven te komen.
 
Integers representeren inderdaad gehele getallen. Maar, stel dat de twee random getallen 21 en 2 zijn.
Dan staat er dus dit:

int y = 21 / 4;

y krijgt een waarde van 5. En deze som wordt gevraagd:

4 * 5 = ...

Waarop alleen het antwoord 21 goed wordt gerekend door het programma.


Dit zou je kunnen verhelpen door met doubles te gaan werken, maar dan zitten er ook zulke vragen tussen:

29 * 1,5862068965517241379310344827586 = ...

Waarop het antwoord overigens 46 is ;)
 
Als je 'mooie sommen' wilt hebben zou ik gewoon met een gegenereerde lijst werken (aan de hand van een aantal restricties, zoals de min en max) , en daar een random waarde daar uit halen.
Dan heb je de 'mooie sommen' en geen last van 21/4 gevallen.

Weet de topic starter zelf het best wat het uit eindelijk moet worden.
 
@ JoZ1 nummer #12:
Maar, stel dat de twee random getallen 21 en 2 zijn.
... Waarop alleen het antwoord 21 goed wordt gerekend door het programma.
Het leidt misschien teveel af, maar dat gaat mijn pet te boven.


  • "Dan staat er dus dit: int y = 21 / 4" > waar komt die y vandaan, en waar gaat ie naar toe?
  • "En deze som wordt gevraagd: 4 * 5 = ..." > als de random getallen 21 en 2 zijn, wordt toch 21*2 gevraagd?

Als ik dit als uitgangspunt neem:


int randomgetal1 = rand.Next(1,100);
int randomgetal2 = rand.Next(0,100/randomgetal1);
antwoord = randomgetal1 * randomgetal2;


Wat is er dan fout aan de volgende redenering?


Stel randomgetal1 = 21
Dan: int randomgetal2 = rand.Next(0,100/21) = rand.Next(0, 4.7619047619047619047619047619048)

Dus: int randomgetal2 is 0, 1, 2, 3 of 4
Stel randomgetal2 = 2
Dan: antwoord = randomgetal1 * randomgetal2 = 21 * 2 = 42


En bij vermenigvuldiging van twee hele getallen is een breuk toch onmogelijk? :rolleyes:

Met vriendelijke groet,
CSShunter
 
Laatst bewerkt:
Ja mijn beide random getallen krijg ik al. Maar het is gewoon nog dat ik 2 kleine dingen wil hebben
zoals de uitkomst mag niet groter zijn dan 100 en als mijn 2checboxen zijn aangevinkt dat ik random een som of een product oefening krijg
dus de computer kiest dat het een som of een vermenigvuldiging word en deze 2punten vind ik dus niet.

Heb deze bovenstaande opties al geprobeert maar krijg dan ofwel fouten ofwel iets dat totaal verkeerd is
 
Laatst bewerkt door een moderator:
@csshunter:
Ik werk volgens een ander principe. Jij doet het als volgt:

x * y = z
met x en y willekeurige getallen. Het klopt dat hier nooit breuken uit kunnen komen.

Het probleem hiermee is - zoals ik al in post #2 uiteenzette - dat er hier geen maximum uitkomst (z) kan worden bepaald.
Dit kan wel als je de z als willekeurig getal genereerd.

Om het duidelijk voor iedereen te houden, zal ik mijn manier hieronder uitwerken.

We hebben de vermenigvuldiging:


x * y = z


Er geldt voor optellen:


z = rand.Next(0,100);
x = rand.Next(0,100);
y = z - x


Voor vermenigvuldigen zou er dan gelden:


y = z / x


waardoor er breuken uit kunnen komen. Dit is op te lossen door een modulo-operator te gebruiken.
Zoiets dus (pseudocode):

Code:
do
    y = z/x
loop until z % y = 0


Het nadeel is dat dit heel lang kan duren, waardoor je zou kunnen gaan kijken naar Bloodshed's oplossing met van te voren opgestelde lijsten.

Ik hoop dat het nu een beetje duidelijk is voor iedereen :)


Heb deze bovenstaande opties al geprobeert maar krijg dan ofwel fouten ofwel iets dat totaal verkeerd is
Wat is je huidige code (in code-tags a.u.b.) ?
 
Laatst bewerkt:
@JoZ1:
Voor het goede begrip zal ik mijn stelling:
int randomgetal1 = rand.Next(1,100);
int randomgetal2 = rand.Next(0,100/randomgetal1);
antwoord = randomgetal1 * randomgetal2;
oftewel:
int x = rand.Next(1,100);
int y = rand.Next(0,100/x);
z = x * y;
ook nog even verduidelijken. ;)


  1. "Ik werk volgens een ander principe."
    Klopt, één van ons tweeën doet het achterstevoren, maar in principe hoeft dat niet uit te maken.

  2. "Jij doet het als volgt: x * y = z, met x en y willekeurige getallen."
    Klopt niet, bij mij is de y helemaal niet willekeurig, maar afhankelijk van de x en het gestelde maximum 100 voor het product:
    int y = rand.Next(0,100/x).​
    Bv.: x=2, dan 100/2=50, en y ligt tussen de 0 en de 50; of x=15, dan 100/15=6,667 cq. afgerond ligt y tussen de 0 en de 6.
    Enz.: gaat altijd goed.

  3. "Het klopt dat hier nooit breuken uit kunnen komen."
    Correct. Na m'n vaststelling van x en y (beide hele getallen) wordt het product x*y berekend, dat dus ook een heel getal is (en onder de 100).
    Klaar! :)

  4. "Het probleem hiermee is ... dat er hier geen maximum uitkomst (z) kan worden bepaald."
    Klopt niet wegens punt 2: het maximum van de y ligt al vast wegens de voorwaarde max.y=100/x, die verdisconteerd is in het random trekken van y. Het probleem van geen max. voor z doet zich dus niet voor, die zit ingebakken. En x en y zijn gemaakt tot hele getallen, dus er hoeft geen modulo aan te pas te komen.

  5. "Maximum uitkomst (z) kan worden bepaald... als je de z als willekeurig getal genereert."
    Klopt ook, je kan ook de z randommen tussen de 0 en de 100, maar dan moet je wel de voorwaarde voor y laten vallen! :d

  6. In dat geval ga je wat ik noem achterstevoren te werk: bij x*y=z de x en de z trekken en dan terugrekenen om de y te bepalen: y=z/x.
    En als z en x beide hele getallen zijn, zal y in tig van de tig gevallen een breuk zijn.
    Dan moet je inderdaad wel een modulo gaan toepassen om ook nog van y een heel getal te maken. Of een int y nemen, die ook afrondt.
    Vervolgens zal je ook nog op basis van de eerder getrokken x en de nu afgeronde y een nieuw product z moeten vaststellen, want x*y moet wel z zijn!

  7. Bv. x=15 getrokken, onafhankelijk wordt z=63 getrokken. Volgens y=z/x is y=63/15=4,2 > afgerond y=4. Dan is x*y=15*4=60 en niet 63 > dus de z moet bijgesteld worden.
  8. Kan ook, maar ik vind dat wat omslachtig: in punt 3 was ik al klaar. ;)

=======

Ter illustratie dat mijn redenering (ook) klopt, heb ik deze met vertaling van het vb-script in javascript op een demo-pagina gezet.


  • Demo: vermenigvuldigsommen.htm
    Hier komen prachtige sommen uit, die allemaal voldoen aan de voorwaarden.
    Zie ook de broncode.

=======

MAAR ... of je het nu met javascript of vb-script doet, dit is slechts het aperitief.
Nu begint het feestje voor een sommen-generator pas echt!

Bij een aantal keer achter elkaar trekken zal opvallen dat er wel erg veel nullen, enen en tweeën als tweede getal tevoorschijn komen...
  • NB: met de reset-knop hoef je niet steeds antwoord te geven. ;)

... en dat klopt als een zwerende vinger.
Want als je het eerste getal willekeurig laat trekken uit 1 tot 100, dan is er volgens de kansrekening bv. 50% kans dat het getal boven de 50 ligt.
  • Bij een x>50 kan de y vervolgens niet anders dan 0 of 1 zijn, anders wordt het product groter dan 100.
  • Evenzo is er 66% kans dat het eerste getal groter is dan 34; dan kom je voor de y niet hoger dan 0, 1 en 2.

Dit kan je mooi zien als je in één klap 50 sommen laat maken.


  • Demo: vermenigvuldigsommen-2.htm
    Gemakshalve zijn de antwoorden achterwege gelaten.
    Voor de demo zijn de sommen gesorteerd op het kleinste getal voorop, en dan in kolommen.
    Behalve de reset zit er ook een knop op om (herhaald) nog eens 10 extra willekeurige sommen te maken.

Zekert bij wat herhalen ziet het evenwicht er aardig verstoord uit; de linkerkant is veel zwaarder. - En daar zitten net de makkelijke.
Het is al even geleden dat ik op de schoolbanken ingewijd werd in de geheimen van mutaties en permutaties, maar ik denk dat als je maar heel veel sommen laat maken de figuur uitkomt op een mooie parabool of hyperbool.

=======

Normaliseren van de verdeelsleutel
Nu zal het niet de bedoeling van de sommen-generator zijn om een hele klas leerlingen wat lacherig te maken bij oefeningen of proefwerken met een overmaat aan opgaven in de gedaante van 0*..=.. , 1*..=.. en 2*..=..
Eén van de manieren om een wat betere spreiding van de (helemaal niet zo) random getallen te krijgen, is om als voorwaarde voor de eerste trekking te stellen dat het getal x niet groter mag zijn dan 10 (en minstens 1 vanwege het onmogelijke delen door nul).
De tweede getallen komen dan in de range van 100/1 - 100/10, ergo het tweede getal ligt dan tussen de 0 en de 99.



Ga je hier heel veel meer sommen tegelijkertijd laten aanmaken, dan zal je vroeger of later toch bij de parabool/hyperbool van nummer 2 uitkomen, want er zijn nu een eenmaal meer producten met kleine getallen onder de 100 dan met grote getallen onder de 100.

=======

Moeilijker maken
Met extra voorwaarden kan je de sommen ook moeilijker maken, bijvoorbeeld:
  • Sommen met 0*..=.. en 1*..=.. worden er uit gewipt.
  • Het aantal sommen met 2*..=.. wordt beperkt tot maximaal 6.
  • Het tweede getal moet altijd hoger dan 10 zijn.

Als je dat combineert, krijg je het volgende uitstapje.



=======

MAAR... er zitten dezelfde sommen bij!
Misschien is het nog niet zo opgevallen, maar in alle voorgaande demo's zitten dubbele (of driedubbele enz.) sommen met exact dezelfde getallen.
Bij toeval kan dat eventueel niet het geval zijn, maar met een paar keer resetten komen er altijd dubbele tevoorschijn. :eek:

Ook dat is logisch: er wordt elke keer met een schone lei begonnen, "dobbelstenen werpen met teruglegging", en dan is er altijd de kans dat er hetzelfde uit komt.
Om dat tegen te gaan, moet je controleren of een getallenkoppel al eerder op de lijst is gezet. En dat wordt meteen een stuk ingewikkelder: je moet een dubbele loop laten uitvoeren. D.w.z. bij elk eerste getal nagaan of dat er al eens is; en als het er is, ook nagaan of dan ook het bijbehorende tweede getal er al is.



=======

Husselen
Om niet steeds het kleinste getal voorop te hebben en het weer wat lastiger te maken, kan je op het eind gaan husselen: om en om het kleinste of het grootste getal voorop zetten in de lijst.
In de uiteindelijke generator hoeft het sorteren natuurlijk niet, dat kan er uit.
Veder kan je behalve het uitzeven van dubbele sommen, naar hartenlust extra voorwaarden stellen (zoals in 3a).
Hier een generator waarin geen 0 en 1 sommen zitten, en het tweede getal altijd hoger dan 10 is.


  • Demo: vermenigvuldigsommen-5.htm
    Dat begint al aardig op ambachtelijk handwerk te lijken, want dat kan natuurlijk ook altijd: dan hoef je je nergens om te bekommeren. :p
    Zoals druk maken om de scriptfout die er in zit: soms worden het niet precies 42 sommen; maar het gaat om het idee. *) ;)

=======

Conclusie
Om voor computer-logica bruikbaar te maken wat voor ons menselijk brein heel eenvoudig is, kan nog wel eens tegenvallen.

Met vriendelijke groet,
CSShunter
___________
*) Troost: er zijn speciaal voor leerkrachten wat online sommen-generators met Google te vinden, maar bv. deze meester-en-juf.nl heeft er prettig veel dubbele tussen zitten. Zowel geheel identieke als van de soort 2*3 / 3*2. En prettig veel hele kleine getallen die met elkaar vermenigvuldigd mogen worden...
De sommenmaker.nl heeft meer instelmogelijkheden en brengt het er een stuk beter van af (ook nog wel kans op dubbele).
Maar beiden kunnen alleen een printbaar rekenblad afleveren, en zijn niet online te beoefenen.
 
Laatst bewerkt:
@csshunter: Een geweldig uitgebreide en verhelderende post!
Het misverstand was, dat ik niet wist dat je de uitkomst z aanpaste aan de x en de y.
In dat geval is de methode die jij beschrijft veel beter!

Ik zal eens kijken of ik een voorbeeldje kan maken in C#.

EDIT: ik heb wat gemaakt.

Het is gebaseerd op deze klassen:

[cpp]public class methode
{
private char[] operators;
private int max; //maximale uitkomst vd sommen
public methode(char[] _operators, int _max)
{
operators = _operators; max = _max; //initialisatie
}

//genereer sommen
public List<som> sommen(int nSommen)
{
List<som> s = new List<som>();
som temp = new som();
for (int i = 0; i < nSommen; i++)
{
int dupControle; //duplicaatcontrole
do
{
dupControle = temp.z;
Random r = new Random();
temp.op = operators[r.Next(0, operators.Length)]; //operator
temp.z = r.Next(1, max); //uitkomst
temp.x = r.Next(1, temp.z);
switch (temp.op)
{
case '+': // z = x + y
temp.y = temp.z - temp.x;
break;
case '-': //z = x - y
temp.y = temp.x;
temp.x = temp.z + temp.y;
break;
case '*': //z = x * y
temp.x = r.Next(1, 10);
temp.y = (int)(temp.z / temp.x);
temp.z = temp.x * temp.y;
break;
case '/': //z = x / y
temp.x = r.Next(1, 10);
temp.y = (int)(temp.z / temp.x);
temp.z = temp.x * temp.y;
//vervormen naar quotiënt
int t = temp.z;
temp.z = temp.y; temp.y = temp.x; temp.x = t;
break;
}
} while (temp.z == dupControle);

s.Add(temp);
}
return s;
}
}
public struct som{
public int x, y, z;
public char op;
public override string ToString(){
return x.ToString() + op.ToString() + y.ToString() + '=' + z.ToString();
}
}[/cpp]

FRk6j.jpg

Download.
 
Laatst bewerkt:
Status
Niet open voor verdere reacties.
Terug
Bovenaan Onderaan