Scheme から表現力の劣る Smalltalk に移そうとすれば、当然、いろいろと抜け落ちてしまい、結果として身も蓋もなくなっちゃっていかんのですが…。まあそこはそれとして(^_^;)。個人的には nfunato さんのがお気に入りです。
それにつけても、copy fixTemps だらけで、Squeak Smalltalk のブロックで再帰なんかやるもんじゃあないですね。orz(くどいようですが、aBlock copy fixTemps というのは、そのままでは再入・再帰ができない Squeak のブロックで、自身と環境のコピーを行なうための作業です。もちろん、無名関数としてのブロックがクロージャで実現されている通常の Smalltalk では不要)。
▼ id:scinfaxi さんの
| tree result loop | tree := #(Root (Spine (Neck (Head)) (RClavicle (RUpperArm (RLowerArm (RHand)))) (LClavicle (LUpperArm (LLowerArm (LHand))))) (RHip (RUpperLeg (RLowerLeg (RFoot)))) (LHip (LUpperLeg (LLowerLeg (LFoot))))). result := OrderedCollection new. loop := [:xs :parent | xs allButFirst isEmpty ifTrue: [nil] ifFalse: [ xs allButFirst do: [:x | parent ifNotNil: [result add: x first -> parent]. loop copy fixTemps valueWithArguments: {x. xs first}]]]. loop copy fixTemps valueWithArguments: {tree. #f}. ^result
▼ Pla さんの
| tree result loop | tree := #(Root (Spine (Neck (Head)) (RClavicle (RUpperArm (RLowerArm (RHand)))) (LClavicle (LUpperArm (LLowerArm (LHand))))) (RHip (RUpperLeg (RLowerLeg (RFoot)))) (LHip (LUpperLeg (LLowerLeg (LFoot))))). result := OrderedCollection new. loop := [:tr | | parent children | tr size > 1 ifTrue: [ parent := tr first. children := tr allButFirst. children do: [:child | loop copy fixTemps value: child. result add: child first -> parent]]]. loop copy fixTemps value: tree. ^result
▼ naoya_t さんの
| tree appendMap itr foo2 foo3 | tree := #(Root (Spine (Neck (Head)) (RClavicle (RUpperArm (RLowerArm (RHand)))) (LClavicle (LUpperArm (LLowerArm (LHand))))) (RHip (RUpperLeg (RLowerLeg (RFoot)))) (LHip (LUpperLeg (LLowerLeg (LFoot))))). appendMap := [:proc :l | (l collect: proc) inject: OrderedCollection new into: [:colln :each | colln addAll: each; yourself]]. "foo1" itr := [:p :t | {t first -> p}, ( t allButFirst ifEmpty: [#()] ifNotEmpty: [ appendMap copy fixTemps value: [:x | itr copy fixTemps value: t first value: x] value: t allButFirst])]. appendMap copy fixTemps value: [:x | itr copy fixTemps value: tree first value: x] value: tree allButFirst. foo2 := [:l | | parent children | parent := l first. children := l allButFirst. appendMap copy fixTemps value: [:child | {child first -> parent}, ( child allButFirst isEmpty ifTrue: [#()] ifFalse: [ foo2 copy fixTemps value: child])] value: children]. foo2 copy fixTemps value: tree. foo3 := [:l | appendMap copy fixTemps value: [:child | {child first -> l first}, ( child allButFirst isEmpty ifTrue: [#()] ifFalse: [ foo3 copy fixTemps value: child])] value: l allButFirst]. foo3 copy fixTemps value: tree "foo4 は省略 "
▼ Shiro さんの
| tree rec | tree := #(Root (Spine (Neck (Head)) (RClavicle (RUpperArm (RLowerArm (RHand)))) (LClavicle (LUpperArm (LLowerArm (LHand))))) (RHip (RUpperLeg (RLowerLeg (RFoot)))) (LHip (LUpperLeg (LLowerLeg (LFoot))))). "get-parent-alist" rec := [:p :t :s | | n ts | n := t first. ts := t allButFirst. {n -> p}, (ts inject: s into: [:result :each | rec copy fixTemps valueWithArguments: {n. each. result}])]. ^tree allButFirst inject: #() into: [:result :each | rec copy fixTemps valueWithArguments: {tree first. each. result}]
▼ nfunato さんの
| tree getParentAlist gather build | tree := #(Root (Spine (Neck (Head)) (RClavicle (RUpperArm (RLowerArm (RHand)))) (LClavicle (LUpperArm (LLowerArm (LHand))))) (RHip (RUpperLeg (RLowerLeg (RFoot)))) (LHip (LUpperLeg (LLowerLeg (LFoot))))). getParentAlist := [:p | (p allButFirst collect: [:c | c first -> p first]), (p allButFirst collect: getParentAlist copy fixTemps) concatenation]. getParentAlist copy fixTemps value: tree. "Shiroさんのを元にしたもの" build := nil. gather := [:p :soFar | p allButFirst inject: soFar into: [:result :each | build copy fixTemps valueWithArguments: {p. each. result}]]. build := [:p :c :soFar | {c first -> p first}, (gather copy fixTemps value: c value: soFar)]. gather copy fixTemps value: tree value: #()
▼ nobsun さんの
| tree appendMap dfs chpa | tree := #(Root (Spine (Neck (Head)) (RClavicle (RUpperArm (RLowerArm (RHand)))) (LClavicle (LUpperArm (LLowerArm (LHand))))) (RHip (RUpperLeg (RLowerLeg (RFoot)))) (LHip (LUpperLeg (LLowerLeg (LFoot))))). appendMap := [:proc :l | (l collect: proc) inject: OrderedCollection new into: [:colln :each | colln addAll: each; yourself]]. dfs := [:t | {t}, (appendMap copy fixTemps value: dfs copy fixTemps value: t allButFirst)]. "tree-child-parent-list" chpa := [:t | | p cs | p := t first. cs := t allButFirst. (cs collect: [:each | each first]) collect: [:each | each -> p]]. appendMap copy fixTemps value: chpa copy fixTemps value: (dfs copy fixTemps value: tree)