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.