Notebook

Rustを触ってみた::8/19

タイムラインでRustという言語についての話題で盛り上がっていたので試しにABC100のA-C*1を解いてみることにした.

D問題については構造体とtraitやownership関係でイザコザして解けなかった.後程に解答を見て学習してみたいところ.

D問題:

fgjiutx.hatenablog.com

Rustが実際の現場で生かされている具体例などがあれば誰か教えていただきたいです.

チュートリアルとしては

https://doc.rust-jp.rs/the-rust-programming-language-ja/1.6/book/getting-started.html

を使っています.

A問題

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

fn read<T>() -> Vec<T>
where
  T: FromStr,
  <T as FromStr>::Err: Debug,
{
  let mut s = String::new();
  stdin().read_line(&mut s).unwrap();
  s.trim()
    .split_whitespace()
    .map(|c| T::from_str(c).unwrap())
    .collect()
}

fn main() {
  let input: Vec<u32> = read();
  println!(
    "{}",
    match &input.into_iter().find(|&v| v > 8) {
      Some(_v) => ":(",
      _ => "Yay!",
    }
  )
}

行ごとの標準入力は

Rustで競技プログラミング用の標準入力関数を作った

を参照しました.

アルゴリズムは所有権とかのノウハウがいまだにつかめない.

into_iterとfoldやfindが競プロにおいてはかなり使い勝手がいいと感じる.

B問題

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

fn read<T>() -> Vec<T> {
...
}

fn main() {
  let x: Vec<u32> = read();
  println!(
    "{}",
    match x[1] {
      100 => (x[1] + 1) * 100u32.pow(x[0]),
      _ => x[1] * 100u32.pow(x[0]),
    }
  );
}

全探索などを使わずとも,簡単なことに気付けばAより簡単な問題でした.

C問題

use std::fmt::Debug;
use std::io::stdin;
use std::iter::Iterator;
use std::str::FromStr;

fn read<T>() -> Vec<T> {
...
}

fn main() {
  let _n: Vec<u32> = read();
  let a: Vec<u32> = read();
  println!(
    "{:?}",
    a.into_iter().fold(0, |mut sum, mut v| {
      while v & 0x1 == 0 {
        v >>= 1;
        sum += 1
      }
      sum
    })
  );
}
  • 3で掛けることは動作に関して全く影響しない
  • 全て2で割る動作ができないが結局のところ最も多くの手数を稼ぐには一つだけ2で割る動作のみをすればいい
  • したがって,各要素が2で割れる回数の総和を取ればよい
  • foldがかなり便利だった.