找到一个固定点


24

给定一个整数和一些黑盒函数,可以在定义的序列找到的固定点。x1 f: ℤ → ℤfxk+1 := f(xk)

细节

  • xfif 的固定点x = 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 meta post中输入黑盒功能默认设置的任何语言。如果您的语言没有这样的默认设置,请按照黑盒函数定义随意添加一个,并确保在该定义中链接您的建议。也不要忘记对它们进行投票。

例子

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

Answers:


16

实际上,1个字节

Y

在线尝试!

Y是“实际上”中的定点函数。在TIO示例中,函数以字符串形式显示,并£用于将其转换为堆栈上的函数。也可以像这样将函数推入堆栈。这是实际上获取函数输入的仅有两种方法。


7
您只是知道有一天这个挑战将要发布,不是吗?:P
暴民埃里克(Erik the Outgolfer)

2
@EriktheOutgolfer我实际上已经使用Y了几个挑战。我显然非常了解:P
Mego

11

APL(Dyalog),2个字节

⍣=

在线尝试!

注意:O←⍣=在输入部分中定义是由于存在一个错误,即无法以TIO喜欢定义的方式定义派生的单子运算符。

是可以像 (function⍣condition) ⍵

它适用的functionf直至(f ⍵) condition ⍵返回true。

⍣=是派生的单子运算符,它采用单子函数,f作为其左参数,并将其应用于右参数,直到f ⍵ = ⍵


也许要注意,这⍣=是一个派生的单子运算符,它采用函数作为左操作数,并在给定的初始值上找到固定点。我会用不同的字母⍣=不是f因为它是一个Ø操作结束时切,而不是一个˚F结。
阿达姆

是的 我会。f在描述中调用“输入”函数是令人困惑的,但是在TIO上,它f是您的解决方案运营商。您还可以O←⍣=在“代码”字段中将up向上移动,以便对其进行计数,并指出这是实际的解决方案,其余(输入)仅在对其进行测试。
阿达姆

对我来说似乎是个虫子。明天我将与相关同事交谈。
亚当

@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
此答案仅作为示例,并不妨碍任何人回答。
瑕疵

当然,如果您调用此Octave,则可以删除两个;s。在线尝试!
桑奇斯

并且在您的匿名函数中,您可以删除50个字节@()之前x的字符。对于包装辅助函数的方式(最后带有g(g))也很赞,我仅设法完成了51个字节@(g,x)(f=@(r,z){@()r(r,m),z}{(m=g(z)==z)+1}())(f,x)。我想知道两种方法的组合是否还更短。
桑奇斯

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





4

果冻,3个字节

vÐL

在线尝试!

将左参数作为表示Jelly链接的字符串(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


黑盒功能示例:

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

迅捷47 42字节

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

天真的方法,假设黑盒函数被命名为 f


我对您的第二次尝试感到怀疑,因为它是一个复杂的闭包,并且除非明确将其转换为,否则其类型是模棱两可的{...}as(<parameter types>)-><return type>。如果您不指定其返回类型,则它将抛出构建时错误,因此我认为它到目前为止是无效的(请注意,强制转换必须包含在字节数中)。不过,您的第一次提交是可以的。
Xcoder先生17年

2

C(gcc),40个字节

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

在线尝试!请注意,这些标志不是必需的,它们可以帮助测试上面定义的定位点功能。

这是一个需要一个int n和一个函数指针的函数b : int → int。滥用写第一个变量参数会设置eax寄存器的事实,这等同于返回。否则,就C高尔夫而言,这是相当标准的。n^b(n)检查是否存在不等式,n并将黑盒应用于n。当不相等时,它将f使用应用程序和黑匣子作为参数再次递归调用fixpoint函数。否则,它将返回固定点。

†需要引用,我隐约记得在某处阅读过,Google似乎证实了我的怀疑

它使用K&R样式的参数类型声明输入:

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

上面第二行的奥术位声明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对于那些元素,它采用了filter的无限应用列表的头,其中f el == el

在线尝试!

如果要更改TIO中的功能,Clean的lambda语法为:

\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

向前(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

tinylisp repl,28个字节

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

假设函数 f是预定义的。

在线尝试!(示例函数是f(x) = (x*2) mod 10。)

不打高尔夫球

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

如果f(x)等于xx则为固定点;把它返还。否则,递归查找从而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或Nan),否则将返回x = f(x)的一个值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操作码,8字节

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

接受输入:(ecx值),(函数地址,接受来自的输入,将结果写入而无需修改的值x0edxecxeaxecxedx

8086操作码,7个字节(但较慢)

    xor     cx,     cx
    call    dx
    loop    $-2
    ret

如果存在一个固定点,则总是将其循环65536次。
取输入:ax(初始值), (功能地址,从取输入,写入输出到不修改的值和)。 在寄存器中输出定点。x0dxaxaxcxdx
ax


如果您使答案更具可读性,那肯定会有所帮助。
user202729 '17

更多编辑以使其正确
l4m2


0

Java 8,42字节

这将使用“ Function<Integer, Integer>或” IntFunction<Integer>和“ int或” Integer(已固化)并返回固定点。

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

在线试用

利用Java从左到右评估子表达式的事实(因此将旧表达式i与新表达式进行比较),这是我在编写此属性时并不了解的属性!

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.