Smallest positive number whose y-th power is divisible by x

15

2

Task

Given integers x and y which are both at least 2, find the smallest positive number whose y-th power is divisible by x.

Example

Given x=96 and y=2, the output should be 24 since 24 is the smallest positive n satisfying n^2 is divisible by 96.

Testcases

x  y output
26 2 26
96 2 24
32 3 4
64 9 2
27 3 3

Scoring

This is . Solution with lowest byte-count wins.

References

Leaky Nun

Posted 2016-08-21T19:03:35.643

Reputation: 45 011

Related. – Leaky Nun – 2016-08-21T19:05:10.710

1Will X always be greater than Y? – Fatalize – 2016-08-22T08:03:26.880

@Fatalize What has that got to do with anything? – Leaky Nun – 2016-08-22T08:10:20.033

There is no test case where X is less than Y, and it can reduce the length of some answers (at least mine) if X is always greater than Y. I would rather have that X can be either bigger or smaller, but then one test case for the latter would be great. – Fatalize – 2016-08-22T08:12:57.997

1Your references list is the best illustration I've seen of the ridiculous arbitrariness of OEIS entry ordering. – Sparr – 2016-08-22T19:32:13.510

Answers

7

Brachylog, 19 17 16 15 12 bytes

2 bytes saved thanks to @LeakyNun.

:[I:1]*$r=#>

Try it online!

Explanation

               Input = [X, Y]
:[I:1]*        Get a list [X*I, Y] (I being any integer at this point)
       $r=     Get the first integer which is the Yth root of X*I
          #>   This integer must be strictly positive
               This integer is the Output

Fatalize

Posted 2016-08-21T19:03:35.643

Reputation: 32 976

1 byte off – Leaky Nun – 2016-08-21T19:22:17.307

@LeakyNun Thanks. This will be much slower though. – Fatalize – 2016-08-21T19:23:54.870

Why will this be slower? – Leaky Nun – 2016-08-21T19:25:00.337

Slower still, but another byte off – Leaky Nun – 2016-08-21T19:26:53.450

@LeakyNun Because it will try all integers from 1 up to the answer. whereas my answer would propagate the constraints before assigning a value. – Fatalize – 2016-08-21T19:26:55.090

4

To quote the famous Fatalize: "don't care about complexity"

– Leaky Nun – 2016-08-21T19:46:41.900

6

Jelly, 6 bytes

ÆE÷ĊÆẸ

Try it online! or verify all test cases.

How it works

ÆE÷ĊÆẸ  Main link. Arguments: x, y

ÆE      Yield the exponents of x's prime factorization.
  ÷     Divide them by y.
   Ċ    Ceil; round the quotients up to the nearest integer.
    ÆẸ  Return the integer with that exponents in its prime factorization.

Dennis

Posted 2016-08-21T19:03:35.643

Reputation: 196 637

1R*%⁸i0 is also 6 bytes. – Leaky Nun – 2016-08-21T19:55:06.447

I think that warrants a separate answer. – Dennis – 2016-08-21T19:59:56.963

6

JavaScript (ES7), 32 bytes

f=(x,y,i=1)=>i**y%x?f(x,y,i+1):i

Neil

Posted 2016-08-21T19:03:35.643

Reputation: 95 035

You never defined f. I think you need to assign the function to f. – kamoroso94 – 2016-08-23T16:07:08.193

1@kamoroso94 Sorry, I'm forever doing that. – Neil – 2016-08-23T18:09:22.690

5

Python 3, 60 43 39 bytes

Thanks to @LeakyNun and @Sp3000 for help

f=lambda x,y,i=1:i**y%x<1or-~f(x,y,i+1)

A function that takes input via argument and returns the output.

How it works

The function uses recursion to repeatedly check integers i, starting with i=1, until one satisfying the required condition, here i**y%x<1, is found. This is achieved by taking the logical or of the condition and the result of the expression for i+1 incremented, which here is -~f(x,y,i+1). This expression continuously evaluates as False until a satisfying value j is found, at which point it evaluates to True and recursion stops. Since these are respectively equivalent to 0 and 1 in Python, and the function has repeatedly been adding 1 via the incrementing part, the function returns (j-1)*False + True + (j-1)*1 = (j-1)*0 + 1 + (j-1)*1 = 1 + j-1 = j, as required.

Try it on Ideone

TheBikingViking

Posted 2016-08-21T19:03:35.643

Reputation: 3 674

1def f(x,y,i=1):¶ while i**y%x:i+=1¶ print(i) – Leaky Nun – 2016-08-21T19:23:31.787

@LeakyNun Thanks. I just thought of a slightly shorter way to do it (43 vs 44) with recursion. – TheBikingViking – 2016-08-21T19:34:30.667

239: f=lambda x,y,z=1:z**y%x<1or-~f(x,y,z+1) – Sp3000 – 2016-08-21T19:35:02.957

@Sp3000 Doesn't your function return True instead of z? – Leaky Nun – 2016-08-21T19:44:17.453

@LeakyNun You're missing the -~ part, but yes it would return True if x was 1. – Sp3000 – 2016-08-21T19:52:52.780

Since this function only works if it's assigned to the variable f, shouldn't that assignment be included in the byte count? Or are those bytes freebies? – Jordan – 2016-08-22T04:17:40.577

@Jordan The 39 count includes the f= – Sp3000 – 2016-08-22T05:45:22.157

5

Jelly, 6 bytes

R*%⁸i0

Try it online! or verify all test cases.

How it works

R*%⁸i0  Main link. Arguments: x, y

R       Yield range from 1 to x inclusive.
 *      Raise each to power y.
  %⁸    Take modulo of each with base x.
    i0  Find the 1-based index of the first
        occurence of zero, returns.

Leaky Nun

Posted 2016-08-21T19:03:35.643

Reputation: 45 011

4

Haskell, 31 bytes

x#y=[n|n<-[1..],mod(n^y)x<1]!!0

Usage example: 96#2 -> 24.

Direct implementation: try all integers n, keep those that meet the condition and pick the first one.

nimi

Posted 2016-08-21T19:03:35.643

Reputation: 34 639

2Also 31: x#y=until(\n->mod(n^y)x<1)(+1)0 – xnor – 2016-08-22T05:41:24.407

4

05AB1E (10 bytes)

>GN²m¹ÖiNq

Try it online

  • > Reads the first argument, increments it, and pushes it on the stack
  • G pops the stack (a) and starts a loop that contains the rest of the program where N takes on the value 1, 2, ... a - 1.
  • N²m pushes N and the second entry from the input history, then pops them both and pushes the first to the power of the second.
  • ¹ pushes the first entry from the input history onto the stack.
  • Ö pops the previous two stack entries, then pushes a % b == 0 on the stack.
  • i pops that from the stack. If true, it executes the rest of the program; otherwise, the loop continues.
  • N pushes N on the stack.
  • q terminates the program.

When the program terminates, the top value of the stack is printed.

ruds

Posted 2016-08-21T19:03:35.643

Reputation: 201

Please post an explanation of how this code works for those nto familiar with your language, but otherwise good job, and nice first post. – Rohan Jhunjhunwala – 2016-08-21T20:23:48.247

That link seems interesting. – Leaky Nun – 2016-08-21T20:24:03.377

2Very nice first answer. – Emigna – 2016-08-21T20:58:17.190

3

MATL, 9 bytes

y:w^w\&X<

Try it online!

Explanation

y       % Take x and y implicitly. Push x again
        % STACK: x, y, x
:       % Range from 1 to x
        % STACK: x, y, [1, 2, ..., x]
w       % Swap
        % STACK: x, [1, 2, ..., x], y
^       % Power, element-wise
        % STACK: x, [1^y,  2^y, ..., x^y]
w       % Swap
        % STACK: [1^y, 2^y, ..., x^y], x
\       % Modulo, element-wise
        % STACK: [mod(1^y,x), mod(2^y,x), ..., mod(x^y,x)]
        % A 0 at the k-th entry indicates that x^y is divisible by x. The last entry
        % is guaranteed to be 0
&X<     % Arg min: get (1-based) index of the first minimum (the first zero), say n
        % STACK: n
        % Implicitly display

Luis Mendo

Posted 2016-08-21T19:03:35.643

Reputation: 87 464

Stack manipulation much. – Leaky Nun – 2016-08-21T19:12:42.060

1Yep. I suspect Jelly will have a big advantage here, since it avoids all those "copy" and "swap" – Luis Mendo – 2016-08-21T19:19:33.727

Don't you have find? – Leaky Nun – 2016-08-21T20:01:04.010

@LeakyNun Yes, f, but that finds all nonzero indices. So it would have to be ~f1): negatve, find, get the first entry – Luis Mendo – 2016-08-21T20:02:46.987

3

Actually, 12 11 bytes

Many thanks to Leaky Nun for his many suggestions. Golfing suggestions welcome. Try it online!

;)R♀ⁿ♀%0@íu

Original 12-byte approach. Try it online!

1WX│1╖╜ⁿ%WX╜

Another 12-byte approach. Try it online!

w┬i)♀/♂K@♀ⁿπ

A 13-byte approach. Try it online!

k╗2`╜iaⁿ%Y`╓N

Ungolfing:

First algorithm

       Implicitly pushes y, then x.
;      Duplicate x.
)      Rotate duplicate x to bottom of the stack.
R      Range [1, x] (inclusive).
♀ⁿ     Map a**y over the range.
♀%     Map a**y%x over the range.
0@í    new_list.index(0)
u      Increment and print implicitly at the end of the program.

Original algorithm

       Implicitly pushes x, then y.
1WX    Pushes a truthy value to be immediately discarded 
         (in future loops, we discard a**y%x)
|      Duplicates entire stack.
         Stack: [y x y x]
1╖     Increment register 0.
╜      Push register 0. Call it a.
ⁿ      Take a to the y-th power.
%      Take a**y mod x.
W      If a**y%x == 0, end loop.
X      Discard the modulus.
╜      Push register 0 as output.

Third algorithm

       Implicitly pushes y, then x.
w      Pushes the full prime factorization of x.
┬      Transposes the factorization (separating primes from exponents)
i      Flatten (into two separate lists of primes and exponents).
)      Rotate primes to the bottom of the stack.
♀/     Map divide over the exponents.
♂K     Map ceil() over all of the divided exponents.
@      Swap primes and modified exponents.
♀ⁿ     Map each prime ** each exponent.
π      Product of that list. Print implicitly at the end of the program.

Fourth algorithm

     Implicitly pushes x, then y.
k╗   Turns stack [x y] into a list [x, y] and saves to register 0.
2    Pushes 2.
  `    Starts function with a.
  ╜i   Pushes register 0 and flattens. Stack: [x y a]
  a    Inverts the stack. Stack: [a y x]
  ⁿ%   Gets a**y%x.
  Y    Logical negate (if a**y is divisible by x, then 1, else 0)
  `    End function.
╓    Push first (2) values where f(x) is truthy, starting with f(0).
N    As f(0) is always truthy, get the second value.
     Print implicitly at the end of the program.

Sherlock9

Posted 2016-08-21T19:03:35.643

Reputation: 11 664

@LeakyNun Waiting for one of your winning golf suggestions :D – Sherlock9 – 2016-08-21T19:34:49.687

@LeakyNun I'd be happy to post those approaches, too, unless you want to post them yourself. – Sherlock9 – 2016-08-21T19:37:04.513

+1 for the smirk ;) – Leaky Nun – 2016-08-21T20:07:13.813

2

dc, 23 22 bytes

Thanks to Delioth for his tip about input methods, saving a byte

sysxz[zdlylx|0<F]dsFxp

Uses the stack depth operator z for incrementing the test case directly on the stack, and the modular exponentiation operator | for, well, modular exponentiation. Repeat testing until remainder is not greater than zero.

Joe

Posted 2016-08-21T19:03:35.643

Reputation: 895

1You technically don't need the ? at the beginning, as a standard way to invoke some things is > echo "x y [program]"|dc, where x and y are the same as the Question- x and y will be dropped onto the stack as normal. – Delioth – 2016-08-22T21:48:00.903

@Delioth Interesting, thanks! I always just used the -e option, but I'll use that from now on. – Joe – 2016-08-22T23:36:24.550

@Delioth, for me, using quotes throws errors reminding me that " is not implemented in dc, while not using quotes obviously gives shell errors. Is there anything to be done about this? I know stderr can be ignored, but it still bothers me. – Joe – 2016-09-04T01:32:19.557

2

R, 61 bytes, 39 bytes, 37 bytes, 34 bytes

I'm still a newbie in R programming and it turns out this is my first function I create in R (Yay!) so I believe there's still room for improvement.

function(x,y){for(n in 2:x){if(n^y%%x==0){cat(x,y,n);break}}}

Online test can be conducted here: RStudio on rollApp.


Major progress:

function(x,y){which.max((1:x)^y%%x==0)}

which.max works because it returns the highest value in a vector and if there are multiple it will return the first. In this case, we have a vector of many FALSEs (which are 0s) and a few TRUEs (which are 1s), so it will return the first TRUE.


Another progress:

function(x,y)which.max((1:x)^y%%x==0)

Finally, it beats out the answer using Python by two bytes. :)

Another progress: (Again!)

function(x,y)which.min((1:x)^y%%x)

Many thanks to Axeman and user5957401 for the help.

Anastasiya-Romanova 秀

Posted 2016-08-21T19:03:35.643

Reputation: 1 673

I think that your test link is dead. – TheBikingViking – 2016-08-22T13:50:09.687

@TheBikingViking Thanks for pointing that out. I'll edit it after having my late lunch – Anastasiya-Romanova 秀 – 2016-08-22T13:52:04.923

2if you use which.min, you could get rid of the ==0. The modulus will return a number, which be no lower than 0. – user5957401 – 2016-08-22T14:31:30.143

1@user5957401 Edited.Bolshoe spasibo... – Anastasiya-Romanova 秀 – 2016-08-22T16:16:41.013

For the same length of 34 bytes you also had the similar function(x,y)which(!(1:x)^y%%x)[1]. – plannapus – 2016-08-23T06:58:09.813

Post it as an answer then @plannapus :) – Anastasiya-Romanova 秀 – 2016-08-23T07:03:20.040

1

05AB1E, 8 bytes

Lsm¹%0k>

Explanation

L         # range(1,x) inclusive
 sm       # each to the power of y
   ¹%     # each mod x
     0k   # find first index of 0 (0-based)
       >  # increment to 1-based

Try it online

Emigna

Posted 2016-08-21T19:03:35.643

Reputation: 50 798

1

Perl 6,  26  25 bytes

{first * **$^y%%$^x,1..$x}
{first * **$^y%%$^x,1..*}

Explanation:

# bare block with two placeholder parameters 「$^y」 and 「$^x」
{
  # find the first value
  first

  # where when it 「*」 is taken to the power
  # of the outer blocks first parameter 「$^y」
  * ** $^y
  # is divisible by the outer blocks second parameter 「$^x」
  %% $^x,

  # out of the values from 1 to Inf
  1 .. *
}

Brad Gilbert b2gills

Posted 2016-08-21T19:03:35.643

Reputation: 12 713

0

Mathematica, 36 bytes

(i=1;While[n=i++;Mod[n^#2,#]!=0];n)&

martin

Posted 2016-08-21T19:03:35.643

Reputation: 1 335

0

Dyalog APL, 11 bytes

Translation of this.

0⍳⍨⊣|(⍳⊣)*⊢

0⍳⍨ find the first zero in
⊣| the division remainders when x divides
(⍳⊣)* the integers one through x, raised to the power of
y

TryAPL online!

Adám

Posted 2016-08-21T19:03:35.643

Reputation: 37 779

0

PowerShell v2+, 48 bytes

param($x,$y)(1..$x|?{!(("$_*"*$y+1|iex)%$x)})[0]

Takes input $x and $y. Constructs a range from 1 to $x, then uses Where-Object to filter those numbers. The filter takes the string "$_*" (i.e., the current number with an asterisk) and uses string-multiplication to concatenate those $y times, then tacks on a final 1 at the end, then pipes that to iex (short for Invoke-Expression and similar to eval). This takes the place of [math]::Pow($_,$y), since PowerShell doesn't have an exponentiation operator, and is two bytes shorter. That's fed into the modulo operator % with $x -- thus, if it's divisible, this will be 0, so we encapsulate that in parens and take the Boolean-not !(...) thereof. Thus, if its divisible, it'll be included by this filter, and all other numbers will be excluded.

Finally, we encapsulate the resultant numbers in parens (...) and take the [0] index. Since the range entered sorted 1..$x, this will be the smallest. That's left on the pipeline and printing is implicit.

Test cases

PS C:\Tools\Scripts\golfing> (26,2),(96,2),(32,3),(64,9),(27,3)|%{($_-join', ')+' -> '+(.\smallest-positive-number-divisor.ps1 $_[0] $_[1])}
26, 2 -> 26
96, 2 -> 24
32, 3 -> 4
64, 9 -> 2
27, 3 -> 3

AdmBorkBork

Posted 2016-08-21T19:03:35.643

Reputation: 41 581

0

PHP, 55 33 bytes

$i=1;while($i**$y%$x)$i++;echo$i;

NETCreator Hosting

Posted 2016-08-21T19:03:35.643

Reputation: 101

0

Perl, 29 26 bytes

Includes +3 for -p (not +1 since the code contains ')

Run with the input on STDIN

power.pl <<< "96 2"

power.pl:

#!/usr/bin/perl -p
/ /;1while++$\**$'%$`}{

Ton Hospel

Posted 2016-08-21T19:03:35.643

Reputation: 14 114

0

Pyth, 9 bytes

AQf!%^THG

A program that takes input of a list of the form [x, y] on STDIN and prints the result.

Try it online

How it works

AQf!%^THG  Program. Input: Q
AQ         G=Q[0];H=Q[1]
  f        First truthy input T in [1, 2, 3, ...] with function:
     ^TH    T^H
    %   G   %G
   !        Logical not (0 -> True, all other modulus results -> False)
           Implicitly print

TheBikingViking

Posted 2016-08-21T19:03:35.643

Reputation: 3 674

-1

PHP 59 bytes

Sorry, but I can't test this from my mobile. :)

function blahblah($x,$y){
  for($i=0;1;$i++){
    if(!$i^$y%$x){
      return $i;
    }
  }
}

Golfed

function b($x,$y){for($i=0;1;$i++){if(!$i^$y%$x)return $i;}

Roman Gräf

Posted 2016-08-21T19:03:35.643

Reputation: 2 915

You're using $z where you should be using $x and I don't think you're incrementing $i in the loop – theLambGoat – 2016-08-22T15:43:20.920