De opdracht
Schrijf een programma wat een getal ontbindt in factoren en laat zien of het een priemgetal is
De makkelijkste oplossing is natuurlijk gebruik van ‘factor’, maar helaas laat dat programma nog niet zien of het getal priem is:
$ factor 30
30: 2 3 5
Team 1
Dit script toont alle getallen waardoor gedeeld kan worden, dus helaas ook getallen die zelf weer ontbonden kunnen worden.
#!/bin/bash
number=$1
prime=true
for i in $(seq 2 1 $(($number - 1)))
do
if [ $(($number % $i)) -eq 0 ]
then
prime=false
out="$out \n number $i a factor"
fi
done
if [ "$prime" = true ]
then
echo "Optimus Prime!"
fi
echo -e $out
Team 2
Dit script heeft hetzelfde euvel als het script van team 1. Er is wel een mooie controle of de meegegeven parameter een getal is.
#!/bin/bash
getal="$1"
re='^[0-9]+$'
if ! [[ $getal =~ $re ]] ; then
echo "Fout: Geen nummer" >&2; exit 1
fi
priemgetal=1;
for (( c=2; c<$getal; c++ ))
do
let "remainder = $getal % $c"
if [ $remainder -eq 0 ]; then
echo "$getal is deelbaar door $c";
priemgetal=0;
fi
done
if [ $priemgetal -eq 1 ]; then
echo "$getal is een priemgetal";
fi
Team 3
Dit script ontbindt keurig in factoren. En heel mooi… met behulp van de exit code kan worden vastgesteld of het een priemgetal is.
#!/bin/bash
if [[ "$#" -ne 1 || ! "$1" =~ ^[0-9]+$ || $1 -eq 0 ]]; then
echo "usage: $0 INT" >&2
echo " where INT>0" >&2
exit 1
fi
NUM=$1
I=2
while [[ "$I" -lt $1 ]]; do
if [ "$((NUM%I))" -eq "0" ]; then
echo $I
NUM=$((NUM/I))
else
I=$((I+1))
fi
done
[[ "$NUM" -ne 1 ]] || exit 1
Team 4
Script werkt juist, maar controleert niet of de invoer een getal is. Ook een tekst-parameter levert het resultaat ‘priemgetal’ op. Bijzonder toch!
#!/bin/bash
[[ $# -eq 0 ]] && { echo "Gebruik: ontbinden <getal>"; exit; }
noemer=2
getal=$1
factoren=1
while (( $noemer <= getal )); do
rest=$(($getal%$noemer))
if [ $rest -eq 0 ]; then
echo "$noemer"
getal=$((getal/noemer))
noemer=2
factoren=$((factoren+1))
else
noemer=$((noemer+1))
fi
done
[[ $factoren -lt 3 ]] && echo "Priemgetal!"
exit
Snelheid
De snelheid van de scripts is nogal verschillend. Bij het ontbinden van het getal 4536731 zijn de tijden:
team | tijd |
---|---|
1 | 0m48.319s |
2 | 1m15.288s |
3 | 1m2.878s |
4 | 0m0.053s |
De snelheid van team4 is vooral te danken aan het slimmigheidje om bij een gevonden factor | |
verder te gaan met het getal dat overblijft na deling. |