Вам дана строка, состоящая из символов 0123456789+*()
. Вы можете предположить, что строка всегда является допустимым математическим выражением.
Ваша задача - убрать лишние скобки, предполагая, что умножение имеет более высокий приоритет, чем сложение.
Скобки следует удалять только тогда, когда они не нужны конструктивно :
- из-за умножения более высокого приоритета:
3+(4*5)
=>3+4*5
- из-за умножения или сложения ассоциативности:
3*(4*5)
=>3*4*5
- когда они избыточны вокруг выражения:
3*((4+5))
=>3*(4+5)
Скобки должны быть сохранены, когда они могут быть упрощены из-за определенных числовых значений:
1*(2+3)
не должно быть упрощено до1*2+3
0*(1+0)
не должно быть упрощено до0*1+0
Примеры:
(4*12)+11 ==> 4*12+11
(1+2)*3 ==> (1+2)*3
3*(4*5) ==> 3*4*5
((((523)))) ==> 523
(1+1) ==> 1+1
1*(2*(3+4)*5)*6 ==> 1*2*(3+4)*5*6
1*(2+3) ==> 1*(2+3)
0*(1+0) ==> 0*(1+0)
(((2+92+82)*46*70*(24*62)+(94+25))+6) ==> (2+92+82)*46*70*24*62+94+25+6
1*(2*(3+4)*5)*6
должен быть интересный тестовый сценарий (для которого мое решение в настоящее время не удается).(2+2)*1
Ответы:
Mathematica,
1059791 байт-6 байт благодаря Роману !
Заменяет
+
и*
на~~
(StringExpression
) и**
(NonCommutativeMultiply
) соответственно, оценивает, структурирует и заменяет операторы обратно.источник
StringExpression
вместоDot
, и удаляя" "->""
предложение:a=StringReplace;ToString@ToExpression@a[#,{"*"->"**","+"->"~~"}]~a~{" ** "->"*","~~"->"+"}&
JavaScript (ES6) 163
178Редактировать 15 байтов сохранено thx @IsmaelMiguel
Меньше гольфа
Тест
источник
y.indexOf('+')
вместоy.indexOf`+`[...]
? ([...] добавлено, чтобы избежать прерывания форматирования).a=>eval(`for(b=s=[]${_=';a!=b;a=b.replace(/'}\\(([^()]*)\\)(?=(.?))/,(x,y,z,p)=>~y.indexOf('+')<0?-s.push(b[p-1]=='*'|z=='*'?x:y):y))b=a;for(b=0${_}-\\d+/,x=>s[~x]))b=a`)
for(b=
,=='*'
и другие повторяющиеся биты. Кроме того, не так~y.indexOf('+')<0
же, как~y.indexOf('+')
? Так как только значение , котороеindexOf()
возвращается , которое оценивает falsy значения является-1
, то ,<0
кажется излишним. Или, если я ошибаюсь, вы могли бы сделатьy.indexOf('+')>1
<0
это дерьмо, оставшееся от неопрятной версии и должно быть удалено. 2: подумав еще раз,for
можно пересмотреть, чтобы включить в повторную часть.Реализация Python3 + PEG в Python , 271 байт
Некоторое время назад я сделал реализацию PEG в Python . Я думаю, что я могу использовать это здесь.
Разбирает выражение в дерево и сохраняет круглые скобки, только если дочерний объект является сложением, а родительский является умножением.
источник
Perl, 132 байта
Источник 129 байт + 3 для
-p
флага:С помощью:
источник
Рубин,
140130 байтИсточник 127 байт + 3 для
-p
флага:И безглым
источник
0 while
синтаксисом?expr while cond
эквивалентноwhile cond; expr; end
. Здесь я хочу выполнять толькоcond
несколько раз, и у меня нет тела цикла. Обычно можно написать это какwhile cond; end
или, возможно,loop{ break unless cond }
но0 while cond
меньше байтов.0
Ничего не делает; это просто потому, что для короткой формы цикла while требуется тело.Сетчатка, 155 байт
Попробуйте онлайн!
Проверьте все тестовые случаи одновременно.
объяснение
Главное, этот код:
Это регулярное выражение может соответствовать любой строке, в которой скобки сбалансированы, например,
1+(2+(3))+4
или2+3
.Для простоты объяснения, пусть это регулярное выражение будет
B
.Кроме того, давайте использовать
<
и>
вместо скобок, а такжеp
иm
для\+
и\*
.Код становится:
Первые две строки соответствуют скобкам, которые состоят только из умножения, например,
(1*2*3)
или даже(1*(2+3)*4)
. Они заменены их содержанием внутри.Последние две строки соответствуют скобкам, которым не предшествует, и за которыми не следует умножение. Они заменены их содержанием внутри.
Начальный
{`
означает «заменить до идемпотента», что означает, что замены выполняются до тех пор, пока они либо не перестанут совпадать, либо будут заменены собой.В этом случае замены выполняются до тех пор, пока они больше не совпадают.
источник
1*(2*(3+4)*5)*6
.(1*(2+3)+4)*5
Python 3,
274269359337336 байтовЭтот метод в основном удаляет каждую возможную пару круглых скобок и проверяет, если он все еще оценивает то же самое.
Test Harness
Обновления
re
Libl
) лямбдаисточник
1*(2+3)
, потому что OP сказал не упрощать для особых случаев чисел. Хороший ответ, хотя; это мой голос.PHP, 358 байт
Не впечатляющая длина, это то, что я получаю за выбор менее оптимального подхода (и использование менее оптимального языка).
Снимает пару скобок, затем удаляет полученное выражение. Если результат совпадает с исходным, он добавляет его в карту допустимых выражений и повторяет до тех пор, пока не будут найдены новые выражения. Затем печатает кратчайшее действительное выражение.
Разрывается, когда результат выражения становится большим и приводятся к двойным / экспоненциальным обозначениям.
источник
Пролог (SWI) ,
122118 байтПопробуйте онлайн!
Определяет предикат,
//2
который удаляет скобки из строкового значения первого аргумента и выводит строку через второй аргумент. Если бы ввод мог быть в терминах Пролога, это было бы только8177 байтов, определяющих+/2
без необходимости иметь дело с многословнымterm_string/2
, но много ненужных скобок просто не существовало бы для начала таким образом, так что это было бы довольно близко к мошенничеству, так как все, что+/2
делает, это обрабатывает ассоциативность.Я пытался использовать
=../2
для всего этого, но это вышло намного дольше, потому что трехбайтовый оператор, который работает со списками, не совсем краткий:Пролог (SWI) , 124 байта
Попробуйте онлайн!
источник