Минимизируйте Те, кто [закрыт]

12

Ваша задача - построить натуральное число, используя наименьшее количество единиц и только операторов +или -. Например, число семь может быть написано 1+1+1+1+1+1+1=7, но оно также может быть написано как 11-1-1-1-1=7. Первый использует 7те, в то время как последний использует только 6. Ваша задача состоит в том, чтобы вернуть минимальное количество единиц, которые можно использовать, если ввести некоторое натуральное число n,.

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

Контрольные примеры

Вход => Выход

0 => 2 (since 1-1=0)
7 => 6
121 => 6
72 => 15
1000 => 7
2016 => 21
codeputer
источник
Хороший первый вызов. Я бы предложил включить больше тестовых случаев. Является ли «VALID OUTPUTS» ошибкой, учитывая, что есть один выход? Кроме того, является ли 0 допустимым вводом, и если да, что должно быть выведено?
xnor
Это интересный вызов. Вы можете добавить пояснения к выводам, изменить VALID OUTPUTS. Это ваш выбор, но обычно люди предпочитают жирный шрифт или курсив, а не ЗАГЛАВНЫЕ БУКВЫ (они заставляют его выглядеть как крик вместо акцента). Жирным шрифтом **bold text**и курсивом *italics text*. Вы также можете использовать ### Textдля жирного текста. В любом случае, добро пожаловать в PPCG!
NoOneIsHere
Вы должны составить машиночитаемую таблицу или список тестовых случаев, на которых люди могут запускать свой код. Смотрите этот совет .
xnor
6
Я голосую, чтобы закрыть этот вопрос, потому что этот вопрос дублирует текущую (активную !!) игру в гольф на codefights.com/challenges . Даже если ОП также является автором оригинальной задачи по борьбе с кодами (в чем я сомневаюсь), вопрос должен быть закрыт до тех пор, пока задача по борьбе с кодами больше не будет активной.
Якуб
1
@Jakube прямая ссылка могла бы быть полезной, но я согласен. Я буду голосовать, чтобы закрыть.
NoOneIsHere

Ответы:

3

JavaScript (ES6), 127 126 87 байт

f=(n,z=2,m=n*9+'',r=m.replace(/./g,1))=>n?m.length+(m<'55'?f(n- --r/10,0)-1:f(r-n,0)):z
Input: <input type="number" oninput="result.textContent=f(this.value)"> Result: <span id="result"></span>

Должно работать примерно до 10 14 15, после чего вы начинаете работать с целочисленными ограничениями JavaScript. Объяснение:

f=(                             Recursive function
 n,                             Parameter
 z=2,                           Zero workaround
 m=n*9+'',                      Magic
 r=m.replace(/./g,1)            Find repunit not less than than n
)=>n?                           Nothing to do if n is zero
 m.length+                      Assume subtracting from repunit
 (m<'55'?                       Should we subtract from repunit?
  f(n- --r/10,0)                No, so subtract previous repuint
   -1:                          Which is one 1 shorter
  f(r-n,0)):                    Subtract from repunit
 z                              Return special case if n is zero

Это использует n*9магию дважды; во - первых, это дает мне длину следующего репьюнитом, во- вторых, если первые две цифры n*9являются 55или выше, то мы должны вычесть nиз этого следующего репьюнитом, в противном случае мы должны вычесть предыдущее репьюнитом (который рассчитывается путем вычитания 1 и деление на 10). Это должно работать до 10 15 .

Нил
источник
2

Pyth, 19 16 байт

ffqQvs+R1Y^c3"+-

Тестирование

Алгоритм грубой силы. Необходимые строки генерируются путем взятия всех списков, элементы которых имеют ['+', '-', '']длину, равную числу тестируемых единиц, добавлением 1 к каждому и конкатенацией к одной строке. Эти строки затем оцениваются и сравниваются с входными данными. Это повторяется до тех пор, пока не будет найдена успешная строка.

Некоторые строки с ведущими +или -проверены, но это не проблема. Это было бы, если бы вход был отрицательным, хотя.

Он может работать до длины 9, пока не станет слишком медленным.

Объяснение:

ffqQvs+R1Y^c3"+-
ffqQvs+R1Y^c3"+-"T    Implicit variable introduction
                      Q = eval(input())
f                     Starting with T = 1 and counting upwards, repeat until true.
                      The value of T where the result is first true is output.
           c3"+-"     Chop "+-" into thirds, giving ['+', '-', '']
          ^      T    Form every list with those elements of length T.
 f                    Filter over those lists, lambda var Y.
      +R1Y            Append a 1 to each element of the list.
     s                Concatenate.
    v                 Eval.
  qQ                  Compare for equality with the input.
                      The inner filter will let through the successful cases.
                      The outer filter will stop when there is a successful case.
isaacg
источник
2

JavaScript (ES6), 92 байта

f=(n,i=3)=>eval([...s=i.toString(3)].map(d=>"-+"[d]||"").join`1`+".0")-n?f(n,i+1):s.length-1
n = <input type="number" oninput="R.textContent=f(this.value)" /><pre id="R"></pre>

объяснение

Рекурсивная функция. Это генерирует все возможные перестановки 1s, разделенные либо +, -либо ничем. Она делает это путем приращения номера базовой-3, превращая ее в массив цифр, преобразование каждой цифры , 0чтобы -, 1чтобы +и 2в пустую строку, а затем объединить их вместе с 1с. Результирующая строка evald является оператором JavaScript, который возвращает результат уравнения.

Поскольку операторы объединяются с 1s между (как +1+1+1+), есть length - 1 1s. Первый оператор игнорируется (потому что +1= 1, <nothing>1= 1и это число, поэтому никогда не будет лидирующего 0для -), а последний оператор также игнорируется (путем добавления .0к уравнению).

Более высокая выходная версия, 96 байт

Другая версия не может возвращать выходные данные выше ~ 10 из-за предела стека рекурсивных вызовов. Эта версия использует цикл for вместо рекурсии, поэтому может возвращать выходные данные до ~ 33. Количество времени увеличивается экспоненциально, поэтому я не рекомендую его тестировать.

n=>eval('for(a=3;eval([...s=a.toString(3)].map(d=>"-+"[d]||"").join`1`+".0")-n;)a++;s.length-1')
user81655
источник
Это звучит слишком сложно, мне это нравится.
Балинт