Bash script

Kezdőlap Fórumok Programozás Bash script

8 bejegyzés megtekintése - 431-438 / 438
  • Szerző
    Bejegyzés
  • #2053608
    Goosfrabaa
    Felhasználó

      Sziasztok!

      A feladat röviden amihez ötleteket várok: véletlenszámok generálása megadott intervallumon belül úgy, hogy két egyforma szám ne keletkezzen és az összes elemet használjuk fel. A dolog triviálisnak látszik (hasonló a lotto számok problémájához), de egy fokkal mégis nehezebb.

      Az általam használt megoldással, ha mondjuk 1-90 között generálok véletlenszámokat, akkor átlagban 81 számig nincs semmi probléma (bár egyre lassabban születnek meg az új számok). Ez után borzalmasan lelassul a szkript.. igazából 84-ig már nem jutottam el, pedig vártam 1-2 percet.
      És akkor még nem is próbáltam mondjuk 1-500 (vagy még nagyobb) számokból listát előállítani.

      Íme az eddigi kód:

      Code:
      for b in $(seq 1 90)
      do
         while echo ${a:=0} | grep -q ${rand:=0}
         do
             let rand=”$RANDOM % (90 – 1 + 1) + 1″
         done
         echo „$b. szam $rand”
         a=”$a $rand”
      done

      Tehát a kérdés, hogyan lehet egyszerűen, de hatékonyan megoldani bash szkripttel a fenti problémát?

      #2053609
      uzsolt
      Felhasználó

        Javaslok egy listát tartani a még benn levő számokról, és abból törölgetni a már „kisorsolt” számokat, és a maximálisan generálható véletlenszám is csökken egyet minden körben. Remélem, érthető az elve 😉

        #2053610
        Goosfrabaa
        Felhasználó
          uzsolt wrote:
          Javaslok egy listát tartani a még benn levő számokról, és abból törölgetni a már „kisorsolt” számokat, és a maximálisan generálható véletlenszám is csökken egyet minden körben. Remélem, érthető az elve 😉

          Az elv igen, bar érdekelne, hogyan csinálnád a gyakorlatban.

          Én tömbökön agyalok – hogy az aktuális fel nem használt listából minden sorsolás után gyártanék egy új tömböt – de nem vagyok biztos benne, hogy gyorsabb lenne.
          Azért kíváncsi vagyok, hátha valaki mond még valami okosat.

          #2053611
          uzsolt
          Felhasználó

            Gyorsabb lenne, már csak azért is, mert nem lenne feleslegesen addig hívogatva a véletlenszám-generálás, amíg jó nem lesz. Ezért lassulsz be a végefelé.
            „Rendes” nyelvben talán egy láncolt lista lenne a legjobb erre.
            Bash-ban talán… kezelném a listát egytől százig, és ha mondjuk a 19 jön ki, akkor a 19. sort törölném (persze előtte kiszedném, és beraknám a többi szám közé).

            #2053612
            uzsolt
            Felhasználó

              Na, egy kész kód, hogy lásd, nem csak a levegőbe beszélek 😉

              Code:
              #!/bin/bash
              MIN=1
              MAX=100
              STEP=$((MAX – MIN + 1))
              POSSIBLE=$(mktemp)
              OUTFILE=randomized.lst

              rm -rf $OUTFILE
              touch $OUTFILE
              seq $MIN $MAX > $POSSIBLE

              while [ $STEP -gt 0 ]; do
                  RND=$(( RANDOM % STEP + 1 ))
                  sed -n „$RND p” $POSSIBLE >> $OUTFILE
                  sed -i „$RND d” $POSSIBLE
                  STEP=$(( STEP – 1 ))
              done

              rm $POSSIBLE
              cat $OUTFILE

              A futása:

              Code:
              $ time ./proba
              90
              62
              55
              27
              30
              14
              46
              26
              95
              38
              2
              79
              76
              49
              75
              4
              57
              9
              65
              33
              35
              31
              58
              40
              18
              24
              10
              70
              52
              50
              98
              100
              15
              61
              11
              6
              12
              83
              51
              68
              74
              8
              63
              84
              89
              45
              80
              67
              21
              7
              20
              85
              81
              3
              43
              37
              69
              5
              96
              59
              88
              66
              25
              16
              82
              87
              1
              42
              39
              73
              23
              48
              99
              54
              92
              28
              94
              60
              29
              64
              91
              19
              72
              97
              78
              93
              22
              44
              71
              41
              17
              77
              86
              36
              34
              13
              47
              53
              56
              32

              real 0m0.418s
              user 0m0.097s
              sys 0m0.290s

              Ha gondolod, ellenőrizd le a számokat 😉

              #2053613
              Goosfrabaa
              Felhasználó

                Nem rossz 😉 és jól átlátható.
                Sebességben is egész kellemes. Az egyetlen amit – ha lesz egy kis időm – szeretnék majd megoldani, az a sed és fájlműveletek kihagyása. Hiába no, kell a kihívás  🙂

                Köszi!

                #2053614
                uzsolt
                Felhasználó
                  Goosfrabaa wrote:
                  Nem rossz 😉 és jól átlátható.
                  Persze, hogy átlátható. Minden programnak ilyennek kell lennie, szóval ez legyen példa mindenki előtt 😀

                  Goosfrabaa wrote:
                  Sebességben is egész kellemes. Az egyetlen amit – ha lesz egy kis időm – szeretnék majd megoldani, az a sed és fájlműveletek kihagyása.
                  Az is megoldható, a fájlművelet biztosan. Egy változóba rakod el a seq kimenetét, de akkor újsor helyett szóköz lesz az elválasztó. A sed… nem vagyok annyira otthon a bash programozásában, de az se kizárt, hogy kihagyható, de így egyszerűbb 😉 Az utánaolvasás rád marad, de kérlek, közöld a végét 🙂
                  #2053615
                  Goosfrabaa
                  Felhasználó

                    Nemrég találtam a problémára egy hihetetlenül egyszerű és gyors megoldást, íme:

                    Code:
                    seq 90 | shuf

                  8 bejegyzés megtekintése - 431-438 / 438
                  • Be kell jelentkezni a hozzászóláshoz.