Je voudrais créer quatre chaînes, chacune avec une longueur aléatoire, mais leur longueur totale devrait être de 10. Les combinaisons de longueur possibles pourraient être:
3 3 3 1
ou
4 0 2 2
Ce qui donnerait alors (respectivement) des chaînes comme ceci:
111 222 333 4
ou
1111 33 44
Comment pourrais-je faire ça?
$RANDOM
vous donnera un entier aléatoire dans la plage 0..32767
. En utilisant une expansion arithmétique, vous pouvez faire:
remaining=10 for i in {1..3}; do next=$((RANDOM % remaining)) # get a number in range 0..$remaining echo -n "$next " ((remaining -= next)) done echo $remaining
Mise à jour: pour répéter le nombre N fois, vous pouvez utiliser une fonction comme celle-ci:
repeat() { for ((i=0; i<$1; i++)); do echo -n $1 done echo } repeat 3 333
Voici un algorithme:
Faites les 3 premières cordes avec une longueur aléatoire, qui n’est pas supérieure à la sum de la longueur (soustrayez-la à chaque fois). Et rest de la longueur – c’est votre dernière corde.
Considère ceci:
sumlen=10 for i in {1..3} do strlen=$(($RANDOM % $sumlen)); sumlen=$(($sumlen-$strlen)); echo $strlen done echo $sumlen
Cela produira vos longueurs, maintenant vous pouvez créer des chaînes, supposez que vous savez comment
solution alternative awk
awk 'function r(n) {return int(n*rand())} BEGIN{srand(); s=10; for(i=1;i<=3;i++) {a=r(s); s-=a; print a} print s}' 3 5 1 1
srand()
pour définir une graine aléatoire, sinon générera les mêmes nombres aléatoires à chaque fois.
Ici, vous pouvez combiner la tâche suivante consistant à générer les chaînes dans le même script awk
$ awk 'function r(n) {return int(n*rand())}; function rep(n,t) {c="";for(i=1;i<=n;i++) c=ct; return c} BEGIN{srand(); s=10; for(j=1;j<=3;j++) {a=r(s); s-=a; printf("%s ", rep(a,j))} printf("%s\n", rep(s,j))}'
généré
1111 2 3 4444