Jak daleko jest n do następnej potęgi b?


32

Pozwolić ni bbyć dodatnimi liczbami całkowitymi większymi niż 1.

Podaj odległość od ndo następnej mocy b.

Dla n=5i b=3następną potęgą 3from 5jest 9( 3^2 = 9), więc wynikiem jest 9 - 5 = 4.

Dla n=8i b=2następną potęgą 2from 8jest 16( 2^4 = 16), więc wynikiem jest 16 - 8 = 8. Zauważ, że njest to moc 2tego przykładu.

Przypadki testowe:

  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

To jest . Najkrótsza odpowiedź w bajtach wygrywa. Obowiązują standardowe luki .

Odpowiedzi:


16

Galaretka ,  4  3 bajty

ạæċ

Dynadyczny link biegnący npo lewej i bpo prawej stronie i zwracający wynik.

Wypróbuj online!

W jaki sposób?

ạæċ - Link: number n, number b | n,b ∈ ℕ
 æċ - ceiling n to the next power of b
ạ   - absolute difference between n and that

4
Przekreślone 4 jest nadal zwykłym 4; (
Uriel

2
@Uriel But  ;)
HyperNeutrino

Na początku początkowo myślisz: „och, to æċ!” zamiast „oww to jest takie trudne…”
Erik the Outgolfer,

Och, to może nie istnieć w historii, ale zmieniłem się z 4 bajtów. To byłæċ_⁸
Jonathan Allan

@JonathanAllan Ponieważ nie było tego w historii, nie miało to sensu i dlatego to zredagowałem.
Erik the Outgolfer,

8

Zestaw x86-64 ( Konwencja wywoływania Windows x64 ), 14 13 bajtów

Nieefektywne (ale svelte!) Iteracyjne podejście (z inspiracją dla @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

Powyższa funkcja przyjmuje dwa parametry całkowite n(przekazane do ECXrejestru) i b(przekazane do EDXrejestru) i zwraca wynik z pojedynczej liczby całkowitej (w EAXrejestrze). Aby wywołać go z C, użyłbyś następującego prototypu:

unsigned HowFarAway(unsigned n, unsigned b);

Jest to ograniczone do zakresu 32-bitowej liczby całkowitej. Można go łatwo zmodyfikować, aby obsługiwał 64-bitowe liczby całkowite za pomocą pełnych długich rejestrów, ale kodowanie tych instrukcji kosztuje więcej bajtów. :-)


Więc nie możesz ustawić eax na 1 w mniej niż 4 bajtach?
Neil

Hmm… Nie w normalny sposób, jakiego użyłby rozsądny programista, ale mógłbyś push 1+ pop raxtylko w 3 bajtach. Ale… wtedy nie musiałbyś pomijać mnożenia, więc nadal byłoby to rozsądną oszczędnością, ponieważ możesz porzucić jmp.
Cody Gray,

Ach, wiedziałem, że musi istnieć sposób na grę w golfa!
Neil

Możesz zrobić to samo z konwencją wywoływania SysV w systemie Linux, korzystając z wersji demonstracyjnej TIO .
Digital Trauma

Oczywiście, że możesz. Możesz to zrobić z dowolną konwencją wywoływania, która przekazuje przynajmniej dwa pierwsze parametry liczb całkowitych w rejestrach. System V, Win x64, Win32 __fastcall itp. Rejestry się zmieniają i musiałem wybrać jeden. Moneta wymyśliła „Windows”.
Cody Gray

6

C (gcc) , 39 35 bajtów

Nowe niezdefiniowane zachowanie dzięki Erikowi

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

Wypróbuj online!


f(n,b,i){for(i=b;b<n;b*=i);n=b-n;}zapisuje 5 bajtów i jest obsługiwany przez gcc
Erik the Outgolfer

@EriktheOutgolfer dlaczego nie b-=n?
Leaky Nun

@LeakyNun Ponieważ jest to pierwszy argument, w którym należy zapisać wartość zwracaną.
Erik the Outgolfer,

Umm, nie zaktualizowałeś kodu.
Erik the Outgolfer,

Czy możesz to zrobić, b-=njeśli zamienisz kolejność bi n?
Zacharý

6

Dyalog APL, 10 bajtów

2 bajty zapisane dzięki @ZacharyT

⊢-⍨⊣*1+∘⌊⍟

Wypróbuj online!

Przyjmuje njako prawy argument i blewy argument.

Oblicza .b⌊logbn + 1⌋ - n


Fajnie, właśnie miałem opublikować to dokładne rozwiązanie
Kritixi Lithos

@KritixiLithos Miałem trudności z trikiem podłogowym. myślisz, że można go przekształcić w pociąg?
Uriel

Tak, to może: ⊣-⍨⊢*1+∘⌊⍟⍨.
Zacharý

@ZacharyT nice one!
Uriel

Dostaję ⊢-⍨⊣*1+∘⌊⍟10 bajtów, ale z podmienionymi argumentami, więc njest to właściwy argument i blewy argument. Wykorzystałem sztuczkę ZacharyT, 1+∘⌊żeby zejść tak daleko.
Kritixi Lithos

6

R , 38 34 bajtów

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

Funkcja anonimowa. Przechowuje wszystkie wartości b do potęgi wszystkiego w zakresie [0, n], odejmuje n od każdego, podzbiór na wartości dodatnie i zwraca min.

TIO ma wersję inną niż pryr, zwaną as f(n,b); ta wersja musi być nazywana jako f(b,n).

Zaoszczędził 4 bajty dzięki Jarko Dubbeldamowi, który następnie mnie obezwładnił.

Wypróbuj online!


Fajnie, znacznie krócej niż rekursja, o której myślałem.
JAD,

pryr::f({a=b^(0:n)-n;min(a[a>0])})jest kilka bajtów krótszy.
JAD

Dzięki. Miałem pecha, pryr::fgdy definiowałem nową zmienną w funkcji; wygląda na to, że tutaj działa.
BLT

2
Hmm, zawsze warto to sprawdzić :) Denerwuje mnie to, że masz coś takiego sapply(x, sum)lub coś, co dodaje sumargumentów.
JAD

4

Cubix , 24 20 bajtów

-4 bajty dzięki MickyT

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

Odczytuje na wejściu jak n,b

Pasuje do kostki 2x2x2:

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

Wyjaśnienie:

I|I0 : odczytać dane wejściowe, przesunąć 0 (licznik) na stos

^w umieszcza adres IP we właściwym miejscu dla pętli:

  • Pp-: oblicz b^(counter), przejdź nna szczyt stosu, obliczb^(counter) - n
  • ? : skręć w lewo, jeśli ujemne, prosto, jeśli 0, w prawo, jeśli pozytywne
    • Pozytywne: O@wyjście z góry stosu (odległość) i wyjście.
    • Negatywne:: |?postępuj tak, jakby wierzchołek stosu wynosił zero
  • <;qu;): skieruj adres IP we właściwym kierunku, pop na górze stosu (liczba ujemna / zerowa), przejdź nna dół stosu, zawracaj, pop na górze stosu ( b^(counter)) i zwiększ licznik
  • Adres IP jest dostępny ^wi program jest kontynuowany.

Obejrzyj online!

Wypróbuj online!


1
Stosując tę ​​samą procedurę, po prostu inną ścieżkęPwp.I|-.;)^0@O?|uq;<
MickyT

@MickyT geniusz! Mam wrażenie, że za każdym razem, gdy przesyłam odpowiedź cubix, przychodzisz i golisz cztery lub pięć bajtów ...
Giuseppe,


2

05AB1E , 9 8 bajtów

sLmʒ‹}α¬

Wypróbuj online!

Wyjaśnienie

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)

1
You beat me by a minute. That's exactly what I wrote, but I used ć instead of ¬.
Riley

@Riley: Also works with filter, but unfortunately doesn't save any bytes.
Emigna

1
@Emigna unfortunately doesn't save any bytes *saves byte(s)*
Erik the Outgolfer

@EriktheOutgolfer: Yes, well. It was an additional change utilizing the weird way implicit input works that saved a byte :)
Emigna

1
@carusocomputing: Yes. It actually saves a byte to have them in the "wrong" order as I can reuse n implicitly, both in the filter comparison and the absolute difference calculation.
Emigna


2

MATL, 10 9 bytes

yy:YAn^w-

Try it online!

Explanation

Consider inputs 694 and 3 as an example.

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 bytes

Very similar to Rick's approach but posted with his permission (and some help saving a byte).

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

Try it

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 bytes

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

thanks Martin

I/O

[343, 7]

2058


You can use 1/Log@## or #2~Log~#. Or even better swap the order of the inputs and use Log@##.
Martin Ender

And then #^Floor[...]# is shorter than #^(Floor[...]+1). And there's the Unicode operators for Floor as well.
Martin Ender

yes, yes of course.I'm working on all these.you are quick!
J42161217

Don't forget Log@##! Actually, if you swap the argument order, #^⌊Log@##⌋#-#2& should be possible for -5 bytes (I think)!
CalculatorFeline

2

C, 42 40 bytes

Thanks to commenter @Steadybox for the tip

o;p(n,b){for(o=b;n>=b;)b*=o;return b-n;}

2
Using for instead of while saves two bytes: o;p(n,b){for(o=b;n>=b;)b*=o;return b-n;}
Steadybox

Suggest n/b instead of n>=b
ceilingcat

2

R, 30 bytes

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

Evaluates to the function

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

Which takes the first power greater or equal than n, and then substracts n from that value.

Changed ceiling(power) to floor(power+1) to ensure that if n is a power of b, we take the next power.


1

JavaScript (ES6), 31 bytes

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

Test cases:


You can save a byte by currying (it didn't matter whether I tried currying both n and b or just n), because that saves you from having to pass n recursively.
Neil

Thanks @Neil, but I'm having trouble figuring out how to do that(?)
Rick Hitchcock

The two versions I came up with were n=>g=(b,p=b)=>p>n?p-n:g(b,p*b) and n=>b=>(g=p=>p>n?p-n:g(p*b))(b).
Neil

Would f=(n,i)=>g=(b=i)=>b>n?b-n:g(b*i) work for 30 bytes? It would need to be called like so: f(324,5)(). EDIT: Ah, @Neil beat me to it.
Shaggy

@Neil, thanks, I need more practice with currying.
Rick Hitchcock







1

Japt, 9 bytes

_q}a@nVpX

Test it online!

Explanation

_  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

1
... Wait. What?
Shaggy

@Shaggy I've added an explanation, hopefully this helps.
ETHproductions

1

Python,  42  41 bytes

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

A recursive function which, starting with v=1, repeatedly multiplies by b until it strictly exceeds a and then returns the difference.

Try it online!

Note: The result will never be zero so a>=v and f(a,b,v*b)or v-a may be replaced with (a<v)*(v-a)or f(a,b,v*b) without causing recursion errors.


Python 3, 37 bytes?

Using an idea of rici's...

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

which uses floating point arithmetic (hence results may stray from their true distance),
try that here.


tio.run/… is a bit shorter but having to output the result with format "%.0f" is probably cheating.
rici

@rici Nice, I think it may be OK to use floating point arithmetic. I'll add it as an alternative (another byte may be saved by switching forms due to b-n never being zero at the same time as n<b is true).
Jonathan Allan



0

Lua, 74 73 Byte

A straight forward solution, I'm using 10 bytes to ensure that the arguments are treated as numbers, and not strings. Outputs to STDIN.

Edit: forgot to remove the space in w=1 n=n+0, saves one byte

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)

Explained

Try it online!

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

I don't know Lua that well, but is the space between 1 and end needed?
Zacharý

@ZacharyT In Lua, hexadecimal numbers can be inlined if they start with a number, 1end would start to be interpreted as the number 1e then throw an error because 1en isn't a valid hexadecimal value. This only occure when the letter following the number is [abcdef] as other letters can't be interpreted as hexadecimal value -> w=1while doesn't throw an error.
Katenkyo

Welcome back to PPCG!
Leaky Nun

0

QBIC, 23 bytes

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

Takes parameter b first, then n.

Explanation

{       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


0

Python 3, 50 48 bytes

Thanks to EriktheOutgolfer for saving 2 bytes!

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

Try it online!

Python doesn't have any fancy log or ceiling builtins, so I just went with the obvious approach with a little bit of golfing flair.


import math;lambda n,b:b**-~int(math.log(n,b))-n saves two bytes and is allowed per meta consensus.
Erik the Outgolfer

@EriktheOutgolfer ceil would not work.
Leaky Nun

@EriktheOutgolfer I wasn't using ceil because it doesn't work for powers of b, but as @Uriel pointed out importing before still saves a byte.
notjagan

You can reformat it to be completely fine: Try it online!. Just place the import after the lambda, and add f= in the header.
Mr. Xcoder

@Mr.Xcoder Ah, you are correct! I don't know why that didn't occur to me.
notjagan

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.