Fungsi Setengah-Eksponensial


21

Fungsi setengah-eksponensial adalah fungsi yang ketika disusun dengan dirinya sendiri memberikan fungsi eksponensial. Misalnya, jika f(f(x)) = 2^x, maka fakan menjadi fungsi setengah-eksponensial. Dalam tantangan ini, Anda akan menghitung fungsi setengah-eksponensial tertentu.

Secara khusus, Anda akan menghitung fungsi dari bilangan bulat non-negatif ke bilangan bulat non-negatif dengan properti berikut:

  • Meningkat secara monoton: jika x < y, makaf(x) < f(y)

  • Setidaknya setengah eksponensial: Untuk semua x,f(f(x)) >= 2^x

  • Leksikografis terkecil: Di antara semua fungsi dengan properti di atas, output yang diminimalkan f(0), yang diberi pilihan yang diminimalkan f(1), kemudian f(2), dan seterusnya.

Nilai awal dari fungsi ini, untuk input 0, 1, 2, ...adalah:

[1, 2, 3, 4, 8, 9, 10, 11, 16, 32, 64, 128, 129, 130, 131, 132, 256, 257, ...]

Anda dapat menampilkan fungsi ini melalui salah satu metode berikut, baik sebagai fungsi atau sebagai program lengkap:

  • Ambil xsebagai input, output f(x).

  • Ambil xsebagai input, output nilai pertama xdari f.

  • Keluarkan semua f.

Jika Anda ingin mengambil xdan output f(x), xharus diindeks nol.

Implementasi referensi

Ini adalah kode golf - kode terpendek dalam byte yang menang. Celah standar dilarang, seperti biasa.


tampaknya definisi tidak diverifikasi untuk 0: f (f (0)) = f (1) = 2 tetapi 2 ^ 0 = 1
Nahuel Fouilleul

dan untuk 1: f (f (1)) = f (2) = 3 tetapi 2 ^ 1 = 2
Nahuel Fouilleul

1
@NahuelFouilleul persyaratannya adalah f (f (x)) > = 2 ^ x.
Martin Ender

1
Haruskah kita tunduk pada OEIS ?
Jeppe Stig Nielsen

Jawaban:


8

JavaScript (ES7), 51 48 byte

Disimpan 3 byte berkat @Arnauld

f=i=>i?f[f[q=f(i-1),r=f[i]||q+1]=(i>1)<<i,i]=r:1

Mengambil n dan mengeluarkan item ke - n dalam urutan.


JavaScript (ES7), 70 68 64 byte

f=(n,a=[],q=1)=>n?f(n-1,a,(n=2**a.indexOf(a.push(q)))<++q?q:n):a

Fungsi rekursif yang menerima xdan mengembalikan xitem pertama dari urutan sebagai array.

Bagaimana itu bekerja

Array a secara prosedural dihasilkan, satu item pada satu waktu, hingga mencapai panjang yang diinginkan. (Port teknik infinite yang digunakan dalam jawaban Python xnor yang sangat baik kemungkinan akan lebih pendek.)

Kita dapat melakukan pengamatan berikut untuk setiap indeks i (diindeks 0):

  • Jika saya ada sebagai item dalam sebuah di indeks j ( a [j] = i ), maka a [i] perlu setidaknya 2 j .

Ini benar karena f (f (j)) harus setidaknya 2 j , dan f (f (j)) setara dengan [a [j]] , yang pada gilirannya setara dengan [i] .

Biasanya opsi yang benar adalah tepat 2 j . Namun, untuk kasus tunggal i = 2 , 2 ada dalam array di index j = 1 , yang berarti bahwa 2 j akan menjadi 2 - tetapi ini berarti bahwa kita akan memiliki 2 pada a [1] dan a [2] . Untuk menyiasatinya, kami mengambil maksimum 2 j dan [i-1] + 1 (satu lebih dari item sebelumnya), yang memberikan 3 untuk i = 2 .

Teknik ini juga terjadi untuk mengurus memutuskan apakah atau tidak j ada-jika tidak, JS ini .indexOf()kembali metode -1 , yang mengarah ke mengambil maks sebuah [i-1] + 1 dan 2 -1 = 0,5 . Karena semua item dalam urutan setidaknya 1 , ini akan selalu mengembalikan item sebelumnya ditambah satu.

(Saya menulis penjelasan ini larut malam, jadi tolong beri tahu saya jika ada sesuatu yang membingungkan atau saya melewatkan sesuatu)


Perhatikan bahwa input 272dan up memberikan jawaban yang salah karena masalah overflow integer. Ini baik-baik saja, karena berfungsi hingga batas datatype.
isaacg

Gunakan 2**bukannya 1<<semoga memperbaiki masalah.
user202729

Sekarang .99bunuh solusinya. Tapi mengapa menggunakan +.99dan tidak adil +.9? Apa bedanya?
user202729

@ user202729 Saya merasa seperti orang idiot - yang tersisa di sana dari versi sebelumnya di mana saya menggunakan Math.log2(...)dan harus menghitung plafon. Sekarang tidak diperlukan sama sekali. Terima kasih! Saya akan melihat ke dalam 2**hal - saya menggunakan 2**...+.99|0awalnya, tetapi 1<<lebih pendek karena saya tidak membutuhkannya |0. Sekarang saya pikir tidak ada perbedaan ...
ETHproduksi




1

Jelly , 14 byte

iL’2*»Ṁ‘$ṭ
⁸Ç¡

Cobalah online!

Bagaimana itu bekerja

⁸Ç¡         Main link. No arguments.

⁸           Set the left argument and the return value to [].
 Ç¡         Read an integer n from STDIN and call the helper link n times, first on
            [], then on the previous result. Return the last result.


iL’2*»Ṁ‘$ṭ  Helper link. Argument: A (array)

 L          Take the length of A. This is the 0-based index of the next element.
i           Find its 1-based index in A (0 if not present).
  ’         Decrement to a 0-based index (-1 if not present).
   2*       Elevate 2 to the 0-based index.
      Ṁ‘$   Take the maximum of A and increment it by 1.
            Note that Ṁ returns 0 for an empty list.
     »      Take the maximum of the results to both sides.
         ṭ  Tack (append) the result to A.

0

Python 2 , 111 byte

def f(x):
 a=range(1,2**x)
 for i in range(1,x):a[i]=max(a[i],a[i-1]+1);a[a[i]]=max(a[a[i]],2**i)
 return a[:x]

Cobalah online!

Ini adalah modifikasi signifikan dari jawaban user202729 . Saya akan memposting peningkatan ini sebagai komentar, tetapi jawabannya dihapus dan komentar dinonaktifkan.


Ini gagal dengan pengecualian "daftar indeks di luar kisaran" pada input 258. Saya pikir masalahnya x**2adalah terlalu kecil.
isaacg

Yah ... Python 2 berbeda (seringkali lebih sedikit byte) dari Python 3.
user202729

1
Seperti yang diharapkan, setengah eksponensial jauh lebih besar daripada kuadratik. Solusinya dapatkan "daftar indeks di luar jangkauan" di x=1000. Anda mungkin ingin mencoba 2**x- sangat besar, tetapi codegolf adalah codegolf.
user202729

@ user202729 Ah, ini benar. Sayangnya itu sekarang menghadapi masalah yang sama sekali berbeda dengan input yang lebih besar yang 2**xmenciptakan jangkauan Python yang terlalu besar untuk melanjutkan.
notjagan

0

Swift , 137 byte

func f(n:Int){var l=Array(1...n).map{$0>3 ?0:$0},p=8;if n>3{for i in 3..<n{if l[i]<1{l[i]=l[i-1]+1};if l[i]<n{l[l[i]]=p};p*=2}};print(l)}

Mengambil input sebagai Int(integer) dan mencetak sebagai [Int](integer array).

Versi tidak disatukan

func f(n:Int){
    var l = Array(1...n).map{$0 > 3 ? 0 : $0} // Create the range from 1 to n and set all
    var p = 8                                 // values greater than 3 to 0
    if n > 3 {
        for i in 3 ..< n {
            if l[i] < 1 {
                l[i] = l[i - 1] + 1
            }
            if l[i] < n {
                l[l[i]] = p
            }
            p *= 2
        }
    }
    print(l)
}

Saya ingin tahu, apa yang akan terjadi jika Anda menghapus ruang sebelum ??
ETHproduk

@ ETHproductions Itu mengarah ke kesalahan kompiler, karena integer tidak bisa dirantai opsional .
Herman L
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.