Как далеко находится n до следующей степени b?

32

Позвольте nи bбыть положительные целые числа больше, чем 1.

Выведите расстояние от nдо следующей степени b.

Для n=5и b=3, следующая степень 3от 5is 9( 3^2 = 9), поэтому вывод 9 - 5 = 4.

Для n=8и b=2, следующая степень 2от 8is 16( 2^4 = 16), поэтому вывод 16 - 8 = 8. Обратите внимание, что nэто сила 2в этом примере.

Testcases:

  n b output
212 2 44
563 5 62
491 5 134
424 3 305
469 8 43
343 7 2058
592 7 1809
289 5 336
694 3 35
324 5 301
  2 5 3

Это . Кратчайший ответ в байтах побеждает. Применяются стандартные лазейки .

Дрянная Монахиня
источник

Ответы:

16

Желе ,  4  3 байта

ạæċ

Двоичная ссылка, берущая nслева и bсправа и возвращающая результат.

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

Как?

ạæċ - Link: number n, number b | n,b ∈ ℕ
 æċ - ceiling n to the next power of b
ạ   - absolute difference between n and that
Джонатан Аллан
источник
4
Вычеркнуто 4 все еще регулярно 4; (
Уриэль
2
@Uriel Но  ;)
HyperNeutrino
tfw ваша изначально первоначальная мысль "о, это æċ!" вместо «ауууууууууууууууу…»
Эрик Аутгольфер
О, это может не существовать в истории, но я изменился с 4 байта. Это былоæċ_⁸
Джонатан Аллан
@JonathanAllan Так как это не было в истории, это не имело смысла, и именно поэтому я отредактировал это.
Эрик Аутгольфер
8

Сборка x86-64 ( Соглашение о вызовах Windows x64 ), 14 13 байт

Неэффективный (но изящный!) Итеративный подход (с благодарностью за @Neil за вдохновение):

               HowFarAway PROC
6A 01             push   1
58                pop    rax         ; temp = 1
               Loop:
0F AF C2          imul   eax, edx    ; temp *= b
39 C8             cmp    eax, ecx
72 F9             jb     Loop        ; keep looping (jump) if temp < n
29 C8             sub    eax, ecx    ; temp -= n
C3                ret                ; return temp
               HowFarAway ENDP

Вышеуказанная функция принимает два целочисленных параметра n(переданных в ECXрегистре) и b(переданных в EDXрегистре) и возвращает один целочисленный результат (в EAXрегистре). Чтобы вызвать его из C, вы должны использовать следующий прототип:

unsigned HowFarAway(unsigned n, unsigned b);

Это ограничено диапазоном 32-разрядного целого числа. Его можно легко модифицировать для поддержки 64-битных целых чисел с помощью полных длинных регистров, но для кодирования этих инструкций потребуется больше байтов. :-)

Коди Грей
источник
Итак, вы не можете установить значение eax равным 1 из менее чем 4 байта?
Нил
Хмм… Не обычным способом, который использовал бы нормальный программист, но вы могли бы push 1+ pop raxвсего за 3 байта. Но ... тогда вам не нужно будет пропускать умножение, так что это все равно будет разумной экономией, потому что вы можете отбросить jmp.
Коди Грей
Ах, я знал, что должен быть способ сыграть в гольф на байте!
Нил
Вы можете сделать то же самое с соглашением о вызовах SysV в Linux, с демонстрацией TIO .
Цифровая травма
Конечно вы можете. Вы можете сделать это с любым соглашением о вызовах, которое передает по крайней мере первые два целочисленных параметра в регистрах. System V, Win x64, Win32 __fastcall и т. Д. Регистры просто меняются, и мне пришлось выбрать один. Монета всплыла "Windows".
Коди Грей
6

C (gcc) , 39 35 байт

Новое неопределенное поведение благодаря Эрику

f(n,b,i){for(i=b;b<=n;b*=i);n=b-n;}

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

cleblanc
источник
f(n,b,i){for(i=b;b<n;b*=i);n=b-n;} сохраняет 5 байт и поддерживается gcc
Эрик Outgolfer
@EriktheOutgolfer почему бы и нет b-=n?
Дрянная монахиня
@LeakyNun Потому что это первый аргумент, в который нужно сохранить возвращаемое значение.
Эрик Outgolfer
Хм, ты не обновил код.
Эрик Outgolfer
Можете ли вы сделать, b-=nесли вы меняете порядок bи n?
Захари
6

Dyalog APL, 10 байт

2 байта сохранены благодаря @ZacharyT

⊢-⍨⊣*1+∘⌊⍟

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

Принимает в nкачестве правого аргумента и в bкачестве левого аргумента.

Рассчитывает .b⌊logbn + 1⌋ - n

Уриэль
источник
Хорошо, я как раз собирался опубликовать это точное решение
Kritixi Lithos
@KritixiLithos Мне было сложно с трюком на полу. Вы думаете, это может быть превращено в поезд?
Уриэль
Да, он может: ⊣-⍨⊢*1+∘⌊⍟⍨.
Захари
@ZacharyT хороший!
Уриэль
Я получаю ⊢-⍨⊣*1+∘⌊⍟за 10 байтов, но с замененными аргументами, так что nэто правильный аргумент и bлевый аргумент. Я использовал хитрость ZacharyT, 1+∘⌊чтобы получить это далеко.
Критиси Литос
6

R , 38 34 байта

pryr::f({a=b^(0:n)-n;min(a[a>0])})

Анонимная функция. Сохраняет все значения b в степени всего в диапазоне [0, n], вычитает n из каждого, подмножества положительных значений и возвращает мин.

TIO имеет версию, не предназначенную для чтения, называемую как f(n,b); эта версия должна называться как f(b,n).

Спас 4 байта благодаря Jarko Dubbeldam, который тогда превзошел меня.

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

BLT
источник
Хорошо, намного короче, чем рекурсия, которую я имел в виду.
JAD
pryr::f({a=b^(0:n)-n;min(a[a>0])})на несколько байтов короче.
JAD
Спасибо. Мне не повезло, pryr::fкогда я определяю новую переменную в функции; Похоже, это работает здесь.
BLT
2
Хм, всегда стоит проверять :) Меня раздражает, если у вас есть что-то подобное sapply(x, sum)или что-то еще, что это добавляет sumк аргументам.
JAD
4

Cubix , 24 20 байт

-4 байта благодаря MickyT

Pwp.I|-.;)^0@O?|uq;<

Читает на входе как n,b

Устанавливается на куб 2x2x2:

    P w
    p .
I | - . ; ) ^ 0
@ O ? | u q ; <
    . .
    . .

Объяснение:

I|I0 : прочитайте ввод, нажмите 0 (счетчик) в стек

^w помещает IP в нужное место для цикла:

  • Pp-: вычислить b^(counter), перейти nна вершину стека, вычислитьb^(counter) - n
  • ? : повернуть налево, если отрицательно, прямо, если 0, вправо, если положительно
    • Положительный: O@ вывести вершину стека (расстояние) и выйти.
    • Отрицательный:: |?действовать так, как если бы вершина стека была нулевой
  • <;qu;): направьте IP-адрес в правильном направлении, вытолкните вершину стека (отрицательное / нулевое число), переместитесь nв нижнюю часть стека, разверните поворот, вытолкните вершину стека ( b^(counter)) и увеличьте счетчик
  • IP на ^wи программа продолжается.

Смотреть онлайн!

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

Giuseppe
источник
1
Используя ту же процедуру, просто другой путьPwp.I|-.;)^0@O?|uq;<
MickyT
@ MickyT гений! Я чувствую, что каждый раз, когда я отправляю ответ cubix, вы приходите и сбриваете четыре или пять байтов ...
Джузеппе
2

05AB1E , 9 8 байт

sLmʒ‹}α¬

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

объяснение

s         # swap order of the inputs
 L        # range [1 ... n]
  m       # raise b to each power
   ʒ‹}    # filter, keep only the elements greater than n
      α   # calculate absolute difference with n for each
       ¬  # get the first (smallest)
Emigna
источник
1
Ты избил меня на минуту. Это именно то, что я написал, но я использовал ćвместо ¬.
Райли
@Riley: также работает с фильтром, но, к сожалению, не сохраняет байты.
Эминья
1
@Emigna, к сожалению, не сохраняет байты * сохраняет байты *
Эрик Игрок в гольф
@EriktheOutgolfer: Да, хорошо. Это было дополнительное изменение, использующее странный способ работы неявного ввода, который сохранил байт :)
Emigna
1
@carusocomputing: Да. Это на самом деле сохраняет байт, чтобы они были в «неправильном» порядке, поскольку я могу использовать их nнеявно, как при сравнении фильтров, так и при расчете абсолютной разности.
Эминья
2

MATL , 10 9 байт

yy:YAn^w-

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

объяснение

Рассмотрим входные данные 694и 3в качестве примера.

y    % Implicitly take two inputs. Duplicate from below
     % STACK: 694, 3, 694
y    % Duplicate from below
     % STACK: 694, 3, 694, 3
:    % Range
     % STACK: 694, 3, 694, [1 2 3]
YA   % Base conversion (of 694 with "digits" given by [1 2 3]
     % STACK: 694, 3, [3 3 2 3 1 2]
n    % Number of elements
     % STACK: 694, 3, 6
^    % Power
     % 694, 729
w    % Swap
     % STACK: 729, 694
-    % Subtract. Implicitly display
^    % 35
Луис Мендо
источник
2

JavaScript (ES6), 29 байт

Очень похоже на подход Рика, но опубликовано с его разрешения (и некоторые помогают сохранить байт).

n=>b=>g=(x=b)=>x>n?x-n:g(x*b)

Попытайся

f=
n=>b=>g=(x=b)=>x>n?x-n:g(x*b)
oninput=_=>o.value=f(+i.value)(+j.value)()
o.value=f(i.value=324)(j.value=5)()
*{font-family:sans-serif;}
input{margin:0 5px 0 0;width:50px;}
<label for=i>n: </label><input id=i type=number><label for=j>b: </label><input id=j type=number><label for=o>= </label><input id=o>

Мохнатый
источник
2

Mathematica, 24 байта

#2^⌊1/#~Log~#2⌋#2-#&

спасибо Мартин

I / O

[343, 7]

2058

J42161217
источник
Вы можете использовать 1/Log@##или #2~Log~#. Или даже лучше поменять порядок входов и использовать Log@##.
Мартин Эндер
А потом #^Floor[...]#короче чем #^(Floor[...]+1). И есть операторы Unicode для Floor.
Мартин Эндер
да, да, конечно. Я работаю над всем этим. Вы быстро!
J42161217
Не забывайте Log@##! На самом деле, если вы меняете порядок аргументов, #^⌊Log@##⌋#-#2&должно быть возможно для -5 байт (я думаю)!
CalculatorFeline
2

С, 42 40 байтов

Спасибо комментатору @Steadybox за подсказку

o;p(n,b){for(o=b;n>=b;)b*=o;return b-n;}
Говинд Пармар
источник
2
Использование forвместо whileсохранения двух байтов:o;p(n,b){for(o=b;n>=b;)b*=o;return b-n;}
Steadybox
Предлагаю n/bвместоn>=b
roofcat
2

R, 30 байт

pryr::f(b^floor(log(n,b)+1)-n)

Оценивает функцию

function (b, n) 
b^floor(log(n, b) + 1) - n

Который принимает первую степень больше или равна n, а затем вычитает nиз этого значения.

Изменено, ceiling(power)чтобы floor(power+1)гарантировать, что если nэто сила b, мы берем следующую власть.

JAD
источник
1

JavaScript (ES6), 31 байт

f=(n,b,i=b)=>b>n?b-n:f(n,b*i,i)

Тестовые случаи:

Рик Хичкок
источник
Вы можете сохранить байты за выделки (это не важно , пробовал ли я выделки как nи bили просто n), потому что избавляет вас от необходимости проходить nрекурсивно.
Нил
Спасибо @Neil, но у меня возникают проблемы с выяснением, как это сделать (?)
Рик Хичкок
Две версии, которые я придумал, были n=>g=(b,p=b)=>p>n?p-n:g(b,p*b)и n=>b=>(g=p=>p>n?p-n:g(p*b))(b).
Нил
Будет f=(n,i)=>g=(b=i)=>b>n?b-n:g(b*i)работать на 30 байтов? Он должен был бы называться так: f(324,5)(). РЕДАКТИРОВАТЬ: Ах @ Нил побил меня к этому.
Лохматый
@ Нил, спасибо, мне нужно больше тренироваться с карри.
Рик Хичкок
1

Japt , 9 байт

_q}a@nVpX

Проверьте это онлайн!

объяснение

_  q}a@  nVpX
Z{Zq}aX{UnVpX}  // Ungolfed
                // Implicit: U, V = input integers
     aX{     }  // For each integer X in [0...1e9), take
          VpX   //   V to the power of X
        Un      //   minus U,
Z{  }           // and return the first one Z where
  Zq            //   Math.sqrt(Z) is truthy.
                //   Math.sqrt returns NaN for negative inputs, and 0 is falsy, so this is
                //   truthy iff Z is positive. Therefore, this returns the first positive
                //   value of V**X - U.
                // Implicit: output result of last expression
ETHproductions
источник
1
... Подожди. Какая?
Лохматый
@ Shaggy Я добавил объяснение, надеюсь, это поможет.
ETHproductions
1

Python ,  42  41 байт

f=lambda a,b,v=1:(a<v)*(v-a)or f(a,b,v*b)

Рекурсивная функция, которая, начиная с v=1 , многократно умножается bдо тех пор, пока она строго не превысит, aа затем возвращает разницу.

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

Примечание: результат никогда не будет нулевым, поэтому a>=v and f(a,b,v*b)or v-a его можно заменить, (a<v)*(v-a)or f(a,b,v*b)не вызывая ошибок рекурсии.


Python 3, 37 байт?

Используя идею Ричи ...

f=lambda n,b:(n<b)*(b-n)or b*f(n/b,b)

который использует арифметику с плавающей точкой (следовательно, результаты могут отклоняться от их истинного расстояния),
попробуйте это здесь .

Джонатан Аллан
источник
tio.run/… немного короче, но вывод результата в формате "% .0f", вероятно, обманывает.
Ричи
@rici Хорошо, я думаю, можно использовать арифметику с плавающей запятой. Я добавлю это как альтернативу (другой байт может быть сохранен путем переключения форм, потому что он b-nникогда не будет равен нулю в то же время, что n<bи истина)
Джонатан Аллан
0

Луа, 74 73 байт

Прямое решение, я использую 10 байтов, чтобы аргументы обрабатывались как числа, а не как строки. Выходы в STDIN.

Редактировать: забыл удалить пробел в w=1 n=n+0, сохраняет один байт

n,b=...b=b+0p=b w=1n=n+0while p<=n do p=math.pow(b,w)w=w+1 end print(p-n)

Разъяснения

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

n,b=...           -- unpack the argument into the variable n and b
b=b+0             -- set b's type to number
n=n+0             -- set n's type to number
p=b               -- set a variable to track the current value of the powered b
w=1               -- set the nth power
while p<=n        -- iterate untill the current power is greater or equals to n
do
  p=math.pow(b,w) -- raise b to the power w
  w=w+1           -- increment w
end
print(p-n)        -- outputs p minus the following power of b
Katenkyo
источник
Я не очень хорошо знаю Lua, но нужно ли пространство между 1и endнеобходимым?
Захари
@ZacharyT В Lua шестнадцатеричные числа могут быть встроены, если они начинаются с числа, 1endначнут интерпретироваться как число, а 1eзатем выдают ошибку, потому что 1enэто недопустимое шестнадцатеричное значение. Это происходит только в том случае, если буква, следующая за цифрой, [abcdef]как и другие буквы, не может быть интерпретирована как шестнадцатеричное значение -> w=1whileне выдает ошибку.
Катенкё
Добро пожаловать в PPCG!
Дрянная монахиня
0

QBIC , 23 байта

{p=:^q~p>:|_xp-b|\q=q+1

bСначала принимает параметр , затемn .

объяснение

{       DO
p=:^q   SET p to input b (read as 'a' by QBIC fromt he cmd line) ** q (starts as 1)
~p>:    IF p exceeds 'n' (read as 'b' by QBIC fromt he cmd line)
|_xp-b| THEN QUIT, printing p minus b
\q=q+1  ELSE increase q, re-run
steenbergh
источник
0

Python 2 , 48 41 байт

  • Упрощение цикла @ Род сэкономил 7 байт!

Полная программа без рекурсии и немного твидлинга:

i=1;n,b=input()
while n>=i:i*=b
print i-n

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

Формат ввода: n, b.

Мистер Xcoder
источник
Вы можете упростить цикл, чтобы уменьшить 7 байтов
Rod
@ Род никогда бы не подумал об этом :). Большое спасибо!
г-н Xcoder
0

Python 3 , 50 48 байтов

Спасибо EriktheOutgolfer за сохранение 2 байта!

lambda n,b:b**-~int(math.log(n,b))-n
import math

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

У Python нет никаких причудливых конструкций из бревен или потолка, поэтому я просто пошел с очевидным подходом с небольшим чутьем игры в гольф.

notjagan
источник
import math;lambda n,b:b**-~int(math.log(n,b))-nсохраняет два байта и допускается на мета-консенсус.
Эрик Outgolfer
@EriktheOutgolfer ceilне будет работать.
Утренняя монахиня
@EriktheOutgolfer Я не использовал, ceilпотому что он не работает для мощностей b, но, как указывал @Uriel при импорте, до сих пор сохраняет байт.
notjagan
Вы можете переформатировать это, чтобы быть полностью прекрасным: Попробуйте это онлайн! , Просто поместите importпосле лямбды, и добавьте f=в шапку.
г-н Xcoder
@ Mr.Xcoder Ах, ты прав! Я не знаю, почему это не произошло со мной.
notjagan