ฟังก์ชันเลขชี้กำลังครึ่งตัว


21

ฟังก์ชั่นครึ่งชี้แจงเป็นหนึ่งซึ่งเมื่อประกอบกับตัวเองให้ฟังก์ชั่นการชี้แจง ตัวอย่างเช่นถ้าf(f(x)) = 2^xไปแล้วfจะเป็นฟังก์ชั่นครึ่งชี้แจง ในความท้าทายนี้คุณจะคำนวณฟังก์ชันเลขชี้กำลังแบบครึ่งหนึ่ง

โดยเฉพาะคุณจะคำนวณฟังก์ชันจากจำนวนเต็มไม่เป็นลบถึงจำนวนเต็มที่ไม่ใช่ลบด้วยคุณสมบัติต่อไปนี้:

  • เพิ่มขึ้นอย่างน่าเบื่อ: ถ้าx < yเช่นนั้นf(x) < f(y)

  • อย่างน้อยครึ่งชี้แจง: สำหรับทุกคนx,f(f(x)) >= 2^x

  • เล็กที่สุดในพจนานุกรม: ในบรรดาฟังก์ชั่นทั้งหมดที่มีคุณสมบัติด้านบนให้ส่งเอาท์พุตที่ย่อเล็กสุดf(0)ซึ่งให้ตัวเลือกนั้นย่อเล็กสุดf(1)จากนั้นf(2)จึงเป็นต้น

ค่าเริ่มต้นของฟังก์ชันนี้สำหรับอินพุต0, 1, 2, ...คือ:

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

คุณสามารถส่งออกฟังก์ชั่นนี้ผ่านวิธีการใด ๆ ต่อไปนี้ไม่ว่าจะเป็นฟังก์ชั่นหรือเป็นโปรแกรมเต็มรูปแบบ:

  • ใช้เป็นอินพุทเอาท์พุทxf(x)

  • ใช้xเป็นอินพุทเอาท์พุทแรกค่าxf

  • fการส่งออกทั้งหมดของอนันต์

หากคุณต้องการที่จะใช้xและเอาท์พุทf(x), xต้องเป็นศูนย์การจัดทำดัชนี

การดำเนินการอ้างอิง

นี่คือรหัสกอล์ฟ - รหัสสั้นที่สุดในหน่วยชนะไบต์ ช่องโหว่มาตรฐานถูกแบนเช่นเคย


ดูเหมือนว่าคำจำกัดความไม่ได้รับการยืนยันสำหรับ 0: f (f (0)) = f (1) = 2 แต่ 2 ^ 0 = 1
Nahuel Fouilleul

และสำหรับ 1: f (f (1)) = f (2) = 3 แต่ 2 ^ 1 = 2
Nahuel Fouilleul

1
@NahuelFouilleul สิ่งที่ต้องการคือ f (f (x)) > = 2 ^ x
Martin Ender

1
เราควรส่งให้OEISหรือไม่
Jeppe Stig Nielsen

คำตอบ:


8

JavaScript (ES7), 51 48 ไบต์

บันทึกแล้ว 3 ไบต์ขอบคุณ @Arnauld

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

ใช้เวลาในnและส่งออกรายการn 'ในลำดับ


JavaScript (ES7), 70 68 64 ไบต์

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

ฟังก์ชั่นวนซ้ำที่รับxและส่งคืนxไอเท็มแรกของลำดับเป็นอาร์เรย์

มันทำงานอย่างไร

อาร์เรย์aถูกสร้างขึ้นตามกระบวนการทีละรายการจนกว่าจะถึงความยาวที่ต้องการ (พอร์ตของเทคนิคอนันต์ที่ใช้ในคำตอบ Python ที่ยอดเยี่ยมของ xnorน่าจะสั้นกว่า)

เราสามารถทำการสังเกตต่อไปนี้สำหรับแต่ละดัชนีi (0-indexed):

  • ถ้าฉันมีอยู่เป็นรายการในที่ดัชนีJ ( a [เจ] = ฉัน ) แล้วa [ผม]จะต้องมีอย่างน้อย2 J

นี้เป็นจริงเนื่องจากf (f (ญ))จะต้องมีอย่างน้อย2 Jและf (f (ญ))เทียบเท่ากับa [a [เจ]]ซึ่งอยู่ในเทียบเท่าหันไปa [ผม]

ปกติตัวเลือกที่ถูกต้องคือว่า2 J อย่างไรก็ตามสำหรับกรณีเอกพจน์i = 2 , 2ที่มีอยู่ในอาร์เรย์ที่ดัชนีJ = 1ซึ่งหมายความว่า2 Jจะเป็น2 -but นี้หมายถึงว่าเราจะมี2ทั้งa [1]และa [2] จะได้รับรอบนี้เราใช้เวลาสูงสุดของ2 เจและa [I-1] + 1 (มากกว่าหนึ่งรายการก่อนหน้า) ซึ่งจะช่วยให้3สำหรับi = 2

เทคนิคนี้ยังเกิดขึ้นในการดูแลของการตัดสินใจหรือไม่ว่าเจมีอยู่ถ้ามันไม่ได้ JS ของ.indexOf()วิธีการส่งกลับ-1ซึ่งนำไปสู่การสูงสุดของa [I-1] + 1และ2 -1 = 0.5 เนื่องจากรายการทั้งหมดในลำดับมีอย่างน้อย1รายการนี้จะส่งคืนรายการก่อนหน้าบวกหนึ่งรายการเสมอ

(ฉันกำลังเขียนคำอธิบายนี้ตอนดึกดังนั้นโปรดแจ้งให้เราทราบหากมีสิ่งที่ทำให้สับสนหรือฉันพลาดอะไร)


โปรดทราบว่าอินพุต272และสูงกว่าให้คำตอบที่ไม่ถูกต้องเนื่องจากปัญหาการล้นของจำนวนเต็ม นี่เป็นเรื่องปกติเนื่องจากทำงานได้ถึงขีด จำกัด ของประเภทข้อมูล
isaacg

ใช้2**แทน1<<หวังว่าจะแก้ปัญหาได้
user202729

ตอนนี้.99ฆ่าโซลูชั่น แต่ทำไมถึงใช้งาน+.99และไม่ใช่แค่+.9? ความแตกต่างคืออะไร?
user202729

@ user202729 ฉันรู้สึกเหมือนคนบ้า - ที่เหลืออยู่ในนั้นจากรุ่นก่อนหน้าที่ฉันใช้Math.log2(...)และต้องคำนวณเพดาน ตอนนี้มันไม่จำเป็นเลย ขอบคุณ! ฉันจะมองเข้าไปใน2**สิ่งที่ - ฉันถูกใช้2**...+.99|0เดิม แต่สั้นเพราะผมไม่ได้ต้องการ1<< |0ตอนนี้ฉันคิดว่าไม่มีความแตกต่าง ...
ETHproductions




1

เยลลี่ขนาด 14 ไบต์

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

ลองออนไลน์!

มันทำงานอย่างไร

⁸Ç¡         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 ไบต์

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]

ลองออนไลน์!

นี่คือการแก้ไขที่สำคัญของคำตอบของผู้ใช้2,02729 ฉันจะโพสต์การปรับปรุงนี้เป็นความคิดเห็น แต่คำตอบจะถูกลบและความคิดเห็นจึงถูกปิดใช้งาน


สิ่งนี้ล้มเหลวด้วยข้อยกเว้น "list index out of range" ในอินพุต 258 ฉันคิดว่าปัญหานั้นx**2เล็กเกินไป
isaacg

ดี ... Python 2 แตกต่างกัน (มักจะน้อยกว่าไบต์) จาก Python 3
user202729

1
ตามที่คาดไว้เลขชี้กำลังจำนวนครึ่งมีขนาดใหญ่กว่ากำลังสองกำลังสอง ว่า "ดัชนีรายชื่อออกจากช่วง" x=1000การแก้ปัญหาที่ได้รับ คุณอาจต้องการลอง2**x- ใหญ่มาก แต่ codegolf เป็น codegolf
user202729

@ user202729 อ้านี่เป็นเรื่องจริง น่าเสียดายที่ตอนนี้พบปัญหาที่แตกต่างอย่างสิ้นเชิงกับอินพุตที่ใหญ่ขึ้นซึ่ง2**xจะสร้างช่วงที่ใหญ่เกินไปสำหรับ Python ที่จะดำเนินการต่อ
notjagan

0

สวิฟท์ , 137 ไบต์

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

รับอินพุตเป็นInt(จำนวนเต็ม) และพิมพ์เป็น[Int](อาร์เรย์จำนวนเต็ม)

เวอร์ชันที่ไม่ดี

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

ฉันอยากรู้อยากเห็นจะเกิดอะไรขึ้นถ้าคุณลบพื้นที่ออกก่อน??
ETHproductions

@ETHproductions ที่นำไปสู่รวบรวมข้อผิดพลาดเนื่องจากจำนวนเต็มไม่สามารถเป็นตัวเลือกที่ถูกล่ามโซ่
เฮอร์แมน L
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.