20
\$\begingroup\$

Powerful numbers are positive integers such that, when expressed as a prime factorisation:

$$a = p_1^{e_1} \times p_2^{e_2} \times p_3^{e_3} \cdots \times p_k^{e_k}$$

all exponents \$e_1, e_2, ...\$ are greater than or equal to \$2\$. Note that the exponents do not include zero exponents, as exampled by \$200 = 2^3 \times 3^0\times 5^2 = 2^3 \times 5^2\$ being a powerful number. This includes all perfect powers, and a few "extra" numbers that are not perfect powers.

Achilles numbers are powerful numbers that are not perfect powers. The smallest Achilles number is \$72 = 2^3 \times 3^2\$. The Achilles numbers less than or equal to \$500\$ are \$72, 108, 200, 288, 392, 432\$ and \$500\$.

You are to take an Achilles number as input and output the smallest Achilles number greater than the input.

You may input and output in any convenient method. This is so the shortest code in bytes wins

Test Cases

input output
   72    108
  108    200
  200    288
  800    864
 1152   1323
 4500   4563
 3456   3528
 4563   4608
43808  43904
90828  91592
28800  29403
64800  64827
29768  30375

The program I used to generate these test cases. Contains spoilers for anyone who can understand Jelly.

\$\endgroup\$
6
  • 1
    \$\begingroup\$ Brownie points for beating my Jelly answer (14 bytes) linked above \$\endgroup\$ Commented Feb 22, 2021 at 19:54
  • 4
    \$\begingroup\$ Nice challenge title, btw. :-) \$\endgroup\$
    – Arnauld
    Commented Feb 22, 2021 at 23:56
  • 1
    \$\begingroup\$ A052486 \$\endgroup\$
    – bigyihsuan
    Commented Feb 23, 2021 at 2:48
  • 1
    \$\begingroup\$ I didn't bother to react immediately but was online when someone down-voted all existing answers (and maybe the challenge as well) around 01:20 GMT. Maybe some math hater in a bad mood?... ¯\_(ツ)_/¯ \$\endgroup\$
    – Arnauld
    Commented Feb 23, 2021 at 10:59
  • 2
    \$\begingroup\$ @Arnauld Well, unless Hector or Paris have come back to life and started haunting the site, I guess we’ll never know... \$\endgroup\$ Commented Feb 23, 2021 at 12:23

11 Answers 11

7
\$\begingroup\$

J, 26 bytes

_(]+1-1</@(=],+./)q:)^:_>:

Try it online!

I started with the "do-until" idiom f^:g^:_ with g boolean (apply f while g is true), but soon realized that the "find next integer" can be written in a single fixpoint (]+1-g)^:_. The only problem is that we don't have a straightforward/more golfy way to express the boolean negation of g other than 1-g.

How it works

_(]+1-1</@(=],+./)q:)^:_>:  NB. Input: n
                        >:  NB. n+1
_(                  )^:_    NB. Fixpoint with left arg of _ (infinity)...
                  q:    NB. (_ q: n) gives prime exponents including zeros
                        NB. _ q: 700 -> 2 0 2 1 (2^2 * 5^2 * 7^1)
          ( ],+./)      NB. Append GCD of ^ to itself
      1    =            NB. Test if each number equals 1 (gives boolean vector)
       </@   NB. Test if the only 1 is the last item
  ]+1-       NB. Negate the condition and add to the input number
\$\endgroup\$
3
  • 1
    \$\begingroup\$ </@ NB. Test if the only 1 is the last item -- Nice. \$\endgroup\$
    – Jonah
    Commented Feb 23, 2021 at 6:32
  • 1
    \$\begingroup\$ (]+1-g)^:_ This is also a useful trick I don't think I've ever seen before. Perhaps worth adding to "Tips for golfing in J". \$\endgroup\$
    – Jonah
    Commented Feb 23, 2021 at 6:49
  • 1
    \$\begingroup\$ (]+1-g)^:_ is pretty cool! With an inverted g: 25b \$\endgroup\$
    – xash
    Commented Feb 23, 2021 at 11:45
7
\$\begingroup\$

Jelly, 12 bytes

‘ÆEg/ḟ$f1Ʋ1#

A full program which prints the next Achilles number.

Try it online! Or see the test-suite.

How?

‘ÆEg/ḟ$f1Ʋ1# - Main Link: Archiles number (or any integer), n
‘            - increment (n)
          1# - find the first k (starting at k=n+1) for which:
         Ʋ   -   last four links as a monad - i.e. f(k):
 ÆE          -     prime exponent vactor (e.g k=400 -> [3,0,2] since 2^3+3^0+5^2)
      $      -     last two links as a monad:
    /        -       reduce by:
   g         -         Greatest Common Divisor -> x
     ḟ       -      filter discard (from [x] if in ÆE result)
        1    -     one
       f     -     filter keep (i.e. [1] if g/ was 1 and 1 not in ÆE result)
                   (empty list is falsey, so we keep incrementing k until we get [1])
\$\endgroup\$
4
  • 1
    \$\begingroup\$ Very clever use of filtering--even if it had occurred to me that I could count on the GCD being 1 if it matters to check if the number is powerful, I probably still wouldn't have come up with that. \$\endgroup\$ Commented Feb 23, 2021 at 13:37
  • \$\begingroup\$ If you’d like to save a byte on this almost three-year-old answer, you can replace f1Ʋ with ỊƊ: tio.run/#%23y0rNyan8//… \$\endgroup\$ Commented Oct 29, 2023 at 13:26
  • \$\begingroup\$ @NickKennedy that won't work even though it passes all the test cases. A counter-example would be an input of \$2^3 \times 5^4 = 5000\$ which should find \$2^2 \times 3^3 \times 7^2 = 5292\$ but will find \$2^6 \times 3^4 = 5184\$ because [2]Ị is [0] which is truthy. \$\endgroup\$ Commented Oct 29, 2023 at 18:31
  • 1
    \$\begingroup\$ Quite right. I thought I’d tested that but must have missed something! Nice solution by the way. \$\endgroup\$ Commented Oct 29, 2023 at 23:16
6
\$\begingroup\$

JavaScript (ES6),  117 ... 99  98 bytes

f=n=>(d=1,h=(n,x)=>++d>n?~x:1/(g=_=>q=n%d?0:g(n/=d)-1)(G=x=>q?G(q,q=x%q):x)|h(n,G(x)))(++n)?f(n):n

Try it online!

Commented

f = n => (              // f is a recursive function taking n
  G = x =>              // G is a helper function computing GCD(x, q)
    q ? G(q, q = x % q) // (NB: actually defined in a dummy argument
      : x,              // passed to g in the last golfed version)
  d = 1,                // initialize the divisor d
  h = (                 // h is a recursive function taking:
    n,                  //   n = updated value
    x                   //   x = GCD of the exponents (but negative)
  ) =>                  //
    ++d > n ?           // increment d; if it's greater than n:
      ~x                //   stop and yield -x - 1
    :                   // else:
      1 / (g = _ =>     //   g is yet another recursive function
        q =             //   which computes q:
          n % d ?       //   the opposite of the number of times n can be
            0           //   divided by d
          :             //
            g(n /= d)   //   we compute 1 / g() followed by a bitwise OR
            - 1         //   to make sure that q is not equal to -1
      )() |             //
      h(                //   recursive call to h:
        n,              //     updated value of n
        G(x)            //     x = GCD(x, q)
      )                 //   end of recursive call
)(++n) ? f(n)           // if the result of h is truthy, try again
       : n              // otherwise, return n
\$\endgroup\$
5
\$\begingroup\$

Jelly, 14 13 bytes

‘‘ÆE’Pȧg/Ʋ’Ɗ¿

Try it online!

Did not look at the linked Jelly answer, but that byte count does look familiar... until I remembered how I was originally checking the GCD anyhow

edit: they're not even remotely alike what the hell

‘                Starting at 1 more than the input,
 ‘         Ɗ¿    increment while:
  ÆE     Ʋ       for the exponents of the prime factorization,
     P           the product of
    ’            each minus 1
      ȧ          logical-AND
       g/        their greatest common denominator
          ’      is not equal to 1.
\$\endgroup\$
2
  • 1
    \$\begingroup\$ Interesting that 14 seems to be the lower bound for Jelly here. I adapted your version into one that looked more like mine, and it was also 14 bytes. Edit: Nevermind then :P \$\endgroup\$ Commented Feb 22, 2021 at 20:40
  • 5
    \$\begingroup\$ @cairdcoinheringaahing now you gotta give the brownie :P \$\endgroup\$
    – Alex bries
    Commented Feb 22, 2021 at 20:43
5
\$\begingroup\$

Pyth, 20 18 bytes

f&!}1J/LPTPTqiFJ1h

Try it online!

-2 bytes thanks to FryAmTheEggman!


Explanation:

f                hQ | first integer T starting at input + 1 such that
      /LPTPT        | each prime factor's count in the prime factor list of T
     J              | (this list will be called J)
  !}1               | does not contain 1
 &                  | AND
             iFJ    | the GCD of all of the elements of J
            q   1   | equals 1
\$\endgroup\$
1
  • \$\begingroup\$ Hey, if you downvote this answer, mind giving a short explanation why? \$\endgroup\$
    – hakr14
    Commented Feb 23, 2021 at 19:51
5
\$\begingroup\$

Husk, 17 19 18 14 bytes

Fixed thanks to Giuseppe but had to add 2 bytes. As Neil and caird coinheringaahing pointed out, not only was my second condition unnecessary, my third condition was just plain wrong. Hopefully it's fixed now.

ḟö§¤>ε▼F⌋mLgp→

Try it online!

ḟö§¤>ε▼F⌋mLgp→
             → Increment input
ḟ              Find the smallest number greater than or equal to n+1 matching this condition:
            p    Prime factorization
           g     Group equal adjacent elements
         m       Map each to
          L       its length (the powers)
  §             Fork (apply two functions to the powers and then combine the results)
      ▼          First function: Minimum power
       F         Second function: Reduce with
        ⌋         gcd
   ¤>ε           Function to combine with:
   ¤              Apply one function to both arguments, then combine with another function
     ε             Check if equal to 1 (1 if 1, 0 otherwise)
    >              Ensure the minimum is not 1, but the gcd is.
\$\endgroup\$
4
  • 2
    \$\begingroup\$ Those aren't actually quite the correct conditions. The first one is fine; the second one is superfluous, while the third one has to check for any common divisor, not just 2. \$\endgroup\$
    – Neil
    Commented Feb 23, 2021 at 0:19
  • 3
    \$\begingroup\$ Your third condition isn't quite correct, and causes it to fail for \$200\$ (Try it online!). It should be "the GCD of the powers is 1" \$\endgroup\$ Commented Feb 23, 2021 at 0:20
  • \$\begingroup\$ @Neil You're right, all I was thinking about were squares \$\endgroup\$
    – user
    Commented Feb 23, 2021 at 0:41
  • \$\begingroup\$ @cairdcoinheringaahing You're right, I've fixed it now (and shortened it a little too) \$\endgroup\$
    – user
    Commented Feb 23, 2021 at 0:42
5
\$\begingroup\$

05AB1E, 12 bytes

A port of Bubbler's J answer.

∞+.ΔÓD¿ªΘ.«‹

Try it online!

∞            # push an infinite list of numbers [1,2,3,...]
 +           # add the input to each number
  .Δ         # find the first integer in this list that satisfies:
    Ó        # the exponents of the prime factorization (including 0's)
     D       # duplicate this list
      ¿      # take the gcd
       ª     # and append it to the exponents
        Θ    # for each value: is it equal to 1?
         .«  # right reduce this list of 0's and 1's
           ‹ # with a < b, this is only 1 if the list had a single 1 at the end

The same length without the builtin:

[>DÓD¿ªΘ.«‹#

Try it online!

\$\endgroup\$
2
  • \$\begingroup\$ .«‹ can be for -1. \$\endgroup\$ Commented Mar 10, 2021 at 10:53
  • \$\begingroup\$ Correction from my 2+ year old comment above, .«‹ can even be just J for -2 bytes (strings like "000001" are still considered 1 and thus truthy). \$\endgroup\$ Commented Jul 28, 2023 at 7:20
4
\$\begingroup\$

Retina 0.8.2, 157 115 bytes

.+
$*11
+`^(1+)((\1(1+))(?=(\3*)\1*$)\3*(?=\4$\5))+1$|^(?!((?=(11+?)\7*$)((?=\7+$)(?=(1+)(\9+)$)\10){2,})+1$)
1$&
1

Try it online! No test suite because it would be too slow. Explanation:

.+
$*11

Convert to unary and add 1.

+`

Repeat while...

^(1+)((\1(1+))(?=(\3*)\1*$)\3*(?=\4$\5))+1$|

... the current value is a perfect power, or...

^(?!((?=(11+?)\7*$)((?=\7+$)(?=(1+)(\9+)$)\10){2,})+1$)

... the current value is not powerful...

1$&

... increment the value.

1

Convert to decimal.

I'm currently testing whether a number is powerful based on taken from my answer to Is it almost-prime? except here I divide at least twice by each (prime) factor and then repeat until all factors have been consumed. In theory it should be possible to take any factors and divide at least twice by each, but for some reason I don't seem to be able to adapt the expression for perfect powers to match a product of perfect powers.

\$\endgroup\$
4
\$\begingroup\$

Java, 194 167 160 152 bytes

Saved 7 bytes thanks to ceilingcat

Saved 8 bytes thanks to user

int a(int n){return p(++n)!=1?a(n):n;}int p(int n){for(int i=1,o=n,c,z;++i<o;){for(c=z=1;n%i<1;c++)n/=i;while(z<o)z*=i;if(c==2|z==o)return 0;}return n;}

Try it online!

\$\endgroup\$
3
  • 2
    \$\begingroup\$ Save a couple bytes using ?: instead of while \$\endgroup\$
    – user
    Commented Feb 26, 2021 at 16:18
  • 2
    \$\begingroup\$ And 152 bytes if you return an int from p instead of a boolean (I can't guarantee this works, though, since I don't understand your algorithm) \$\endgroup\$
    – user
    Commented Feb 26, 2021 at 16:21
  • \$\begingroup\$ @user Thanks for the help. \$\endgroup\$ Commented Feb 26, 2021 at 16:26
3
\$\begingroup\$

Brachylog, 17 16 bytes

<.ḋḅ{{Ṁlf⊇}ᵛ!}Ȯ∧

Try it online!

Looked like it might compete with Jelly until I realized where I'd have to put that cut! Trying to see if maybe I could do not-a-perfect-power checking without going through the factors of the prime exponents.

 .                  The output
<                   is a number strictly greater than the input
   ḅ                of which the runs of
  ḋ                 the prime factors
     {    }ᵛ        each
      Ṁ             contain at least two elements,
        f           and the factors of
       l            the lengths of which
    {    ⊇ ᵛ!}      have a largest common subset
               ∧    (not necessarily equal to the output)
              Ȯ     which contains only one element.
\$\endgroup\$
2
\$\begingroup\$

Japt, 24 bytes

Definitely struggled to cut this short since some of the operations are bulky by themselves, for example getting the exponents.

_=k ü mÊ;Zry ¶1©Ze¨2}aUÄ
                      UÄ // Starting at input plus one,
                     a   // find the next integer that returns true when
_                   }    // run through the function:
 =                       // Z = 
  k                      // prime factors
    ü                    // grouped by value
      mÊ                 // and mapped to length, e.g. the exponents of prime factors.
        ;                // Return whether
         Zry ¶1          // GCD of Z equals 1
               ©         // and
                Ze¨2     // every member of Z is geq 2.

Try it out here.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.