nunulkのプログラミング徒然日記

毎日暇なのでプログラミングの話題について書きたいことがあれば書いていきます。

アルゴ式が楽しい

はじめに

この記事について

最近暇なので、アルゴリズムの勉強でもしようかと思い、ネットで見かけた「アルゴ式」というプログラミング学習サービスを使って、アルゴリズムの基礎を学んでいます。始めてから1ヶ月ほど経ったので感想などをまとめておきます。

アルゴ式とは

algo-method.com

主にアルゴリズムを学ぶための無料で利用できるプログラミング学習サービスです。

アルゴ式の特徴は以下で、

  • C++, Python をメインにしているが複数の言語から好きな言語を選択できる
  • 他人の解答が見られる
  • 解説(解答例付き)を読める
  • 時間制限がない

2023/2/9 時点で 20 以上のセクション、800 以上の問題があり、各セクション内の問題は易しいものから徐々に難しくなっていくので、段階的に学ぶことができます。

自分は Rust を使い始めたばかりなので Rust で書いてます(ただし、一部 Python のみをターゲットにしたコンテンツもありますし、正規表現のような追加のクレートが必要なものは対応できないです)。

自分のバックグラウンド

自分はコンピュータサイエンスを学んだことはなく、この領域は完全に素人なので、こうやって基礎的な部分から段階的に学べるサービス(しかも無料!)は大変ありがたいです。

昔ハードウェアの制御とかやってたのでさすがに2進法とか16進法とかはわかりますが、動的計画法とかグラフ理論とかまで行くとちんぷんかんぷんといったところです。

アルゴ式の好きなところ

  • 自分専用のテンプレートを保存できる
  • 易しい問題から段階的に学べる

自分専用のテンプレートを保存できる

各問題を開いたときにデフォルトで表示されるコードを保存しておくことができます。

自分は以下のコードをテンプレートにしています。 一行にひとつ値(数値か文字列)がある場合と一行に型が同一の複数の値がスペース区切りであるケースに対応しています。

use std::io;
use std::str::FromStr;
use std::fmt::Debug;

fn input<T>() -> Result<T, T::Err> where
    T: FromStr,
    T::Err: Debug {
    let mut line = String::new();
    io::stdin()
        .read_line(&mut line)
        .expect("Failed to read line.");
    return line.trim().parse::<T>();
}

fn inputs<T>() -> Vec<T> where
    T: FromStr,
    T::Err: Debug {
    let mut line = String::new();
    io::stdin()
        .read_line(&mut line)
        .expect("Failed to read line.");
    return line.trim()
        .split(' ')
        .map(|el| el.parse::<T>().expect("Failed to parse value."))
        .collect::<Vec<T>>();
}

fn main() {
    println!("Hello World!");
}

ほかにもっといい書き方があるかもしれませんが(他の方のコードをチラ見したらマクロで対応されてる方もいました)、いまのところこれで問題はありません(複数の値は返り値がベクタになって、デストラクチャできないので、タプルで返すようにしたほうがやや楽になるかもしれません)。

易しい問題から段階的に学べる

たとえば、ビット演算のセクションでは、ビットとはなにかの解説から始まって、2進法の簡単な問題からビットシフト、ビット演算を経て最終的にはナップサック問題のような応用的な問題に至ります。

アルゴ式の惜しいところ

アルゴリズムに特化してるので仕方ないんですが、なかなかユーザーデータ型(Rust でいうと構造体や列挙体とか)を使う場面がないのがちょっと残念ではあります。

「さまざまなデータ構造」のセクションで連結リストとかツリーとかを自作する問題もありますが、実際にはこの辺はライブラリを使いたい種類のものなので、より実務よりというか、複数のフィールドが存在する RDB 上のデータみたいなのを使ってなにか計算させたり、ポリモーフィズムを使って表現できるようななにかを使うとか、そういうのもちょっとほしいです(解答の正否ではなくユーザーデータ型で表現可能かどうかなので、既存の問題でも無理やりやろうと思えばできるやつもあるかもしれません。もしあればやってみようと思います)。

おわりに

アルゴ式は競技プログラミングの練習という役割もあると思いますが、自分のようにコンテストには興味はないが日常的に数学的な問題を解きたい、みたいな層にはぴったりだと思いますし、全問解き終わるまでだらだらとやっていこうと思います。

もちろん、いきなりコンテストに出るよりはまず基礎を固めてから、と考えてる方にもおすすめです。

競技プログラミングに興味のある方はいちど覗いてみるといいんじゃないでしょうか(「統計学機械学習のための確率分布」や「日本情報オリンピック (予選) 過去問」とかも面白そうなので、それ以外の方も)。