Скрипт Bash, который перечисляет числа 1-1000 последовательно с коэффициентами, обозначенными желтым, даже зеленым, а простые числа - синим - PullRequest
0 голосов
/ 04 декабря 2018

Очевидно, что это классное задание.Я играл с ним уже пару дней.У меня легко получился четный и нечетный аспект, чтобы он работал нормально, но у меня постоянно возникают проблемы с простыми числами.

Это нечетное / четное и работает

  #!/bin/bash
  for i in $(seq 1000)
  do
    if (($i % 2));then  #even
        echo -e "\e[32m$i\e[0m"  #green

    else  #odd
        echo -e "\e[33m$i\e[0m"  #yellow

    fi
  done

Это нечетное/ даже / премьер, и я не могу заставить его работать.

  #!/bin/bash
  for i in $(seq 1000)
  do
    if (($i % 2));then  #even
            if
                    ($i -eq factor {2..1000})
                            echo -e "\e[34m$i\e[0m" #blue
            else
                    echo -e "\e[32m$i\e[0m"  #green
            fi
    else  #odd
            if
                    ($i -eq factor {2..1000})
                            echo -e "\e[34m$i\e[0m" #blue
            else
                    echo -e "\e[33m$i\e[0m"  #yellow
            fi
    fi
  done

Это всего лишь моя последняя попытка.Я пробовал пару разных способов и не работать.Небольшая помощь будет оценена.Возможно, я делаю это совершенно неправильно, может быть, я близок, но я потратил много времени на изучение этого и, кажется, никогда не смогу применить его к моему сценарию.

Ответы [ 3 ]

0 голосов
/ 04 декабря 2018

Это довольно просто.

# from https://stackoverflow.com/questions/45392068/check-if-a-number-is-a-prime-in-bash
isPrime() {
    if (( $1 == 2 || $1 == 3 )); then
        return 0  # prime
    fi
    if (( $1 % 2 == 0 || $1 % 3 == 0 )); then
        return 1  # not a prime
    fi
    local i w
    i=5
    w=2
    while (( i * i <= $1 )); do
        if (( $1 % i == 0 )); then
            return 1  # not a prime
        fi
        i=$((i + w))
        w=$((6 - w))
    done
    return 0  # prime
}

isEven() {
    (( $1 % 2 == 0 ))
}


seq 1000 |
while IFS= read -r n; do
   if isPrime "$n"; then
       echo blue "$n"
   elif isEven "$n"; then
       echo green "$n"
   else
       echo yellow "$n"
   fi
done

isPrime функция только что скопирована из этой цепочки , которая была первым результатом поиска bash how to check for prime number в Google.Исправлено возвращаемое значение, поэтому он возвращает 0 (успех), если число простое, и возвращает ненулевое значение, если число не простое, и изменено на использование только ариметических расширений.

Поскольку OP понимает, как использовать escape-последовательностидля печати цветного вывода на терминалах, я просто сделал простое эхо для удобства чтения.

@ edit Исправлена ​​опечатка в функции isPrime / while / s / == / <= / <br>@edit и, конечно, isEven.следует поменять местами ...

0 голосов
/ 04 декабря 2018

Базовый подход использования factor для определения, является ли число простым, в порядке, но для извлечения информации требуется небольшая работа.Эта измененная версия исходного кода является одним из способов сделать это:

#!/bin/bash

# A glob pattern to match 'factor' output that has at least two numbers
# separated by whitespace after a colon (e.g. '30: 2 3 5')
composite_factors_glob='*:*[0-9]*[[:space:]]*[0-9]*'

for i in {1..1000} ; do
    factors=$(factor "$i")
    # shellcheck disable=SC2053
    if (( i > 1 )) && [[ $factors != $composite_factors_glob ]] ; then
        echo -e "\e[34m$i\e[0m" # prime => blue
    elif ((i%2 == 0)) ; then
        echo -e "\e[32m$i\e[0m" # even  => green
    else
        echo -e "\e[33m$i\e[0m" # odd   => yellow
    fi
done

Комментарий # shellcheck подавляет ложное предупреждение Shellcheck .

0 голосов
/ 04 декабря 2018

После псевдокода простого числа - https://en.wikipedia.org/wiki/Primality_test#Pseudocode, довольно просто перенести его на скрипт BASH:

#! /bin/bash

# Given an integer as an argument
# return 1 if the number is prime, 0 otherwise
function isPrime
{
    number=$1

    if [ $number -le 3 ]; then
        if [ $number -gt 1 ]; then
            return 1
        else
            return 0
        fi
    elif [ $(( $number % 2 )) -eq 0 ] || [ $(( $number % 3 )) -eq 0 ]; then
        return 0
    fi

    i=5
    while [ $(( $i * $i )) -le $number ]; do
        iplus2=$(( $i + 2 ))
        if [ $(( $number % $i )) -eq 0 ] || [ $(( $number % $iplus2 )) -eq 0 ]; then
            return 0
        fi
        i=$(( $i + 6 ))
    done

    return 1
}

Нет необходимости использовать $ с нотацией $varвнутри числовых выражений, например: $(( x + 1 )) - это нормально, но я намеренно оставляю это там, так как я думаю, что это делает работу кода более очевидной для читателя, не использующего сценарии.

Функции BASH на самом деле не могутвозвращать значение в традиционном смысле программирования, это в основном код выхода.Таким образом, «возвращаемое» значение должно быть получено через $?.

isPrime $1
primal=$?
if [ $primal -eq 1 ]; then
    echo "$1 is prime"
else
    echo "$1 is not prime"
fi

. Вывод:

$ ./isPrime.sh 7
7 is prime
$ ./isPrime.sh 8
8 is not prime
...