Проект Эйлера 1 - Умножение 3 и 5 по Локи

Мультипликации из 3 и 5

  

Мультипликации 3 и 5
  Проблема 1

     

Если мы перечислим все натуральные числа ниже 10, кратные 3 или 5, получим 3, 5, 6 и 9. Сумма этих кратных значений равна 23.

     

Найдите сумму всех кратных 3 или 5 ниже 1000.

Используется командная строка (bash):

(seq 0 3 999; seq 0 5 999) | sort | uniq | xargs | tr ' ' '+' | bc

Для диапазона это показалось достаточно хорошим:

> time (seq 0 3 999; seq 0 5 999) | sort | uniq | xargs | tr ' ' '+' | bc
233168

real    0m0.021s
user    0m0.019s
sys     0m0.019s
8 голосов | спросил Martin York 2 Mayam17 2017, 11:05:17

3 ответа


9

Вы можете заменить sort | uniq на sort -u. Обратите внимание, что (...) выполняется в под-оболочке. Группировка с помощью { ...; } будет более эффективной, и эквивалент того, что вы сделали.

Таким образом, без оптимизации, сохраняя его простым и легким в использовании, вы получаете:

{ seq 0 3 999; seq 0 5 999; } | sort -u | xargs | tr ' ' '+' | bc

Тем не менее, сортировка звучит не очень хорошо. Вероятно, было бы лучше не сортировать, но добавить сумму seq 0 -15 -999.

seq не переносится. И это дополнительный процесс. Вы можете либо использовать собственный синтаксис Bash {start..end..step}, либо собственный счет Bash for, но я уверен, что вы намеренно не сделали этого, потому что это немного дольше.

И поскольку Bash может легко сделать такую ​​простую математику, вам действительно не нужен bc.

Вот более эффективная версия, использующая меньшее количество процессов:

((x = $({ seq 0 3 999; seq 0 5 999; } | tr '\n' '+')$(seq 0 -15 -999))); echo $x

Вот еще одна версия, использующая только собственные функции Bash:

x=0
for ((i = 0; i < 1000; i += 3)); do ((x += i)); done
for ((i = 0; i < 1000; i += 5)); do ((x += i)); done
for ((i = 0; i < 1000; i += 15)); do ((x -= i)); done
echo $x

Наиболее эффективное решение, конечно, использует формулу закрытого формула:

n=999; echo $((3 * (n / 3) * (n / 3 + 1) / 2 + 5 * (n / 5) * (n / 5 + 1) / 2 - 15 * (n / 15) * (n / 15 + 1) / 2))
ответил janos 2 Maypm17 2017, 14:47:44
3

Довольно интересный выбор языка для решения проблемы Эйлера проекта. Собираетесь ли вы решить остальные проблемы в bash?

Общей ошибкой этой конкретной проблемы Эйлера является включение 15-ти, поскольку они делятся на 3 и 5. Добавляя uniq после sort вы избегаете этой ловушки.

Хорошее использование tr и bc для вычисления суммы, однако имейте в виду, что если вы увеличите количество последовательностей, вы можете столкнуться с проблемами, связанными с длинами аргументов. Если вы это сделаете, то xargs также может начать действовать смешно. ( Обновление: Как видно из комментариев, это может быть предотвращено путем введения вторичного уровня xargs, tr и bc)

Это не так много, чтобы комментировать, кроме того, что это unix, так что есть много способов сделать это. Включение различных опций с помощью sed, awk, perl, bash scripting и т. д. Это, однако, приятное, аккуратное и простое решение, которое идеально подходит для расширенного принципа YAGNIA , То есть: Вам больше не понадобится .

ответил holroy 2 Maypm17 2017, 12:54:38
0

Как я уже сказал в комментарии (теперь удален), я не думаю, что это действительно решение «bash».

В чистом bash вы можете сделать что-то вроде этого, цикл один раз:

#!/bin/bash

COUNTER=0
TOTALSUM=0
A=0
while [  $COUNTER -lt 1000 ]; do
    let A=COUNTER%5
    if [[ $A = 0 ]]; then
        let TOTALSUM=TOTALSUM+COUNTER
    else
        let A=COUNTER%3
        if [[ $A = 0 ]]; then
            let TOTALSUM=TOTALSUM+COUNTER
        fi
    fi
    let COUNTER=COUNTER+1 
done

echo $TOTALSUM

Но если вам нужна версия с одним слоем (которая в конце концов не одна строка):

for ((i = 0; i < 1000; i += 1)); do let A=i%5; let B=i%3; if [[ $A = 0 || $B = 0 ]]; then let TOTALSUM=TOTALSUM+i; fi; done; echo $TOTALSUM
ответил ChatterOne 2 Maypm17 2017, 21:58:15

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132