Распределение номеров


11

В этом задании вы будете распределять продукт по суммам и разницам чисел, как описано здесь .

введите описание изображения здесь

Примеры

  Input      |     Output
-------------|-------------
23(12+42)    | (23*12)+(23*42)
9(62-5)      | (9*62)-(9*5)
4(17+8-14)   | (4*17)+(4*8)-(4*14)
15(-5)       | -(15*5)
2(3)         | (2*3)
8(+18)       | +(8*18)
8(-40+18)    | -(8*40)+(8*18)

Технические характеристики

На входе будет строка вида n(_)с единственным положительным целым числом без знака, nза которым следует выражение в скобках _. Это выражение _будет состоять из сумм и разности одной из более положительно целочисленных терминов , разделенного +и -признаков. Первому термину может предшествовать +знак, -знак или знак.

В выходных данных начальное число nдолжно быть распределено для умножения каждого из членов. Каждый член aдолжен быть умножен на лево, nчтобы получить заключенное в скобки выражение (n*a), и эти новые термины должны быть объединены +и -подписаны точно так же, как и исходные термины.

Неверные входы

Это примеры входных данных, которые вам не нужно обрабатывать.

3(5 plus 3)
6(5 13)
(5+8)(6+6)
(5+3)8

выигрыш

Это , поэтому выигрывает самый короткий код в байтах.


Мне приходит в голову, что регулярное выражение действительно хорошо подходит для этой проблемы. Если вы не согласны с решениями reg-ex, вы можете запретить их, хотя люди могут уже работать над этим.
xnor

Разрешены ли библиотеки?
orlp

@orlp В определенной степени, что обсуждалось на мета .
Даунгоут

Интересный случай:8(-40+18)
BrainSteel

Ответы:


2

Пип, 28 байт

DQaUnxWa^'(xR`\d+`'(.n.`*&)`

Объяснение:

                              a is first cmdline arg (implicit)
DQa                           Remove (DeQueue) the closing paren from a
   UnxWa^'(                   Unify n and x with a split on open paren--Python equivalent
                                n,x=a.split("(")
                              n is thus the number to be distributed, and x is the
                                addition/subtraction expression
           xR                 In x, replace...
             `\d+`            ... regex matching numbers...
                  '(.n.`*&)`  ... with the replacement pattern (n*&), where n is the
                                appropriate number and & substitutes the complete match
                              Print result (implicit)

Объекты Pattern Pip в основном следуют синтаксису регулярных выражений Python, но &шаблон замены заимствован из sed.

Узнайте больше о Pip в хранилище Github


9

JavaScript 65 байт

s=>(q=s.split(/[()]/))[1].replace(/(\D?)(\d+)/g,`$1(${q[0]}*$2)`)

Это примет участие. Получите + или -, затем цифры, затем замените их в правильном порядке.

объяснение

s=>   // Function with argument "s"
  (q= // Set q to...
    s.split(/[()]/) // Splits on parenthesis, returns array
  )
  [1] // Gets second match or text inside brackets
  .replace(/ // Replaces string 
     (\D?)  // Try to match a non-digit, the +-/* (group 1)
     (\d+)  // Then match one or more digits (group 2)
  /,
      // $1 is group 1 and $2 is group 2 q[0] is the text before the parenthesis 
  `$1(${q[0]}*$2)`
  ) 

использование

Это работает только в Firefox и Safari Nightly, может быть, Edge? потому что он использует функции ES6. Вы можете запустить его:

var t = s => (q = s.split (/ [()] /)) [1] .replace (/ (\ D?) (\ d +) / g, `$ 1 ($ {q [0]} * $ 2) `)

t ( «5 (-6 + 7 + 3-8 + 9)» ); // - (5 * 6) + (5 * 7) + (5 * 3) - (5 * 8) + (5 * 9)

(.?)(\d+)сломан. Это терпит неудачу 23(12+42), производя 1(23*2)+(23*42).
orlp

@ orlp Я исправил это

Этот код будет работать только в Firefox b / c функции стрелок, но это нормально
MayorMonty

@SpeedyNinja Это также работает в Edge. Для Chrome / Opera необходимо включить «экспериментальные функции JavaScript».
rink.attendant.6

\D?может быть использован вместо[+-]?
edc65

6

Python 2.7, 110 108 байт

import re
p=re.findall('([+-]?)(\d+)',raw_input())
print"".join("%s(%s*%s)"%(e[0],p[0][1],e[1])for e in p[1:])

Программа принимает входные данные из stdin, ищет совпадения с - ([+-]?)(\d+)regex и создает выходную строку.
Тестирование это -

<< 23(12+42)
>> (23*12)+(23*42)

<< 9(62-5)
>> (9*62)-(9*5)

<< 4(17+8-14)
>> (4*17)+(4*8)-(4*14)

<< 15(-5)
>> -(15*5)

<< 2(3)
>> (2*3)

<< 8(+18)
>> +(8*18)

<< 8(-40+18)
>> -(8*40)+(8*18)

4

Сетчатка , 40 байт

+`(\d+)\((\D)?(\d+)
$2($1*$3)$1(
\d+..$
<empty line>

Каждая строка должна идти в свой собственный файл, но вы можете запустить код как один файл с -sфлагом. Например:

>echo -n "8(-40+18)"|retina -s distributing_numbers
-(8*40)+(8*18)

Первые две строки помещают множитель рядом с каждым числом в ожидаемой форме:

8(-40+18)
-(8*40)8(+18)
-(8*40)+(8*18)8()

Последние две строки удаляют ненужную завершающую часть:

-(8*40)+(8*18)8()
-(8*40)+(8*18)

3

sed, 105 байт

Просто хотел посмотреть, можно ли это сделать с помощью sed.
Может быть, немного старой школы, но это работает.

$ cat distnum.sed
s@\([0-9]*\)(\([0-9]*\)\([+-]*\)\([0-9]*\)\([+-]*\)\([0-9]*\))@(\1*\2)\3(\1*\4)\5(\1*\6)@
s@([0-9]*\*)@@g

$ cat distnum.txt
23(12+42)
9(62-5)
4(17+8-14)
15(-5)
2(3)
8(+18)
8(-40+18)

$ sed -f distnum.sed distnum.txt
(23*12)+(23*42)
(9*62)-(9*5)
(4*17)+(4*8)-(4*14)
-(15*5)
(2*3)
+(8*18)
-(8*40)+(8*18)


2

REGXY , 45 байт

Использует REGXY, язык подстановки регулярных выражений.

/(\d+)\((\D)?(\d+)/\2(\1*\3)\1(/
//
/\d+\(.//

Как //работает? Я полагаю, что это происходит до вершины, пока строка не изменится, но я не могу найти на странице esolang, почему.
рандома

Это немного дерзкое злоупотребление неопределенностью в спецификации языка, но я объяснил это здесь: codegolf.stackexchange.com/questions/52946/…
Jarmex

1
Я до сих пор не понимаю, почему не //создается бесконечный цикл, поскольку nothingон всегда будет совпадать, поэтому мы всегда возвращаемся к первой строке.
рандома

Знаешь что? Я на самом деле понятия не имею, почему. Вы абсолютно правы, думать об этом сейчас не имеет никакого логического смысла, но он определенно компилируется и запускается в предоставленном интерпретаторе. Даже взгляд на скомпилированный Perl, который он генерирует, смущает меня, потому что выглядит еще более ясным, что это должен быть бесконечный цикл: pastebin.com/9q7M0tpZ
Jarmex

2

Perl, 36 байт

35-байтовый код + 1-байтовая командная строка

($a,$_)=split/[()]/;s/\d+/($a*$&)/g

Использование:

echo "4(17+8-14)" | perl -p entry.pl

1

Pyth, 39 38 байт

Ужасное решение для регулярных выражений:

P:eJcz\("([+-]?)(\d+)"X"\\1(_*\\2)"3hJ

Я не могу заставить его работать в онлайн-переводчике .
BrainSteel

@BrainSteel Работает в офлайновом переводчике, похоже, проблема с герою.
orlp

@orlp Это не проблема с герою. Динамический импорт отключен в безопасном режиме, чтобы уменьшить вероятность взлома, а модуль re выполняет динамический импорт. Поэтому его нельзя использовать в безопасном режиме, в том числе онлайн.
Исаак

1

Рубин, 94 байта

gets.scan(/(\d+)\(([[-+]?\d+]+)/){|a,b|b.scan(/([-+]?)(\d+)/).map{|c,d|$><<"#{c}(#{a}*#{d})"}}

1

CJam, 50 байтов

l__'(#_@<'*+@@)>);'+/'-f/\ff{1$'(@@++')+L?}'-f*'+*

Попробуйте онлайн

CJam не имеет поддержки регулярных выражений или чего-либо, кроме поиска и разбиения строк, что очень удобно для разбора выражений. Так что здесь есть немного труда.

Объяснение:

l__   Get input and push 2 copies for splitting.
'(#   Find index of '(.
_     Copy index, will be used twice.
@<    Get one copy of input to top, and slice to get first multiplier.
'*+   Append '* to first multiplier.
@@    Get another copy of input and '( index to top.
)>    Increment and slice to get everything after '(.
);    Remove trailing ').
'+/   Split at '+.
'-f/  Split each part at '-.
\     Swap first multiplier to top.
ff{   Apply block to nested list of second multipliers.
  1$    Copy term. Will use this copy as condition to skip empty second multipliers
        that result from unary + or -.
  '(    Opening parentheses.
  @@    Get first and second multiplier to top.
  ++    Concatenate it all.
  ')+   Concatenate closing parentheses.
  L     Push empty string for case where term is skipped.
  ?     Ternary if to pick term or empty string.
}     End of loop over list of second multipliers.
'-f*  Join sub-lists with '-.
'+*   Join list with '+.

1

поглазеть - 60 58

$0=gensub(/(.*\()?(+|-)?([0-9]+))?/,"\\2("$0+0"*\\3)","G")

Фу ... давно не работал с регулярным выражением.


1

Perl 5, 70 60 55 44 байта + 1 штраф

Решение Perl, которое использует только split и 1 регулярное выражение.
Также рассчитывает более длинные входы.

($a,$_)=split/[()]/;s/(\D?)(\d+)/$1($a*$2)/g

Тест

$ echo "8(9-10+11-12+13-14)"|perl -p distnums.pl   
(8*9)-(8*10)+(8*11)-(8*12)+(8*13)-(8*14)

Версия, которая принимает параметр

($a,$_)=split/[()]/,pop;s/(\D?)(\d+)/$1($a*$2)/g;print

Версия, которая использует только регулярные выражения.

s/(\d+)\((.*)\)/$2:$1/;s/(\D?)(\d+)(?=.*:(\d+)).*?/$1($3*$2)/g;s/:.*//

Этот работает через группу захвата в пределах положительного взгляда и ленивого соответствия. Вероятно, использовал бы позитивный взгляд назад, если бы Perl 5 поддерживал это, но увы. Мне потребовалось время, чтобы понять, что это возможно с помощью регулярных выражений.


1
Эй, Люк, ты можешь сохранить некоторые символы, используя -pопцию командной строки (я думаю, что это +1 символ против 9 для ,<>и ;print), так как splitбудет работать $_по умолчанию (что будет в любом месте <>), и печать также включена в цикл ! Надеюсь, это поможет!
Дом Гастингс

1
Благодаря! Это помогло. Опция -p просто не пришла мне в голову. Вероятно, так как это то, что редко используется вне контекста игры в гольф. Почему вы думаете, что это +1 символ? Эта задача ничего не говорит о штрафах за использование ключей.
LukStorms

Я не могу найти пост сейчас, но в этом мета посте упоминается оценка для флагов Perl.
Дом Гастингс

1
Плохо, похоже, что я подошел и опубликовал для вас очень похожее решение, которое, по сути, является чуть более вашей версией для гольфа! По сути, вам даже не нужно захватывать [+ -], потому что вы все равно оставляете их нетронутыми в замене: codegolf.stackexchange.com/a/57117/26977
Jarmex

Это круто. Благодаря вам Perl превосходит даже решения Pyth / Cjam в этой задаче. Я не должен был заботиться о недействительных входных данных в любом случае после того, как это разделение сняло скобки.
LukStorms

1

Retina , 50 51 43 байта

Я думаю, что это может быть моей первой программой Retina. Если нет, то это моя первая программа Retina, которая такая сложная (на самом деле не такая уж сложная). Каждая строка идет в своем собственном файле.

+`(\d+)\((\D?)(\d+)
$1($'$2($1*$3)
.+?\)
$'

Я на самом деле не тестировал это с Retina, я тестировал его с помощью тестера regex-replace несколько раз, но он должен работать.

Описание для первого примера:

Поскольку существует четное количество файлов, Retina использует режим замены. Первая замена (первые два файла) удаляет номер, подлежащий распределению, и добавляет эту пару распределения (23*12)в конец, давая 23(+42)(23*12). +`в начале говорит Retina многократно заменять, пока шаблон не совпадает, и так как это снова сопоставляется, шаблон заменяет это на 23()(23*12)+(23*42). Это больше не соответствует, поэтому следующие 2 файла используются для следующей замены. На этот раз он просто удаляет 23(). Это хорошо работает: поскольку продукты добавляются в конец, мне не нужно делать ничего странного, если число не имеет знака, так как единственным, который может быть без знака, является первое число.

РЕДАКТИРОВАТЬ: $'в замене представляет остальную часть строки после матча, так что я могу удалить конечные (.*)s.


0

к, 98 байт

Не очень в гольфе.

{,/(*x){(s#y),("*"/:(x;(s:(*y)in"+-")_y))/:$"()"}/:1_x@:&~~#:'x:((0,&~x in .Q.n)_x){x_'x?'y}/"()"}

Разделите на нецифровые символы, удалите парены, удалите пустые строки, затем сохраните xконстанту в качестве первой строки, объедините *с каждой оставшейся строкой y, заключите в скобки и переместите знак в начало, если оно есть; свести вывод в одну строку.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.