LINUX.ORG.RU

Олимпиадная задача на баше

 ,


1

4

Ряд чисел разделенных дефисами должен быть умножен на два и вместо дефисов должны быть восклицательные знаки Например 2-7-9-10 должно стать 4!14!18!20! И это все должно быть решено одной командой Ну совсем нету никаких идей что делать, что посоветуете почитать?



Последнее исправление: cetjs2 (всего исправлений: 1)
echo 2-7-9-10 | awk -F- 'BEGIN {OFS="!"} {a=1; while (a<=NF) {$a=$a*2; a++}; print $0 }'
bl ★★★
()

echo '2-7-9-10' | awk -F'-' '{for (i=1; i<=NF; i++){a[$i]++}}{for (i in a) {printf i*2."!«}}'

anonymous
()

Где гарантии что последнии три сообщения это не тот самый патч?

Debasher ★★★★★
()

Вообще какая-то странная олимпиада. Олимпиады должные быть по алгоритмам по идее, а тут какой-то ковбойский выстрел с бедра.

anonymous
()
Ответ на: комментарий от anonymous
perl -e'map {print $_ *= 2, "!"} split /-/, shift' 2-7-9-10
Deleted
()
src=1-2-3 ; rslt='' ; for i in ${src//-/ } ; do rslt="$rslt$((i * 2)) " ; done ; echo ${rslt// /\!}

Чистый bash, без perl'ов, awk'ов и прочего.

dexpl ★★★★★
()

Что значит одной командой? Команды, которая превращает 2-7-9-10 в 4!14!18!20! нет, или «команда» это вызов скрипта на баше, перле и т.д.?

at ★★
()
Последнее исправление: at (всего исправлений: 1)

Очевидно же

join-by-ifs() {
    printf '%s\n' "$*"
}
ret() {
    declare -n _ans=$1
    "${@:2}"
}
map() {
    local i elem
    for (( i = 0; i < ${#_ans[@]}; ++i )); do
        ret elem "$@" "${_ans[i]}"
        _ans[i]=$elem
    done
}
mul() {
    _ans=$(( $1 * $2 ))
}

IFS='-' read -ra arr
ret arr map mul 2
IFS='!' join-by-ifs "${arr[@]}"
anonymous
()
Ответ на: комментарий от Studentik2000

with pipes, seb, tail, bc, tr , head

Так не интересно. И видимо все-таки не seb, а sed.

dexpl ★★★★★
()
Ответ на: Очевидно же от anonymous

И это все должно быть решено одной командой

bash -c 'join-by-ifs() {
    printf "%s\n" "$*"
}
ret() {
    declare -n _ans=$1
    "${@:2}"
}
map() {
    local i elem
    for (( i = 0; i < ${#_ans[@]}; ++i )); do
        ret elem "$@" "${_ans[i]}"
        _ans[i]=$elem
    done
}
mul() {
    _ans=$(( $1 * $2 ))
}

IFS="-" read -ra arr
ret arr map mul 2
IFS="!" join-by-ifs "${arr[@]}"'
anonymous
()

Ряд чисел разделенных дефисами должен быть умножен на два и вместо дефисов должны быть восклицательные знаки Например 2-7-9-10 должно стать 4!14!18!20! И это все должно быть решено одной командой Ну совсем нету никаких идей что делать, что посоветуете почитать?

python -c 'import sys; print("!".join(str(int(x) * 2) for x in sys.argv[1].split("-")))' '2-7-9-10'
user_id_68054 ★★★★★
()
Ответ на: комментарий от dexpl

нет перевода строки в конце таковой. Впрочем, в ТЗ его тоже нет :)

src=1-22-3

echo "$(for i in ${src//-/ } ; do echo -n "$(($i*2))"\! ; done)"

однако остался неудачный восклицательный знак в конце!

а в ТЗ просили только заменять (но не добавлять)

user_id_68054 ★★★★★
()
Последнее исправление: user_id_68054 (всего исправлений: 4)
Ответ на: комментарий от user_id_68054

а в ТЗ просили только заменять (но не добавлять)

Судя по приведенному в ТЗ примеру, ! в конце как раз-таки нужен.

Upd: перечитав ТЗ, пришел к выводу — автор не в ладах с пунктуацией, вследствие чего трудно сказать наверняка.

dexpl ★★★★★
()
Последнее исправление: dexpl (всего исправлений: 1)
echo 2-7-9-10 | ( read line; echo -e ${line//[-]/*2\\n}*2) | while read line; do echo -n "$((line))!"; done
anonymous
()
Ответ на: комментарий от Studentik2000

Написано было with pipes, seb, tail, bc, tr , head

интересно, а зачем bc ? :-)

ну ладно...

вот — заиспользовать всё что нужно — как смог по максимому (кроме head и tail — куда их вляпать понятия не имею :) )

src=2-7-9-10

echo "$(echo "$src" | tr '-' '\n' | echo $(while read x; do echo "$x * 2"; done | bc) | tr ' ' \!)"
user_id_68054 ★★★★★
()
Последнее исправление: user_id_68054 (всего исправлений: 3)

Pure POSIX shell

str=8-44-32-11
IFS="-"
set -- $str
for arg; do r="${r}"${r:+'!'}$((arg * 2)); done
echo $r # 16!88!64!22
joy4eg ★★★★★
()
Последнее исправление: joy4eg (всего исправлений: 1)
Ответ на: комментарий от dexpl

А как иначе в bash умножить целое число на 2? :)

ага.. вот и я подумал :-D

user_id_68054 ★★★★★
()

2-7-9-10 должно стать 4!14!18!20!

В костыльных традициях:

mikhail@lens ~ $ echo '2-7-9-10' |tr '-' '\n' | while read num; do echo $(($num * 2)); done | tr '\n' '!'
4!14!18!20!

Deleted
()

Вот еще:

STR="8-44-32-11" ; STR="${STR}-" ; R=$( while [[ -n "$STR" ]]; do echo -n "$(( ${STR%%-*}*2 ))!" ; STR="${STR#*-}" ; done ) ; echo "${R::-1}"

Kroz ★★★★★
()

ОДНОЙ bash коммандой

STR="8-44-32-11" ; eval echo $( sed 's/\([0-9]\+\)/$((\1*2))/g ; s/-/!/g' <<< "$STR" )
Kroz ★★★★★
()
Ответ на: комментарий от anonymous

Вообще какая-то странная олимпиада

Специальная

fang
()

src=1-22-3; for i in ${src//-/ } ; do echo -n «$(($i*2))»'!' ; done ; Кто может прокомментировать данный скрипт?

Studentik2000
() автор топика
Ответ на: комментарий от Deleted

Привет, спасибо за ответ в моей теме, прокомментируй вот это действие ${src//-/ } и вот это echo -n «$(($i*2))»'!' ; в частности «$(($i*2))»'!'

Studentik2000
() автор топика
Ответ на: комментарий от Studentik2000

Привет.

${src//-/ } - замена символа "-" на " ". Из строки 2-3-4 получается 2 3 4 на выходе. Для того чтобы for мог распарсить корректно.

в частности «$(($i*2))»'!'

$(($i*2)) - $(()) - арифметическая операция в баше. $(($i*2)) - выведет $i умноженное на 2, как в задании. Дальше к результату дописывается "!". Вне выражения умножения, иначе получаем event not found

Можно ещё без кавычек: echo -n $(($i*2))! но не факт что в каком-то ksh/zsh не выдаст ошибку

Deleted
()
Ответ на: комментарий от user_id_68054

а ты можешь прокоментировать дейстивая твоего скрипта? src=2-7-9-10

echo «$(echo »$src" | tr '-' '\n' | echo $(while read x; do echo «$x * 2»; done | bc) | tr ' ' \!)"

Studentik2000
() автор топика
Ответ на: комментарий от Studentik2000

Написано было with pipes, seb, tail, bc, tr , head

Ну совсем нету никаких идей что делать, что посоветуете почитать?

Советуем почитать man bash, man sed, man tail, man bc, man tr и man head.

Pythagoras ★★
()
Ответ на: комментарий от Studentik2000

сначало tr заменяет символы "-" на " ":

было 2-7-9-10, а стало 2 7 9 10.

затем цикл while добавляет для каждого слова " * 2" (и символ новой строки возникает из-за echo):

было «2 7 9 10» а стало

2 * 2
7 * 2
9 * 2
10 * 2

потом bc высчитывает это и получает

4
14
18
20

затем через echo мы преобразовываем это просто в последовательность слов (то есть убираются символы новой строки. слова разделены пробелами):

получается 4 14 18 20.

потом заключительный tr заменяет символы " " на "!":

получается 4!14!18!20

# P.S.: вообщем — это наверно самое нерациональное решение задачи... зато заиспользовал tr и bc :-)

user_id_68054 ★★★★★
()
Последнее исправление: user_id_68054 (всего исправлений: 7)
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.