指定數字以內的所有排列組合:
定義名稱版:
=pmtt(指定數字) pmtt=LAMBDA(x,IF(x=1,1,VSTACK(pmtt(x-1),REDUCE(SEQUENCE(x),SEQUENCE(,x-1)^0*x,LAMBDA(a,b,TOCOL(a&SEQUENCE(,b)))))))
不定義名稱版:
=LET(fx,LAMBDA(npmtt,x,IF(x=1,1,VSTACK(npmtt(npmtt,x-1),REDUCE(SEQUENCE(x),SEQUENCE(,x-1)^0*x,LAMBDA(a,b,TOCOL(a&SEQUENCE(,b))))))),fx(fx,指定數字))
這個指定數不能太小,1的話,就只有1。
看一下2的結果:
沒幾個是吧?那就3:
看看這增長的架勢,再大點的數就不截圖了,且,最大就只能到7。
嗯,才7,返回的值有87萬多,一個工作表才一百多萬行……
好吧,言歸正傳,這公式要怎麼理解,鄭重點,加條分割線吧,順帶居中一下。
***********************************************************************
這公式分成兩個部分,遞迴部分就是一個堆疊,前一個值的結果和當前值的結果堆疊在一起,這沒啥好說的,重點是Reduce部分(本文是不是不該歸類為遞迴?)
假設x為2,Reduce部分的公式就可以寫成:
=REDUCE(SEQUENCE(2),SEQUENCE(,2-1)^0*2,LAMBDA(a,b,TOCOL(a&SEQUENCE(,b))))
公式返回的結果就是11、12、21、22。
初始值是縱向矩陣1和2,陣列就是一個2,然後Reduce的功能就是為迪卡爾積運算而生的,Lambda裡使用&連線就可以了,需要注意的是連線的物件不是簡單的a&b,而是a連線以b為列數的一行,這裡就是橫向的1和2。
在這公式裡,陣列引數的寫法明顯很累贅,這其實是為遞迴而設定的具有統一性的一個公式,x為2的時候感覺上去還沒啥,再來看當x為3的時候。
好吧,接下來的內容已經沒辦法在一個平面內正常展示了,只能透過腦電波“搬磚”,就比如a&SEQUENCE(,b),b本身就是一個橫向陣列,要怎麼橫向?想說所以才用ToCol?不,ToCol的功能絕不是簡單的轉成一列,不然把ToCol部分去掉試試,結果就不對了。
那麼,一步一步來吧。
第一步運算(這個步子有點大哈):
縱向的1、2、3和橫向的1、2、3連線,結果就是11-33的9個值。
ToCol的目的是把這9個值轉成一列,然後,這一列就搖身一變,變成了第二步運算的a:
接下來就是新的a和SEQUENCE(,b)的連線。
然後,3個數的所有組合就全部出來了。
好累~