Kezdőlap › Fórumok › Programozás › Bash script
- This topic has 437 hozzászólás, 56 résztvevő, and was last updated 13 years, 5 months telt el by
Goosfrabaa.
-
SzerzőBejegyzés
-
2009-12-08-14:27 #2053608
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”
doneTehát a kérdés, hogyan lehet egyszerűen, de hatékonyan megoldani bash szkripttel a fenti problémát?
2009-12-08-15:50 #2053609Javaslok 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 😉
2009-12-08-20:14 #2053610uzsolt 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.2009-12-08-20:54 #2053611Gyorsabb 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é).2009-12-08-21:49 #2053612Na, 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.lstrm -rf $OUTFILE
touch $OUTFILE
seq $MIN $MAX > $POSSIBLEwhile [ $STEP -gt 0 ]; do
RND=$(( RANDOM % STEP + 1 ))
sed -n „$RND p” $POSSIBLE >> $OUTFILE
sed -i „$RND d” $POSSIBLE
STEP=$(( STEP – 1 ))
donerm $POSSIBLE
cat $OUTFILEA 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
32real 0m0.418s
user 0m0.097s
sys 0m0.290sHa gondolod, ellenőrizd le a számokat 😉
2009-12-09-08:02 #2053613Nem 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!
2009-12-09-14:28 #2053614Goosfrabaa 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 🙂2011-12-06-22:25 #2053615Nemrég találtam a problémára egy hihetetlenül egyszerű és gyors megoldást, íme:
Code:seq 90 | shuf -
SzerzőBejegyzés
- Be kell jelentkezni a hozzászóláshoz.
legutóbbi hsz