ค้นหาจุดคงที่


24

ป.ร. ให้ไว้เป็นจำนวนเต็มและบางฟังก์ชั่นกล่องดำหาจุดคงที่ในลำดับที่กำหนดโดยx1 f: ℤ → ℤfxk+1 := f(xk)

รายละเอียด

  • ค่าxมีการกล่าวถึงเป็นจุดคงที่หากfx = f(x)

    ตัวอย่างเช่นถ้าf(x) := round(x/pi)เรามีจุดเริ่มต้นจากนั้นเราได้รับแล้วแล้วและในที่สุดซึ่งหมายความว่าการส่งควรกลับx1 = 10x2 = f(x1) = f(10) = 3x3 = f(x2) = f(3) = 1x4 = f(x3) = f(1) = 0x5 = f(x4) = f(0) = 00

  • คุณสามารถสมมติว่าลำดับที่สร้างขึ้นมีจุดคงที่จริง
  • คุณสามารถใช้ชนิดพื้นเมืองสำหรับจำนวนเต็มในสถานที่ของ
  • คุณสามารถใช้ภาษาใด ๆ ที่มีค่าเริ่มต้นสำหรับการป้อนข้อมูลฟังก์ชั่นสีดำกล่องในมาตรฐานการโพสต์เมตา IO หากไม่มีการตั้งค่าเริ่มต้นสำหรับภาษาของคุณอย่าลังเลที่จะเพิ่มเข้าไปในความหมายของฟังก์ชั่นกล่องดำและตรวจสอบให้แน่ใจว่าได้เชื่อมโยงข้อเสนอของคุณในคำนิยามนั้น อย่าลืมโหวตพวกเขาด้วย

ตัวอย่าง

f(x) = floor(sqrt(abs(x)))
0 -> 0,  all other numbers -> 1

f(x) = c(c(c(x))) where c(x) = x/2 if x is even; 3*x+1 otherwise
all positive numbers should result in 1,2 or 4 (Collatz conjecture)

f(x) = -42
all numbers -> -42

f(x) = 2 - x
1 -> 1

โปรดทราบว่าในขณะที่มันบอกเป็นนัยในรายละเอียดว่าฟังก์ชั่นกล่องดำจะมาบรรจบกันที่จุดคงที่ตัวอย่างสุดท้ายบอกเป็นอย่างอื่น
phflack

1
@phflack กล่องดำมีเพียงการรวมเข้าด้วยกันสำหรับอินพุตที่กำหนด
ข้อบกพร่อง

โอ้เดิมฉันคิดว่าการส่งมอบนั้นไม่ได้รับ x_0 ซึ่งทำให้ฉันสับสน ผมคิดว่าวิธีการแก้ปัญหาควรจะเป็น (Jelly) ~Nƭ⁻Ç$¿ซึ่งเป็นสิ่งที่ต้องการ for x in [0, -1, 1, -2, 2, -3, 3, -4, 4, ...]: if (x == f(x)): break; print(x); (รหัสเทียม) นั่นอาจคุ้มค่ากับการท้าทายอื่น
user202729

1
หมายเหตุสำหรับผู้เข้าชมในอนาคต: การค้นหาใด ๆจุดคงไม่ทำงานคุณจะต้องพบกับจุดคงเข้าถึงได้จาก x_0 รับประกันได้ว่ามีอยู่จริง
user202729

และถ้าไม่มีจุดคงที่, สำหรับฟังก์ชั่น f, และค่าเริ่มต้นหนึ่งค่า x0 ... สิ่งที่ควรคืนค่าคืออะไร? และถ้า x0 = 0 และ f = int (9 / (x-1)) สำหรับ x1 = x0 + 1 f (x1) = f (1) เป็นข้อผิดพลาดเดียว ... สิ่งที่ควรคืนค่าโอเปอเรเตอร์สำหรับ f นั้น x0?
RosLuP

คำตอบ:


16

ที่จริงแล้ว 1 ไบต์

Y

ลองออนไลน์!

Yเป็นฟังก์ชันจุดคงที่ในความเป็นจริง ในตัวอย่าง TIO ฟังก์ชันจะแสดงเป็นสตริงและ£ใช้เพื่อแปลงเป็นฟังก์ชันบนสแต็ก นอกจากนี้ยังเป็นไปได้ที่จะเพียงแค่กดฟังก์ชั่นในการสแต็คเช่นดังนั้น นี่เป็นเพียงสองวิธีในการรับฟังก์ชั่นอินพุตในที่จริง


7
คุณเพิ่งรู้ว่าบางวันความท้าทายนี้จะถูกโพสต์ใช่มั้ย : P
Erik the Outgolfer

2
@EriktheOutgolfer ฉันใช้Yกับความท้าทายหลายอย่างแล้ว เห็นได้ชัดว่าฉันprecognizant มาก : P
Mego

11

APL (Dyalog) 2 ไบต์

⍣=

ลองออนไลน์!

หมายเหตุ:ฉันกำหนดไว้O←⍣=ในส่วนอินพุตเนื่องจากข้อผิดพลาดในตัวดำเนินการ monadic ที่ได้รับไม่สามารถกำหนดได้ในวิธีที่ TIO ชอบกำหนดสิ่งต่าง ๆ

เป็นตัวดำเนินการที่สามารถใช้งานได้เช่น (function⍣condition) ⍵

มันนำไปใช้function, fไปจนถึง(f ⍵) condition ⍵ผลตอบแทนที่แท้จริง

⍣=เป็นตัวดำเนินการ monadic ที่รับค่าฟังก์ชัน monadic f, เป็นอาร์กิวเมนต์ซ้ายและใช้กับอาร์กิวเมนต์ขวา, จนกระทั่งf ⍵ = ⍵


อาจจะทราบว่า⍣=เป็นตัวดำเนินการ monadicที่ได้รับฟังก์ชั่นเป็นตัวถูกดำเนินการด้านซ้ายและค้นหาจุดแก้ไขบนค่าเริ่มต้นที่กำหนด ผมจะใช้ตัวอักษรที่แตกต่างกันสำหรับ⍣=กว่าfมันเป็นo perator ไม่ตื่นเต้น
อดัม

ใช่. ฉันจะ มันสับสนว่าคุณเรียกฟังก์ชั่น "อินพุต" fในคำอธิบายของคุณ แต่จากนั้นใน TIO fเป็นผู้ให้บริการโซลูชันของคุณ นอกจากนี้คุณยังสามารถเลื่อนO←⍣=ขึ้นในฟิลด์รหัสเพื่อให้นับและชี้ให้เห็นว่านั่นคือทางออกที่แท้จริงและที่เหลือ (อินพุต) เป็นเพียงการทดสอบ
อดัม

ดูเหมือนว่าเป็นข้อบกพร่องสำหรับฉัน พรุ่งนี้ฉันจะคุยกับเพื่อนร่วมงานที่เกี่ยวข้อง
อดัม

@ Adámอัปเดตแล้ว แจ้งให้เราทราบหากข้อผิดพลาดได้รับการแก้ไข
H.PWiz


9

MATLAB , 41 ไบต์

function x=g(f,x);while f(x)-x;x=f(x);end

นอกจากนี้ยังมีความงามนี้ที่ไม่ต้องการไฟล์ฟังก์ชั่น น่าเสียดายที่มันยาวกว่านี้เล็กน้อย:

i=@(p,c)c{2-p}();g=@(g,f,x)i(f(x)==x,{@()x,@()g(g,f,f(x))});q=@(f,x)g(g,f,x)

ลองออนไลน์!


7
คำตอบนี้มีไว้เพื่อเป็นตัวอย่างและไม่ได้ป้องกันไม่ให้ใครตอบ
ข้อบกพร่อง

แน่นอนถ้าคุณเรียกว่าคู่นี้คุณสามารถลบสอง;s ลองออนไลน์! .
Sanchises

และในฟังก์ชั่นนิรนามของคุณคุณสามารถลบ@()ก่อนหน้านี้ได้x50 ไบต์ ความรุ่งโรจน์เช่นกันสำหรับวิธีที่คุณห่อฟังก์ชั่นตัวช่วยของคุณ ( g(g)ในที่สุด) ฉันจัดการเพียง 51 ไบต์@(g,x)(f=@(r,z){@()r(r,m),z}{(m=g(z)==z)+1}())(f,x)เท่านั้น ฉันสงสัยว่ามีทั้งสองวิธีผสมกันหรือไม่
Sanchises

6

ML มาตรฐาน (MLton) 30 ไบต์

fun& $g=if$ =g$then$else&(g$)g

ลองออนไลน์! & n blackboxใช้เป็น

ฟังก์ชั่นกล่องดำถูกกำหนดดังนี้:

fun blackbox1 x = floor(Math.sqrt(Real.fromInt(abs x)))

fun blackbox2 x = c(c(c(x))) 
and c x = if x mod 2 = 0 then x div 2 else 3*x+1

fun blackbox3 _ = ~42

fun blackbox4 x = 2-x

เวอร์ชันที่ไม่ถูกปรับแต่ง:

fun fixpoint n g = if n = g n then n else fixpoint (g n) g

1
ดีใจที่ได้เห็น SML ในป่า! เราใช้สำหรับชั้นเรียนการเขียนโปรแกรมการทำงานของเราที่มหาวิทยาลัยของเรา
vijrox

6

R , 36 35 ไบต์

ขอบคุณ JayCe ที่ลงเล่นเป็นไบต์

function(f,x){while(x-(x=f(x)))0;x}

ลองออนไลน์!

ตรวจสอบฟังก์ชั่นตัวอย่าง!

R พอร์ตของการแก้ปัญหาของข้อบกพร่อง


สำหรับสิ่งที่คุ้มค่า ... function(f,x){while(x-(x=f(x)))0;x}ประหยัดได้หนึ่งไบต์
JayCe

โอ้0ว ขอบคุณมาก!
จูเซปเป้


4

Python 2 , 39 37 33 ไบต์

ขอบคุณ@ Mr.Xcoderสำหรับ -2 ไบต์

s=lambda k:s(f(k))if k-f(k)else k

ลองออนไลน์!

สมมติว่าฟังก์ชั่นกล่องดำเป็นชื่อ f


ไม่จำเป็นต้องส่งผ่านฟังก์ชันเป็นพารามิเตอร์หรือไม่ ฉันไม่คิดว่าตัวแปรที่กำหนดไว้ล่วงหน้าเป็นวิธีป้อนข้อมูลที่ยอมรับได้
mbomb007

ฉันไม่แน่ใจว่าคุณได้รับอนุญาตให้สมมติว่าฟังก์ชั่นfนั้นเป็นรูปแบบของการสมมติว่าอินพุตเป็นตัวแปรหรือไม่? (แก้ไข: ninja'd โดย mbomb)
FlipTack

@ mbomb007 มีความเห็น
ovs

4

JavaScript (Node.js) , 25 22 21 ไบต์

ขอบคุณHerman Lauenstein ที่แสดงฉันทามตินี้
ด้วย@ l4m2สำหรับ -1 ไบต์

fถือว่าการทำงานของกล่องดำที่จะตั้งชื่อ

g=k=>f(k)-k?g(f(k)):k

ลองออนไลน์!



f (k) -k แทน
l4m2

4

เยลลี่ 3 ไบต์

vÐL

ลองออนไลน์!

รับอาร์กิวเมนต์ด้านซ้ายเป็นสตริงที่แสดงถึงลิงค์ของเยลลี่ ( 2_ตัวอย่าง) และอาร์กิวเมนต์ที่ถูกต้องเป็นจำนวนเต็ม

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

 ÐL - While the output is unique...
v   -   Evaluate the function with the argument given

4

Brain-Flakขนาด 24 ไบต์

(()){{}(({})<>[({})])}{}

ลองออนไลน์!

(สำหรับฟังก์ชั่นกล่องดำx -> 2-xในตัวอย่างด้านล่าง)

ฟังก์ชั่นกล่องดำที่จัดให้ควรเป็นโปรแกรมที่กำหนดxไว้ที่ด้านบนของสแต็กป๊อปxและพุชf(x)- ในคำอื่น ๆ ก็ควรประเมินฟังก์ชั่นfค่าที่ด้านบนของสแต็ค

Mini-Flak ที่เทียบเท่ากันคือ 26 ไบต์ (ขอบคุณ Wheat Wizard สำหรับการบันทึก 2 ไบต์):

(()){{}(({})( )[{}({})])}{}
             ^ put the function f here

(ไม่นับความคิดเห็นและช่องว่าง)

ใช้ฟังก์ชั่น (ภายใน<>) และตัวเลขจากอินพุต (โปรดทราบว่า Brain-Flak เป็นภาษาลึกลับและไม่สามารถโต้แย้งการทำงานเป็นอินพุตได้)x0


ตัวอย่างฟังก์ชั่น blackbox:

x -> 2-x: ลองออนไลน์!


คำอธิบาย:


(()){{}(({})<f>[({})])}{}   Main program.
                            Implicit input from stdin to stack.
(  )                        Push
 ()                         literal number 1.
                            Now the content of the stack: [1, x0]
    {                 }     While stack top ≠ 0:
                            current stack content: [something ≠ 0, x]
     {}                       Pop stack top (something). stack = [x]
       (             )        Push
        ({})                    Stack top = x. Current stack = [x]
             f                  Evaluate f. Current stack = [f(x)]
            < >                   (suppress the value of f(x), avoid adding it)
               [    ]           plus the negative of
                ({})            the top of the stack ( = -f(x) )
                              In conclusion, this change (x) on the stack to
                              (f(x)), and then push (x + -f(x))
                            If it's 0, break loop, else continue.
                       {}   Pop the redundant 0 on the top.
                            Implicit output stack value to stdout.


3

Swift , 47 42 ไบต์

func h(_ n:Int){f(n)==n ?print(n):h(f(n))}

ไร้เดียงสาสันนิษฐานว่าชื่อฟังก์ชั่นกล่องดำ f


{...}as(<parameter types>)-><return type>ผมมีข้อสงสัยเกี่ยวกับการพยายามครั้งที่สองของคุณเพราะมันเป็นปิดที่ซับซ้อนและประเภทของมันคือไม่ชัดเจนจนกว่าคุณจะโยนมันอย่างชัดเจน หากคุณไม่ระบุประเภทการคืนสินค้ามันจะโยนข้อผิดพลาดในการบิลด์ดังนั้นฉันไม่คิดว่ามันจะใช้ได้ในขณะนี้ (โปรดทราบว่าการส่งจะต้องรวมอยู่ในการนับไบต์) แม้ว่าการส่งครั้งแรกของคุณจะไม่เป็นไร
นาย Xcoder

2

C (gcc) , 40 ไบต์

f(n,b)int(*b)(_);{n=n^b(n)?f(b(n),b):n;}

ลองออนไลน์! โปรดทราบว่าไม่จำเป็นต้องใช้ค่าสถานะซึ่งมีไว้เพื่อช่วยในการทดสอบฟังก์ชัน fixpoint ที่กำหนดไว้ด้านบน

นี้เป็นฟังก์ชั่นที่ใช้เป็น int และตัวชี้ฟังก์ชั่นn b : int → intเหยียดหยามความจริงที่ว่าเขียนถึงอาร์กิวเมนต์ตัวแปรชุดแรกeaxลงทะเบียนซึ่งเทียบเท่ากับการกลับมา† มิฉะนั้นนี่เป็นมาตรฐานที่สวยเท่าสนามกอล์ฟ C n^b(n)การตรวจสอบความไม่เท่าเทียมกันของและกล่องสีดำนำไปใช้กับn nเมื่อไม่เท่ากันจะเรียกใช้ฟังก์ชัน fixpointfอีกครั้งซ้ำโดยใช้แอปพลิเคชันและกล่องดำเป็นอาร์กิวเมนต์ มิฉะนั้นจะส่งคืน fixpoint

†จำเป็นต้องมีการอ้างอิงฉันจำได้ว่าอ่านบางแห่งและ Google ดูเหมือนจะยืนยันข้อสงสัยของฉัน

มันประกาศอินพุตด้วยการพิมพ์พารามิเตอร์สไตล์ K & R:

f(n, b)
int(*b)(_);
{
    n=n^b(n)?f(b(n),b):n;
}

บิต arcane บนบรรทัดที่สองด้านบนประกาศว่าbเป็นตัวชี้ฟังก์ชันที่ใช้พารามิเตอร์จำนวนเต็ม - ชนิดเริ่มต้นของการ_สันนิษฐานว่าเป็นจำนวนเต็ม ในทำนองเดียวกันnจะถือว่าเป็นจำนวนเต็มและfจะถือว่ากลับเป็นจำนวนเต็ม ไชโยสำหรับการพิมพ์โดยนัย?


2

ทำความสะอาด , 46 ไบต์

import StdEnv
p x=hd[n\\n<-iterate f x|f n==n]

สมมติว่าฟังก์ชั่นถูกกำหนดให้เป็น f :: !Int -> Int

มันเป็นหัวหน้าของรายการที่ไม่มีที่สิ้นสุดของการใช้งานของตัวf f f ... xกรองสำหรับองค์ประกอบเหล่านั้นf el == elกรองสำหรับองค์ประกอบเหล่านั้นที่

ลองออนไลน์!

หากคุณต้องการเปลี่ยนฟังก์ชั่นใน TIO ไวยากรณ์แลมบ์ดาของ Clean คือ:

\argument = expression

(อันที่จริงมันมีความซับซ้อนมากขึ้น แต่โชคดีที่เราต้องใช้ฟังก์ชันยูนารี)


2

APL (Dyalog Unicode)ขนาด 14 ไบต์

{⍵=⍺⍺⍵:⍵⋄∇⍺⍺⍵}

ลองออนไลน์!

ฟังก์ชั่นที่ส่วนหัวเทียบเท่ากับ f(x) = floor(sqrt(abs(x)))

ขอบคุณ @ Adámที่ชี้ให้เห็นว่าคำตอบเดิมไม่ถูกต้องตามฉันทามติ PPCG

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

{⍵=⍺⍺⍵:⍵⋄∇⍺⍺⍵}  Main 'function' (this is actually an operator)
      :          if
 ⍵=⍺⍺⍵           the right argument (⍵) = the left function (⍺⍺, which is f) of 
                return 
                else
         ∇⍺⍺⍵    return this function (∇) with argument f(⍵)

{⍵ = f⍵: ⍵⋄∇ (f⍵)} จะโอเคสำหรับฟังก์ชั่นนิรนามที่แยกออกจากชื่อ (n)
RosLuP

2
สิ่งนี้ถือว่าfเป็นสิ่งที่กำหนดไว้ล่วงหน้าซึ่งฉันคิดว่าเป็นสิ่งต้องห้ามโดยฉันทามติ PPCG {⍵=⍺⍺⍵:⍵⋄∇⍺⍺⍵}จะเป็นวิธีการแก้ปัญหาผู้ประกอบการที่ถูกต้อง
อดัม

1

อ็อกเทฟ 37 ไบต์

function x=g(f,x);while x-(x=f(x))end

ลองออนไลน์!

อ็อกเทฟมีการกำหนดแบบอินไลน์ แต่ MATLAB ไม่ได้ดังนั้นนี่จึงเป็นวิธีแก้ปัญหาข้อบกพร่องของ Octave พอร์ตข้อ

นอกจากนี้ยังมีพอร์ตไว้อย่างสวยงามเพื่อ R



1

Forth (gforth), 36 ไบต์

รุ่นนี้เพิ่งถือว่าfมีการกำหนดไว้ล่วงหน้า มันไม่เจ๋งเหมือนคำตอบด้านล่าง ทั้งสองโปรแกรมจะออกพร้อมกับสแต็คโอเวอร์โฟลว์หากไม่พบหรือสแต็กอันเดอร์โฟล์ลหากพบ

ลองออนไลน์

: g dup f over = IF . THEN recurse ;

Forth (gforth), 52 ไบต์

สิ่งนี้ทำให้โทเค็นการทำงานของฟังก์ชันถูกส่งผ่านเป็นพารามิเตอร์และเป็นวิธีแก้ปัญหาที่เย็นกว่าแน่นอน

: g 2dup execute rot over = IF . THEN swap recurse ;

ลองออนไลน์

คำอธิบาย:

: g             \ x1 f          Define g. Params on the stack. f is on top
2dup execute    \ x1 f x2       duplicate both params, execute f(x1)
rot over        \ f x2 x1 x2    move x1 to top and copy x2 to top
= IF . THEN                     compare, if equal, print
swap recurse ;                  otherwise, recurse


1

tiffanyisp repl, 28 ไบต์

(d P(q((x)(i(e(f x)x)x(P(f x

สมมติว่าฟังก์ชันfมีการกำหนดไว้ล่วงหน้า

ลองออนไลน์! (ฟังก์ชันตัวอย่างคือf(x) = (x*2) mod 10)

Ungolfed

(load library)
(def P
 (lambda (x)
  (if (equal? (f x) x)
   x
   (P (f x)))))

ถ้าf(x)เท่ากับxนั้นxเป็นจุดคงที่; กลับมา มิฉะนั้นซ้ำมองหาจุดคงที่เริ่มต้นจากการแทนf(x)x


1

APL NARS 65 ตัวอักษร

r←(f v)n;c
   c←0⋄→B
E: r←∞⋄→0
A: n←r
B: r←f n⋄c+←1⋄→E×⍳c>1e3⋄→A×⍳r≠n

ตัวดำเนินการ v จะส่งคืน∞ (หรืออาจเป็น -oo หรือน่าน) สำหรับข้อผิดพลาดอีกหนึ่งค่า x กับ x = f (x) ในการทดสอบ f = floor (sqrt (abs (x))), f1 = 2-x, f2 = c (c (c (x))) ด้วย c = x% 2 == 0? x / 2: 3 * x +1

  f←⌊∘√∘|
  f v 0
0
  f v 9
1
  f1←{2-⍵}
  f1 v 1
1
  f1 v ¯10
∞
  f1 v 2
∞
  c1←{0=2∣⍵:⍵÷2⋄1+3×⍵}
  f2←c1∘c1∘c1
  f2 v 1
1
  f2 v 2
2
  f2 v 7
2
  f2 v 82
4

1

Clojure, 45 43 ไบต์

นี่มันสั้นที่สุดและน่าเกลียดที่สุด:

#(loop[a + b %2](if(= a b)a(recur b(% b))))

+x0มีแทนหมายเลขเพื่อที่จะไม่เท่ากับค่าใด ๆ

55 ไบต์และใช้งานได้:

#(reduce(fn[a b](if(= a b)(reduced a)b))(iterate % %2))

ตัวอย่าง:

(def f #(...))
(defn collaz [x] (if (even? x) (-> x (/ 2)) (-> x (* 3) (+ 1))))
(f (->> collaz (repeat 3) (apply comp)) 125)
; 1

1

x86 opcode 8 ไบต์

fun:
        call    edx          ; 2B
        cmpxchg eax,    ecx  ; 3B, on 8086 use xchg and cmp instead
        jnz     fun          ; 2B
        ret                  ; 1B

รับอินพุต: ecx (ค่า), (ที่อยู่ฟังก์ชันรับอินพุตจากเขียนผลลัพธ์ไปยังโดยไม่แก้ไขค่าของและ)x0edxecxeaxecxedx

opcode 8086, 7 ไบต์ (แต่ช้า)

    xor     cx,     cx
    call    dx
    loop    $-2
    ret

หากมีจุดคงที่การวนซ้ำ 65536 ครั้งจะขับตรงนั้นเสมอ
รับอินพุต: ax(ค่าเริ่มต้น), (ที่อยู่ฟังก์ชันรับอินพุตเขียนเอาต์พุตไปโดยไม่แก้ไขค่าของและ)x0dxaxaxcxdx
axเอาท์พุทจุดคงที่ในการลงทะเบียน


มันจะช่วยได้อย่างแน่นอนหากคุณทำให้คำตอบอ่านง่ายขึ้น
user202729

แก้ไขเพิ่มเติมเพื่อให้ถูกต้อง
l4m2


0

Java 8, 42 ไบต์

นี้จะใช้เวลาFunction<Integer, Integer>หรือIntFunction<Integer>และintหรือInteger(แกงกะหรี่) และผลตอบแทนที่จุดคงที่

f->i->{while(i!=(i=f.apply(i)));return i;}

ลองใช้ออนไลน์

ใช้ประโยชน์จากความจริงที่ว่า Java ประเมิน subexpressions จากซ้ายไปขวา (ดังนั้นเก่าiเทียบกับใหม่) ซึ่งเป็นคุณสมบัติที่ฉันไม่ทราบว่าในขณะที่เขียนนี้!

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