[心得] EIORU tree

看板Mathematica作者 (Hysterisis)時間12年前 (2012/07/18 18:34), 編輯推噓0(002)
留言2則, 1人參與, 最新討論串1/1
這篇文章靈感是EIORU大在帕索板提出的問題,每次EIORU提出的問題都蠻適合練習 Mathematica或其他程式之解題技巧 @@ 作者: EIORU () 看板: puzzle 標題: [問題] 樹幹 樹枝 果實 有一棵 樹 種進土裡後 長出了樹幹 │ ╲╱ <- 左/右 樹枝 往前/後的樹枝->∣ ╲╱ 第一天早上 長出了樹枝 │ <- 樹幹 ∣ ∣ <-樹幹 ∣ ∣ ╲╱ ╲╱ 第一天晚上 樹枝上長出了樹幹 │ ∣ 原本的樹枝變成了樹幹 第二天 在左邊的樹幹 往 前/後 長出了樹枝 , 在右邊的樹幹 往 左/右 長出了樹枝 第二天晚上 樹枝上長出了樹幹 原本的樹枝變成了樹幹 第三天 在前方的樹幹 往 前/後 長出了樹枝 , 在後方的樹幹 往 左/右 長出了樹枝 在左邊的樹幹 往 前/後 長出了樹枝 , 在右邊的樹幹 往 左/右 長出了樹枝 第三天晚上 樹枝上長出了樹幹 原本的樹枝變成了樹幹 第四天之後 會重複有顏色的行為 如果早上兩枝樹枝 碰到了一起 在晚上就會結出了果實 而不會長出樹幹 PS. 在頂端的樹幹才有生長能力 樹枝長度 = √2 , 樹幹長度 = 1 樹枝生長永遠和地面呈45度 樹幹生長永遠和地面呈90度 Q1. 第10天早上 會長出幾枝樹枝? Q2. 從第一天開始到第幾天晚上能採收到第100顆果實? 題外話 ... OEIS 沒有樹枝數量的數列 XD ... 畫到一半感覺像 某 立體結構的 聚合物 = = = = 分析 by jurian0101= = = = O代表原枝幹 WASD代表前左後右 (XD) 上一天的以小寫wasd表示。 Q代表果子,一個位置結了果實就不會再往上長,第二天就忽視他。 以下是轉變法則,用字代表就不會忘了是什麼朝向的枝幹,也可以方便繪圖(設定坐標) W W w AsD a AdD S S 假設要算枝幹總長度的話(原題沒有但可以算) 就是一層層加上去,正是每一層中 __ __ W=A=S=D = 1+V 2 ,Q = 2V 2 ,初始枝幹O=1 這樣 = = = = 手動實作 = = = = 第一天 (第0層) O 長度1 第二天 W __ o 長度 2* (1+V 2 ) S 第三天 W w 以下省略長度,一樣意思就好 S AsD 第四天 果子 +=1 W w S QsD aAdD S 第五天 果子 +=2 W w S AsD QsD aAdD AsQ 第六天 果子 += 2 W w S QsD aAdD S QdD W aAdD a S S ........依此類推,是個二維cellular automata QQ = = = = 最後是解答與Mathematica碼 = = = = 先形容一下畫出來這顆神奇的樹, "分層畫"的輸出可以看到,每層中同一側形成無間隙的枝幹網格。果子也是交替排列。 這個構造姑且叫做基底膜好了@@ 相對方向形成兩種排列形式 1.cluster: 形狀不一的離散團塊,似乎彼此長像是一樣的 或 2. escalator,一路連回基底膜的長短不一的纖維狀構造 然後就是整體了,窩的天啊它長的超像 Sierpinski triangle (轉到側面) 相異點是 這個...就叫他 EIORU XD triangle 好了...是由多於而非原本1:2的挖空比例構成的 /\ /__\ <-- 很差的示意圖 /\/\/\ 以下一是傷眼Mathematica函數,速度效率很差,但計較這點可能要重寫過就...算了 Clear[枝幹];枝幹[直][0]={{0,0}->"W"}; 枝幹[直][n_]/;n>0:= 枝幹[直][n]= (枝幹[斜][n]=Sort[枝幹[直][n-1]/.rule1])//. {p___,q_Rule,r___,s_Rule,t___}/;q[[1]]==s[[1]]:>{p,q[[1]]->"Q",t} (*迭代規則。到下一層Q=果子須移除,是故有Q一行*) rule1={ (*W*)({x_,y_}->"W"):>Sequence[{x,y+1}->"W",{x,y-1}->"S"], (*A*)({x_,y_}->"A"):>Sequence[{x,y+1}->"W",{x,y-1}->"S"], (*S*)({x_,y_}->"S"):>Sequence[{x-1,y}->"A",{x+1,y}->"D"], (*D*)({x_,y_}->"D"):>Sequence[{x-1,y}->"A",{x+1,y}->"D"], (*Q*)({_,_}->"Q")->Sequence[] }; (*把第i層枝幹data轉換成繪圖物件。枝幹[直][i]裡包含Q=果子,是往上畫。枝幹[斜 ][i]不包含Q,是往下畫*) Clear[轉換]; 轉換[i_]:=Join[{Hue[Mod[i,10]/10]}, 枝幹[斜][i]/.x:{_Integer,_}:>Append[x,2i-1]/.rule2, 枝幹[直][i]/.x:{_Integer,_}:>Append[x,2i-1]/.rule3 ] (*斜枝幹變斜線*) rule2={ (*W*)({x_,y_,z_}->"W"):>Line[{{x,y,z},{x,y-1,z-1}}], (*A*)({x_,y_,z_}->"A"):>Line[{{x,y,z},{x+1,y,z-1}}], (*S*)({x_,y_,z_}->"S"):>Line[{{x,y,z},{x,y+1,z-1}}], (*D*)({x_,y_,z_}->"D"):>Line[{{x,y,z},{x-1,y,z-1}}] }; (*直枝幹或果子*) rule3={ (*Q*)({x_,y_,z_}->"Q"):>{color=Black,PointSize[0.03],Point[{x,y,z}]}, (*else*) ({x_,y_,z_}->Except["Q"]):>Line[{{x,y,z},{x,y,z+1}}] }; = = = = = = = (*起始!,50層在我電腦跑很慢,約5分鐘*)(*不知道這麼慢的原因是...*) 枝幹[直][50]; = = = = = = = (*輸出測試*) 枝幹[斜][5] 枝幹[直][10] = = = = = = = (*單層graphics測試*) Graphics3D[轉換[10]] = = = = = = = (*多層graphics,視角是正上方,以看清分布*) Table[Graphics3D[轉換[i], ViewPoint -> Top, BoxStyle -> Dashed], {i, 1, 50(*層數*)}] = = = = = = = (*重頭戲!! 大融合繪圖。果子大小為手動調整,0是看不見*) Graphics3D[ Flatten@Table[轉換[i], {i, 1, 50(*層數*)}] /. PointSize[_] -> PointSize[0(*大小*)], ViewPoint -> Top, BoxStyle -> Dashed] = = = = = = = = = (*第i層的果實計數*) c=Table[Count[枝幹[直][i],"Q",Infinity],{i,1,50}] (*到第n天總共果實計數*) Accumulate[c] (*斜枝幹計數*) Table[Length@枝幹[斜][i],{i,1,50}] (*直枝幹計數,含果子,自行扣除*) Table[Length@枝幹[直][i],{i,1,50}] = = =全文完的分隔線= = = ※ 編輯: jurian0101 來自: 140.112.213.88 (07/18 18:40)

07/18 18:43, , 1F
到底為什麼需要跑這麼久呢Hmm 若不能用ReplaceAll就等
07/18 18:43, 1F

07/18 18:43, , 2F
於是要重寫了。
07/18 18:43, 2F
文章代碼(AID): #1G1f58EL (Mathematica)
文章代碼(AID): #1G1f58EL (Mathematica)