Find a Fixed Point

24

Given an integer x1 and some black box function f: ℤ → ℤ find a fixed point of f in the sequence defined by xk+1 := f(xk).

Details

  • A value x is said to be a fixed point of f if x = f(x).

    For instance if f(x) := round(x/pi)and we have a starting point x1 = 10 then we get x2 = f(x1) = f(10) = 3, then x3 = f(x2) = f(3) = 1, then x4 = f(x3) = f(1) = 0, and finally x5 = f(x4) = f(0) = 0 which means the submission should return 0.

  • You can assume that the generated sequence actually contains a fixed point.
  • You can use the native type for integers in place of .
  • You can use any language for which there are defaults for black box functions input in the standard IO meta post. If there are no such default for your language feel free to add one in the sense of the definition of black box functions, and make sure to link your proposals in that definition. Also don't forget to vote on them.

Examples

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

flawr

Posted 2017-12-08T18:37:50.213

Reputation: 40 560

Note that while it's implied in the details that the black box function will converge on the fixed point, the last example says otherwise – phflack – 2017-12-08T20:03:59.167

1@phflack The blackbox only has to converge for the given input. – flawr – 2017-12-08T20:09:21.010

Oh, originally I thought that the submission is not given x_0, which caused me some confusion. I thought a solution should be (Jelly) ~Nƭ⁻Ç$¿, which is something like, (pseudo code) for x in [0, -1, 1, -2, 2, -3, 3, -4, 4, ...]: if (x == f(x)): break; print(x);. That may worth another challenge. – user202729 – 2017-12-09T04:44:55.793

1Note for future visitors: Finding any fixed point doesn't work, you must find a fixed point reachable from x_0. It's guaranteed that there exists one. – user202729 – 2017-12-09T04:46:13.690

And if not exist a fixed point, for a function f, and one initial value x0... What should be the value it have to return? And if x0=0 and f=int(9/(x-1)) with for x1=x0+1 f(x1)=f(1) is already one error... What should return the operator for that f , x0? – RosLuP – 2017-12-11T08:33:52.957

@RosLuP Your program just has to work if there is such a fixed point (see second bullet point in the details) – flawr – 2017-12-11T10:36:08.097

What if the program just repeatedly apply <the number of values in the native integer data type> times the function f on x_0? Is that abuse of native integer data type? – user202729 – 2017-12-14T07:05:56.610

Yes, you can assume that the numbers required to compute the sequence are all in a reasonable range. – flawr – 2017-12-14T11:15:17.183

Answers

16

Actually, 1 byte

Y

Try it online!

Y is the fixed point function in Actually. In the TIO example, the function is shown being taken as a string, and £ is used to transform it to a function on the stack. It's also possible to just push the function to the stack like so. These are the only two ways to get a function input in Actually.

Mego

Posted 2017-12-08T18:37:50.213

Reputation: 32 998

7You just knew that some day this challenge was going to be posted, didn't you? :P – Erik the Outgolfer – 2017-12-08T20:01:21.517

2

@EriktheOutgolfer I've actually used Y for several challenges. I'm apparently extremely precognizant :P

– Mego – 2017-12-08T20:08:54.177

11

APL (Dyalog), 2 bytes

⍣=

Try it online!

NB: I define O←⍣= in the the input section due to a bug in that derived monadic operators can't be defined in the way that TIO likes to define things.

Is an operator that can be used like (function⍣condition) ⍵

It applies the function, f, to until (f ⍵) condition ⍵ returns true.

⍣= is a derived monadic operator that takes a monadic function, f, as its left argument and applies it to its right argument, , until f ⍵ = ⍵

H.PWiz

Posted 2017-12-08T18:37:50.213

Reputation: 10 962

Maybe note that ⍣= is a derived monadic operator which takes a function as left operand and finds the fix point on the given initial value. I would use a different letter for ⍣= than f as it is an operator, not a function. – Adám – 2017-12-10T21:13:28.390

Yeah. I would. It is confusing that you call the "input" function f in your description, but then on TIO, f is your solution operator. You can also move the O←⍣= up in the Code field to let it be counted and to point out that that is the actual solution, and that the rest (Input) is just testing it. – Adám – 2017-12-10T21:20:07.630

Looks like a bug to me. I'll speak with relevant colleague tomorrow. – Adám – 2017-12-10T21:56:16.677

@Adám Updated. Let me know if the bug gets fixed – H.PWiz – 2017-12-12T18:35:49.040

10

Haskell, 17 bytes

until=<<((==)=<<)

Try it online!

nimi

Posted 2017-12-08T18:37:50.213

Reputation: 34 639

3

In case someone is interested: here is an explanation why until=<<((==)=<<) finds a fix point of a given function.

– Laikoni – 2017-12-09T10:12:42.237

9

MATLAB, 41 bytes

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

There is also this beauty that does not need function files. Unfortunately it is a little bit longer:

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)

Try it online!

flawr

Posted 2017-12-08T18:37:50.213

Reputation: 40 560

7This answer was meant as an example and does not prevent anyone from answering. – flawr – 2017-12-08T21:04:26.937

Of course, if you called this Octave, you could remove two ;s. Try it online!.

– Sanchises – 2017-12-14T08:37:44.307

And in your anonymous function, you can remove the @() before x for 50 bytes. Kudos too for the way you wrap your helper function (with the g(g) in the end), I only managed to do 51 bytes @(g,x)(f=@(r,z){@()r(r,m),z}{(m=g(z)==z)+1}())(f,x). I'm wondering if there's any combination of both approaches that's shorter still. – Sanchises – 2017-12-14T08:55:34.517

6

R, 36 35 bytes

thanks to JayCe for golfing down a byte

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

Try it online!

Verify the example functions!

R port of flawr's solution.

Giuseppe

Posted 2017-12-08T18:37:50.213

Reputation: 21 077

For what it's worth... function(f,x){while(x-(x=f(x)))0;x} saves one byte. – JayCe – 2018-07-12T16:55:13.790

Oh, 0, nice. Thanks much! – Giuseppe – 2018-07-12T19:07:26.543

6

Standard ML (MLton), 30 bytes

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

Try it online! Use as & n blackbox.

The black box functions are defined as following:

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

Ungolfed version:

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

Laikoni

Posted 2017-12-08T18:37:50.213

Reputation: 23 676

1Good to see SML in the wild! We use it for our functional programming class at our university. – vijrox – 2017-12-10T20:29:44.547

5

Mathematica, 11 bytes

#2//.x_:>#&

Try it online!

Mathematica, 10 bytes

FixedPoint

Try it online!

J42161217

Posted 2017-12-08T18:37:50.213

Reputation: 15 931

4

Python 2, 39 37 33 bytes

thanks to @Mr.Xcoder for -2 bytes

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

Try it online!

assumes the black-box function to be named f

ovs

Posted 2017-12-08T18:37:50.213

Reputation: 21 408

Doesn't the function need to be passed as a parameter? I don't think pre-defined variables is an accepted input method. – mbomb007 – 2017-12-08T22:37:51.090

I'm not sure you're allowed to assume the function is f, isn't that a form of assuming input is in a variable? (edit: ninja'd by mbomb) – FlipTack – 2017-12-08T22:37:57.607

@mbomb007 There is a consensus which allows it for black-box functions

– ovs – 2017-12-08T22:41:07.313

4

Jelly, 3 bytes

vÐL

Try it online!

Takes the left argument as a string representing a Jelly link (2_ for instance), and the right argument as an integer

How it works

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

caird coinheringaahing

Posted 2017-12-08T18:37:50.213

Reputation: 13 702

4

JavaScript (Node.js), 25 22 21 bytes

thanks Herman Lauenstein for showing me this consensus
thanks to @l4m2 for -1 byte

Assumes the black-box function to be named f.

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

Try it online!

ovs

Posted 2017-12-08T18:37:50.213

Reputation: 21 408

This can be shortened if black-box functions to be taken as input can be assumed to be predefined under a given name

– Herman L – 2017-12-08T19:47:36.507

f(k)-k instead of – l4m2 – 2017-12-09T16:36:40.053

4

Brain-Flak, 24 bytes

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

Try it online!

(for the black box function x -> 2-x in the example below)

The provided black box function should be a program, that given x on the top of the stack, pop x and push f(x) - in other word, it should evaluate the function f on the value on the top of the stack.

Equivalent Mini-Flak is 26 bytes (thanks to Wheat Wizard for saving 2 bytes):

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

(not counting the comments and spaces)

Take the function (inside the <>) and a number x0 from input. (note that Brain-Flak is an esoteric language and can't take functional argument as input)


Example blackbox functions:

x -> 2-x: Try it online!


Explanation:


(()){{}(({})<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.

user202729

Posted 2017-12-08T18:37:50.213

Reputation: 14 620

3

Swift, 47 42 bytes

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

Naive approach, assumes that the black box function is named f

Herman L

Posted 2017-12-08T18:37:50.213

Reputation: 3 611

I am in doubt regarding your second attempt, because it is a complex closure and its type is ambiguous unless you explicitly cast it to {...}as(<parameter types>)-><return type>. If you don't specify its return type, it will throw build-time errors so I don't think it is valid as of now (note that the cast must be included in the byte count). Your first submission is fine, though. – Mr. Xcoder – 2017-12-08T19:55:40.900

2

APL (Dyalog Unicode), 14 bytes

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

Try it online!

The function at the header is equivalent to f(x) = floor(sqrt(abs(x)))

Thanks @Adám for pointing out that the original answer wasn't valid according to PPCG consensus.

How it works:

{⍵=⍺⍺⍵:⍵⋄∇⍺⍺⍵} ⍝ 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(⍵)

J. Sallé

Posted 2017-12-08T18:37:50.213

Reputation: 3 233

{⍵=f⍵:⍵⋄∇(f⍵)} would be ok for separate anonymous function from its name (n) – RosLuP – 2017-12-09T10:22:50.260

2This assumes that f is preassigned, which I think is prohibited by PPCG consensus. {⍵=⍺⍺⍵:⍵⋄∇⍺⍺⍵} would be a valid operator solution. – Adám – 2017-12-10T21:18:00.440

2

C (gcc), 40 bytes

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

Try it online! Note that the flags are not necessary, they are there to aid with testing the fixpoint function defined above.

This is a function that takes an int n and a function pointer b : int → int. Abusing the fact that writing to the first variable argument sets the eax register, which is equivalent to returning. Otherwise, this is pretty standard as far as C golf goes. n^b(n) checks for the inequality of n and the black box applied to n. When unequal, it calls the fixpoint function f again recursively with the application and black box as arguments. Otherwise, it returns the fixpoint.

†Citation needed, I vaguely remember reading this somewhere and google seems to confirm my suspicions

It declares input with K&R-style parameter typing:

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

The arcane bit on the second line above declares b to be a function pointer that takes an integer parameter—the default type of _ is assumed to be an integer. Similarly, n is assumed to be an integer, and f is assumed to return an integer. Hooray for implicit typing?

Conor O'Brien

Posted 2017-12-08T18:37:50.213

Reputation: 36 228

2

Clean, 46 bytes

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

Assumes the function is defined as f :: !Int -> Int

It takes the head of the infinite list of applications of f f f ... x filtered for those elements where f el == el.

Try it online!

If you want to change the function in the TIO, Clean's lambda syntax is:

\argument = expression

(actually it's far more complicated, but thankfully we only need unary functions)

Οurous

Posted 2017-12-08T18:37:50.213

Reputation: 7 916

1

Octave, 37 bytes

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

Try it online!

Octave has inline assignment but MATLAB doesn't, so this is a golfier Octave port of flawr's solution.

It also ports nicely to R.

Giuseppe

Posted 2017-12-08T18:37:50.213

Reputation: 21 077

1

Kotlin, 50 bytes

{f,k->var a=k;var b=a+1;while(b!=a){b=a;a=f(a)};a}

Try it online!

ovs

Posted 2017-12-08T18:37:50.213

Reputation: 21 408

1

Forth (gforth), 36 bytes

This version just assumes f is predefined. It's not as cool as the solution below it. Both programs exit with a stack overflow if not found, or a stack underflow if found (after printing the result).

Try it online

: g dup f over = IF . THEN recurse ;

Forth (gforth), 52 bytes

This allows a function's execution token to be passed as a parameter, and is definitely the cooler solution.

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

Try it online

Explanation:

: 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

mbomb007

Posted 2017-12-08T18:37:50.213

Reputation: 21 944

1

Ruby, 31 28 bytes

->x,f{x=f[x]until x==f[x];x}

Try it online!

Reinstate Monica -- notmaynard

Posted 2017-12-08T18:37:50.213

Reputation: 1 053

25 bytes - ->x,f{1while x!=x=f[x];x} – G B – 2017-12-14T07:39:11.423

1

Clojure, 45 43 bytes

Well, this is the shortest and ugliest:

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

+ is there instead of a number so that it is not equal to any value of x0.

55 bytes and functional:

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

Example:

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

NikoNyrh

Posted 2017-12-08T18:37:50.213

Reputation: 2 361

1

tinylisp repl, 28 bytes

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

Assumes that the function f is predefined.

Try it online! (The example function is f(x) = (x*2) mod 10.)

Ungolfed

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

If f(x) equals x, then x is a fixed point; return it. Otherwise, recursively look for a fixed point starting from f(x) instead of x.

DLosc

Posted 2017-12-08T18:37:50.213

Reputation: 21 213

1

APL NARS 65 chars

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 operator would return ∞ (or possibly -oo or Nan) for error, else one value x with x=f(x). In test f=floor(sqrt(abs(x))), f1=2-x, f2=c(c(c(x))) with 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

RosLuP

Posted 2017-12-08T18:37:50.213

Reputation: 3 036

1

x86 opcode, 8 bytes

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

Take input: ecx (value x0), edx (function address, take input from ecx, write result to eax without modifying the value of ecx and edx)

8086 opcode, 7 bytes (but slow)

    xor     cx,     cx
    call    dx
    loop    $-2
    ret

If there exists a fixed point, looping 65536 times always drive it there.
Take input: ax (initial value x0), dx (function address, take input from ax, write output to ax without modifying the value of cx and dx).
Output the fixed point in register ax.

l4m2

Posted 2017-12-08T18:37:50.213

Reputation: 5 985

It would certainly help if you make the answer more readable. – user202729 – 2017-12-14T07:04:07.500

more edit to make it correct – l4m2 – 2017-12-14T07:33:06.927

0

Perl 5, 18 + 1 (-p)

$_=f$_ while$_^f$_

try it online

Nahuel Fouilleul

Posted 2017-12-08T18:37:50.213

Reputation: 5 582

0

Java 8, 42 bytes

This takes a Function<Integer, Integer> or IntFunction<Integer> and an int or Integer (curried) and returns the fixed point.

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

Try It Online

Takes advantage of the fact that Java evaluates subexpressions from left to right (so the old i is compared to the new), a property which I was unaware of while writing this!

Jakob

Posted 2017-12-08T18:37:50.213

Reputation: 2 428