Вверх идут биты!


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

Ответы:


15

Python 2 , 31 байт

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

Попробуйте онлайн!


3
Не могли бы вы объяснить, как это работает?

+n%2+1добавляет крайний правый двоичный бит плюс 1 к возвращаемому значению, n/2сдвиг вправо nна 1 двоичный бит, 3*f(n/2)рекурсивно добавляет в 3 раза это вычисление для этих сдвинутых вправо битов и n andзаканчивает рекурсию, когда nравно 0
Noodle9

11

JavaScript (Node.js) , 23 байта

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

Попробуйте онлайн!


x>>1так же, как x/2не так ли?
mbomb007

@ mbomb007 Я думал и предлагал то же самое только что, но, видимо, это делается Infinityв JS .. Попробуйте онлайн. (Возможно, вы захотите добавить TIO-ссылку к вашему ответу, I4m2 )
Кевин Круйссен,

2
@ mbomb007 Нет. 1>>1=0пока1/2=0.5
l4m2

4
@ mbomb007 ... Питон?
user202729

2
Да. Посмотрите на ответ Python. Вот причина того, что n/2работает в этом, и причина, по которой я предложил это здесь.
mbomb007

9

Java (JDK 10) , 44 байта

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

Попробуйте онлайн!


1
Может -~поможет?
user202729

2
Нет, правила приоритета.
user202729

Тот же вопрос к вам: почему long? :) И тут я подумал, что мой подход к последовательности был умным. Вы взорвали его из парка менее чем за 5 минут ..>.>: '(
Кевин Круйссен,

@KevinCruijssen Чтобы быть честным с тобой ...
user202729


6

J 7 байт

3#.1+#:

Попробуйте онлайн!

Спасибо Галену Иванову за -4 байта! Мне действительно нужно улучшить свои навыки игры в гольф ...


1
7 байт: 3#.1+#: TIO
Гален Иванов,

Также спасибо за шаблон, мне нужно кое-что узнать : 0.
user202729

Шаблон не мой, я забыл, кто его автор.
Гален Иванов

2
Это был бы я :)
Конор О'Брайен

6

R , 55 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

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

Java 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 в течение нескольких минут ..: '(


Re n.toString(n,2).getBytes()... Я думаю, что ручное преобразование может быть короче.
user202729

1
Кстати, а почему longнет int?
user202729

1
Я думаю, что в версии последовательности вы можете заменить (int)Math.pow(2,t)на 1<<t..., а затем вставить это выражение и опустить переменную i ( 152 байта )
musicman523

1
В реальной жизни я бы использовал 31-Integer.numberOfLeadingZeros(n)вместо (int)(Math.log(n)/Math.log(2)), но это не короче. Если вы не используете import staticв заголовке, что может слишком сильно расширить правила.
Хольгер

1
Я просто попытался преобразовать цикл вашего первого варианта в потоковое решение, но с успехом:n -> n.toString(n,2).chars().reduce(0,(r,c)->r*3+c-47)
Хольгер,





3

Атташе , 19 байт

FromBase&3@1&`+@Bin

Попробуйте онлайн!

Это композиция из трех функций:

  • FromBase&3
  • 1&`+
  • Bin

Сначала он преобразуется в двоичный ( Bin), увеличивает его ( 1&`+), затем преобразует в троичный ( FromBase&3).

альтернативы

Без точки, 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

Неоднократно делим на 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

MATL , 12 7 6 байт

BQ3_ZA

Попробуйте онлайн!

Сэкономили 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потому что я использую Convertи Math.


Выбор дает индекс в качестве необязательного параметра. Так что вы можете избавиться от своей 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 «s Java ответ . Попробуйте это онлайн здесь . Спасибо Кевину Круйссену за игру в гольф 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 байт, заменяя returnс x=и реверсирования троичной поэтому !больше не нужно: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 байтов: попробуйте онлайн!
Sanchises

А с 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);}

Попробуйте онлайн!

Благодаря Кристофу , меньше байтов, если работает с 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!!"
Франциско Хан


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 делаю: swap, проверяю 0, меняем ли обратно. Хороший сборочный ответ, хотя. Итак, я добавил +1. :)
Кевин Круйссен

Я все еще думаю, что вы можете избавиться от n < 1проверки, нажимая значения до тех пор, пока n не станет равным 0, а затем выталкивая их, пока вы не достигнете своего граничного значения (0). Глубина стека не должна храниться в явном виде и даже не должна
меняться

@ qwr " Я все еще думаю, что вы можете избавиться от проверки n <1, нажимая значения до тех пор, пока n не станет равным 0 " Умм .. проверяя, n < 1(или n == 0) ИС не толкает значения до тех пор, пока не nстанет 0 .. Или я что-то здесь неправильно понимаю:: S « Глубина стека не должна храниться в явном виде » В Java это происходит, иначе я не могу создать массив. Я мог бы использовать java.util.Stackвместо этого, но я просто использовал массив, чтобы сделать его менее многословным. В Whitespace стек имеет неопределенный размер.
Кевин Круйссен






Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.