Cubix、33 32バイト
u*.$s.!(.01I^<W%NW!;<,;;q+p@Opus
ネット形式:
u * .
$ s .
! ( .
0 1 I ^ < W % N W ! ; <
, ; ; q + p @ O p u s .
. . . . . . . . . . . .
. . .
. . .
. . .
オンラインでお試しください!
ノート
- 170以上の入力で動作します。より高い入力は、その階乗が
Infinity
数値を生成するため、無限ループになります(技術的には、ウィンドウオブジェクトの書き込み不可、列挙不可能、構成不可能なプロパティです)。
- 2 53(= 9 007 199 254 740 992)を超える数値はJavaScriptに正確に保存できないため、入力19以上では精度が失われます。
説明
このプログラムは2つのループで構成されています。最初は入力の階乗を計算し、もう一方は結果を数字に分割し、それらを加算します。その後、合計が印刷され、プログラムが終了します。
開始
まず、スタックを準備する必要があります。その部分では、最初の3つの指示を使用します。IPは、東を指す4行目から始まります。スタックは空です。
. . .
. . .
. . .
0 1 I . . . . . . . . .
. . . . . . . . . . . .
. . . . . . . . . . . .
. . .
. . .
. . .
スタックの一番下に合計を保持するため、スタックの一番下に0
保存して合計にすることから始める必要があります。次に1
、入力を最初にその数で乗算するため、をプッシュする必要があります。これがゼロの場合、階乗も常にゼロになります。最後に、入力を整数として読み取ります。
これで、スタックが[0, 1, input]
あり、IPは4番目の行、4番目の列にあり、東を指します。
階乗ループ
これは、スタックの上位2つの要素(前のループと入力-nの結果)を乗算し、入力をデクリメントする単純なループです。入力が0に達すると中断します。$
命令はIPをスキップさせますu
-ループはキューブの次の部分で、IPは4行4列目から始まります。
u * .
$ s .
! ( .
. . . ^ < . . . . . . .
. . . . . . . . . . . .
. . . . . . . . . . . .
. . .
. . .
. . .
^
キャラクターのために、IPはすぐに北へ移動し始めます。次に、u
IPが向きを変え、1つ右に移動します。下部には別の矢印があります:<
IPをに向け^
ます。スタックはから始まります。[previousresult, input-n]
ここn
で、は反復回数です。ループ内で次の文字が実行されます。
*s(
* # Multiply the top two items
# Stack: [previousresult, input-n, newresult]
s # Swap the top two items
# Stack: [previousresult, newresult, input-n]
( # Decrement the top item
# Stack: [previousresult, newresult, input-n-1]
次に、スタックの最上部(入力の減少)が命令0
によってチェックされ、チェックされている!
場合0
、u
文字はスキップされます。
数字を合計する
IPはキューブを包み込み、最終的に4行目の最後の文字で終わり、最初は西を指します。次のループは、ほとんどすべての残りの文字で構成されています。
. . .
. . .
. . .
. . . . . W % N W ! ; <
, ; ; q + p @ O p u s .
. . . . . . . . . . . .
. . .
. . .
. . .
ループは、最初にスタックから最上位のアイテム(10
または0
)を削除し、次に階乗の結果の残りをチェックします。それがに減少した場合0
、スタックの一番下(合計)が出力され、プログラムが停止します。それ以外の場合、次の命令が実行されます(スタックはとして開始します[oldsum, ..., factorial]
)。
N%p+q;;,s;
N # Push 10
# Stack: [oldsum, ..., factorial, 10]
% # Push factorial % 10
# Stack: [oldsum, ..., factorial, 10, factorial % 10]
p # Take the sum to the top
# Stack: [..., factorial, 10, factorial % 10, oldsum]
+ # Add top items together
# Stack: [..., factorial, 10, factorial % 10, oldsum, newsum]
q # Send that to the bottom
# Stack: [newsum, ..., factorial, 10, factorial % 10, oldsum]
;; # Delete top two items
# Stack: [newsum, ..., factorial, 10]
, # Integer divide top two items
# Stack: [newsum, ..., factorial, 10, factorial/10]
s; # Delete the second item
# Stack: [newsum, ..., factorial, factorial/10]
そして、ループfactorial/10
は0に等しくなるまで再び開始されます。
n>21