1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Qiita Engineer Festa 2024(キータ・エンジニア・フェスタ 2024) - Qiita
において、約1ヶ月で38記事という大量の記事の投稿を要求されることがわかった。
そこで、あまりコストをかけずに記事数を稼ぐ方法を考えた結果、「Welcome to AtCoder を様々な言語で解く」ことを思いついた。
単に解くだけでなく、使用する言語仕様の解説を入れれば、記事として一応成立するだろう。

Welcome to AtCoder

PracticeA - Welcome to AtCoder

Welcome to AtCoder では、以下の形式で整数 $a$, $b$, $c$ および文字列 $s$ が入力として与えられる。

a
b c
s

この入力をもとに、与えられた整数の和 $sum = a + b + c$ および文字列 $s$ を、以下の形式で出力することが求められる。

sum s

今回用いた Factor の機能

Factor cookbook - Factor Documentation

プログラムの要素

Factor のプログラムには、以下の要素がある。

プログラム中に値を書くと、その値をスタックに積むという意味になる。
今回用いる値には、数値、t (真)、f (偽) がある。

word

word とは、命令のようなものである。
スタックに積まれている要素を必要に応じて参照して処理を行い、追加・削除・変更を行う。

USING

USING: 使用するライブラリのリスト ;

使用するライブラリ (vocabulary) をまとめて読み込み、それらのライブラリに含まれる word を使用できるようにする。

コメント

各行の ! 以降の部分はコメントである。

quotation

quotation とは、命令列を [] で囲んだものである。
命令のブロックを作成し、フロー制御を行う word の入力とする用途などに用いる。

配列

要素の列を {} で囲むことで、配列を作成できる。

今回用いた word

以下の「意味」において、「1番目」はスタックトップを、「2番目」はスタックトップの次の要素を、「3番目」はスタックトップの次の次の要素を表す。
プッシュやポップなどのスタック操作を行う場合でも、これらは操作開始時の要素を表す。

演算・論理

vocabulary word 意味
math * 1番目と2番目をポップし、これらの積をプッシュする
math + 1番目と2番目をポップし、これらの和をプッシュする
math - 1番目と2番目をポップし、
2番目から1番目を引いた差をプッシュする
math /mod 1番目と2番目をポップし、2番目を1番目で割る
商をプッシュし、続いて余りをプッシュする
kernel = 1番目と2番目をポップし、
これらが等しいかを表す値をプッシュする
math < 1番目と2番目をポップし、
2番目が1番目未満かを表す値をプッシュする
math >= 1番目と2番目をポップし、
2番目が1番目以上かを表す値をプッシュする
kernel and 1番目と2番目をポップし、
これらが両方真なら真 (1番目の値)を、
そうでなければ偽 (f) をプッシュする
kernel not 1番目をポップし、これが真なら偽 (f) を、
そうでなければ真 (t) をプッシュする

スタック操作

vocabulary word 意味
kernel drop 1番目をポップし、捨てる
kernel dup 1番目をプッシュする (コピーする)
kernel over 2番目をプッシュする (コピーする)
kernel swap 1番目と2番目の値を入れ替える
kernel swapd 2番目と3番目の値を入れ替える

フロー制御

Control flow cookbook - Factor Documentation

vocabulary word 意味
kernel if 1番目・2番目・3番目をポップし、
3番目が f (偽) なら1番目を、
そうでなければ2番目を実行する
kernel loop 1番目をポップし、実行する
実行後スタックトップをポップし、
それが f (偽) でなければ実行を (何回でも) 繰り返す
math times 1番目と2番目をポップし、
1番目を、2番目で指定する回数繰り返し実行する

配列操作

vocabulary word 意味
sequences prefix 1番目と2番目をポップし、2番目の配列の先頭に
1番目の要素を追加した配列をプッシュする

標準入出力

vocabulary word 意味
io read1 標準入力から1バイト読み込み、数値としてプッシュする
EOF の場合は f をプッシュする
io write 1番目をポップし、その配列の要素を順に
バイトとして標準出力に出力する
io write1 1番目をポップし、その値を標準出力に (1バイト) 出力する

提出コード

USING: kernel math sequences io ;

! ----------- 3個の数値の和を求める -----------

0                   ! 和となる数値をスタックに積む
3 [                 ! times により3回繰り返す
  0                 ! 1個の数値を読み込んだ結果となる数値をスタックに積む
  [                 ! 1個の数値の読み込みを行う (loop)
    read1           ! 1文字読み込む
    dup 48 >=       ! 読み込んだ文字が '0' 以上かを調べる
    over 58 <       ! 読み込んだ文字が '9' 以下かを調べる ('0' 以上かがあるので、over を用いる)
    and             ! 2個の判定を組み合わせ、読み込んだ文字が数字かを調べる
    [               ! 読み込んだ文字が数字である (t) 場合、以下の処理を行う
      48 -          ! 読み込んだ文字(コード)から '0' を引き、数値に変換する
      swap 10 * +   ! これまでの変換結果の10倍に、変換した数値を足す (変換結果を更新する)
      t             ! 変換のループを続行する
    ]
    [               ! 読み込んだ文字が数字でない (f) 場合、以下の処理を行う
      drop          ! 読み込んだ文字を捨てる
      f             ! 変換のループを終了する
    ]
    if              ! 読み込んだ文字が数字かによって、上記の処理を行う
  ] loop
  +                 ! 読み込んだ数値を和に加算する
] times

! ----------- 求めた和を十進数で表現し、出力する -----------

{ } swap            ! 和(数値)の後ろに、十進数表現を格納する配列を置く
[                   ! 和(数値)を十進数に変換する (loop)
  10 /mod           ! 和(数値)を10で割り、商と余りを求める
  48 +              ! 求めた余りに '0' を足し、数字に変換する
                    ! この時点でのスタック:配列 商 数字
  swapd             ! 数字を配列に追加するため、配列を移動する
                    ! この時点でのスタック:商 配列 数字
  prefix            ! 数字を配列の先頭に追加する
                    ! この時点でのスタック:商 配列
  swap              ! 配列の位置を戻す
                    ! この時点でのスタック:配列 商
  dup 0 = not       ! 残っている商が0でないかを判定する (0でない間ループを続ける)
] loop
drop                ! 商 (0) を捨てる
write               ! 変換結果の配列を出力する

! ----------- 値と文字列の間の空白を出力する -----------

32 write1           ! 数値と文字列の間の空白を出力する

! ----------- 文字列 s を出力する -----------

[                   ! 文字列の出力を行う (loop)
  read1             ! 1文字読み込む
  dup write1        ! 読み込んだ文字を確認できるようにコピーし、出力する
  10 = not          ! 読み込んだ文字が '\n' かを判定する ('\n' でない間ループを続ける)
] loop

提出 #55331433 - AtCoder Beginners Selection

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?