Can this number be written in (3^x) - 1 format?

41

2

Challenge:

Create a program that accepts a positive integer and checks if it can be written in the form of (3^x)-1, where X is another positive integer.

If it can, output X

If it can't, output -1 or a falsy statement.

Example inputs/outputs

Input:

2

It can be written as (3^1) - 1, so we output x which is 1

Output:

1

Input:

26

26 can be written as (3^3) - 1, so we output x (3)

Output:

3

Input:

1024

1024 can't be written in the form of (3^x) - 1, so we output -1

Output:

-1

This is so least amount of bytes wins


Related OEIS: A024023

P. Ktinos

Posted 2017-01-06T14:47:54.043

Reputation: 2 742

4I ask to output X because I believe it's more challenging that way. Simply finding if it is of format 3^x - 1 would be too easy for a challenge, in my opinion. – P. Ktinos – 2017-01-06T14:56:02.173

Maybe instead of -1 can we output some other distinct falsy value? – user41805 – 2017-01-06T15:04:05.457

Yes you can. I edited my question, and now you can output a falsy value. – P. Ktinos – 2017-01-06T15:08:33.307

Would this kind of "magic formula" make sense? if (OEIS Sequence contains the number) return number; else return -1 – devRicher – 2017-01-06T16:29:10.883

Can 0 be returned instead of -1, seeing as the result will never be 0 (because X has to be positive)? – FlipTack – 2017-01-06T16:55:37.017

2Unless if it's a falsy statement in your programming language, then no. – P. Ktinos – 2017-01-06T16:57:33.510

You said it should output -1 or falsy, so why is -1 invalid? – devRicher – 2017-01-06T17:18:59.443

@devRicher I never said -1 is invalid, I answered to FlipTack who asked if 0 is valid.

Also I didnt understand your question. What do you mean if oeis sequence contains the number. The sequence for 3^x-1 is obviously infinite – P. Ktinos – 2017-01-06T17:25:21.137

2May I want the number to be input in ternary? – John Dvorak – 2017-01-06T17:35:13.220

@JanDvorak No you may not. Most programming languages can't accept base3 numbers / convert decimal to ternary or vice versa easily (having a built-in method) so it would be unfair for them – P. Ktinos – 2017-01-06T21:28:27.320

1How large of a number does our program need to support? – HyperNeutrino – 2017-01-07T03:06:58.110

2having to handle non-negative intergers would make 0 3^0-1 a valid output and thus not useable as false, – Jasen – 2017-01-07T07:40:44.093

2anyone thinking of using log() in their answer should confirm it giives the correct answer 5 when 242 is input. – Jasen – 2017-01-07T09:57:32.353

@AlexL. The input should only be limited by memory to store the number. If the algorithm would work with any number in real life, it would be fine to use any integer max value. – P. Ktinos – 2017-01-07T14:11:37.653

does that mean bignums, or is it ok to use a normal integer type? and if so how small? – Jasen – 2017-01-07T19:04:20.547

@Jasen Just use the "average" integer size. By average I mean, not "long", not "short". Eg, in VB.NET you have int16, int32, int64. In that case, you would use int32. Of course, if you want to use "long" becase it is less bytes, go ahead. Size doesnt matter, if you use something that was designed to store numbers. – P. Ktinos – 2017-01-07T19:10:51.207

Answers

23

Mathematica, 21 16 bytes

-1&@@Log[3,#+1]&

Makes use of Mathematica's symbolic computation. If #+1 is a power of three then Log[3,#+1] will compute an integer result which is an atomic value. Otherwise we'll get Log[#+1]/Log[3] as is. Since this is not an atomic value, it's an expression which is always of the form head[val1,val2,...]. In this case it's actually something like Times[Power[Log[3], -1], Log[#+1]].

We distinguish between the two cases by applying another function to the result. What applying really does is that it replaces the head part of an expression. Since integer results are atomic, applying any function to them does nothing at all. In particular f @@ atom == atom.

However, in the other case, the head does get replaced. The function we're using is -1& which is a simple function that ignores its arguments and returns -1. So we get something -1&[Power[Log[3], -1], Log[#+1]] in non-integer cases, which evaluates directly to -1. Special casing via magic.

Martin Ender

Posted 2017-01-06T14:47:54.043

Reputation: 184 808

13

Haskell, 35 bytes

f x=last(-1:[i|i<-[1..x],3^i-1==x])

Usage example: f 26 -> 3.

nimi

Posted 2017-01-06T14:47:54.043

Reputation: 34 639

PS: Try it online! supports Haskell! (Nice answer btw!)

– flawr – 2017-01-06T16:11:53.367

13

Python, 46 44 bytes

lambda x:max(n*(3**n-1==x)for n in range(x))

Try it online!

In this case, 0 would be the falsy value. Thanks to @mbomb007 for pointing out my incorrect output as well as a 2 bytes no [] savings.

nmjcman101

Posted 2017-01-06T14:47:54.043

Reputation: 3 274

you can rewrite as [n for n in range(x)if 3**n-1==x] for -4 bytes, empty list as falsy – Rod – 2017-01-06T15:53:39.003

Fixed, thank you! @Rod then it would return [n] instead of n I think – nmjcman101 – 2017-01-06T15:58:36.640

@nmjcman101 that shouldn't be a problem – Rod – 2017-01-06T16:01:44.153

@Rod I'd prefer adhering strictly to spec for now – nmjcman101 – 2017-01-06T16:14:51.827

@Rod If outputting an integer is required, you cannot output it in a list unless the OP specifically allows it. – mbomb007 – 2017-01-06T16:17:23.157

11

05AB1E, 7 bytes

3IÝm<¹k

Try it online!

Explanation

3        # push 3 
 I       # push input
  Ý      # range [0 ... input]
   m     # 3^[0 ... input]
    <    # -1
     ¹k  # find index of input, return -1 if not found

Emigna

Posted 2017-01-06T14:47:54.043

Reputation: 50 798

05AB1E is apparently good at base conversion is this really the best approach? – Jasen – 2017-01-07T07:26:51.760

1@Jasen: My attempts with base conversion all turned out longer. If there is a better way than this I'm not seeing it. Feel free to prove me wrong though :) – Emigna – 2017-01-07T09:46:50.887

fair enough, I've only read the description of the language, and, so expected to see a 5 byte solution.... – Jasen – 2017-01-07T11:43:37.303

1@Jasen <3zm©.ïi® is the closest I've got not using ranges like he did. – Magic Octopus Urn – 2017-01-10T15:28:05.440

13DÝms<k... Nevermind... Can't shave off one more byte, could of sworn I could. – Magic Octopus Urn – 2017-01-12T19:33:51.813

@carusocomputing: I'm pretty sure this is the minimum count using this strategy. Haven't found a different strategy able to improve on it, but it could be possible. – Emigna – 2017-01-12T19:47:41.827

9

Jelly, 5 bytes

R3*’i

Outputs x or 0 (falsy).

Try it online!

How it works

R3*’i  Main link. Argument: n

R      Range; yield [1, ..., n].
 3*    Map each k to 3**k.
   ’   Decrement the results.
    i  First index of n (0 if not found).

Dennis

Posted 2017-01-06T14:47:54.043

Reputation: 196 637

6

Perl, 31 bytes

say grep{3**$_-1==$i}0..($i=<>)

Requires -E flag to run:

perl -E 'say grep{3**$_-1==$i}0..($i=<>)' <<< 26

Explanations:
grep{3**$_-1==$i}0..($i=<>) returns a list of the elements of the range 0..$_ (ie. from 0 to the input) that satisfies the test 3**$_-1==$i. Only one element at most can satisfy this test, so this instruction will return an array of 0 or 1 element. We then print this list: either the X or nothing (which is falsy).

Dada

Posted 2017-01-06T14:47:54.043

Reputation: 8 279

6

Python 2, 41 bytes

f=lambda n,i=0:i*0**n or n%3/2*f(n/3,i+1)

A recursive function that returns 0 for non-matching inputs. Repeatedly floor-divides the input by 3, counting the number of steps in i, which is output in the end. But, if any step produces a value n that isn't 2 modulo 0, the number was not of for 3^i-1, so the output is multiplied by 0.

xnor

Posted 2017-01-06T14:47:54.043

Reputation: 115 687

5

Pyth, 11 bytes

?-JjQ3 2ZlJ

Converts to base 3 and checks equality to [2, 2, ..., 2].

orlp

Posted 2017-01-06T14:47:54.043

Reputation: 37 067

You can reduce this by one byte with ?-2JjQ3ZlJ, since <col> <num> and <num> <col> are interchangeable for - in Pyth. – notjagan – 2017-01-07T05:06:52.857

5

Processing, 60 56 bytes

void q(float n){n=log(n+1)/log(3);print(n>(int)n?-1:n);}

Outputs -1 if falsy.

Explanation

void q(float n){              // n is input
  n=log(n+1)/log(3);          // finds X in 3^X+1=n as a float (here we'll storing that in n)
  print(n>(int)n?-1:n);       // checks if the float is greater than
                              // the number rounded down (by int casting)
                              // if it is greater, output -1
                              // otherwise output X
}

void is 1 byte shorter than using float, so that's why this function directly outputs instead of returning a value.

Alternative Solution

void z(float n){int c=0;for(++n;n>1;c++)n/=3;print(n==1?c:-1);}

for 63 bytes, but I think this alt can be golfed to be shorter than the original solution. I'm working on it.

user41805

Posted 2017-01-06T14:47:54.043

Reputation: 16 320

@FlipTack Yeah, I knew it wouldn't be in Java. I just asked since I wasn't sure that Processing hadn't added something along those lines. The "distinct value" to be used was -1 though, not 0. It's been changed since, though, so I'll probably clean up my comments about it. – Geobits – 2017-01-06T16:51:45.667

Wait, so can I return 0 now? – user41805 – 2017-01-06T16:52:55.173

I'd still say no. The question gives an alternative integer value to use if falsy, but 0 is never falsy in Java/Processing that I know of. – Geobits – 2017-01-06T16:53:44.400

I thougt Processing was supposed to be less versbose than Java

– Pavel – 2017-01-07T08:24:47.263

@Pavel But I don't use lambdas :/ – user41805 – 2017-01-07T08:35:19.920

does it work with 242 as input (result 5)? – Jasen – 2017-01-07T09:39:52.410

@Jasen Yes, it outputs 5 for 242 as input – user41805 – 2017-01-07T09:48:30.387

5

JavaScript (ES7), 38 36 34 bytes

f=(n,k=33)=>3**k-n-1&&--k?f(n,k):k

Or just 30 29 bytes if it's OK to exit with an error on failure:

f=(n,k)=>~(n-3**k)?f(n,-~k):k

Test

f=(n,k=33)=>3**k-n-1&&--k?f(n,k):k

console.log(f(177146))
console.log(f(847288609442))
console.log(f(5559060566555522))
console.log(f(123456))

Arnauld

Posted 2017-01-06T14:47:54.043

Reputation: 111 334

5

Java 8, 37 58 67 bytes

i->{String s=i.toString(i,3);return s.matches("2*")?s.length():-1;}

This lambda fits in a Function<Integer, Integer> reference and uses the simple base 3 trick.

This time it should work correctly.

user18932

Posted 2017-01-06T14:47:54.043

Reputation:

3Wouldn't that only print True or False when it can be written in the format? But I asked for the exponent when the result is True – P. Ktinos – 2017-01-06T21:22:15.193

2That's genius! +1 for a very clever approach – James – 2017-01-06T22:26:16.377

This is clever... i believe you can remove the parens and just make it i->. Also, if you take i as a Long, you can then use a.toString(...) (ides will give some warnings about using static functions incorrectly, but should compile). However, as OP said, you need to return the value, not just True or False. – FlipTack – 2017-01-06T23:25:01.887

If the lambda is stored in a different function type then the static trick works. I also fixed the return value. I must have missed that part. – None – 2017-01-07T02:51:01.987

4

Brachylog, 8 bytes

,3:.^-?,

Try it online!

Outputs the value if true and false. if this is impossible.

Explanation

This is a direct transcription of the given relation:

,     ,      (Disable implicit unification)
 3:.^        3^Output…
     -?              … - 1 = Input

Fatalize

Posted 2017-01-06T14:47:54.043

Reputation: 32 976

You can almost golf this down to 7 bytes as +~^r~:3, but unfortunately ~: doesn't do what you might expect (likely because : is syntax rather than a builtin), and seems to be treated identically to :. – None – 2017-01-06T18:17:30.093

@ais523 That's correct, : is a control symbol, and ~ only works on predicates. – Fatalize – 2017-01-06T18:35:16.193

3

Perl 6,  25  24 bytes

{first $_==3** *-1,0..$_}

Try it

{first $_==3***-1,0..$_}

Removing the space after ** works because it is longer than the other infix operator that could match *.
So …***… is parsed as … ** * … rather than … * ** ….

Try it

Expanded:

{  # bare block lambda with implicit parameter 「$_」

  first
    $_ == 3 ** * - 1,   # WhateverCode lambda
    #          ^- current value

    0 .. $_             # a Range up-to (and including) the input

}

Brad Gilbert b2gills

Posted 2017-01-06T14:47:54.043

Reputation: 12 713

3

R, 24 bytes

A different approach from plannapus' answer, and one byte shorter!

match(scan(),3^(1:99)-1)

Generates all integers from 3^1-1 to 3^99-1, and checks if stdin matches. If so, it returns the index at which it matches, which is x. If not, returns NA as falsy value.

Incidentally, it will accept multiple values as input, and test all of them, which is a neat feature.

rturnbull

Posted 2017-01-06T14:47:54.043

Reputation: 3 689

3

Prolog, 20 bytes

d(A,X):-A#=(3**X)-1.

This language is cool as hell.

| ?- d(1024,X).

no
| ?- d(26,X).

X = 3

yes
| ?- d(2,X).

X = 1

yes

Name McChange

Posted 2017-01-06T14:47:54.043

Reputation: 131

2

05AB1E, 9 bytes

DÝ3sm<Q1k

Try it online!

Prints -1 for falsy.

D         # Duplicate the input
 Ý3sm     # Push [0 .. input]^3 (e.g. [0^3, 1^3, 2^3, 4^3 ...])
     <    # subtract 1
      Q   # push a 1 everywhere that equals the input, and 0 everywhere else
       1k # push the index of the 1, or -1 if not found
          # implicit output

Riley

Posted 2017-01-06T14:47:54.043

Reputation: 11 345

2

Japt, 11 bytes

o æ@U+1¥3pX

Try it here.

Big thanks to ETHproductions for helping!

Oliver

Posted 2017-01-06T14:47:54.043

Reputation: 7 160

2

Python 3, 74 66 64 bytes

-10 bytes thanks to @mbomb007, @FlipTack and @nmjcman101

from math import*
def f(n):x=ceil(log(n,3));print((3**x-1==n)*x)

dfernan

Posted 2017-01-06T14:47:54.043

Reputation: 528

You can put all of your code on one line and use from math import*. Also return n==3**x-1and x. – mbomb007 – 2017-01-06T15:56:02.243

65 byte solution – mbomb007 – 2017-01-06T16:16:00.153

@mbomb007 Functions are allowed to print the result to STDOUT, so you can change that return to a print. – FlipTack – 2017-01-06T16:43:46.010

If you present this as a SageMath solution rather than a Python one, you can drop the first line altogether.

– Federico Poloni – 2017-01-06T17:00:03.883

Along with the other reduction to 65 bytes, you can use import math and math.ceil for a single byte. Also you can turn 3**x-1==n and x to x*(3**x-1==n) – nmjcman101 – 2017-01-06T22:00:14.710

@nmjcman101 math.log is also in play, so from math import * compensates. – dfernan – 2017-01-06T23:55:44.937

@FedericoPoloni please post your golf suggestion as comment, you can also add a link to an online compiler with the golfed code, but edits on others' answers are not a good pratice

– Rod – 2017-01-10T11:09:05.433

@Rod, the suggested Sagemath solution, though related with Python, relates to another software entirely, making the edit suitable for a new answer altogether in this case. – dfernan – 2017-01-10T12:37:23.243

@dfernan yep, I was just showing him why his (suggested) edit on your answer was rejected – Rod – 2017-01-10T12:39:31.227

@Rod I have already posted it as a comment, but it was ignored. I suggested it as an edit to make it more explicit. I will post it as a new answer now, as per dfernan's suggestion. – Federico Poloni – 2017-01-10T13:31:28.273

2

MATL, 8 bytes

3i:^qG=f

This outputs the number x if it exists, or otherwise outputs nothing, which is falsy.

Try it online!

Explanation

3    % Push 3
i    % Input n
:    % Range: gives `[1 2 ... n]
^    % Power, element-wise. Gives [3^1 3^2 ... 3^n]
q    % Subtract 1, element-wise. Gives [3^1-1 3^2-1 ... 3^n-1]
=    % Test for equality. Contains 'true' at the position x, if any,
     % where 3^x-1 equals n
f    % Find. Gives index of the 'true' position, which ix x; or gives
     % an empty array if no such position exists. Implicitly display

Luis Mendo

Posted 2017-01-06T14:47:54.043

Reputation: 87 464

2

Bash / Unix utilities, 37 35 bytes

bc<<<`dc<<<3o$1p|grep ^2*$|wc -c`-1

Try it online!

Uses dc to convert to base 3, checks that the resulting string is all 2s, counts the number of characters (including a newline), and then uses bc to subtract 1.

If the number in base 3 is not all 2s, then grep outputs nothing (not even a newline), so the character count is 0, and subtracting 1 yields -1.

Mitchell Spector

Posted 2017-01-06T14:47:54.043

Reputation: 3 392

2

C compiled with Clang 3.8.1, 53, 52, 54, 51 Bytes

n;f(y){y++;for(n=0;y%3==0;y/=3)n++;return y^1?0:n;}

@SteadyBox already posted a solution in C, but I'm using a different approach.

@Thanks to Jasen for helping save bytes.

Wade Tyler

Posted 2017-01-06T14:47:54.043

Reputation: 261

1yeah, but does it work? comparing floats for equality is often a recipe for unexpected failure (try large inputs) – Jasen – 2017-01-07T06:49:46.897

@Jasen Hmm, haven't tried that, but in C log returns double so maybe it might work. – Wade Tyler – 2017-01-07T06:54:24.183

double is a type of floating point value so he problem persists. – Jasen – 2017-01-07T07:29:22.587

seems to work ok for 3^19 which is probably large enough. – Jasen – 2017-01-07T07:35:45.457

@Jasen It doesn't work for 3^10 – Wade Tyler – 2017-01-07T07:37:01.880

use a 16 bit compiler then :) – Jasen – 2017-01-07T07:38:47.210

@Jasen Check my edit, interestingly enough, if I put the result from log into a float it works even for larger numbers. – Wade Tyler – 2017-01-07T07:45:24.340

with float fails on 4782967 (3^14) here with double on 243 (3^5-1) – Jasen – 2017-01-07T09:10:15.537

@Jasen Check my edit, this time I tried with simple divisions, works for all powers up to 19. – Wade Tyler – 2017-01-07T20:25:30.773

yeah, that works. It now seems quite similar, but superior, to my answer, y==1 and y+=1 can both be golfed further. Also, 0 is allowed instead of -1. that would get you to 51 – Jasen – 2017-01-08T01:56:19.723

@Jasen Thanks for helping me save bytes. – Wade Tyler – 2017-01-08T19:08:54.753

y%3==0 => y%3<1 – l4m2 – 2017-12-25T11:10:47.340

return y^1?0:n; => return--y?0:n; if want to keep the word return; or yo can use some operation to give EAX the value, and directly go out – l4m2 – 2017-12-25T11:12:10.593

2

Ruby, 30 bytes

Returns nil (a falsy value) if no number was found. [Try it online]

->n{(0..n).find{|i|3**i-1==n}}

Value Ink

Posted 2017-01-06T14:47:54.043

Reputation: 10 608

2

C, 56 bytes

 n;f(a){n=0;for(a++;!(a%3)&&(a/=3);++n);return --a?-1:n;}

add one to the input and then repeatedly divide by three until a remainder is found, if the one is reached return the count of divides else -1

Jasen

Posted 2017-01-06T14:47:54.043

Reputation: 413

Save one byte with a%3<1 instead of !(a%3). One more with 0 for falsy. – Titus – 2017-01-07T11:36:55.520

Assuming you're using GCC to compile you can save a total of 10(11) bytes: you don't need to initialize n to zero if you know you'll call this function only once since then n will be zero by default (because it's global) - that's 4 bytes less; also you don't need the return statement, by writing a=--a?-1:n; you'll save 5 bytes. if a non-void function has no return, it'll just use the last assignment. Also what @Titus said. – Etaoin Shrdlu – 2017-01-09T20:26:26.897

1Suggest a%3?0:(a/=3) instead of !(a%3)&&(a/=3) – ceilingcat – 2018-12-11T18:34:09.803

2

Pyt, 10 9 bytes

←⁺3ĽĐĐƖ=*

Explanation:

←                Get input
 ⁺               Add one
  3Ľ             Log base 3
    ĐĐ           Triplicate top of stack
      Ɩ          Convert top of stack to integer
       =         Check for equality between top two on stack
        *        Multiply by log_3(input+1)


Saved a byte by using the increment function instead of explicitly adding 1

mudkip201

Posted 2017-01-06T14:47:54.043

Reputation: 833

in what code page is that 9 bytes? (in UTF-8 it's 17 bytes) – Jasen – 2018-12-11T22:08:35.107

2

C, 42 Bytes, optimized from Wade Tyler's

n;f(y){for(n=0;y%3>1;y/=3)n++;return!y*n;}

Try

C, 37 Bytes, without return

n;f(y){for(n=0;y%3>1;y/=3)n++;n*=!y;}

Try

n is global but (I)MUL can only have its dest operand in a register, so have to put into EAX(the usual choice) and mov there

JavaScript 6, 32 Bytes

f=(y,n)=>y%3>1?f(y/3|0,-~n):!y*n
;[1,2,3,8,12,43046720].forEach(x=>console.log(f(x)))

If the "falsy" need to be same, 33 Bytes:

f=(y,n)=>y%3>1?f(y/3|0,-~n):!y&&n

l4m2

Posted 2017-01-06T14:47:54.043

Reputation: 5 985

1

Python, 64 bytes

Outputs False if the number cannot be written in that format.

def f(n):L=[3**x-1for x in range(n)];print n in L and L.index(n)

This also works in 64 bytes, and prints empty string as a falsy output:

def f(n):
 try:print[3**x-1for x in range(n)].index(n)
 except:0

A creative solution for 65 bytes, outputting 0 for falsy:

lambda n:-~",".join(`3**x-1`for x in range(n+1)).find(',%s,'%n)/2

mbomb007

Posted 2017-01-06T14:47:54.043

Reputation: 21 944

Does not output x nor -1. – dfernan – 2017-01-06T15:17:12.910

The program should output x instead of n in case of a match. – dfernan – 2017-01-06T15:20:59.040

No, it should output the positive integer that when replaced with X, you get the input. The question refers to X as a variable, not as a string – P. Ktinos – 2017-01-06T15:22:31.793

@P.Ktinos Fixed it. – mbomb007 – 2017-01-06T15:31:31.257

1

R, 34 25 bytes

a=log(scan()+1,3);a*!a%%1

Calculate the base 3 logarithm of the input + 1. Test if the result is an integer, if it is it outputs it, if not it outputs 0 as falsey value. Thanks to @Billywob for the extra 9 bytes off!

Test cases:

> a=log(scan()+1,3);a*!a%%1
1: 1024
2: 
Read 1 item
[1] 0

> a=log(scan()+1,3);a*!a%%1
1: 26
2: 
Read 1 item
[1] 3

Old version at 34 bytes which outputs -1 as falsey value.

a=log(scan()+1,3);`if`(!a%%1,a,-1)

plannapus

Posted 2017-01-06T14:47:54.043

Reputation: 8 610

If you do a*!a%%1 it will output a if true and 0 otherwise and you can skip the if thing. – Billywob – 2017-01-06T16:07:41.597

The spec says "If it can't, output -1 or a falsy statement." and 0 is interpreted as FALSE in R so I would say it's valid. – Billywob – 2017-01-06T16:19:28.497

1

Pyth, 10 bytes

*J@hQ3!%J1

Try it here!

Blue

Posted 2017-01-06T14:47:54.043

Reputation: 26 661

1

Pyke, 9 6 bytes

3m^Qh@

Try it here!

3m^    -  map(3**i, range(input))
     @ - V in ^
   Qh  -  input + 1

Old 9 byte version:

b3'l}\2q*

Try it here!

Blue

Posted 2017-01-06T14:47:54.043

Reputation: 26 661

1

Julia, 30 bytes

n->findfirst(n.==3.^(0:n)-1)-1

It's a simple function - it creates a vector that has a true only in the corresponding position in 3^a-1, where a is a vector containing integers between 0 and n. It finds the "first" position that is true and subtracts 1 (if it's all false, the find evaluates to zero, and it returns -1).

As 0:n has 0 in the first spot, the subtract 1 corrects for indexing and also enables the -1 false response.

Glen O

Posted 2017-01-06T14:47:54.043

Reputation: 2 548

1

Pyth 8 bytes

xm^3dUQh

     UQ  # generate all values 1..Q (Q is the input)
 m^3d    # map 3^d over this ^ list
x      h # find the input+1 (hQ) in the result of the last command

Try here

Rod

Posted 2017-01-06T14:47:54.043

Reputation: 17 588

1

C, 81 bytes

i,j,k;f(n){for(i=0;++i<n;){for(k=3,j=0;++j<i;k*=3);if(n==k-1)return i;}return-1;}

Steadybox

Posted 2017-01-06T14:47:54.043

Reputation: 15 798

I think you save bytes by using pow(3,i) instead of defining your own. Gcc complains about the missing #include <math.h> but compiles it anyway. I did have to cast to int. You also may be able to gain some by adding an r variable, initializing to -1, and then if(n==k-1)r=i;}return r;} – nmjcman101 – 2017-01-06T18:54:22.343

2@nmjcman101 Thanks, but pow() produces some incorrect results because of floating point inaccuracy. (When cast to int, 2.9999 will be 2, not 3). Adding a variable r sounds like a good idea, but it actually results in a 2 bytes longer code. – Steadybox – 2017-01-06T22:33:47.327

yeah, log doesn't work, pow probably won't either. – Jasen – 2017-01-07T09:28:41.417

1

Japt, 8 bytes

o m!³a°U

Try it online!

This code expands into the following:

Uo m!p3 a++U

Uo            // Create the range [0...U).
   m!p3       // Map each item X to 3**X.
        a++U  // Take the index of U+1. Returns -1 if it doesn't exist.
              // Implicit: output result of last expression

ETHproductions

Posted 2017-01-06T14:47:54.043

Reputation: 47 880

Very nice solution. – Oliver – 2017-01-07T06:04:30.903

1

Octave, 23 bytes

@(x)find(3.^(1:x)-1==x)

Verify all test cases!

Explanation:

This is an anonymous function that takes a positive integer x as input. .^ is element-wise power in Octave, so 3.^(1:x) is 3^1, 3^2, 3^3 .... Subtracting 1 gives 3^1-1, 3^2-1, 3^3-1 ... which can be compared to x.

find(a,b) takes a vector a as input, and attempts to find the scalar b in that vector and returns its index. If it's not found then it will output an empty matrix []. An empty matrix is a falsey value in Octave.

find(3.^(1:x)-1==x) searches for x in the vector 3^1-1, 3^2-1, 3^3-1 ... and attempts to return its index. If it's not in the vector then it returns an empty (falsey) matrix.

Stewie Griffin

Posted 2017-01-06T14:47:54.043

Reputation: 43 471

1

GolfScript, 11 bytes

~..3\?\)%!*

Try it online!

Uses the fact that 3n is divisible by n+1 if and only if n+1 itself is a power of 3. Outputs its input n if n+1 is a power of 3, otherwise outputs 0 (which is falsy in GolfScript).

De-golfed:

~             # eval the input, converting it from string to integer
 ..           # make two copies of the input number
   3\?        # raise 3 to the power of the input number
      \)%     # reduce the result modulo the input number plus one
         !    # boolean negate the result, mapping 0 to 1 and all other values to 0
          *   # multiply the input number with the result

Ps. Here's a simple test harness that runs the code above (minus the initial ~, which is not needed since the inputs are already numbers) on all integers from 0 to 9999 and prints those for which it returns a truthy result:

10000,{ ..3\?\)%!* },`

The output of this program should be:

[2 8 26 80 242 728 2186 6560]

(The output doesn't include 0 because, even though the formula used does correctly detect it as one less than a power of 3, the result is still 0 × 1 = 0, and thus falsy. Fortunately, 0 is not a positive integer, and thus isn't a valid input for this challenge anyway.)

Ilmari Karonen

Posted 2017-01-06T14:47:54.043

Reputation: 19 513

1

c++ 60 bytes

int f(n){float o=log1p(n)/log(3);return o/floor(o)!=1?-1:o;}

explanation:

int f(n){             
  float o=log1p(n)/log(3);       // eval for x using log3 function 
  return o/floor(o)!=1?-1:o;     // if no remainder output X 
}

mreff555

Posted 2017-01-06T14:47:54.043

Reputation: 111

I think you don't have to use uint16_t. You can use normal int. – Roman Gräf – 2017-01-08T19:55:50.763

I guess I could to save a few bytes but it seemed to me that if I wasn't safeguarding against negative integer input then I wasn't following the guidelines. – mreff555 – 2017-01-14T21:04:00.380

this compile to me: int f(n){float o=log1p(n)/log(3);return o/floor(o)!=1?-1:o;} – RosLuP – 2017-04-29T15:53:13.867

1@mreff555 You don't need to safeguard against negative input, you can assume positive input. – Erik the Outgolfer – 2017-04-29T16:05:23.917

1

C, 76 bytes

main(i,a,c){scanf("%d",&a);for(c=0,++a;i<a;i*=3,++c);printf("%d",(i==a)*c);}

Etaoin Shrdlu

Posted 2017-01-06T14:47:54.043

Reputation: 145

1

Sagemath, 45 bytes

This is simply @dfernan's solution repackaged as Sagemath (which is basically Python + some math libraries loaded by default and syntactic sugar).

In Sagemath, we can avoid the import math and we can use ^ for exponentiation, so we save a few chars.

def f(n):x=ceil(log(n,3));print((3^x-1==n)*x)

Test it online

Federico Poloni

Posted 2017-01-06T14:47:54.043

Reputation: 151

1

Python 2, 34 bytes

lambda n:(~n>>3**n%-~n*n)**4/80%80

Try it online!

Works for all Python ints, up to at least 2^100.

xnor

Posted 2017-01-06T14:47:54.043

Reputation: 115 687

1

Pip, 13 bytes

aTB:3MNa=2&#a

Try it online!

Explanation

               a is 1st command-line argument (implicit)
aTB:3          Convert a to base 3 and assign back to a
     MNa=2     Does the min of a's digits equal 2?
          &    Logical-and
           #a  Length of a
               If there are non-2 digits, we get the falsey value 0; otherwise, we get
               the number of digits

DLosc

Posted 2017-01-06T14:47:54.043

Reputation: 21 213

"26 can be written as (3^3) - 1" 124 can be written as (5^3)-1 but your code for 124 not print 5 print 0 – RosLuP – 2018-02-02T15:48:12.220

Ok I confuse exponent and base – RosLuP – 2018-02-02T15:51:06.453

1

05AB1E, 6 bytes

>3.n.ï

Try it online!

> increments, 3 pushes a 3 to the stack, .n find the logarithm with base 3, checks if it is equal to its integer part.

Returns 0 for falsy: If it can't, output -1 or a falsy statement.

Mr. Xcoder

Posted 2017-01-06T14:47:54.043

Reputation: 39 774

"26 can be written as (3^3) - 1" 124 can be written as (5^3)-1 but your code for 124 not print 5 print 0 – RosLuP – 2018-02-02T15:47:12.987

@RosLuP I believe the output of my program is correct, and other answers seem to agree

– Mr. Xcoder – 2018-02-02T15:49:24.937

Ok I confuse the exponent and the base – RosLuP – 2018-02-02T15:50:40.177

1

APL (Dyalog Unicode), 12 bytesSBCS

Anonymous tacit prefix function.

(⊢×⌊=⊢)3⍟1+⊢

Try it online!

1+⊢ increment

3⍟ log3

() apply the following function:

⌊=⊢ is the floor equal to the argument? (0 or 1)

⊢× multiply the argument by that

Adám

Posted 2017-01-06T14:47:54.043

Reputation: 37 779

"26 can be written as (3^3) - 1" 124 can be written as (5^3)-1 but your code for 124 not print 5 print 0 – RosLuP – 2018-02-02T15:44:58.253

Ok I confuse exponent and base – RosLuP – 2018-02-02T15:51:49.497

1

APL NARS, 14 chars or 28 bytes

{r×r=⌊r←3⍟1+⍵}

Test:

  f←{r×r=⌊r←3⍟1+⍵}
  f 2     
1
  f 26
3
  f 1024
0

RosLuP

Posted 2017-01-06T14:47:54.043

Reputation: 3 036

This is 28 bytes in NARS, but exactly the same solution is only 14 bytes in Dyalog APL. Also, you can save two bytes by conversion to tradfn, r×r=⌊r←3⍟1+⎕, letting the program prompt for input.

– Adám – 2017-12-25T16:15:10.167

@Adám i prefer functions – RosLuP – 2017-12-25T19:47:48.053

1

APL (Dyalog), 11 bytes

⊢|⊢⍳⍨¯1+3*⍳

Try it online!

Uses ⎕IO←0.

How?

- range of 0 to n-1.

3* - raise 3 to the power of each element.

¯1+ - decrement each by 1.

⊢⍳⍨ - search the index of n in that list (if not exists, this would return the maximum index plus 1 - which is n.

⊢| - modulo by n. This would keep the index, if found, and zero-out numbers not contained in the list that would produce n % n = 0.


APL (Dyalog), 14 bytes

(∧/×≢)2=3⊥⍣¯1⊢

Try it online!

Uriel

Posted 2017-01-06T14:47:54.043

Reputation: 11 708

"26 can be written as (3^3) - 1" 124 can be written as (5^3)-1 but your code for 124 not print 5 print 0 – RosLuP – 2018-02-02T15:45:52.380

Ok I confuse exponent and base – RosLuP – 2018-02-02T15:52:19.127

@RosLuP you mind deleting the comments? people use to DV without much thinking when seeing these – Uriel – 2018-02-03T16:17:08.610

1

Husk, 4 bytes

£İ3→

Returns 0 if there's no such x, try it online!

Explanation

This works because £ assumes the list to be sorted and aborts the search once it sees a larger element:

£İ3→  -- implicit input N, for example: 80
   →  -- increment N -> 81
 İ3   -- list [3,9,27,81…
£     -- if it's in the list return index; -> 4
      -- else return 0

ბიმო

Posted 2017-01-06T14:47:54.043

Reputation: 15 345

1

Befunge-93, 26 bytes

&1+>:3%v
1+\^v-1_3/\
.@.$_

Try It Online

Prints 0 as the falsey.

How it Works

&1+... Gets the input and adds one
......
......

...>:3%v    Check if the number is divisible by 3
1+\^..._3/\ If not, divide the number by 3 and increment a counter
...         Repeat until the number is not divisible by 3

.........   If the final number is a one, print the counter
....v-1_... Else pop the counter and print a 0
.@.$_       End the program

Jo King

Posted 2017-01-06T14:47:54.043

Reputation: 38 234

0

JavaScript (ES6), 40 bytes

f=(n,p=0,k=1)=>n<k?n>k-2&&p:f(n,p+1,k*3)

Returns false or the power. A simple port of @Arnauld's ES7 answer would have taken 43 bytes.

Neil

Posted 2017-01-06T14:47:54.043

Reputation: 95 035

I think f=(n,p,k=1)=>n<k?n>k-2&&p:f(n,-~p,k*3) works and saves 2 bytes. – Arnauld – 2017-01-07T00:24:54.933

0

Java 7, 180 bytes

class A{public static void main(String[]q)throws Exception{int a,b=0;while((a=System.in.read()-48)>=0)b=b*10+(a);double k=Math.log(b+1)/Math.log(3);System.out.print(k%1==0?k:-1);}}

Really simple approach. Input, then add one, then log3 the number, and if it's a integer, print it; otherwise, print -1. Could use some work.

Only works up to (3^19)-1.

HyperNeutrino

Posted 2017-01-06T14:47:54.043

Reputation: 26 575

Why is this non-competing? The Non-Competing status is only reserved for languages or language features that were added after the challenge was posted. – user41805 – 2017-01-07T11:10:23.407

As I said, size doesn't matter, so this can compete. – P. Ktinos – 2017-01-07T20:55:34.137

@KritixiLithos Oh okay. I wasn't aware of the exact meaning of Non-Competing. Thanks. Also, I'll update the title. – HyperNeutrino – 2017-01-08T03:19:37.937

1You can use interface A{...} and drop the public from main(). Why do you have (a) instead of a in the while loop. I think you can use float k=... instead of double k=.... Should be -5 bytes if I counted right. – Roman Gräf – 2017-01-08T20:04:45.217

@RomanGräf I appreciate your suggestions; however, none of them are of any use for me, unfortunately. Your first suggestion only works in Java 8, and there is already a far better Java 8 solution out there. I have (a) in the while loop because I am doing a comparison of an assignment statement, and assignment has the lowest priority on the order of operations and thus requires a set of brackets around it. Finally, I have double because Math#log returns a double and casting would obviously be much slower. Regardless, thank you for the suggestions, but I will not be incorporating them. – HyperNeutrino – 2017-01-09T03:20:21.073

0

PHP, 36 47 bytes

If log(input+1,3) differs from its integer value, print 0; else print the logarithm:
<?=(0|$x=log($argv[1]+1,3))-$x?0:$x; (36 bytes) fails for 242.
<?=strstr($x=log($argv[1]+1,3),".")?0:$x; and <?=(0|$x=log($argv[1]+1,3))-$x>1e-7?0:$x; (41 bytes) may fail for larger $x.

This version is safe:

for(;3**++$x<$n=1+$argv[1];);echo$n<3**$x?0:$x;

1.Loop $x up from 1 while 3^$x is smaller than argument+1.
2.Print 0 if the expression is larger than input+1, $x else.

Takes input from command line argument. Run with -nr.

Titus

Posted 2017-01-06T14:47:54.043

Reputation: 13 814

1gives wrong answer for 242 input – Jasen – 2017-01-07T09:22:47.987

@Jasen: The downvote was ridiculous, but it´s fixed now. – Titus – 2017-01-07T11:36:03.297

0

Common Lisp (SBCL), 83 50 bytes

(let*((i(read))(r(log(1+ i)3)))(if(=(mod r 1)0)r))

Old version:

(let((i(read)))(if(find-if(lambda(x)(not(eq x #\2)))(format()"~3R"i))()(log(1+ i)3)))

Feedback encouraged!

Harry

Posted 2017-01-06T14:47:54.043

Reputation: 1 189

0

CJam, 11 bytes

ri3b_2-!\,*

Basically it determines if the number's trinary (base 3) representation contains only 2's, and if it does, outputs the number of 2's. It outputs 0 if the number is not only 2's.

Try it online!

Explanation

ri          e# Get input as an integer
  3b        e# Convert to base 3 (an array of the digits in base 3)
    _       e# Duplicate
     2-     e# Remove all 2's from the array
       !    e# Boolean negation. Yields 1 if the array contained only 2's (and is now 
            e# empty), 0 otherwise
        \   e# Swap top 2 elements of stack
         ,  e# Take the length of the base 3 digits array
          * e# Multiply by the boolean value from before

Business Cat

Posted 2017-01-06T14:47:54.043

Reputation: 8 927

"Trinary" is more commonly referred to as Ternary. – FlipTack – 2017-01-09T18:23:36.303

0

C 90 bytes

f(x){i=1;for(;i<x;i++){if((pow(3,i)-1)==x){printf("%d",i);break;}if(i==(x-1))puts("-1");}}

Ungolfed Version:

void f(int x)
{
  int i=1;
  for(;i<x;i++)
  {
    if((pow(3,i)-1)==x)
    {
        printf("%d",i);
        break;      
    }   
    if(i==(x-1))
        puts("-1");     
  } 
}

Abel Tom

Posted 2017-01-06T14:47:54.043

Reputation: 1 150

for x=1 what would return/print that above? – RosLuP – 2017-04-29T15:43:20.703

0

SmileBASIC, 32 bytes

INPUT X
X=LOG(X+1,3)?X*(X==X>>0)

Outputs 0 for false.

12Me21

Posted 2017-01-06T14:47:54.043

Reputation: 6 110

0

Cardinal, 91 bytes

%
:
+
~
v~d<
0  /{<
+  A #-?+M?"-1"@
+  !   @.-<
+  M #  M!/        <
>~ # ^  } \       +^%

According to the specifications of Cardinal, this shouldn't work for inputs above 255. However, due to the implementation in TIO accepting values over 255, it will work past 255 up to 3^34.

Try it online!

Explanation

%
:
+

Input + 1

~
v~d<
0  /{<
+  A 
+  !  
+  M
>~ # ^

While divisible by 3

#-?+M?"-1"@

Output -1 if not divisible by 3 or equal to 1 and end program

   .-<
#  M!/        <
   } \       +^%

Output counter for how many times the input + 1 has been divided by 3 before equalling 1

fəˈnɛtɪk

Posted 2017-01-06T14:47:54.043

Reputation: 4 166

0

TI-Basic (TI-84 Plus CE) 17 15 bytes

logBASE(Ans+1,3)
Ansnot(Ans-int(Ans

All tokens used are one-byte except logBASE(, which is two.

Explanation:

logBASE(Ans+1,3)   # inverse of 3^n-1 is log3(x+1)
Ansnot(Ans-int(Ans # if X is an integer, `X-int(x` is 0, so `not(X-int(X` is 1, which is multiplied by X
                   # if X is not an integer, `X-int(X` is not 0, so `not(X-int(X` is zero, which is multiplied by X
                   # last value evaluated is implicitly returned

pizzapants184

Posted 2017-01-06T14:47:54.043

Reputation: 3 174

0

QBIC, 18 bytes

:[a|c=3^b-1~c=a|?b

Explanation

:        Get 'a' from the cmd-line
[a|      FOR b=1; b<=a; b++  (this runs a lot longer than we need...)
c=3^b-1  Set c to be 3^b-1
~c=a     IF this is the input given
|?b      THEN print b
         END IF and NEXT are added implicitly

This would print multiple bs if it would be possible to have multiple solutions. Right now, it runs on after finding a solution. We could substitute ?b for _Xb to quit after finding a solution, but that adds a byte. Also, the FOR-loop [a| could be initialised as [a/3| to save us a lot of iterations, but that adds another 2 bytes.

steenbergh

Posted 2017-01-06T14:47:54.043

Reputation: 7 772

0

Axiom,72 65 63 bytes

g(x:PI):INT==(z:=floor(y:=log(x+1.)/log(3.));y-z~=0=>-1;z::INT)

some test

(51) -> [[x,g(x)]  for x in [1,2,3,4,5,6,7,8,9,10,26,27,79,80,242]]
   (51)
   [[1,- 1], [2,1], [3,- 1], [4,- 1], [5,- 1], [6,- 1], [7,- 1], [8,2],
    [9,- 1], [10,- 1], [26,3], [27,- 1], [79,- 1], [80,4], [242,5]] 

RosLuP

Posted 2017-01-06T14:47:54.043

Reputation: 3 036

0

J, 14 bytes

[:(*>.=])3^.>:

Try it online!

Here's a variant using a range of powers and indexing (@Dennis's method).

(~:*])>:i.~3^i.

Here's a variant using base conversion (@orlp's method).

[:(#*&(*/)2=])3&#.inv

cole

Posted 2017-01-06T14:47:54.043

Reputation: 3 526

0

JavaScript 28 bytes (where static X is passed to function)

f=(n,x)=>Math.pow(3,x)-1==n&&x

console.log(
  f(8,2)
, f(26,3)
)

67 bytes (where a Map of the possible values is created once)

m=new Map;for(x=45;x>2;m.set(Math.pow(3,--x)-1,x))
f=n=>m.get(n)||!1

console.log(
  f(8)
, f(26)
, f(1024)
)

guest271314

Posted 2017-01-06T14:47:54.043

Reputation: 1