Bisakah angka ini ditulis dalam format (3 ^ x) - 1?

41

Tantangan:

Buat program yang menerima bilangan bulat positif dan periksa apakah dapat ditulis dalam bentuk (3 ^ x) -1, di mana X adalah bilangan bulat positif lainnya .

Jika bisa, output X

Jika tidak bisa, output -1 atau pernyataan palsu .

Contoh input / output

Memasukkan:

2

Itu dapat ditulis sebagai (3 ^ 1) - 1, jadi kita menghasilkan x yang 1

Keluaran:

1

Memasukkan:

26

26 dapat ditulis sebagai (3 ^ 3) - 1, jadi kami output x (3)

Keluaran:

3

Memasukkan:

1024

1024 tidak dapat ditulis dalam bentuk (3 ^ x) - 1, jadi kami menghasilkan -1

Keluaran:

-1

Ini adalah sehingga jumlah byte yang menang paling sedikit


OEIS Terkait: A024023

P. Ktinos
sumber
4
Saya meminta output X karena saya percaya itu lebih menantang seperti itu. Cukup menemukan jika formatnya 3 ^ x - 1 akan terlalu mudah untuk sebuah tantangan, menurut saya.
P. Ktinos
2
Kecuali jika itu pernyataan palsu dalam bahasa pemrograman Anda, maka tidak.
P. Ktinos
2
Bolehkah saya ingin nomor menjadi masukan di ternary?
John Dvorak
2
harus menangani intergers non-negatif akan menjadikan 0 3^0-1 output yang valid dan karenanya tidak dapat digunakan sebagai false,
Jasen
2
siapa pun yang berpikir untuk menggunakan log()dalam jawaban mereka harus mengonfirmasikannya dengan memberikan jawaban yang benar 5ketika 242 dimasukkan.
Jasen

Jawaban:

23

Mathematica, 21 16 byte

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

Memanfaatkan perhitungan simbolik Mathematica. Jika #+1kekuatan tiga maka Log[3,#+1]akan menghitung hasil integer yang merupakan nilai atom. Kalau tidak, kita akan mendapatkan Log[#+1]/Log[3]apa adanya. Karena ini bukan nilai atom, ini adalah ekspresi yang selalu berbentuk head[val1,val2,...]. Dalam hal ini sebenarnya seperti itu Times[Power[Log[3], -1], Log[#+1]].

Kami membedakan antara dua kasus dengan menerapkan fungsi lain pada hasilnya. Apa yang benar-benar diterapkan adalah bahwa itu menggantikan headbagian dari ekspresi. Karena hasil bilangan bulat adalah atom, menerapkan fungsi apa pun padanya tidak menghasilkan apa-apa. Khususnya f @@ atom == atom.

Namun, dalam kasus lain, kepala diganti. Fungsi yang kami gunakan adalah -1&fungsi sederhana yang mengabaikan argumen dan pengembaliannya -1. Jadi kami mendapatkan sesuatu -1&[Power[Log[3], -1], Log[#+1]]dalam kasus non-integer, yang dievaluasi langsung ke -1. Casing khusus melalui sihir.

Martin Ender
sumber
13

Python, 46 44 byte

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

Cobalah online!

Dalam hal ini, 0akan menjadi nilai palsu. Terima kasih kepada @ mbomb007 karena menunjukkan output yang salah dan 2 byte tanpa []penghematan.

nmjcman101
sumber
Anda dapat menulis ulang [n for n in range(x)if 3**n-1==x]untuk -4 byte, kosongkan daftar sebagai falsy
Rod
Diperbaiki, terima kasih! @Rod maka itu akan mengembalikan [n] alih-alih n saya pikir
nmjcman101
@ nmjcman101 yang seharusnya tidak menjadi masalah
Rod
@Rod Saya lebih suka berpegang teguh pada spec untuk saat ini
nmjcman101
@ Rad Jika mengeluarkan bilangan bulat diperlukan, Anda tidak dapat menampilkannya dalam daftar kecuali OP secara khusus mengizinkannya.
mbomb007
13

Haskell, 35 byte

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

Contoh penggunaan: f 26-> 3.

nimi
sumber
PS: Coba online! mendukung Haskell! (Jawaban bagus btw!)
flawr
11

05AB1E , 7 byte

3IÝm<¹k

Cobalah online!

Penjelasan

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
sumber
05AB1E tampaknya bagus dalam konversi basis, apakah ini benar-benar pendekatan terbaik?
Jasen
1
@ Yasen: Upaya saya dengan konversi basis semua ternyata lebih lama. Jika ada cara yang lebih baik dari ini saya tidak melihatnya. Jangan ragu untuk membuktikan saya salah :)
Emigna
cukup adil, saya hanya membaca deskripsi bahasa, dan, jadi diharapkan untuk melihat solusi 5 byte ....
Jasen
1
@ Yasen <3zm©.ïi®adalah yang terdekat saya tidak menggunakan rentang seperti yang dia lakukan.
Magic Octopus Mm
1
3DÝms<k... Nevermind ... Tidak dapat memotong satu byte lagi, bisa bersumpah aku bisa.
Magic Gurita Guci
9

Jelly , 5 byte

R3*’i

Output x atau 0 (falsy).

Cobalah online!

Bagaimana itu bekerja

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
sumber
6

Python 2, 41 byte

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

Fungsi rekursif yang mengembalikan 0input yang tidak cocok. Berulang kali membagi input dengan 3, menghitung jumlah langkah i, yang merupakan output pada akhirnya. Tetapi, jika langkah apa pun menghasilkan nilai nyang bukan 2 modulo 0, angkanya bukan untuk 3^i-1, sehingga output dikalikan dengan 0.

Tidak
sumber
6

Perl, 31 byte

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

Membutuhkan -Ebendera untuk dijalankan:

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

Penjelasan:
grep{3**$_-1==$i}0..($i=<>)mengembalikan daftar elemen rentang 0..$_(mis. Mulai dari 0 hingga input) yang memenuhi tes 3**$_-1==$i. Hanya satu elemen paling banyak yang dapat memenuhi tes ini, jadi instruksi ini akan mengembalikan array elemen 0 atau 1. Kami kemudian mencetak daftar ini: salah Xatau tidak sama sekali (yang salah).

Dada
sumber
5

Pyth, 11 byte

?-JjQ3 2ZlJ

Konversi ke basis 3 dan memeriksa kesetaraan untuk [2, 2, ..., 2].

orlp
sumber
Anda dapat mengurangi ini satu byte dengan ?-2JjQ3ZlJ, karena <col> <num>dan <num> <col>dapat dipertukarkan dengan -Pyth.
notjagan
5

JavaScript (ES7), 38 36 34 byte

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

Atau hanya 30 29 byte jika OK untuk keluar dengan kesalahan kegagalan:

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

Uji

Arnauld
sumber
5

Java 8, 37 58 67 byte

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

Lambda ini cocok dengan Function<Integer, Integer>referensi dan menggunakan trik dasar 3 sederhana.

Kali ini seharusnya bekerja dengan benar.


sumber
3
Bukankah itu hanya mencetak Benar atau Salah ketika itu dapat ditulis dalam format? Tetapi saya meminta eksponen ketika hasilnya Benar
P. Ktinos
2
Itu jenius! +1 untuk pendekatan yang sangat cerdas
DJMcMayhem
Ini pintar ... saya percaya Anda dapat menghapus parens dan hanya membuatnya i->. Juga, jika Anda menganggapnya isebagai Long, Anda dapat menggunakan a.toString(...)(id akan memberikan beberapa peringatan tentang menggunakan fungsi statis secara tidak benar, tetapi harus dikompilasi). Namun, seperti kata OP, Anda harus mengembalikan nilainya, bukan hanya Benar atau Salah.
FlipTack
Jika lambda disimpan dalam jenis fungsi yang berbeda maka trik statisnya berfungsi. Saya juga memperbaiki nilai pengembalian. Saya pasti melewatkan bagian itu.
5

Memproses, 60 56 byte

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

Keluaran -1jika salah.

Penjelasan

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
}

voidadalah 1 byte lebih pendek daripada menggunakan float, jadi itu sebabnya fungsi ini secara langsung menghasilkan bukannya mengembalikan nilai.

Solusi alternatif

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

untuk 63 byte, tapi saya rasa alt ini bisa golf lebih pendek dari solusi aslinya. Saya sedang mengerjakannya.

Kritixi Lithos
sumber
@ Lipup Ya, saya tahu itu tidak akan di Jawa. Saya hanya bertanya karena saya tidak yakin bahwa Processing tidak menambahkan sesuatu di sepanjang baris itu. "Nilai berbeda" yang akan digunakan adalah -1, bukan 0. Sudah diubah sejak, jadi saya mungkin akan membersihkan komentar saya tentang hal itu.
Geobits
Tunggu, jadi bisakah saya kembali 0sekarang?
Kritixi Lithos
Saya masih mengatakan tidak. Pertanyaannya memberikan nilai integer alternatif untuk digunakan jika falsy, tetapi 0tidak pernah falsy di Java / Processing yang saya tahu.
Geobits
Saya pikir Pemrosesan seharusnya kurang versbose dari Jawa
Pavel
@Pavel Tapi saya tidak menggunakan lambdas: /
Kritixi Lithos
4

Brachylog , 8 byte

,3:.^-?,

Cobalah online!

Output nilai jika benar dan false.jika ini tidak mungkin.

Penjelasan

Ini adalah transkripsi langsung dari relasi yang diberikan:

,     ,      (Disable implicit unification)
 3:.^        3^Output…
     -?              … - 1 = Input
Fatalisasi
sumber
Anda hampir dapat menurunkan ini hingga 7 byte +~^r~:3, tetapi sayangnya ~:tidak melakukan apa yang Anda harapkan (kemungkinan karena :sintaks daripada builtin), dan tampaknya diperlakukan secara identik :.
@ ais523 Itu benar, :adalah simbol kontrol, dan ~hanya berfungsi pada predikat.
Fatalkan
3

Perl 6 ,  25  24 byte

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

Cobalah

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

Menghapus ruang setelah **bekerja karena lebih panjang dari operator infiks lain yang bisa cocok *.
Jadi …***…diuraikan sebagai … ** * …bukan … * ** ….

Cobalah

Diperluas:

{  # 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
sumber
3

R, 24 byte

Pendekatan yang berbeda dari jawaban plannapus , dan satu byte lebih pendek!

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

Menghasilkan semua bilangan bulat dari 3^1-1ke 3^99-1, dan memeriksa apakah stdin cocok. Jika demikian, ia mengembalikan indeks yang cocok, yaitu x. Jika tidak, kembali NAsebagai nilai falsy.

Kebetulan, itu akan menerima beberapa nilai sebagai input, dan menguji semuanya, yang merupakan fitur yang rapi.

rturnbull
sumber
3

Prolog, 20 byte

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

Bahasa ini keren sekali.

| ?- d(1024,X).

no
| ?- d(26,X).

X = 3

yes
| ?- d(2,X).

X = 1

yes
Beri nama McChange
sumber
2

05AB1E , 9 byte

DÝ3sm<Q1k

Cobalah online!

Mencetak -1 untuk 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
sumber
2

MATL , 8 byte

3i:^qG=f

Ini menghasilkan angka xjika ada, atau tidak menghasilkan apa-apa, yang salah.

Cobalah online!

Penjelasan

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
sumber
2

Japt , 11 byte

o æ@U+1¥3pX

Coba di sini .

Terima kasih banyak kepada ETHproductions untuk membantu!

Oliver
sumber
2

Python 3, 74 66 64 byte

-10 byte terima kasih kepada @ mbomb007, @FlipTack dan @ nmjcman101

from math import*
def f(n):x=ceil(log(n,3));print((3**x-1==n)*x)
dfernan
sumber
Anda dapat meletakkan semua kode Anda pada satu baris dan menggunakan from math import*. Juga return n==3**x-1and x.
mbomb007
Solusi 65 byte
mbomb007
@ mbomb007 Fungsi diizinkan untuk mencetak hasilnya STDOUT, sehingga Anda dapat mengubahnya kembali ke cetakan.
FlipTack
Jika Anda mempresentasikan ini sebagai solusi SageMath daripada yang Python, Anda bisa membuang baris pertama sama sekali.
Federico Poloni
Seiring dengan pengurangan lainnya menjadi 65 byte, Anda dapat menggunakan import mathdan math.ceiluntuk satu byte. Anda juga dapat beralih 3**x-1==n and xkex*(3**x-1==n)
nmjcman101
2

Ruby, 30 byte

Mengembalikan nil(nilai palsu) jika tidak ada angka yang ditemukan. [Coba online]

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

C, 56 byte

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

tambahkan satu ke input dan kemudian berulang kali bagi tiga hingga sisa ditemukan, jika satu tercapai kembalikan jumlah pembagian yang lain -1

Jasen
sumber
Simpan satu byte dengan a%3<1sebagai gantinya !(a%3). Satu lagi dengan 0falsy.
Titus
Dengan asumsi Anda menggunakan GCC untuk mengkompilasi Anda dapat menyimpan total 10 (11) byte: Anda tidak perlu menginisialisasi n ke nol jika Anda tahu Anda akan memanggil fungsi ini hanya sekali sejak saat itu n akan menjadi nol secara default ( karena global) - itu kurang dari 4 byte; Anda juga tidak perlu pernyataan pengembalian, dengan menulis a=--a?-1:n;Anda akan menghemat 5 byte. jika fungsi non-void tidak memiliki pengembalian, itu hanya akan menggunakan tugas terakhir. Juga apa yang dikatakan @Titus.
Etaoin Shrdlu
1
Sarankan a%3?0:(a/=3)alih-alih!(a%3)&&(a/=3)
ceilingcat
2

Utilitas Bash / Unix, 37 35 byte

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

Cobalah online!

Menggunakan dc untuk mengonversi ke basis 3, memeriksa apakah string yang dihasilkan semuanya 2s, menghitung jumlah karakter (termasuk baris baru), dan kemudian menggunakan bc untuk mengurangi 1.

Jika angka dalam basis 3 tidak semua 2s, maka grep tidak menghasilkan apa-apa (bahkan bukan baris baru), sehingga jumlah karakter adalah 0, dan mengurangi 1 menghasilkan -1.

Mitchell Spector
sumber
2

C dikompilasi dengan Dentang 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 sudah memposting solusi dalam C, tapi saya menggunakan pendekatan yang berbeda.

@Terima kasih kepada Jasen karena membantu menyelamatkan byte.

Wade Tyler
sumber
1
ya, tetapi apakah itu berhasil? membandingkan pelampung untuk kesetaraan sering merupakan resep untuk kegagalan yang tidak terduga (coba input besar)
Jasen
@ Yasen Hmm, belum mencobanya, tetapi di C logkembali doublejadi mungkin itu mungkin berhasil.
Wade Tyler
dobel adalah jenis nilai floating point sehingga masalah tetap ada.
Jasen
tampaknya berfungsi ok untuk 3 ^ 19 yang mungkin cukup besar.
Jasen
@ Yasen Tidak berfungsi untuk 3 ^ 10
Wade Tyler
2

C, 42 Bytes, dioptimalkan dari Wade Tyler

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

Mencoba

C, 37 Bytes, tanpa return

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

Mencoba

nbersifat global tetapi (I)MULhanya dapat memiliki operan dest di register, jadi harus dimasukkan ke EAX(pilihan biasa) dan pindah ke sana

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

Jika "falsy" harus sama, 33 Bytes:

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

Pyt , 10 9 byte

←⁺3ĽĐĐƖ=*

Penjelasan:

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


Menyimpan byte dengan menggunakan fungsi kenaikan alih-alih secara eksplisit menambahkan 1

mudkip201
sumber
di halaman kode apa 9 byte itu? (dalam UTF-8 17 byte)
Jasen
1

Python, 64 byte

Keluaran Falsejika nomor tidak dapat ditulis dalam format itu.

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

Ini juga berfungsi dalam 64 byte, dan mencetak string kosong sebagai output falsy:

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

Solusi kreatif untuk 65 byte, menghasilkan 0untuk falsy:

lambda n:-~",".join(`3**x-1`for x in range(n+1)).find(',%s,'%n)/2
mbomb007
sumber
Tidak menghasilkan xjuga -1.
dfernan
Program harus menampilkan xbukan njika terjadi kecocokan.
dfernan
Tidak, itu harus menghasilkan bilangan bulat positif yang ketika diganti dengan X, Anda mendapatkan input. Pertanyaannya merujuk pada X sebagai variabel, bukan sebagai string
P. Ktinos
@ P. Ktinos Memperbaikinya.
mbomb007
1

Julia, 30 byte

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

Ini adalah fungsi sederhana - ini menciptakan vektor yang truehanya memiliki posisi yang sesuai 3^a-1, di mana avektor berisi bilangan bulat antara 0 dan n. Ia menemukan posisi "pertama" yaitu truedan mengurangi 1 (jika itu semua false, temuan itu bernilai nol, dan mengembalikan -1).

Seperti yang 0:ntelah 0di tempat pertama, kurangi 1 mengoreksi untuk pengindeksan dan juga memungkinkan -1tanggapan palsu.

Glen O
sumber
1

Pyth 8 byte

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

Coba di sini

tongkat
sumber