Поширення чисел


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)

Об'єкти Pip's Pattern в основному слідують синтаксису регулярного виразів 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] .замінити (/ (\ 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+)регулярного виразу та створює вихідний рядок.
Тестування -

<< 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 чому.
randomra


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

Знаєте, що? Я насправді поняття не маю, чому. Ви абсолютно праві, думаючи про це зараз, це не має жодного логічного сенсу, але це, безумовно, компілюється і працює в наданому перекладачем. Навіть дивлячись на складений 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 Це працює в офлайн-перекладачі, схоже, це проблема з heroku.
orlp

@orlp З героїкою це не проблема. Динамічний імпорт вимикається в безпечному режимі, щоб зменшити ймовірність зламу, і повторно модуль робить динамічний імпорт. Тому їх не можна використовувати в безпечному режимі, включаючи Інтернет.
isaacg

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")

Phew ... вже давно не працювали з regexp.


1

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

Рішення perl, яке використовує лише розділений та 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 char vs 9 for ,<>і ;print), як це splitбуде працювати $_за замовчуванням (що буде все, що є <>), і друк також включений у цикл ! Сподіваюся, що це допомагає!
Дом Гастінгс

1
Дякую! Це допомогло. Варіант -p просто не перейшов мені на думку. Можливо, тому, що це рідко використовується поза контекстом для гольфу. Чому ви вважаєте, що це +1 char? У цьому виклику нічого не згадується про штрафи за використання перемикачів.
LukStorms

Зараз я не можу знайти цю посаду, але в цьому мета-пості згадується оцінка прапорів Перла.
Дом Гастінгс

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

Круто. Через вас Perl перемагає навіть рішення Pyth / Cjam у цьому виклику. Я не повинен був би піклуватися про недійсні входи після того, як розкол видалив дужки.
LukStorms

1

Сітківка , 50 51 43 байт

Думаю, це може бути моя перша програма Retina. Якщо ні, то це моя перша програма Retina, яка є такою складною (не дуже складною.) Кожен рядок має свій власний файл.

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

Я насправді не перевіряв це за допомогою Retina, протестував його за допомогою тестера заміни регулярних виразів кілька разів, але він повинен працювати.

Опис першого прикладу:

Оскільки є парне число файлів, Retina використовує режим заміни. Перша заміна (перші два файли) видаляє число, яке потрібно розподілити, і додає цю розподільну пару (23*12)до кінця, надаючи 23(+42)(23*12). +`на початку повідомляє Retina повторно замінювати, поки шаблон не збігається, і оскільки це знову збігається, шаблон замінює це на 23()(23*12)+(23*42). Це більше не відповідає, тому наступні 2 файли використовуються для наступної заміни. Цього разу це просто прибирає 23(). Це прекрасно працює: оскільки продукти додаються до кінця, мені не потрібно робити нічого дивного, якщо номер не має знаку, оскільки єдиний, який може бути без знака, - це перший номер.

EDIT: $'замість цього відображається решта рядка після матчу, тому я можу видалити кінцеві (.*)s.


0

k, 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.