Cyber で Welcome to AtCoder を解いてみた

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

# Welcome to AtCoder

[PracticeA - Welcome to AtCoder](https://atcoder.jp/contests/abs/tasks/practice_1)

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

```text
a
b c
s
```

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

```text
sum s
```

# Cyber (言語) の情報の入手方法

「Cyber」でググっても一般的な言葉すぎて出ない。
「Cyber 言語」でも出ない。
バージョンを入れた「Cyber v0.2-Latest」でも出ない。

そこで、まずは AtCoder のコードテストを利用してメッセージを得てみた。

(空だと実行できないので) まずは改行1個だけを入れて実行してみた。
すると、以下のメッセージが得られた。

```text
ParseError: Expected one statement.

/judge/Main.cy:2:1:

^
```

しかし、「Cyber ParseError: Expected one statement.」でググっても、まだ情報が得られなかった。

次に、「a(改行)」を実行してみた。
すると、以下のメッセージが得られた。

```text
CompileError: Missing symbol: `a`

/judge/Main.cy:1:1:
a
^
```

これを取り入れた「Cyber ParseError: Expected one statement. CompileError: Missing symbol」でググってみると、ようやく情報にたどり着けた。
しかし、これでたどり着けたページ

[Cyber Docs](https://fubark.github.io/cyber/)

は、「v0.4-dev 262-467ae30」に関するもののようである。
一方、AtCoder で使われているのは「Cyber v0.2-Latest」である。
そして、単にバージョンが少し違うだけではなく、

* モジュールを参照する際、ページには `use math` と書かれているが、実際は `import m 'math'` のように書くことを求められる
* 変数の宣言は、ページには `var a = 123` と書かれているが、実際は `var` をつけずに `a = 123` のように書くことを求められる

など、このページには実際の仕様と合わない記述が多いようであった。
そこで、より実際の仕様と合う資料を探した。

このページの「Playground」を開くと、GitHub へのリンクがあった。(リンクのテキストは、小文字の h を用いた「Github」である)
このリンクから GitHub を開き、さらに Releases から 0.2 のタグを開いた。
さらに探索すると、以下の場所に実際の仕様に近い資料が入っているようだった。

[cyber/docs/hugo/content at 0.2 · fubark/cyber · GitHub](https://github.com/fubark/cyber/tree/0.2/docs/hugo/content)

# 今回用いた Cyber の機能

## 変数

[Variables.](https://github.com/fubark/cyber/blob/0.2/docs/hugo/content/docs/toc/syntax.md#variables)

```
変数名 = 値
```

のように書くことで、変数 (local variables) を定義できる。

:::note info
```
var 変数名 = 初期値
```

のように `var` をつけた変数は、static variables といい、グローバル変数のようなものである。
これは実行前に初期化されるので、初期値には local variables を用いることができない。
:::

## 数値の加算

[Operators.](https://github.com/fubark/cyber/blob/0.2/docs/hugo/content/docs/toc/syntax.md#operators)

```
a + b
```

のように `+` 演算子を用いることで、数値の和を求めることができる。

## 標準入出力

[Core Module.](https://github.com/fubark/cyber/blob/0.2/docs/hugo/content/docs/toc/modules.md#core-module)
[object rawstring](https://github.com/fubark/cyber/blob/0.2/docs/hugo/content/docs/toc/data-types.md#object-rawstring)

```
print 値
```

のように書くことで、「値」を標準出力に出力し、さらに改行を出力できる。

:::note info
`print` のかわりに `s` を追加した `prints` を用いると、改行を出力せず、「値」のみを出力できる。
:::

```
getInput()
```

を用いると、標準入力から1行読み込むことができる。
結果に改行文字は含まれない。
ただし、これは結果を `rawstring` 型で返す。`rawstring` 型のままだと

* `int` による整数への変換がうまくいかない
* 出力しようとしても内容が出力されない

など、通常の `string` 型より扱いにくい点がある。

```
getInput().utf8()
```

とすると、読み込んだ行を `string` 型で得ることができる。

:::note info
これは、`rawstring` 型のメソッド `utf8` を用いて `rawstring` を `string` に変換する操作である。
:::

## 文字列の操作

[Strings.](https://github.com/fubark/cyber/blob/0.2/docs/hugo/content/docs/toc/data-types.md#strings)
[Core Module.](https://github.com/fubark/cyber/blob/0.2/docs/hugo/content/docs/toc/modules.md#core-module)

`''` で囲むことで、(1行の) 文字列を表現できる。

文字列中に `{}` で囲んだ式を書くことで、その式の値を文字列に埋め込むことができる。

```
文字列[始点..終点]
```

と書くと、文字列の「始点」以降「終点」より前の部分文字列を得ることができる。
「始点」を省略すると最初から、「終点」を省略すると最後までになる。

```
文字列.find(検索対象)
```

と書くと、「文字列」の中で「検索対象」の文字列が最初に現れる位置を表す整数を得ることができる。

:::note info
資料にはこれを行うメソッドとして `index` が載っているが、これを使うと

> string.index() is deprecated since 0.2: Use string.find() instead.

というメッセージが出力された。
しかも、`find` メソッドは資料に載っていない。
:::

```
int(文字列)
```

により、「文字列」をそれが表す整数に変換できる。

# 提出コード

```
line1 = getInput().utf8()
line2 = getInput().utf8()
line3 = getInput().utf8()

spacepos = line2.find(' ')
bstr = line2[..spacepos]
cstr = line2[spacepos+1..]

sum = int(line1) + int(bstr) + int(cstr)
print '{sum} {line3}'
```

[提出 #55031554 - AtCoder Beginners Selection](https://atcoder.jp/contests/abs/submissions/55031554)