Чи можна записати це число у форматі (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, було б занадто просто.
П. Ктінос

2
Якщо це неправдиве твердження у вашій мові програмування, тоді ні.
П. Ктінос

2
Чи можу я хочу, щоб це число було введене в трійці?
Джон Дворак

2
маючи обробляти негативні інтергери, це зробить 0 3^0-1 дійсним результатом і, таким чином, не використовуватиметься як хибне,
Jasen

2
той, хто думає використати log()у своїй відповіді, повинен підтвердити, що він дає правильну відповідь, 5коли 242 вводиться.
Ясен

Відповіді:


23

Математика, 21 16 байт

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

Використовує символічні обчислення Mathematica. Якщо #+1потужність три, то 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

Пітон, 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-х байт, порожній список як фальшивий
Rod

Виправлено, дякую! @Rod тоді повернеться [n] замість n Я думаю
nmjcman101

@ Nmjcman101 , що не повинно бути проблемою
Rod

@Rod Я вважаю за краще дотримуватися строго специфіки на даний момент
nmjcman101

@Rod Якщо потрібне виведення цілого числа, ви не можете вивести його у список, якщо OP спеціально не дозволяє.
mbomb007


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, мабуть, добре в базовій конверсії - це справді найкращий підхід?
Ясен

1
@Jasen: Мої спроби з перетворенням бази все тривали довше. Якщо є кращий спосіб, ніж цей, я цього не бачу. Не соромтесь доводити мене неправильно :)
Емінья

досить чесно, я лише прочитав опис мови, і тому очікував побачити 5-байтне рішення ....
Ясен

1
@Jasen <3zm©.ïi®- це найближче у мене не використання діапазонів, як він.
Чарівний восьминіг Урна

1
3DÝms<k... Нічого не пам'ятаю ... Не можу поголити ще один байт, міг присягати, що міг.
Чарівний восьминога Урна


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, число не було для 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;}

Ця лямбда підходить до Function<Integer, Integer>посилання та використовує просту базу 3 хитрості.

Цього разу це повинно працювати правильно.


3
Чи не надрукував би це лише True чи False, коли він може бути записаний у форматі? Але я попросив показника, коли результат Правда
П. Ктінос

2
Це геній! +1 за дуже розумний підхід
DJMcMayhem

Це розумно ... я вважаю, ви можете вилучити парони і просто зробити це i->. Крім того, якщо ви приймаєте iяк a Long, ви можете використовувати його a.toString(...)(ides даватиме попередження про неправильне використання статичних функцій, але слід компілювати). Однак, як сказав ОП, вам потрібно повернути значення, а не лише True або False.
FlipTack

Якщо лямбда зберігається в іншому типі функції, то статичний трюк працює. Я також зафіксував повернене значення. Я, мабуть, пропустив цю частину.

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. Це було змінено з тих пір, тому я, ймовірно, очищую свої коментарі до цього.
Геобіц

Зачекайте, тож я можу 0зараз повернутися ?
Kritixi Lithos

Я б все одно сказав "ні". Питання дає альтернативне ціле значення, яке слід використовувати, якщо помилкове, але 0ніколи не є хибним у Java / Processing, про яке я знаю.
Геобіц

Я думав, що обробка повинна була бути меншою, ніж Java
Павло

@Pavel Але я не використовую лямбда: /
Kritixi Lithos

4

Брахілог , 8 байт

,3:.^-?,

Спробуйте в Інтернеті!

Виводить значення, якщо є істинним, і 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..$_}

Вилучення місця після **роботи, оскільки він довший за іншого оператора інфіксації, який міг би відповідати *.
Так …***…розбирається як … ** * …швидше … * ** ….

Спробуй це

Розширено:

{  # 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 байти

Інший підхід від відповіді планунапу , і на один байт коротший!

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

Генерує всі цілі числа від 3^1-1до 3^99-1та перевіряє, чи відповідає stdin. Якщо так, він повертає індекс, з яким він відповідає, який є x. Якщо ні, повертається NAяк хибне значення.

Між іншим, він прийме декілька значень як вхідних даних і перевірить їх усі, що є акуратною особливістю.


3

Пролог, 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


@ mbomb007 Функціям дозволено друкувати результат STDOUT, щоб ви могли змінити це повернення до друку.
FlipTack

Якщо ви представляєте це як рішення SageMath, а не Python, ви можете повністю скинути перший рядок.
Федеріко Полоні

Поряд з іншим скороченням до 65 байт, ви можете використовувати import mathі math.ceilдля одного байта. Також ви можете звернутися 3**x-1==n and xдоx*(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за фальш.
Тит

Якщо припустити, що ви використовуєте GCC для компіляції, ви можете зберегти в цілому 10 (11) байт: вам не потрібно ініціалізувати n до нуля, якщо ви знаєте, що ви будете викликати цю функцію лише один раз, оскільки тоді n буде за замовчуванням ( бо це глобально) - це на 4 байти менше; також вам не потрібна операція повернення, написавши, a=--a?-1:n;ви збережете 5 байт. якщо недійсна функція не має повернення, вона просто використовуватиме останнє призначення. Також те, що сказав @Titus.
Етаоін Шрдлу

1
Запропонувати a%3?0:(a/=3)замість!(a%3)&&(a/=3)
roofcat

2

Утиліти Bash / Unix, 37 35 байт

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

Спробуйте в Інтернеті!

Використовує dc для перетворення в базу 3, перевіряє, що в отриманому рядку є всі 2s, підраховує кількість символів (включаючи новий рядок), а потім використовує bc для віднімання 1.

Якщо число в базі 3 не всі 2, то греп не видає нічого (навіть нового рядка), тому кількість символів дорівнює 0, а віднімання 1 дає -1.


2

C, складений Кланг 3.8.1, 53 , 52 , 54 , 51 байт

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

@SteadyBox вже розмістив рішення в C, але я використовую інший підхід.

@ Дякую Ясену за допомогу в збереженні байтів.


1
так, але це працює? порівнювати поплавці за рівність часто є рецептом несподіваної невдачі (спробуйте великі входи)
Ясен

@Jasen Хм, не пробував цього, але в C logповертається, doubleтак що, можливо, це може спрацювати.
Уейд Тайлер

double - тип значення з плаваючою комою, тому проблема не зникає.
Ясен

здається, працює нормально для 3 ^ 19, що, ймовірно, досить велике.
Ясен

@Jasen Це не працює 3 ^ 10
Уейд Тайлер

2

C, 42 байти, оптимізований за допомогою Уейда Тайлера

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

Спробуйте

С, 37 байт, без return

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

Спробуйте

nє глобальним, але (I)MULможе мати лише його призначення операнд в реєстрі, тому доведеться вносити 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)))

Якщо "фальшивка" повинна бути однаковою, 33 байти:

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

2

Pyt , 10 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 байт)
Ясен

1

Пітон, 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для помилки:

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

Не виводить xні -1.
dfernan

Програма повинна виводити, xа не nу разі відповідності.
dfernan

Ні, воно повинно вивести ціле число, що при заміні на X ви отримуєте введення. Питання стосується X як змінної, а не як рядка
П. Ктінос

@ P.Ktinos Виправлено.
mbomb007


1

Джулія, 30 байт

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

Це проста функція - вона створює вектор, який має trueєдине у відповідному положенні в 3^a-1, де aвектор, що містить цілі числа між 0 і n. Він знаходить «перше» положення, яке є, trueі віднімає 1 (якщо це все false, знахідка оцінюється до нуля, і повертається -1).

Як 0:nі 0в першому місці, віднімання 1 виправляє індексацію, а також дозволяє -1помилкову відповідь.



Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.