可以用(3 ^ x)-1格式写这个数字吗?


41

挑战:

创建一个接受正整数的程序,并检查它是否可以(3 ^ x)-1的形式编写,其中X是另一个正整数

如果可以,输出X

如果不能,则输出-1或伪造的语句。

输入/输出示例

输入:

2

可以写成(3 ^ 1)-1,所以我们输出x就是1

输出:

1

输入:

26

26可以写成(3 ^ 3)-1,所以我们输出x(3)

输出:

3

输入:

1024

1024不能以​​(3 ^ x)-1的形式写入,因此我们输出-1

输出:

-1

这是因此最少的字节数获胜


相关OEIS:A024023


4
我要求输出X,因为我认为这样更具挑战性。我认为,简单地确定它是否为3 ^ x-1格式对于挑战来说太容易了。
P. Ktinos

2
除非这是您的编程语言中的虚假陈述,否则不会。
P. Ktinos

2
我可以将数字输入三进制吗?
John Dvorak

2
不得不处理非负整数的操作将使0 3^0-1 成为有效输出,因此不能用作false,
Jasen

2
任何想log()在答案中使用的人都应确认 输入5时给出正确答案242
Jasen

Answers:


23

Mathematica,21个16字节

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

利用Mathematica的符号计算。如果#+1是3的幂,Log[3,#+1]则将计算一个整数结果,该结果是一个原子值。否则我们会照Log[#+1]/Log[3]原样。由于这不是原子值,因此它始终是形式的表达式head[val1,val2,...]。在这种情况下,实际上就像Times[Power[Log[3], -1], Log[#+1]]

我们通过对结果应用另一个函数来区分这两种情况。应用的真正作用是替换head表达式的一部分。由于整数结果是原子的,因此将任何函数应用于它们根本没有任何作用。特别是f @@ atom == atom

但是,在其他情况下,磁头确实会被更换。我们正在使用的函数-1&是一个简单的函数,它将忽略其参数并返回-1。因此,-1&[Power[Log[3], -1], Log[#+1]]在非整数情况下,我们得到的结果直接为-1。通过魔术特殊的外壳。


13

Python,46 44字节

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

在线尝试!

在这种情况下,0将是虚假的值。感谢@ mbomb007指出我的错误输出以及2字节的未[]节省空间。


您可以重写[n for n in range(x)if 3**n-1==x]为-4字节,空白列表为falsy
Rod Rod

固定,谢谢!@Rod然后它将返回[n]而不是n我认为
nmjcman101

@ nmjcman101应该没什么问题
Rod

@Rod我现在更愿意严格遵守规范
nmjcman101

@Rod如果需要输出整数,则除非OP明确允许,否则无法将其输出到列表中。
mbomb007 '01


11

05AB1E,7个字节

3IÝm<¹k

在线尝试!

说明

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

05AB1E显然擅长于基数转换,这真的是最好的方法吗?
Jasen

1
@Jasen:我尝试进行基本转换的时间更长。如果有比这更好的方法,我看不到。不过请随时证明我错了:)
Emigna'1

公平地说,我只阅读了该语言的说明,因此希望看到一个5字节的解决方案
。...– Jasen

1
@Jasen <3zm©.ïi®是我没有像他那样使用范围的最接近的。
魔术八达通Ur

1
3DÝms<k...没关系...不能再剃一个字节,我可以发誓。
魔术章鱼缸

9

果冻,5个字节

R3*’i

输出x0(错误)。

在线尝试!

这个怎么运作

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).

6

Python 2,41个字节

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

0为不匹配的输入返回的递归函数。反复将输入除以3,然后计算的步数i,最后将输出。但是,如果任何步骤产生的值n不是2模0,则该数字不是for的3^i-1,因此输出乘以0。


6

Perl,31个字节

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

需要-E标志才能运行:

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

说明:
grep{3**$_-1==$i}0..($i=<>)返回0..$_满足测试范围的元素列表(即从0到输入)3**$_-1==$i。最多只有一个元素可以满足此测试,因此此指令将返回一个0或1个元素的数组。然后,我们打印此列表:X或不打印(虚假)。


5

Pyth,11个字节

?-JjQ3 2ZlJ

转换为基数3并检查等于[2, 2, ..., 2]


您可以使用来将其减少一个字节?-2JjQ3ZlJ,因为<col> <num><num> <col>可以-在Pyth 中互换。
notjagan

5

JavaScript(ES7),38 36 34字节

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

或仅30个 29字节(如果可以退出并出现错误错误):

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

测试


5

Java 8、37 58 67字节

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

此lambda适合Function<Integer, Integer>参考,并使用简单的base 3技巧。

这次应该可以正常工作了。


3
当可以格式写入时,不是仅打印True还是False?但是,当结果为True时,我要求提供指数
P. Ktinos

2
天才!+1是一种非常聪明的方法
DJMcMayhem

这很聪明...我相信您可以将paren拆下并放入i->。另外,如果您将i用作Long,则可以使用a.toString(...)(IDE将给出一些有关错误使用静态函数的警告,但应进行编译)。但是,正如OP所说,您需要返回值,而不仅仅是True或False。
FlipTack

如果lambda存储在其他函数类型中,则静态技巧起作用。我还固定了返回值。我一定错过了那部分。

5

处理中,60 56字节

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

-1如果错误,则输出。

说明

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比使用短1个字节float,因此这就是为什么此函数直接输出而不是返回值的原因。

替代解决方案

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

63个字节,但我认为可以比原始解决方案更短。我在做这个工作。


@FlipTack是的,我知道它不会用Java。我只是问了一下,因为我不确定Processing是否没有按照这些原则添加任何内容。不过,要使用的“区别值”是-1,而不是0。但是,由于此值已更改,因此我可能会整理一下有关它的注释。
Geobits

等一下,我0现在可以回来吗?
Kritixi Lithos

我还是拒绝。该问题给出了一个可选的整数值(如果为falsy时使用),但0在我所知道的Java / Processing中从不为falsy。
Geobits

我thougt处理应该是 versbose比Java的
帕维尔

@Pavel但是我不使用lambdas:/
Kritixi Lithos

4

Brachylog,8个字节

,3:.^-?,

在线尝试!

如果为true false.则输出该值,如果不可能则输出。

说明

这是给定关系的直接转录:

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

几乎可以将它压缩到7个字节+~^r~:3,但是很遗憾,~:它并没有达到您的期望(可能是因为:语法而不是内置函数),并且似乎与相同:

@ ais523是的,:是控制符号,~仅对谓词有效。
致命

3

Perl 6的 25  24个字节

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

试试吧

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

下班后删除空格,**因为它比其他匹配的infix运算符长*
因此…***…被解析为… ** * …而不是… * ** …

试试吧

展开:

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

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

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

}

3

R,24个字节

Plannapus的答案不同,而且要短一个字节!

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

从生成所有整数3^1-13^99-1,如果标准输入匹配检查。如果是这样,它将返回匹配的索引,即x。如果不是,则返回NA假值。

顺便说一句,它将接受多个值作为输入,并测试所有这些值,这是一个很好的功能。


3

Prolog,20个字节

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

这种语言很酷。

| ?- d(1024,X).

no
| ?- d(26,X).

X = 3

yes
| ?- d(2,X).

X = 1

yes

2

05AB1E,9个字节

DÝ3sm<Q1k

在线尝试!

打印-1表示错误。

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

2

MATL,8字节

3i:^qG=f

x如果存在该数字,则输出该数字,否则不输出任何数字,这是虚假的。

在线尝试!

说明

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


2

Python 3,74 66 64字节

-10个字节,感谢@ mbomb007,@ FlipTack和@ nmjcman101

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

您可以将所有代码放在一行上并使用from math import*。也return n==3**x-1and x
mbomb007'1


@ mbomb007允许函数将结果打印到STDOUT,因此您可以将返回值更改为打印。
FlipTack

如果将其作为SageMath解决方案而不是Python解决方案呈现,则可以完全删除第一行。
Federico Poloni'1

除了其他减少到65个字节外,您还可以将import mathmath.ceil用于单个字节。你也可以打开3**x-1==n and xx*(3**x-1==n)
nmjcman101


2

C,56个字节

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

将一个加到输入中,然后重复除以三,直到找到余数,如果达到一个则返回除数的计数,否则为-1


使用a%3<1而不是保存一个字节!(a%3)。一个多用0的falsy。
泰特斯

假设您正在使用GCC进行编译,则总共可以保存10(11)个字节:如果您知道只调用一次此函数,则无需将n初始化为零,因为默认情况下,n将为零(因为它是全球性的)-少了4个字节;同样,您不需要return语句,通过编写,a=--a?-1:n;您将节省5个字节。如果非void函数没有返回值,它将仅使用最后一个赋值。还有@Titus说的。
Etaoin Shrdlu

1
建议a%3?0:(a/=3)不要使用!(a%3)&&(a/=3)
ceilingcat '18

2

Bash / Unix实用程序,37 35字节

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

在线尝试!

使用dc转换为基数3,检查结果字符串是否全为2,计算字符数(包括换行符),然后使用bc减去1。

如果以3为底的数字不是全为2,则grep不输出任何内容(甚至不包含换行符),因此字符计数为0,减去1得出-1。


2

Ç编译铛3.8.1,535254,51个字节

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

@SteadyBox已经在C语言中发布了一个解决方案,但是我使用了另一种方法。

@感谢Jasen帮助保存字节。


1
是的,但是行得通吗?比较浮点数是否相等通常是导致意外失败的原因(尝试大量输入)
Jasen

@Jasen Hmm,还没有尝试过,但是在C语言中log返回,double所以也许可行。
韦德·泰勒

double是浮点值的一种,因此问题仍然存在。
Jasen

似乎对于3 ^ 19来说还可以,这可能足够大。
杰森

@Jasen它不适合3 ^ 10个工作
韦德泰勒

2

C,42字节,从Wade Tyler's优化

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

尝试

C,37字节,无 return

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

尝试

n是全局的,但(I)MUL只能将其dest操作数存储在寄存器中,因此必须放入EAX(通常的选择)并移至该位置

JavaScript 6,32字节

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)))

如果“ falsy”必须相同,则为33个字节:

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

2

Pyt10 9字节

←⁺3ĽĐĐƖ=*

说明:

←                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)


通过使用增量功能而不是显式加1保存一个字节


这9个字节在哪个代码页中?(在UTF-8中为17个字节)
Jasen

1

Python,64位元组

False如果无法以该格式写入数字,则输出。

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

这也可以以64字节工作,并输出空字符串作为伪造的输出:

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

65字节的创造性解决方案,输出0为falsy:

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

不输出x也不-1
dfernan'1

程序应该输出x而不是n匹配。
dfernan'1

不,它应该输出正整数,当用X替换时,您将得到输入。问题称X为变量,而不是字符串
P. Ktinos

@ P.Ktinos修复了它。
mbomb007'1


1

朱莉娅,30个字节

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

这是一个简单的函数-它创建一个向量,该向量true仅在的相应位置具有3^a-1,其中a一个向量包含0到之间的整数n。它找到的是“第一个”位置,true然后减去1(如果为all false,则查找结果为零,并返回-1)。

作为0:n具有0在第一点中,减1个校正用于索引和也使-1假响应。



1

Pyth 8个字节

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

试试这里

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.