Vinnaren i pepparkakshustävlingen!
  • 1
  • 2
2018-04-22, 01:12
  #13
Moderator
Neksnors avatar
Citat:
Ursprungligen postat av RostigHink
Enligt rubriken gäller det c++ så kan man använda vektorer och lite magisk indexering. Dragning utan återläggning implementeras som att sätta en bolls värde till -1. Loopen testar om värdet är negativt och drar i så fall ett nytt slumptal. For-looparna kräver minst 2011 års standard. Det går att implementera looparna på klassiskt vis om man vill. Detta är bara ett sätt, det finns flera.
Kod:
#include <iostream>
#include <vector>
#include <ctime>

using std::vector;
using std::cout;
using std::endl;

int main() {

  vector<int> bollar{-1,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,31,32,33,  34,35};
  vector<int> rad{0,0,0,0,0,0,0};

  int boll;
  srand(time(NULL));
  for (auto&& i: rad) {
    do {
      boll = rand() % 35 + 1;  // slumptal mellan 1 och 35
      if (bollar[boll] > 0) {
        i = bollar[boll];
      }
    } while (bollar[boll] < 0);
    bollar[boll] = -1;
  }

  for (auto&& i: rad) {
    cout << i << " ";
  }
  cout << endl;
}
Fast det fetade gör att körtiden kan bli väldigt lång.

Citera
2018-04-22, 09:03
  #14
Moderator
RostigHinks avatar
Citat:
Ursprungligen postat av Neksnor
Fast det fetade gör att körtiden kan bli väldigt lång.
Jomenvisst fast sannolikheten att körtiden på mitt fulhack överskrider en implementation som blandar och ger är nog rätt låg. När sjunde bollen dras är sannolikheten att springa på en negativ boll en av 5. Men vi kan ju göra en mer akademisk variant i dessa feministiska tidevarv.
Kod:
#include <iostream>
#include <vector>
#include <utility>
#include <ctime>

using std::vector;
using std::swap;
using std::cout;
using std::endl;

int main() {

  vector<int> bollar{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,31,32,33,34,  35};

  size_t p = bollar.size();
  size_t q;

  srand(time(NULL));

  // Sattolos algoritm
  while (p > 1) {
    p--;
    q = rand() % p;
    swap(bollar[p], bollar[q]);
  }

  for (size_t i = 0; i < 7; ++i) {
    cout << bollar[i] << " ";
  }
  cout << endl;
}
Eller så fuskar vi och använder hela arsenalen av biblioteksfunktioner i c++.
Kod:
#include <iostream>
#include <vector>
#include <algorithm>
#include <random>
#include <ctime>

using std::vector;
using std::shuffle;
using std::default_random_engine;
using std::cout;
using std::endl;

int main() {

  vector<int> bollar{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,31,32,33,34,  35};

  unsigned seed = time(NULL);
  shuffle(bollar.begin(), bollar.end(), default_random_engine(seed));

  for (size_t i = 0; i < 7; ++i) {
    cout << bollar[i] << " ";
  }
  cout << endl;
}
Men jag måste nog medge att jag inte tänkte på blanda och ge först. 40 år sedan jag gick programmeringskurser på den nivån sist
Citera
2018-05-06, 12:02
  #15
Medlem
Tack för hjälpen allesammans!
Jag gick igenom det som ni skrev tills jag förstod vad allting gjorde, tack så hemskt mycket!
Citera
2018-05-09, 16:56
  #16
Medlem
Brunbeverns avatar
Citat:
Ursprungligen postat av L3Finschk1
Det är så att jag behöver hjälp med en c++ uppgift, som jag inte direkt vet hur jag ska lösa.

Programmet ska slumpa fram och skriva ut en lottorad på 7 siffror, mellan 1-35.

Detta är en skoluppgift som jag försöker att lösa. Vi fick en kod som inte fungerade, som vi skulle lösa. Jag har löst det mesta (förhoppningsvis), men när jag kör koden så skriver den ut 6 stycken siffror istället för 7. Någon som kan se något/några problem i koden nedanför?

Tackar ödmjukast för hjälp!

Kod:
#include <iostream>
#include <cstdlib>

using namespace std;

int main()
{
    
int lottorad[7]; // Ett heltalsfält som lagrar lottoraden
    
bool lika=false;

    for(
int i=1i<7i++){
        
lottorad[i]=rand()%35+1// Slumpar ett tal mellan 1 och 35

        
for(int j=1j<ij++) // Loopar igenom de tidigare slumpade tal och kontrollerar om det aktuella talet redan har dragits
            
if(lottorad[i]==lottorad[j])
                
lika=true;

        if(
lika) {   // Om det aktuella talet redan dragits så minskas i med 1. Man går alltså tillbaka ett steg i loopen och slumpar ett nytt tal
            
i--;
            
lika=false;
            }

            else {  
// Om det aktuella talet inte hade dragits tidigare så skrivs det ut
            
cout << lottorad[i] << endl;
            }

    }

    return 
0;


Istället för att skapa slumptal och sedan kolla om ett tal är taget redan. Varför inte bara skapa sekvensen 1, 2, 3, 4, ..., n och shuffla dessa siffror i en datastruktur. Sedan plocka ut dem en efter en istället. Då behöver du inte kolla efter dubletter eftersom inga dubletter finns till att börja med.

Kod:
#include <algorithm>
#include <array>

int main()
{
    std::array<int, 30> randomNumbers;
    std::iota(randomNumbers.begin(), randomNumbers.end(), 1);
    std::random_shuffle(randomNumbers.begin(), randomNumbers.end());

    return 0;
}

Nu innehåller randomNumbers 30 slumpade tal och det är bara att plocka de sju första elementen för att få 7 slumpade lottonummer. Således skulle en lottorad av 7 rader kunna vara de 7 första siffrorna.
Citera
2018-05-10, 00:40
  #17
Moderator
Neksnors avatar
Citat:
Ursprungligen postat av Brunbevern
Istället för att skapa slumptal och sedan kolla om ett tal är taget redan. Varför inte bara skapa sekvensen 1, 2, 3, 4, ..., n och shuffla dessa siffror i en datastruktur. Sedan plocka ut dem en efter en istället. Då behöver du inte kolla efter dubletter eftersom inga dubletter finns till att börja med.

Kod:
#include <algorithm>
#include <array>

int main()
{
    std::array<int, 30> randomNumbers;
    std::iota(randomNumbers.begin(), randomNumbers.end(), 1);
    std::random_shuffle(randomNumbers.begin(), randomNumbers.end());

    return 0;
}

Nu innehåller randomNumbers 30 slumpade tal och det är bara att plocka de sju första elementen för att få 7 slumpade lottonummer. Således skulle en lottorad av 7 rader kunna vara de 7 första siffrorna.
Så som uppgiften beskrivs i trådstarten verkar det vara en helt OK lösning, men jag hoppas att läraren ställt lite hårdare krav än vad som framgår, exempelvis att man förväntas implementera någon sorts algoritm själv. Annars skulle man ju kunna leta upp en enkelradare som gör allt.
Citera
2018-05-11, 21:25
  #18
Medlem
Citat:
Ursprungligen postat av Brunbevern
Istället för att skapa slumptal och sedan kolla om ett tal är taget redan. Varför inte bara skapa sekvensen 1, 2, 3, 4, ..., n och shuffla dessa siffror i en datastruktur. Sedan plocka ut dem en efter en istället.

Citat:
Ursprungligen postat av Brunbevern
Nu innehåller randomNumbers 30 slumpade tal och det är bara att plocka de sju första elementen för att få 7 slumpade lottonummer. Således skulle en lottorad av 7 rader kunna vara de 7 första siffrorna.

Eller de sju sista, eller varannan, osv... poängen är att du behöver inte blanda alltihop om du inte ska dra alltihop, det är bortslösat arbete. Här finns tid att tjäna!

Välj istället ett slumptal från listan (1, 2, 3...), presentera det eller gör något annat trevligt med det, kopiera det sista talet i listan till detta index, minska listans storlek med ett, repetera.

Fast kanske finns det potential till säkerhetshål, om än långsökt, att kortet dras just när det behövs t.ex. precis när en användare har klickat på "hit me". Blandning av kortlekarna på slumpmässiga tider okända för allmänheten är säkrast, och man kan aldrig vara för säker.
__________________
Senast redigerad av Kissdemokrat 2018-05-11 kl. 21:28.
Citera
2018-05-13, 15:14
  #19
Medlem
kaks avatar
Citat:
Ursprungligen postat av Kissdemokrat
Eller de sju sista, eller varannan, osv... poängen är att du behöver inte blanda alltihop om du inte ska dra alltihop, det är bortslösat arbete. Här finns tid att tjäna!

Välj istället ett slumptal från listan (1, 2, 3...), presentera det eller gör något annat trevligt med det, kopiera det sista talet i listan till detta index, minska listans storlek med ett, repetera.

Fast kanske finns det potential till säkerhetshål, om än långsökt, att kortet dras just när det behövs t.ex. precis när en användare har klickat på "hit me". Blandning av kortlekarna på slumpmässiga tider okända för allmänheten är säkrast, och man kan aldrig vara för säker.
Edit: Läste fel
Citera
  • 1
  • 2

Stöd Flashback

Flashback finansieras genom donationer från våra medlemmar och besökare. Det är med hjälp av dig vi kan fortsätta erbjuda en fri samhällsdebatt. Tack för ditt stöd!

Stöd Flashback