Trova un punto fisso


24

Dato un numero intero e alcune funzioni della scatola nera trovano un punto fisso nella sequenza definita da .x1 f: ℤ → ℤfxk+1 := f(xk)

Dettagli

  • Si xdice che un valore sia un punto fisso di fif x = f(x).

    Ad esempio se f(x) := round(x/pi)e abbiamo un punto di partenza, allora otteniamo , quindi , quindi , e infine il che significa che la presentazione dovrebbe tornare .x1 = 10x2 = f(x1) = f(10) = 3x3 = f(x2) = f(3) = 1x4 = f(x3) = f(1) = 0x5 = f(x4) = f(0) = 00

  • Si può presumere che la sequenza generata contenga effettivamente un punto fisso.
  • È possibile utilizzare il tipo nativo per numeri interi al posto di .
  • È possibile utilizzare qualsiasi lingua per cui sono presenti valori predefiniti per le funzioni della scatola nera immesse nel meta post IO standard . Se non esiste un valore predefinito per la tua lingua, sentiti libero di aggiungerne uno nel senso della definizione delle funzioni della scatola nera e assicurati di collegare le tue proposte in quella definizione. Inoltre, non dimenticare di votare su di loro.

Esempi

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

Si noti che mentre è implicito nei dettagli che la funzione della scatola nera converge sul punto fisso, l'ultimo esempio dice il contrario
phflack

1
@phflack La blackbox deve convergere solo per l'input dato.
Flawr

Oh, inizialmente pensavo che alla presentazione non venisse dato x_0, il che mi ha causato confusione. Ho pensato che una soluzione dovrebbe essere (Jelly) ~Nƭ⁻Ç$¿, che è qualcosa di simile (pseudo codice) for x in [0, -1, 1, -2, 2, -3, 3, -4, 4, ...]: if (x == f(x)): break; print(x); . Potrebbe valere un'altra sfida.
user202729

1
Nota per i futuri visitatori: la ricerca di un punto fisso non funziona, è necessario trovare un punto fisso raggiungibile da x_0. È garantito che ne esiste uno.
user202729

E se non esiste un punto fisso, per una funzione f, e un valore iniziale x0 ... Quale dovrebbe essere il valore che deve restituire? E se x0 = 0 e f = int (9 / (x-1)) con for x1 = x0 + 1 f (x1) = f (1) è già un errore ... Cosa dovrebbe restituire l'operatore per quella f, x0?
RosLuP l'

Risposte:


16

In realtà , 1 byte

Y

Provalo online!

Yè la funzione punto fisso in In realtà. Nell'esempio TIO, la funzione viene mostrata come una stringa e £viene utilizzata per trasformarla in una funzione nello stack. È anche possibile semplicemente spingere la funzione nello stack in questo modo . Questi sono gli unici due modi per ottenere un input di funzione in Realmente.


7
Sapevi solo che un giorno questa sfida sarebbe stata pubblicata, vero? : P
Erik the Outgolfer,

2
@EriktheOutgolfer Ho effettivamente usato Yper diverse sfide. Apparentemente sono estremamente precognitivo : P
Mego

11

APL (Dyalog) , 2 byte

⍣=

Provalo online!

NB: Definisco O←⍣=nella sezione input a causa di un bug che gli operatori monadici derivati ​​non possono essere definiti nel modo in cui a TIO piace definire le cose.

È un operatore che può essere usato come (function⍣condition) ⍵

Si applica la function, fper fino (f ⍵) condition ⍵restituisce true.

⍣=è un operatore monadico derivato che assume una funzione monadica f, come argomento di sinistra e la applica all'argomento di destra , fino a quandof ⍵ = ⍵


Forse si noti che ⍣=è un operatore monadico derivato che assume una funzione come operando di sinistra e trova il punto fisso sul valore iniziale dato. Voglio utilizzare una lettera diversa ⍣=rispetto fquanto è un o perator, non una f unzione.
Adám,

Si. Vorrei. È confuso che tu chiami la funzione "input" fnella tua descrizione, ma poi su TIO fè l'operatore della tua soluzione. Puoi anche spostare in O←⍣=alto nel campo Codice per consentirne il conteggio e sottolineare che questa è la soluzione effettiva e che il resto (Input) lo sta solo testando.
Adám,

A me sembra un bug. Domani parlerò con un collega competente.
Adám,

@ Adám Aggiornato. Fammi sapere se il bug viene corretto
H.Piz,


9

MATLAB , 41 byte

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

C'è anche questa bellezza che non ha bisogno di file di funzioni. Purtroppo è un po 'più lungo:

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)

Provalo online!


7
Questa risposta era intesa come esempio e non impedisce a nessuno di rispondere.
flawr

Naturalmente, se hai chiamato Octave, potresti rimuovere due ;secondi. Provalo online! .
Sanchises,

E nella tua funzione anonima, puoi rimuovere il @()precedente xper 50 byte. Complimenti anche per il modo in cui avvolgi la tua funzione di supporto (con il g(g)alla fine), sono riuscito a fare solo 51 byte @(g,x)(f=@(r,z){@()r(r,m),z}{(m=g(z)==z)+1}())(f,x). Mi chiedo se c'è qualche combinazione di entrambi gli approcci che sia ancora più breve.
Sanchises,

6

ML standard (MLton) , 30 byte

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

Provalo online! Usa come & n blackbox.

Le funzioni della scatola nera sono definite come segue:

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

Versione non golfata:

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

1
Bello vedere SML allo stato brado! Lo usiamo per il nostro corso di programmazione funzionale nella nostra università.
Vijrox,



4

Python 2 , 39 37 33 byte

grazie a @ Mr.Xcoder per -2 byte

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

Provalo online!

presuppone che la funzione scatola nera sia denominata f


La funzione non deve essere passata come parametro? Non credo che le variabili predefinite siano un metodo di input accettato.
mbomb007,

Non sono sicuro che tu abbia il permesso di supporre che la funzione sia f, non è che una forma di assunzione dell'input sia in una variabile? (modifica: ninja'd di mbomb)
FlipTack



4

Gelatina , 3 byte

vÐL

Provalo online!

Accetta l'argomento sinistro come stringa che rappresenta un collegamento Jelly ( 2_ad esempio) e l'argomento destro come intero

Come funziona

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

4

Brain-Flak , 24 byte

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

Provalo online!

(per la funzione scatola nera x -> 2-xnell'esempio seguente)

La funzione di black box fornita dovrebbe essere un programma, quello dato xin cima allo stack, pop xe push f(x)- in altre parole, dovrebbe valutare la funzione fsul valore in cima allo stack.

Mini-Flak equivalente è di 26 byte (grazie a Wheat Wizard per il salvataggio di 2 byte):

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

(senza contare i commenti e gli spazi)

Prendi la funzione (all'interno del <>) e un numero dall'input. (nota che Brain-Flak è un linguaggio esoterico e non può accettare argomenti funzionali come input)x0


Funzioni blackbox di esempio:

x -> 2-x: Provalo online!


Spiegazione:


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

Rapido , 47 42 byte

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

Approccio ingenuo, presuppone che la funzione scatola nera sia denominata f


Sono in dubbio riguardo al tuo secondo tentativo, perché è una chiusura complessa e il suo tipo è ambiguo a meno che tu non lo espressi esplicitamente {...}as(<parameter types>)-><return type>. Se non specifichi il suo tipo restituito, genererà errori di build-time, quindi non credo che sia valido al momento (nota che il cast deve essere incluso nel conteggio dei byte). Il tuo primo invio va bene, però.
Mr. Xcoder,

2

C (gcc) , 40 byte

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

Provalo online! Si noti che i flag non sono necessari, sono lì per aiutare con il test della funzione fixpoint definita sopra.

Questa è una funzione che accetta un npuntatore int e una funzione b : int → int. Abusare del fatto che scrivere sul primo argomento variabile imposta il eaxregistro, che equivale a restituire . Altrimenti, questo è abbastanza standard per quanto riguarda il golf C. n^b(n)verifica la disuguaglianza ne la casella nera applicata a n. Se disuguale, chiama fnuovamente la funzione fixpoint in modo ricorsivo con l'applicazione e la scatola nera come argomenti. Altrimenti, restituisce il fixpoint.

† Citazione necessaria, ricordo vagamente di averlo letto da qualche parte e google sembra confermare i miei sospetti

Dichiara input con la digitazione di parametri in stile K & R:

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

Il bit arcano sulla seconda riga sopra dichiara bdi essere un puntatore a funzione che accetta un parametro intero: _si presume che il tipo predefinito di sia un numero intero. Allo stesso modo, nsi presume che sia un numero intero e fsi presume che restituisca un numero intero. Evviva per la digitazione implicita?


2

Pulito , 46 byte

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

Presuppone che la funzione sia definita come f :: !Int -> Int

Prende la testa della lista infinita di applicazioni f f f ... xfiltrate per quegli elementi in cui f el == el.

Provalo online!

Se si desidera modificare la funzione nel TIO, la sintassi lambda di Clean è:

\argument = expression

(in realtà è molto più complicato, ma per fortuna abbiamo solo bisogno di funzioni unarie)


2

APL (Dyalog Unicode) , 14 byte

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

Provalo online!

La funzione nell'intestazione è equivalente a f(x) = floor(sqrt(abs(x)))

Grazie @Adám per aver sottolineato che la risposta originale non era valida secondo il consenso di PPCG.

Come funziona:

{⍵=⍺⍺⍵:⍵⋄∇⍺⍺⍵}  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⍵)} sarebbe ok per una funzione anonima separata dal suo nome (n)
RosLuP

2
Questo presuppone che fsia preassegnato, che penso sia proibito dal consenso di PPCG. {⍵=⍺⍺⍵:⍵⋄∇⍺⍺⍵}sarebbe una soluzione valida per l'operatore.
Adám,



1

Forth (gforth), 36 byte

Questa versione presuppone che fsia predefinita. Non è bello come la soluzione sottostante. Entrambi i programmi escono con uno stack overflow se non trovato o uno stack underflow se trovato (dopo aver stampato il risultato).

Provalo online

: g dup f over = IF . THEN recurse ;

Forth (gforth), 52 byte

Ciò consente al token di esecuzione di una funzione di essere passato come parametro ed è sicuramente la soluzione più interessante.

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

Provalo online

Spiegazione:

: 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

tinylisp sostitu , 28 byte

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

Presuppone che la funzione fsia predefinita.

Provalo online! (La funzione di esempio èf(x) = (x*2) mod 10 .)

Ungolfed

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

Se f(x)uguale a x, allora xè un punto fisso; restituirlo. Altrimenti, ricorsivamente cercare un punto fisso a partire da f(x)invece di x.


1

APL NARS 65 caratteri

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 operatore restituirebbe ∞ (o possibilmente -oo o Nan) per errore, altrimenti un valore x con x = f (x). Nel test f = floor (sqrt (abs (x))), f1 = 2-x, f2 = c (c (c (x))) con 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 byte

Bene, questo è il più breve e il più brutto:

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

+c'è invece di un numero in modo che non sia uguale a nessun valore di x0.

55 byte e funzionale:

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

Esempio:

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

1

Opcode x86, 8 byte

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

Accetta input: ecx(valore ), (indirizzo della funzione, accetta input , scrive il risultato senza modificare il valore di e )x0edxecxeaxecxedx

8086 codice operativo, 7 byte (ma lento)

    xor     cx,     cx
    call    dx
    loop    $-2
    ret

Se esiste un punto fisso, il loop 65536 volte lo guida sempre lì.
Accetta input: ax(valore iniziale ), (indirizzo funzione, accetta input da , scrive output su senza modificare il valore di e ). Emette il punto fisso nel registro .x0dxaxaxcxdx
ax


Sarebbe sicuramente utile se rendessi la risposta più leggibile.
user202729

più modifica per renderlo corretto
l4m2


0

Java 8, 42 byte

Questo richiede un Function<Integer, Integer>o IntFunction<Integer>ed una into Integer(curry) e restituisce il punto fisso.

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

Provalo online

Approfitta del fatto che Java valuta le sottoespressioni da sinistra a destra (quindi il vecchio iviene confrontato con il nuovo), una proprietà di cui non ero a conoscenza durante la scrittura di questo!

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.