[このノートブックは以下のcommunityのポストをLLMツールにより日本語に翻訳したものです:
​
​Reconstructing the classic ASCII Donut in Wolfram language using FunctionCompile​
by Shenghui Yang​
Wolfram Community, STAFF PICKS, October 24, 2025
​https://community.wolfram.com/groups/-/m/t/3564927]

FunctionCompileを使用してWolfram言語で古典的なASCIIドーナツを再構築する

by Shenghui Yang
本研究では,Andy SloaneのFixed-point donut.cをWolfram言語にコード変換したものを提示し,効率的な計算のためにFunctionCompile機能を活用している.このプロジェクトは,低レベルのCアルゴリズムが高レベルの記号環境において忠実に再現可能であることを実証している.StyleとListAnimateを組み合わせることにより,この実装はカスタマイズ可能な色効果を持つ滑らかなASCIIベースのアニメーションを可能にしている.
In[]:=
Clear[RotateStep,IntDonutFrame];
関数の宣言を格納するコンパイラ環境を作成する:
In[]:=
env=CreateCompilerEnvironment[];
CORDIC + Newton法のステップを用いて反復計算における精度を保持する:
In[]:=
decl1=FunctionDeclaration[RotateStep,Typed[​​{"PackedArray"::["MachineInteger",1],"MachineInteger","MachineInteger"}​​->"PackedArray"::["MachineInteger",1]​​]@Function[​​{arg1,mul,shift},​​Module[{xx=arg1[[1]],yy=arg1[[2]],tmp,star},tmp=xx;​​xx=xx-BitShiftRight[mul*yy,shift];​​yy=yy+BitShiftRight[mul*tmp,shift];​​star=BitShiftRight[3145728-xx*xx-yy*yy,11];​​xx=BitShiftRight[xx*star,10];​​yy=BitShiftRight[yy*star,10];​​{xx,yy}]​​]];
回転とASCII描画を処理する中核関数を宣言する:
In[]:=
decl2=FunctionDeclaration[IntDonutFrame,Typed[​​{"MachineInteger","MachineInteger","MachineInteger","MachineInteger"}->"ListVector"::["String"]​​]​​@Function[{cA,sA,cB,sB},​​Module[{w=80,h=22,​​chars={".",",","-","~",":",";","=","!","*","#","$","@"},​​b=CreateDataStructure["FixedArray"," ",1760],​​z=CreateDataStructure["FixedArray",127,1760],​​sj=0,cj=1024,si=0,ci=0,​​R1=1,R2=2048,K2=5120*1024,​​x0,x1,x2,x3,x4,x5,x6,x7,x,y,Nl=1,o=0,zz},​​Do[si=0;ci=1024;​​Do[x0=R1*cj+R2;​​x1=BitShiftRight[ci*x0,10];​​x2=BitShiftRight[cA*sj,10];​​x3=BitShiftRight[si*x0,10];​​x4=R1*x2-BitShiftRight[sA*x3,10];​​x5=BitShiftRight[sA*sj,10];​​x6=K2+R1*1024*x5+cA*x3;​​x7=BitShiftRight[cj*si,10];​​x=40+Quotient[30*(cB*x1-sB*x4),x6];​​y=12+Quotient[15*(cB*x4+sB*x1),x6];​​Nl=BitShiftRight[-cA*x7-cB*(BitShiftRight[-sA*x7,10]+x2)-ci*BitShiftRight[cj*sB,10],10];​​Nl=BitShiftRight[Nl-x5,7];​​o=x+80*y;​​zz=BitShiftRight[x6-K2,15];​​If[0<y<22&&0<x<80&&zz<z["Part",o+1],​​z["SetPart",o+1,zz];​​b["SetPart",o+1,chars[[If[Nl>0,Nl+1,1]]]]​​];​​{ci,si}=RotateStep[{ci,si},5,8];,{i,0,323,1}];​​{cj,sj}=RotateStep[{cj,sj},9,7];,{j,0,89,1}];​​b["Elements"]​​]]];
2つの宣言を1つの環境に配置する:
In[]:=
CompilerEnvironmentAppendTo[env,{decl1,decl2}]
Out[]=
CompilerEnvironmentObject
Target systems:
MacOSX-x86-64
User types:
0
User functions:
2

回転関数とコア関数をコンパイルする:
In[]:=
cfRotateStep=FunctionCompile[Function[{​​Typed[arg1,"PackedArray"::["MachineInteger",1]],​​Typed[m,"MachineInteger"],​​Typed[s,"MachineInteger"]​​}​​,RotateStep[arg1,m,s]],CompilerEnvironment->env];
In[]:=
Information@cfRotateStep
Out[]=
Compiled Code Function
Argument Types
{PackedArray::[Integer64,1],Integer64,Integer64}
Return Type
PackedArray::[Integer64,1]
Type
{PackedArray::[Integer64,1],Integer64,Integer64}PackedArray::[Integer64,1]
LLVM Binary
MacOSX-x86-64ByteArray[<9504>]
In[]:=
cfIntDonutFrame=FunctionCompile[Function[{​​Typed[cA,"MachineInteger"],​​Typed[sA,"MachineInteger"],​​Typed[cB,"MachineInteger"],​​Typed[sB,"MachineInteger"]​​}​​,IntDonutFrame[cA,sA,cB,sB]],CompilerEnvironment->env];
関数の内部構造の要約:
In[]:=
Information@cfIntDonutFrame
Out[]=
Compiled Code Function
Argument Types
{Integer64,Integer64,Integer64,Integer64}
Return Type
ListVector::[String]
Type
{Integer64,Integer64,Integer64,Integer64}ListVector::[String]
LLVM Binary
MacOSX-x86-64ByteArray[<42272>]
コンパイル済み関数cfRotateStepを使用して,3次元ドーナツの600組の向きを持つリストを作成する:
In[]:=
configs=Join@@@Transpose@{NestList[cfRotateStep[#,5,7]&,{0,1024},600],​​NestList[cfRotateStep[#,5,7]&,{1024,0},600]};
関数の定義をサブカーネルに配布する:
In[]:=
Once[LaunchKernels[];DistributeDefinitions[cfRotateStep,cfIntDonutFrame]];
Mac air M2において,8つの並列サブカーネル上で600フレームすべてを生成するのに2秒未満しかかからない:
In[]:=
AbsoluteTiming[data=ParallelMap[StringJoin/@Partition[cfIntDonutFrame[Sequence@@#],80]&,configs];]
Out[]=
{10.5076,Null}
例で使用される配色をカスタマイズ:
In[]:=
(*hbrw=RGBColor[107/256,218/256,70/256];tomatchcolorschemeinmactermimalhomebrewcolor*)​​clb=Blend[{White,RGBColor["#9B2A7F"],RGBColor["#748358"],RGBColor["#57C78B"],RGBColor["#E647AE"],White},#]&;
Styleファンクションの他の設定でアニメーションを実行してサイズを調整する.ダークモードでコードを実行することを強く推奨する:
In[]:=
ListAnimate[Table[​​Style[Column[data[[i]],Spacings->0.2],Bold,​​FontFamily->"Courier",FontSize->12,clb[i/600](*hbrw*)],{i,600}],60,​​SaveDefinitions->True]
Out[]=
コンパイル版は非コンパイル版と比較して約100倍高速である.

このノートブックを引用する

Reconstructing the classic ASCII Donut in Wolfram language using FunctionCompile​
by Shenghui Yang​
Wolfram Community, STAFF PICKS, October 24, 2025
​https://community.wolfram.com/groups/-/m/t/3564927