往上走!


26

给定整数N,请执行以下步骤:(以9为例)。

  1. 接收输入N。(9
  2. 将N从base10转换为base2。(1001
  3. 每增加1。(2112
  4. 将结果视为base3并将其转换回base10。(68
  5. 返回/输出结果。

输入项

可以以任何合理的数字格式接收。
您只需要处理N> 0的情况。


输出量

以数字或字符串形式返回,或打印到stdout


规则

  • 这是,以字节为单位的最短代码获胜。
  • 禁止默认漏洞。

测试用例

1 -> 2
2 -> 7
5 -> 23
9 -> 68
10 -> 70
20 -> 211
1235 -> 150623
93825 -> 114252161

Answers:


15

Python 2,31个字节

f=lambda n:n and 3*f(n/2)+n%2+1

在线尝试!


3
您能解释一下这是如何工作的吗?

+n%2+1将最右边的二进制位加1到返回值,n/2右移n1个二进制位,3*f(n/2)对这些右移的位递归加3次此计算,并n andn0 时结束递归
Noodle9 '18

11

JavaScript(Node.js),23字节

f=x=>x&&x%2+1+3*f(x>>1)

在线尝试!


x>>1x/2不是一样?
mbomb007 '18

@ mbomb007我还以为并提出了相同的建议,但显然它出现Infinity在JS中。请在线尝试。(您可能想为您的答案添加一个TIO链接,I4m2
Kevin Cruijssen

2
@ mbomb007号1>>1=0while1/2=0.5
l4m2 '18

4
@ mbomb007 ... Python?
user202729 '18

2
是的 查看Python答案。这就是n/2在那个版本中起作用的原因,也是我在这里建议的原因。
mbomb007'4




6

R55 43字节

function(n)(n%/%2^(x=0:log2(n))%%2+1)%*%3^x

在线尝试!

使用R中的标准基本转换技巧(递增),然后使用幂为的点积3转换回整数。

感谢@ user2390246删除了12个字节!


由于转换为二进制不是最终输出,因此数字的顺序无关紧要。因此,代替floor(log(n)):0可以执行0:log(n)并保存一些字节:43个字节
user2390246 '18

@ user2390246当然,谢谢。
朱塞佩


6

Java 10,81 52个字节(基本转换)

n->n.toString(n,2).chars().reduce(0,(r,c)->r*3+c-47)

在线尝试。

-29个字节,感谢@Holger

说明:

n->{                         // Method with Long as both parameter and return-type
  n.toString(n,2)            //  Convert the input to a Base-2 String
  .chars().reduce(0,(r,c)->  //  Loop over its digits as bytes
    r*3+c-47)                //  Multiply the current result by 3, and add the digit + 1
                             //  (which is equal to increasing each digit by 1,
                             //  and then converting from Base-3 to Base-10)

爪哇10,171个 167 151 150 149字节(序列)

n->{int t=31-n.numberOfLeadingZeros(n);return a(t+1)+b(n-(1<<t));};int a(int n){return--n<1?n+2:3*a(n)+1;}int b(int n){return n<1?0:n+3*b(n/=2)+n*2;}

-16个字节(感谢@ musicman523更改(int)Math.pow(2,t)为)(1<<t)
-1个字节感谢@Holger,更改(int)(Math.log(n)/Math.log(2))31-n.numberOfLeadingZeros(n)

在线尝试。

说明:

n->{                         // Method with Integer as both parameter and return-type
  int t=31-n.numberOfLeadingZeros(n);
                             //  2_log(n)
  return a(t+1)              //  Return A060816(2_log(n)+1)
         +b(n-(1<<t));}      //   + A005836(n-2^2_log(n))

// A060816: a(n) = 3*a(n-1) + 1; a(0)=1, a(1)=2
int a(int n){return--n<1?n+2:3*a(n)+1;}

// A005836: a(n+1) = 3*a(floor(n/2)) + n - 2*floor(n/2).
int b(int n){return n<1?0:n+3*b(n/=2)+n*2;}

当我们查看序列时:

2,  7,8,  22,23,25,26,  67,68,70,71,76,77,79,80,  202,203,205,206,211,212,214,215,229,230,232,233,238,239,241,242, ...

我们可以看到多个子序列:

A053645(n):
0,  0,1,  0,1,2,3,  0,1,2,3,4,5,6,7,  0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,  ...

A060816(A053645(n)):
2,  7,7,  22,22,22,22,  67,67,67,67,67,67,67,67,  202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,  ...

A005836(A053645(n)+1)
0,  0,1,  0,1,3,4,  0,1,3,4,9,10,12,13,  0,1,3,4,9,10,12,13,27,28,30,31,36,37,39,40,  ...

因此,要求的顺序是:

A060816(A053645(n)) + A005836(A053645(n)+1)

我很着迷于发现模式,因此我为上面的发现感到骄傲。.话虽如此,@ user202729在几分钟内在Java中找到了一种更好,更短的方法 ..:'(


重新n.toString(n,2).getBytes()...我认为手动转换可能会更短。
user202729'4

1
顺便说一句,为什么longint
user202729'4

1
我认为在序列版本中,您可以更改(int)Math.pow(2,t)1<<t...,然后内联该表达式并删除变量i(152字节
musicman523 '18

1
在现实生活中,我会使用31-Integer.numberOfLeadingZeros(n)代替(int)(Math.log(n)/Math.log(2)),但是它并不短。除非您import static在标题中使用,否则可能会使规则延伸得太远。
Holger '18

1
我只是尝试将您的第一个变量的循环转换为流解决方案,但获得了成功:n -> n.toString(n,2).chars().reduce(0,(r,c)->r*3+c-47)
Holger





3

附件,19字节

FromBase&3@1&`+@Bin

在线尝试!

这是三个功能的组合:

  • FromBase&3
  • 1&`+
  • Bin

这首先转换为二进制(Bin),将其递增(1&`+),然后转换为三进制(FromBase&3)。

备择方案

非pointfree,21字节: {FromBase[Bin!_+1,3]}

如果没有内置函数,则为57个字节: Sum@{_*3^(#_-Iota!_-1)}@{If[_>0,$[_/2|Floor]'(1+_%2),[]]}


3

视网膜0.8.2,36字节

.+
$*
+`^(1+)\1
$1;1
^
1
+`1;
;111
1

在线尝试!说明:

.+
$*

从十进制转换为一元。

+`^(1+)\1
$1;1

重复将divmod除以2,然后将1加到模的结果上。

^
1

也将1添加到第一位。

+`1;
;111

从一元编码的基数3转换为一元。

1

转换为十进制。


3

Japt,6个字节

¤cÄ n3
¤      // Convert the input to a base-2 string,
 c     // then map over it as charcodes.
  Ä    // For each item, add one to its charcode
       // and when that's done,
    n3 // parse the string as a base 3 number.

将输入作为数字,输出数字。

在线尝试!


该死的!我为什么没想到呢?做得很好。
毛茸茸的

3

MATL12 7 6字节

BQ3_ZA

在线尝试!

感谢Giuseppe,节省了5个字节,感谢Luis Mendo,节省了5个字节。

旧的7个字节的答案:

YBQc3ZA

在线尝试!

说明:

YB        % Convert to binary string
  Q       % Increment each element
   c      % Convert ASCII values to characters
    3     % Push 3
     ZA   % Convert from base 3 to decimal.

旧的12个字节:

BQtz:q3w^!Y*

在线尝试!

哦,我的,那太乱了……这是:`BQ3GBn:q ^!Y *。

说明:

               % Implicit input
B              % Convert to binary vector
 Q             % Increment all numbers
  t            % Duplicate
   z           % Number of element in vector
    :          % Range from 1 to that number
     q         % Decrement to get the range from 0 instead of 1
      3        % Push 3
       w       % Swap order of stack
        ^      % Raise 3 to the power of 0, 1, ...
         !     % Transpose
          Y*   % Matrix multiplication
               % Implicit output

3

C#(Visual C#编译器),128字节

using System;using System.Linq;i=>{int z=0;return Convert.ToString(i,2).Reverse().Select(a=>(a-47)*(int)Math.Pow(3,z++)).Sum();}

在线尝试!

我在数数System是因为我使用ConvertMath


选择将给您索引作为可选参数。这样您就可以摆脱z变量。另外,在表达体,你可以摆脱的{}return语句。像这样n=>Convert.ToString(n,2).Reverse().Select((x,i)=>(x-47)*Math.Pow(3,i)).Sum();
-NtFreX


2

C,32 27字节

n(x){x=x?x%2+1+3*n(x/2):0;}

基于user202729的Java 答案在这里在线尝试。感谢Kevin Cruijssen打高尔夫球5个字节。

非高尔夫版本:

n(x) { // recursive function; both argument and return type are implicitly int
    x = // implicit return
    x ? x % 2 + 1 + 3*n(x/2) // if x != 0 return x % 2 + 1 + 3*n(x/2) (recursive call)
    : 0; // else return 0
}

您可以通过更换保存5个字节returnx=和扭转三元所以!不再需要:n(x){x=x?x%2+1+3*n(x/2):0;}
凯文Cruijssen

@KevinCruijssen尼斯。谢谢!
OOBalance


2

带通讯工具箱的八度33 32字节

@(x)(de2bi(x)+1)*3.^(0:log2(x))'

在线尝试!

使用将de2bi所有数字递增,将输入转换为二进制向量。矩阵乘法是否将垂直向量3提升到适当的幂:1, 3, 9, ...,从而在不显式调用的情况下获得总和sum


尽管这非常聪明,但您也可以使用32个字节来执行此操作:在线尝试!
桑契斯

使用MATLAB甚至可以@(x)base2dec(de2bi(x)+49,3)运行27天(罕见的情况是MATLAB比Octave宽容)
Sanchises

2

PHP,84 64字节

在线尝试!

原始码

function f($n){$b=decbin($n);echo base_convert($b+str_repeat('1',strlen($b)),3,10);}

在线尝试!

感谢Cristoph,如果使用php -R运行更少的字节

function f($n){echo base_convert(strtr(decbin($n),10,21),3,10);}

说明

function f($n){
$b=decbin($n);                    #Convert the iteger to base 2
echo base_convert(                  #base conversion PHP function
    $b+str_repeat('1',strlen($b)),  #It adds to our base 2 number
    3,                              #a number of the same digits length
    10);                            #with purely '1's
}

这是当我看到我在编程时有一种轻松的方式。...不知道存在strtr
弗朗西斯科·哈恩

1
会做!,对不起<?="Will do!!"
Francisco Hahn,

2

CJam,8个字节

ri2b:)3b

在线尝试!

说明

ri   e# Read input as an integer
2b   e# Convert to base 2. Gives a list containing 0 and 1
:)   e# Add 1 to each number in that list
3b   e# Convert list from base 3 to decimal. Implicitly display

我有点喜欢:)..
Ian H.

2

空格,117个字节

[S S S N
_Push_0][S N
S _Duplicate_0][S N
S _Duplicate_0][T   N
T   T   _Read_STDIN_as_number][T    T   T   _Retrieve][N
S S S N
_Create_Label_OUTER_LOOP][S N
S _Duplicate][S S S T   S N
_Push_2][T  S T T   _Modulo][S S S T    N
_Push_1][T  S S S _Add][S N
T   _Swap][S S S T  S N
_Push_2][T  S T S _Integer_division][S N
S _Duplicate][N
T   S N
_If_0_jump_to_Label_INNER_LOOP][N
S N
S N
_Jump_to_Label_OUTER_LOOP][N
S S N
_Create_Label_INNER_LOOP][S S S T   T   N
_Push_3][T  S S N
_Multiply][T    S S S _Add][S N
T   _Swap][S N
S _Duplicate][N
T   S T N
_If_0_jump_to_Label_PRINT_AND_EXIT][S N
T   _Swap][N
S N
N
_Jump_to_Label_INNER_LOOP][N
S S T   N
_Create_Label_PRINT_AND_EXIT][S N
T   _Swap][T    N
S T _Output_integer_to_STDOUT]

字母S(空格),T(制表符)和N(换行符)仅作为突出显示而添加。
[..._some_action]仅作为说明添加。

在线尝试(仅使用空格,制表符和换行符)。

伪代码中的解释:

我首先将递归函数int f(int n){return n<1?0:n%2+1+3*f(n/2);}转换为其迭代形式(以伪代码):

Integer n = STDIN as integer
Add starting_value 0 to the stack
function OUTER_LOOP:
  while(true){
    Add n%2+1 to the stack
    n = n/2
    if(n == 0):
      Jump to INNER_LOOP
    Else:
      Jump to next iteration OUTER_LOOP

function INNER_LOOP:
  while(true){
    n = 3*n
    n = n + Value at the top of the stack (the ones we calculated with n%2+1)
    Swap top two items
    Check if the top is now 0 (starting value):
      Jump to PRINT_AND_EXIT
    Else:
      Swap top two items back
      Jump to next iteration INNER_LOOP

function PRINT_AND_EXIT:
  Swap top two items back
  Print top to STDOUT as integer
  Exit program with error: Exit not defined

然后,我使用默认堆栈在基于堆栈的语言Whitespace中实现了这种迭代方法。

示例运行:

输入: 1

Command    Explanation                   Stack           Heap    STDIN   STDOUT   STDERR

SSSN       Push 0                        [0]
SNS        Duplicate top (0)             [0,0]
SNS        Duplicate top (0)             [0,0,0]
TNTT       Read STDIN as integer         [0,0]           {0:1}   1
TTT        Retrieve                      [0,1]           {0:1}
NSSSN      Create Label OUTER_LOOP       [0,1]           {0:1}
 SNS       Duplicate top (1)             [0,1,1]         {0:1}
 SSSTSN    Push 2                        [0,1,1,2]       {0:1}
 TSTT      Modulo top two (1%2)          [0,1,1]         {0:1}
 SSSTN     Push 1                        [0,1,1,1]       {0:1}
 TSSS      Add top two (1+1)             [0,1,2]         {0:1}
 SNT       Swap top two                  [0,2,1]         {0:1}
 SSSTSN    Push 2                        [0,2,1,2]       {0:1}
 TSTS      Int-divide top two (1/2)      [0,2,0]         {0:1}
 SNS       Duplicate top (0)             [0,2,0,0]       {0:1}
 NTSN      If 0: Go to Label INNER_LOOP  [0,2,0]         {0:1}
 NSSN      Create Label INNER_LOOP       [0,2,0]         {0:1}
  SSSTTN   Push 3                        [0,2,0,3]       {0:1}
  TSSN     Multiply top two (0*3)        [0,2,0]         {0:1}
  TSSS     Add top two (2+0)             [0,2]           {0:1}
  SNT      Swap top two                  [2,0]           {0:1}
  SNS      Duplicate top (0)             [2,0,0]         {0:1}
  NTSTN    If 0: Jump to Label PRINT     [2,0]           {0:1}
  NSSTN    Create Label PRINT            [2,0]           {0:1}
   SNT     Swap top two                  [0,2]           {0:1}
   TNST    Print top to STDOUT           [0]             {0:1}           2
                                                                                  error

在线尝试(仅使用空格,制表符和换行符)。
因错误而停止:未定义退出。

输入: 4

Command    Explanation                   Stack           Heap    STDIN   STDOUT   STDERR

SSSN       Push 0                        [0]
SNS        Duplicate top (0)             [0,0]
SNS        Duplicate top (0)             [0,0,0]
TNTT       Read STDIN as integer         [0,0]           {0:4}   4
TTT        Retrieve                      [0,4]           {0:4}
NSSSN      Create Label OUTER_LOOP       [0,4]           {0:4}
 SNS       Duplicate top (4)             [0,4,4]         {0:4}
 SSSTSN    Push 2                        [0,4,4,2]       {0:4}
 TSTT      Modulo top two (4%2)          [0,4,0]         {0:4}
 SSSTN     Push 1                        [0,4,0,1]       {0:4}
 TSSS      Add top two (0+1)             [0,4,1]         {0:4}
 SNT       Swap top two                  [0,1,4]         {0:4}
 SSSTSN    Push 2                        [0,1,4,2]       {0:4}
 TSTS      Int-divide top two (4/2)      [0,1,2]         {0:4}
 SNS       Duplicate top (2)             [0,1,2,2]       {0:4}
 NTSN      If 0: Go to Label INNER_LOOP  [0,1,2]         {0:4}
 NSNSN     Jump to Label OUTER_LOOP      [0,1,2]         {0:4}
 SNS       Duplicate top (2)             [0,1,2,2]       {0:4}
 SSSTSN    Push 2                        [0,1,2,2,2]     {0:4}
 TSTT      Modulo top two (2%2)          [0,1,2,0]       {0:4}
 SSSTN     Push 1                        [0,1,2,0,1]     {0:4}
 TSSS      Add top two (0+1)             [0,1,2,1]       {0:4}
 SNT       Swap top two                  [0,1,1,2]       {0:4}
 SSSTSN    Push 2                        [0,1,1,2,2]     {0:4}
 TSTS      Int-divide top two (2/2)      [0,1,1,1]       {0:4}
 SNS       Duplicate top (1)             [0,1,1,1,1]     {0:4}
 NTSN      If 0: Go to Label INNER_LOOP  [0,1,1,1]       {0:4}
 NSNSN     Jump to Label OUTER_LOOP      [0,1,1,1]       {0:4}
 SNS       Duplicate top (1)             [0,1,1,1,1]     {0:4}
 SSSTSN    Push 2                        [0,1,1,1,1,2]   {0:4}
 TSTT      Modulo top two (1%2)          [0,1,1,1,1]     {0:4}
 SSSTN     Push 1                        [0,1,1,1,1,1]   {0:4}
 TSSS      Add top two (1+1)             [0,1,1,1,2]     {0:4}
 SNT       Swap top two                  [0,1,1,2,1]     {0:4}
 SSSTSN    Push 2                        [0,1,1,2,1,2]   {0:4}
 TSTS      Int-divide top two (1/2)      [0,1,1,2,0]     {0:4}
 SNS       Duplicate top (0)             [0,1,1,2,0,0]   {0:4}
 NTSN      If 0: Go to Label INNER_LOOP  [0,1,1,2,0]     {0:4}
 NSSN      Create Label INNER_LOOP       [0,1,1,2,0]     {0:4}
  SSSTTN   Push 3                        [0,1,1,2,0,3]   {0:4}
  TSSN     Multiply top two (0*3)        [0,1,1,2,0]     {0:4}
  TSSS     Add top two (2+0)             [0,1,1,2]       {0:4}
  SNT      Swap top two                  [0,1,2,1]       {0:4}
  SNS      Duplicate top (1)             [0,1,2,1,1]     {0:4}
  NTSTN    If 0: Jump to Label PRINT     [0,1,2,1]       {0:4}
  SNT      Swap top two                  [0,1,1,2]       {0:4}
  NSNN     Jump to Label INNER_LOOP      [0,1,1,2]       {0:4}
  SSSTTN   Push 3                        [0,1,1,2,3]     {0:4}
  TSSN     Multiply top two (2*3)        [0,1,1,6]       {0:4}
  TSSS     Add top two (1+6)             [0,1,7]         {0:4}
  SNT      Swap top two                  [0,7,1]         {0:4}
  SNS      Duplicate top (1)             [0,7,1,1]       {0:4}
  NTSTN    If 0: Jump to Label PRINT     [0,7,1]         {0:4}
  SNT      Swap top two                  [0,1,7]         {0:4}
  NSNN     Jump to Label INNER_LOOP      [0,1,7]         {0:4}
  SSSTTN   Push 3                        [0,1,7,3]       {0:4}
  TSSN     Multiply top two (7*3)        [0,1,21]        {0:4}
  TSSS     Add top two (1+21)            [0,22]          {0:4}
  SNT      Swap top two                  [22,0]          {0:4}
  SNS      Duplicate top (0)             [22,0,0]        {0:4}
  NTSTN    If 0: Jump to Label PRINT     [22,0]          {0:4}
  NSSTN    Create Label PRINT            [22,0]          {0:4}
   SNT     Swap top two                  [0,22]          {0:4}
   TNST    Print top to STDOUT           [0]             {0:4}           22
                                                                                  error

在线尝试(仅使用空格,制表符和换行符)。
因错误而停止:未定义退出。


此时,为什么不编写汇编呢?我的回答也有一个稍微简单的迭代方法codegolf.stackexchange.com/a/161833/17360
qwr

我进一步简化了我的python伪代码。
qwr

1
@qwr您的Python代码与显示的Java代码几乎相同。Java只是更加冗长且容易出错。唯一的区别是我的Java代码是一个嵌套的while循环,而您的则是分开的。我也可以在Java中做到这一点,但是由于它嵌套在Whitespace中,所以我选择也以Java伪代码编写它。另外,空白没有任何方法可以知道堆栈上剩余的项目数,这就是为什么我在开始时将0推入的原因,并且在代码的INNER_LOOP部分中这样做:交换,检查是否为0,交换回去。好的大会答案,但是。所以我+1了。:)
Kevin Cruijssen

我仍然认为您可以n < 1通过将值推送到n为0,然后弹出它们直到达到边界值(0)来摆脱检查。堆栈深度不需要显式存储,甚至不需要交换(如果您希望像lisp那样交换前两个值)
qwr,

@qwr“ 我仍然认为您可以通过将值推送到n为0来摆脱n <1检查。Umm ..检查n < 1(或n == 0)是否将值推送到n0。 “ 堆栈深度不需要显式存储 ”在Java中,否则,我无法创建数组。我本可以使用a java.util.Stack代替,但是我只是使用了一个数组来使它变得不太冗长。在空白中,堆栈的大小不确定。
凯文·克鲁伊森






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.