V 言語で競技プログラミング

V 言語が競技プログラミングに適しているかどうかはわかりませんが、ちょっと V 言語をさわってみたかったので試しに競プロやってみます。

1. V 言語とは

2019 年 6 月に公開されたプログラミング言語です。
構文は Go 言語っぽいです。

  • なんか速いらしい
  • ヌルがない
  • C 言語のソースを V 言語に変換可能
    • バージョン 0.3 で追加予定(現在 v0.1.21)
  • バックエンドが C

私はこれくらいのことしか知らないので、もっと詳しく知りたい方は GitHub へ!

名称は公式が「V」としています。
話すときに Go 言語みたいに「ブイラング」と言うのは避けたほうがいいのでしょうか。

Please note that the name of the language is "V", not "Vlang" or "V-Lang" etc.
公式ドキュメント参照

2. 概要と方針

V 言語で競技プログラミングやります。
ただメジャーリリース(2019 年 12 月予定)がされていない状態で、V 言語対応している競プロサイトはおそらくないです。

V 1.0 release is planned for December 2019. Right now V is in an alpha stage.
GitHub 参照

そこで V 言語のソースを「間接的に」競プロサイトに提出します。
V 言語はバックエンドが C 言語ということもあり、-keep_c オプションをつけることで C 言語のファイルを出力することができます。

出力された C 言語のソースを提出することで、V 言語で間接的に競プロサイトのオンラインジャッジ機能を使えます。

3. V 言語の環境構築

README の手順通りにやりました。

  1. インストール
$ git clone https://github.com/vlang/v
$ cd v
$ make
  1. シンボリックリンク
    別のディレクトリでも V コマンドを実行できるようにします。
$ sudo ./v symlink

ディレクトリに移動して試して見ます。

$ v -h
Usage: v [options/commands] [file.v | directory]

   When V is run without any arguments, it is run in REPL mode.

// 省略

アップデートは以下のコマンドです。

$ v up

4. やってみる

V 言語で初の「AtCoder に登録したら解くべき精選過去問 10 問を 〇〇 言語 で解いてみた」の記事を出せるぞと意気揚々とググってみたら、すでにやられている方がいらっしゃいました。
はやすぎる...

記事はこちらです。

上記記事でも書いてありますが、V 言語には 2019 年 10 月現在、標準入力のライブラリがありません。
ただ C 言語のライブラリを呼び出せるのでそちらを使います。

今回は AOJAtCoder の問題を 1 問ずつ解いてみます。
V 言語の GitHub のソースを見ると、インデントはスペースではなく「タブ」のようです。

AtCoder Beginner Contest 143: A - Curtain

V 言語のソース

  • mut をつけずに宣言した変数は変更不可
  • C.hoge で C 言語のライブラリを呼び出し
fn main(){
    a := 0
    b := 0
    C.scanf("%d %d", &a, &b)

    mut ans := a - b * 2
    if ans < 0{
        ans = 0
    }

    println(ans)
}

mut をつけて変更がない変数があった場合はコンパイルエラーになります。

<file>.v:11:11: `ans` is declared as mutable, but it was never changed

宣言して使われないない変数があった場合は、コンパイルは通りますが警告が出ます。

warning: <file>.v:5:5: `a` declared and not used

出力された C 言語のソース

以下コマンドで、<file>.tmp.c というファイルが出力されます。

$ v run <file>.v -keep_c

とんでもない行数のソースが出力されるので、該当箇所だけ切り抜きました。

 void main__main() {

int a= 0 ;

int b= 0 ;

 scanf ( "%d %d" ,  & a ,  & b ) ;

int ans= a - b * 2 ;

 if ( ans < 0 ) {

 ans  =  0 ;

 }
 ;

 /*opt*/printf ("%d\n",  ans ) ;

 }

これで V 言語で AtCoder に参加することができます!

AOJ: Ring

V 言語のソース

C 言語の文字列を V 言語の文字列に変換する必要あります。
そこは Qiita の記事を参考にしました。

fn main(){
    s := malloc(1)
    p := malloc(1)
    C.scanf("%s %s", s, p)
    s_str := string(s) + string(s)
    p_str := string(p)

    mut flag := false
    for i := 0; i < (s_str.len / 2); i++ {
        if p_str == s_str.substr(i, i + p_str.len) {
            flag = true
        }
    }

    if flag {
        println("Yes")
    }else{
        println("No")
    }
}

私が確認した範囲では文字列を検索する関数はなかったのでループ回してます。

AOJ の提出コード長の制約

出力される C 言語のコードは 80,000 文字以上になりますが、AOJ では 30,000 文字以上のコードは提出することができません。

f:id:Doarakko:20191023002441p:plain

出力された C 言語のソースのメイン関数を読みながら、不要な箇所を削除(必要な箇所だけ追加)する必要があります。
V 言語と一緒に C 言語も勉強したい方にはおすすめです。

5. おわりに

C 言語のソース出力はオプションつけるだけなので記事にするほどではないかなと思いましたが、ドキュメント等に C 言語のソースを出力できることについての記載がなく、コマンドのヘルプ出して初めてわかったのでまとめてみました。

V 言語の公式 Twitter では、度々構文などについてどれがいいかアンケートが行われています。

どれくらい開発に影響しているかわかりませんがおもしろいです。
今後の V 言語に注目していきたいと思います。

6. 参考資料