Помните детсадовскую задачку «Сколько будет два плюс два умножить на два?»
Решил это выяснить на sed:
$ sed -f ./1.sed
2+2*2
;2+;2*;2
::+::*::
::+::*:
::+::;::*
::+::::
::::::
6
s/[0-9]/;&/gp
s/0//g; s/1/:/g; s/2/::/g; s/3/:::/g; s/4/::::/g; s/5/:::::/g; s/6/::::::/g; s/7/:::::::/g; s/8/::::::::/g; s/9/:::::::::/g
: ;; s/:;/;::::::::::/gp; t ;
s/;//gp
s/*:/*/gp
: *;
s/\(:*\)\*:/\1;\1*/gp;
t *
s/*//g
s/;//gp
s/+//gp
: -; s/:-:/-/gp; t -
s/-$//gp
: ?
s/::::::::::/;/gp
s/;\([0-9]*\)$/;0\1/p
s/:::::::::/9/; s/::::::::/8/; s/:::::::/7/; s/::::::/6/; s/:::::/5/; s/::::/4/; s/:::/3/; s/::/2/; s/:/1/
s/;/:/gp
t ?
s/^$/0/
Меня хватило на реализацию операций +-*, до деления ход не дошёл.
Практической пользы не ищите — здесь её нет.
Комментарии (12)
impwx
25.07.2016 16:57+8Практической пользы нет, объяснения принципа работы тоже нет. Вы случаем не перепутали хабр и gist?
simpleadmin
25.07.2016 17:00-4Мне казалось, что принцип понятен из
Заголовок спойлера$ sed -f ./1.sed 2+2*2 ;2+;2*;2 ::+::*:: ::+::*: ::+::;::* ::+:::: :::::: 6
impwx
25.07.2016 17:28+13Это вы показали, что делает ваша программа. Остались вопросы — зачем (выяснили, причины нет) и как. Для человека, который не знаком с sed, исходник выглядит как китайская грамота и ответа на этот вопрос не дает. Комментарии к каждой строчке сильно спасли бы ситуацию.
simpleadmin
25.07.2016 21:30+2и как
Здесь действительно нечего описывать. Для человека имеющего минимальные знания sed всё прозрачно и понятно.
Для неимеющего придётся начинать рассказ с элементарных основ sed, но это то же самое, что выложить исходник на C и в одной статье попытаться ему обучить несведущего читателя. Но, попробую.
Sed — потоковый текстовый редактор. Он не «умеет» никаких арифметических действий, более того у него нет переменных. Из всех плюшек только операции условного и безусловного переходов. В нашем случае условного "t" переходящего на метку ": метка" при условии выполнения команды замены "s///". Команда s/pattern1/pattern2/ заменяет соответствие шаблону pattern1, на pattern2. При наличии оператора g делает сие глобально, ну и p позволяет вывести на печать.
Это всё что используется в тексте кода и комментировать такое абсурдно.
Зная этот минимум можно увидеть, что для решения детсадовской задачки мы и действуем дошкольными методами, т.е. счётными палочками (точнее, как отметил potan алгорифмами Маркова).
1 — одна палочка
2 — две палочки
…
У нас в качестве
— палочек ":"
— разрядных единиц ";"
(Вероятно сделал ошибку в выборе ":;" так потерялась наглядность из-за наличия этих же знаков в синтаксисе sed)
Зная это Вы легко прочитаете вывод
5+6 ;5+;6 :::::+:::::: ::::::::::: ;: :1 11
зачем (выяснили, причины нет)
Причины использовать данныйкодизврат действительно нет и я надеюсь, что никто в здравом уме не станет использовать его на практике.
Skorpyo
25.07.2016 20:19Поигрался немного, спасибо автору. Мне бы не хватило на это терпения.
P.S. Нашел бажок.
Пример2+2*2+3-8+1
;2+;2*;2+;3-;8+;1
::+::*::+:::-::::::::+:
::+::*:+:::-::::::::+:
::+::;::*+:::-::::::::+:
::+::::+:::-::::::::+:
:::::::::-:::::::::
::::::::-::::::::
:::::::-:::::::
::::::-::::::
:::::-:::::
::::-::::
:::-:::
::-::
:-:
— 0
А должно быть 2. Он к 8 добавляет 1 и отнимает уже как -9. Попробуете починить?simpleadmin
25.07.2016 20:28Там ещё много чего править «до ума». Коректно будет работать только до первого умножения.
Так уже не будет:
sed -f ./1.sed 2*2*2 ;2*;2*;2 ::*::*:: ::*:*: ::;::*;* :::: 4
simpleadmin
26.07.2016 08:48+1Skorpyo
26.07.2016 09:45Эту статью тоже читал. Сколько у них времени и терпения. Но меня сейчас мало что удивляет. Дай людям возможность, они и не такое придумают.
hottabxp
25.07.2016 20:19+5«Чтоб ничего не сломать занимаюсь всякой фигнёй.» — первое правило it'шника)
shpaker
Мсье знает толк в sed'е