Учитывая строку символов, +=-
где есть хотя бы один =
, вставьте положительные целые числа между всеми символами и в начале и в конце так, чтобы выполнялись математические уравнения.
Например, учитывая вход
+-=-=
вам нужно вставить положительные целые числа от A до F, как это
A+B-C=D-E=F
так что все уравнения выполняются, т. е. A + B - C
и D - E
и F
все имеют одинаковое число.
Есть много возможных способов сделать это, так как, пока уравнения работают, любой набор положительных целых чисел может использоваться. Каждая строка здесь является возможным допустимым выводом для ввода +-=-=
:
2+3-4=6-5=1
1+1-1=2-1=1
4+2-4=4-2=2
100+1-10=182-91=91
89+231-77=1024-781=243
Обратите внимание, что значение выражений не обязательно должно быть положительным целым числом, как в случае вставленных чисел. Например, при заданном входе -=-
выходы 1-10=8-17
(значение до -9) и 10-1=17-8
(значение до 9) одинаково действительны. Конечно, для некоторых входных данных, например =
, нельзя использовать отрицательное выражение, поскольку 5=5
можно вставлять только положительные числа, подобные .
Обратите внимание, что ноль не является положительным целым числом.
Самый короткий код в байтах побеждает.
Вы можете выводить числа в виде списка, а не вставлять их непосредственно в строку. Если вы выводите строку, могут быть пробелы, разделяющие символы и цифры. Итак, для ввода +-=-=
, вывода
2, 3, 4, 6, 5, 1
или
2 + 3 - 4 = 6 - 5 = 1
эквивалентно выводу
2+3-4=6-5=1
Тестовые случаи
Input | One Possible Output
= | 1=1
== | 2=2=2
+= | 1+3=4
=+ | 2=1+1
-= | 30-10=20
=- | 1=2-1
=-= | 3=7-4=3
=+= | 2=1+1=2
=== | 100=100=100=100
+=- | 3+2=7-2
-=+ | 7-2=3+2
+=+ | 3+3=3+3
-=- | 1-10=8-17
--= | 60-1-1=58
++= | 60+1+1=62
-+= | 60-9+1=52
+-= | 60+9-1=68
+-=-= | 2+3-4=6-5=1
--=-- | 2-1-1=2-1-1
==-== | 47=47=50-3=47=47
=++=+-=-+=--= | 3=1+1+1=3+1-1=1-1+3=5-1-1=3
+--++-=-+-+- | 35+10-16-29+20+107-1000=5-4+3-2+1-876
====== | 8=8=8=8=8=8=8
источник
Ответы:
Сетчатка , 58 байт
Попробуйте онлайн!
Альтернативное решение с тем же количеством байтов:
Попробуйте онлайн!
объяснение
Основная идея состоит в том, чтобы превратить все
+
s и-
s в простые+1
и-1
операции, а затем добавить достаточно большое число, которое заставляет работать все уравнения. Чтобы привести уравнения в соответствие, мы можем просто добавить одно и то же число к каждому из них, а затем уменьшить его на единицу для каждого+1
и увеличить на единицу для каждого-1
после него. Поскольку мы будем работать с унарными числами, единственный улов заключается в том, что первое число должно быть достаточно большим, чтобы мы могли уменьшить его в 1 раз.Мы начинаем с вставки
1
после каждого-
или+
.В
\B
гарантирует , что эти матчи либо в начале ввода, или между=
и+
или-
, то есть все позиции , где мы хотим вставить ведущее число выражения. Затем((\+1)|(-1))*
часть просто считает количество+1
s и-1
s в группах2
и3
соответственно. Теперь давайте разберем строку подстановки:Неоднократно удаляйте
1_
из строки, применяя необходимые отмены из+1
s.Наконец, замените все строки
1
s их длинами, чтобы преобразовать их из унарной в десятичную.источник
Python 2 , 76 байт
Попробуйте онлайн!
источник
eqtn_len + plus_signs + minus_signs - 2 * plus_signs = eqtn_len + minus_signs - plus_signs
. Тогда, поскольку все остальные числа в чанке равны единице, итоговое значение для чанка получаетсяeqtn_len + minus_signs - plus_signs - minus_signs + plus_signs = eqtn_len
. Длина уравнения должна быть положительной, поэтому все получается.Python 2,
199179178172162158156152151 байтСлишком долго, но решение было легко создать.
Попробуйте онлайн
Это попробует каждую возможность, пока не найдет решение. Программа очень медленная. Он также выполняет замену строки на каждой итерации. Редактирование «172» сделало его значительно медленнее, поскольку вместо того, чтобы начинать с небольшого диапазона, оно начинается с максимума. Например, входы
-=
или=+
нужно попробовать 2 ** 32 попытки до достижения решения.Чтобы ускорить программу, используйте версию с 178 байтами из истории редактирования.
источник
range
в python2 не создается весь диапазон в виде списка сразу? IIRC вы могли бы ускорить его, используяxrange
вместо этого, так как я думаю, что это версия с отложенной загрузкой (Python3 по умолчанию использует lazyrange
)print range(1,65537)
и это завершилось за 0,034 с.l=...
, а помещая это прямо вproduct(range(...),repeat=len(s)+1)
. Если вам нужны скобки, он сохраняет только один байт (\ n)len(s)+1
, я мог бы использовать-~len(s)
вместо них, которые не требуют паренсов.JavaScript (ES6),
9282 байтаГольф 8 байтов с трюком от @xnor
Хитрость заключается в том, чтобы вставить
1
после каждого+
или-
, а затем добавить к каждому выражению число, которое делает выражение равным длине ввода. Таким образом, мы можем гарантировать, что число всегда положительно; поскольку=
в строке всегда есть хотя бы 1 , число+
s никогда не может достигать длины строки, поэтому остаток всегда равен по крайней мере1
. Вы можете убедиться в этом, введя произвольное число+
s в приведенном выше фрагменте.источник
Python 2 ,
120119 байт-1 байт благодаря mbomb007
Попробуйте онлайн! или проверить все контрольные примеры
Сначала я вставляю
1
в каждую позицию, чтобы проверить самое высокое значение, затем добавляю его как смещение для каждого уравнения. Это работает, потому что вы не можете добавлять отрицательные числа, поэтому минимальный результат определяется количеством+
в уравнении, которое имеет только+
.источник
GNU Prolog, 156 байт
объяснение
Нам нужно решить несколько уравнений, так почему бы не использовать реальный решатель уравнений?
x
в основном является оценщиком уравнений для уравнений вида+-+
; в дополнение к самому уравнению у него есть два дополнительных аргумента (список разностей,L,R
который содержит значения уравнения и значениеV
, к которому уравнение оценивает). Как обычно в Прологе, его можно использовать любым способом (например, вы можете указатьV
и получитьL,R
, указатьL,R
и получитьV
, указать и то, и другое, и убедиться, что значение верное, или не указывать ни то, ни другое, в этом случае соответствующие ограничения будут наложены на обаV
иL,R
). «Текущий элемент» изL,R
названE
, и мы также включаем утверждение, чтоE
больше 0 (потому что вопрос требует использования положительных чисел). Эта функция немного более многословна, чем мне бы хотелось, например, мне пришлось написать[E|R]
шаблон сопоставления / несоответствия дважды из-за того факта, что списки ассоциированы справа, но сложение и вычитание ассоциированы слева. К сожалению, для работы нам нужно использовать фактический список, а не придумывать свой собственный левоассоциативный тип списка из cons-ячеекfd_labeling
.q
похожеx
, но также включает в себя=
. Это в основном просто звонкиx
, а само по себе рекурсивно. Кстати, это очень наглядная демонстрация того , как разница списки работы, показывая , что вы можете объединить два разностных спискиL,T
иT,R
в единый список разницыL,R
. Основная идея заключается в том, что список различий является частичной функцией, которая принимает аргументR
и возвращает значение, кL
которомуR
добавлен сам список. Таким образом, идентифицируя аргумент одного списка различий и возвращаемое значение другого, мы можем составлять функции и, таким образом, объединять списки.Наконец,
s
функция, которая фактически решает задачу в вопросе, является функцией-оболочкой, вызываемойq
с аргументами. Мы преобразуем список различий в обычный список, предоставляя[]
его в качестве аргумента, и используем его,fd_labeling
чтобы найти решение уравнения, которое мы создали. (По умолчанию, похоже, что значение 1 установлено, если нет причин устанавливать их на что-то другое. Однако его можно настроить; оноvalue_method(random)
дает более «интересные» решения, чем, например, повсеместное размещение 1 с, и все еще очень быстро. )Образец вывода
С программой как написано:
Если я добавлю программу немного дольше
value_method(random)
, результат будет разным, но выглядит примерно так:В обоих случаях,
?
в конце вывода означает, что может быть более одного решения. (Конечно, в этом случае мы знаем, что существует гораздо больше, чем одно решение!)источник
Mathematica, 116 байт
Чистая функция, принимающая строку в качестве входных данных и возвращающая список натуральных чисел. Основная стратегия: мы только добавляем 1 и вычитаем 1, и мы выбираем начальные числа в каждом выражении, чтобы сделать все равными.
c=Characters@StringSplit[#,"="]/."+"->-1/."-"->1
разделит входную строку на каждый знак равенства, а затем заменит каждый+
на-1
и каждый-
на1
. Однако, если в начале или конце есть знак равенства, он будет проигнорирован. Поэтому мы искусственно добавляем новый символ в каждый конец ("0"<>#<>"0"
) и убираем его после завершения разбиения строки (/."0"->Nothing
).Сумма каждого подсписка теперь равна целому числу, которое мы можем поставить перед
+
s и-
s, чтобы сделать каждое выражение равным.1-Min[Tr/@c]
это наименьшее целое число, которое мы можем добавить к каждому итогу, чтобы сделать их все положительными. Таким образом,Prepend[#^2,1-Min[Tr/@c]+Tr@#]&
берет каждый подсписок (^2
поворачивает все их записи1
) и добавляет его общее смещение на это наименьшее компенсирующее целое число. Полученные спискиJoin
редактируются вместе, чтобы произвести вывод.источник
Руби, 76
Целевое значение для выражений установлено в
5**8
минус 1 по причинам, связанным с игрой в гольф! Первоначально я использовалs.size+1
минус 1.Неуправляемый в тестовой программе
Выход
источник
PHP,
207204197114 байтовпрямой подход: намного короче и быстрее
Запустите
echo '<input>' | php -nR '<code>'
или протестируйте его онлайн .сломать
!$c
верно в первой итерации, приведенной к1
для индексации строки;"="[1]
пустой.После этого
$c
устанавливается и!$c
ложь, приводится к0
и"="[0]
является первым символом.таким образом, мы определенно в безопасности с длиной ввода. Все условия оценят к этому.
chunk_split($s,$n,$i)
вставляет$i
после каждого$n
символа$s
- и в конце.Чтобы предотвратить обращение пустых терминов к
1
, принудительно устанавливается ошибка, устанавливающая длину куска0
.источник
Röda ,
112110109 байтПопробуйте онлайн!
Функция разделения не работала так, как я предполагал с этой программой. Например,
split("", sep="")
возвращает одну пустую строку вместо ничего. Как это логично? Благодаря этому программа почти на 20 байтов больше, чем могла бы быть, если бы семантика разбиения была идеальной.Идея этого ответа состоит в том, что мы знаем, что длина входной строки должна быть больше или равна значению уравнения, поэтому мы определяем значение уравнения как длину строки. Для каждой части уравнения мы думаем, что каждый оператор является
+1
или-1
и вычитаем и добавляем их к значению уравнения.Ungolfed:
источник