Naomi's notebook

Naomi's notebook

AtCoder Beginners Selection in Rust

Rustをやってほしいという声が出たので
TypeScriptもお勧めがあったのですが、忙しくなってきたのでとりあえずしばらくこのABSシリーズはお休みしようと思います

過去の記事
naomi-notebook.hatenablog.com
naomi-notebook.hatenablog.com
naomi-notebook.hatenablog.com
naomi-notebook.hatenablog.com
naomi-notebook.hatenablog.com
naomi-notebook.hatenablog.com

参考にしたもの

stdのドキュメント
std - Rust
出来るだけドキュメントだけを見て書いてみました(某さんに勧められたので)。英語がつらい…けど楽しかったです。

PracticeA Welcome to AtCoder

use std::io;
fn main(){
let mut str1= String::new();
let mut str2= String::new();
let mut str3= String::new();
io::stdin().read_line(&mut str1);
io::stdin().read_line(&mut str2);
let mut itr=str2.split_whitespace();
io::stdin().read_line(&mut str3);
let a: i32=str1.trim().parse().unwrap();
let b: i32 =itr.next().unwrap().parse().unwrap();
let c: i32 =itr.next().unwrap().parse().unwrap();
println!("{} {}",a+b+c,str3.trim());
}

ABC086A Product

use std::io;
fn main(){
let mut s= String::new();
io::stdin().read_line(&mut s);
let mut itr = s.split_whitespace();
let a: i32=itr.next().unwrap().parse().unwrap();
let b: i32=itr.next().unwrap().parse().unwrap();
if a*b%2==0 {
    println!("Even");
}else{
    println!("Odd");
}
}

ABC081A Placing Marbles

use std::io;
fn main(){
let mut s= String::new();
io::stdin().read_line(&mut s);
println!("{}",s.matches("1").count());
}

ABC081B Shift only

use std::io;
fn main(){
let mut sN= String::new();
let mut sA= String::new();
io::stdin().read_line(&mut sN);
io::stdin().read_line(&mut sA);
let mut nums: Vec<u32>=sA.split_whitespace().map(|x| x.parse::<u32>().unwrap()).collect();
let mut cnt: u32 = 0;
while nums.iter().all(|x|x%2==0) {
    cnt+=1;
    nums=nums.iter().map(|x|x/2).collect()
}
println!("{}",cnt);
}

ABC087B Coins

inputを使いまわそうとしたらunwrapでエラーが出たので安直に書いてしまった
後の処理に対して整合性が出るように型推定しようとしたら失敗したのかな。
もっと短くするとすれば入力を全部読み込んでからlines()でmapして整数にするとかかな

use std::io;
fn main(){
let mut input1= String::new();
let mut input2= String::new();
let mut input3= String::new();
let mut input4= String::new();
io::stdin().read_line(&mut input1);
let a: u32=input1.trim().parse().unwrap();
io::stdin().read_line(&mut input2);
let b: u32=input2.trim().parse().unwrap();
io::stdin().read_line(&mut input3);
let c: u32=input3.trim().parse().unwrap();
io::stdin().read_line(&mut input4);
let x: u32=input4.trim().parse().unwrap();
let mut cnt: u32=0;
for i in 0..(a+1){
    for j in 0..(b+1){
        if (x-i*500-j*100)/50>=0&&(x-i*500-j*100)/50<=c {
            cnt+=1;
        }
    }
}
println!("{}",cnt);
}

ABC083B Some Sums

流石にそのままはつまらないので、書く桁の数字を合計するところでちょっとだけ工夫

use std::io;
fn main(){
let mut input= String::new();
io::stdin().read_line(&mut input);
let mut itr=input.split_whitespace();
let n: u32=itr.next().unwrap().parse().unwrap();
let a: u32=itr.next().unwrap().parse().unwrap();
let b: u32=itr.next().unwrap().parse().unwrap();
let mut ans: u32=0;
for i in 1..(n+1){
    let mut dsum: u32=i.to_string().chars().map(|x| x.to_digit(10).unwrap()).sum();
    if dsum>=a && dsum <=b {ans+=i;}
}
println!("{}",ans);
}

ABC088B Card Game for Two

use std::io;
fn main(){
let mut input1= String::new();
let mut input2= String::new();
io::stdin().read_line(&mut input1);
io::stdin().read_line(&mut input2);
let mut n: i32=input1.trim().parse().unwrap();
let mut a: Vec<i32>=input2.split_whitespace().map(|x| x.parse::<i32>().unwrap()).collect();
a.sort();
let mut ans: i32=0;
for i in a{ ans=i-ans;}
println!("{}",ans.abs());
}

なんとなくみたらRustのなかでshortestだった(他のもそうかもしれない)

ABC085B Kagami Mochi

itertools - Rust を使おうとしたらcan't find crate for `itertools`がでた、対応してないのか〜
でもよく見たら
.sort().dedup()std::vec::Vec - Rustでuniqueみたいなことができたのでできた。

read_to_stringはio::Read。

use std::io;
use std::io::Read;

fn main(){
let mut input1= String::new();
let mut input2= String::new();
io::stdin().read_line(&mut input1);
io::stdin().read_to_string(&mut input2).unwrap();
let mut n: i32=input1.trim().parse().unwrap();
let mut d: Vec<i32>=input2.split_whitespace().map(|x| x.parse::<i32>().unwrap()).collect();
d.sort();
d.dedup();
println!("{}",d.len());
}

ABC085C Otoshidama

use std::io;
use  std::process;

fn main(){
let mut input= String::new();
io::stdin().read_line(&mut input);
let mut itr=input.split_whitespace();
let n: u32=itr.next().unwrap().parse().unwrap();
let mut y: u32=itr.next().unwrap().parse().unwrap();
y/=1000;
for i in 0..(n+1){
    for j in 0..(n+1-i){
        if y-i*10-j*5==n-i-j {
            println!("{} {} {}",i,j,n-i-j);
            process::exit(0);
        }
    }
}
println!("-1 -1 -1");
}

ABC049C 白昼夢 / Daydream

正規表現できないじゃん…
Haskellの時と同じようにやりました。
AtCoder Beginners Selection in Haskell 完走 - Naomi's notebook
input.trim()で最後の改行文字を取り除くのを忘れずに(YESがNOになる)

AtCoderのRustのバージョンが1.15.1なんだけど、getを使おうとしたら1.20.0からなのでコンパイルエラーになったコード
Optionが例外処理をやってくれるから長さの確認とかいらなかった(Rustのいいところが感じられたかも)

use std::io;

fn recfn(inp: &str) -> bool{
    if inp.len()==0 {return true;}
    else if inp.get(..7)==Some("dreamer") {return recfn(inp.get(7..).unwrap()) || recfn(inp.get(5..).unwrap());}
    else if inp.get(..6)==Some("eraser")  {return  recfn(inp.get(6..).unwrap()) || recfn(inp.get(5..).unwrap());}
    else if inp.get(..5)==Some("dream")  {return recfn(inp.get(5..).unwrap());}
    else if inp.get(..5)==Some("erase") {return recfn(inp.get(5..).unwrap());}
    else {return false;}
}
fn main(){
let mut input= String::new();
io::stdin().read_line(&mut input);
if recfn(&input.trim()) {
    println!("YES");
}else{
    println!("NO");
}
}

こちらなら1.15でも通る

use std::io;

fn recfn(inp: &str) -> bool{
    if inp.len()==0 {return true;}
    else if inp.len()>=7&& &inp[..7]=="dreamer" {return recfn(&inp[7..]) || recfn(&inp[5..]);}
    else if inp.len()>=6&& &inp[..6]=="eraser" {return recfn(&inp[6..]) || recfn(&inp[5..]);}
    else if inp.len()>=5&& &inp[..5]=="dream" {return recfn(&inp[5..]);}
    else if inp.len()>=5&& &inp[..5]=="erase" {return recfn(&inp[5..]);}
    else {return false;}
}
fn main(){
let mut input= String::new();
io::stdin().read_line(&mut input);
if recfn(&input.trim()) {
    println!("YES");
}else{
    println!("NO");
}
}

ABC086C Traveling

もっと工夫するとしたらread_to_stringして多次元配列にしたものを前から…みたいな感じにすれば(rubyかなんかでやった)短くなるかな?でも一応一番短いっぽかった

use std::io;
use std::process;

fn main(){
let mut input= String::new();
io::stdin().read_line(&mut input);
let n: i32= input.trim().parse().unwrap();
let tb: i32=0;let xb: i32=0;let yb: i32=0;
for i in 0..n {
    let mut inputs= String::new();
    io::stdin().read_line(&mut inputs);
    let mut itr=inputs.split_whitespace();
    let t: i32=itr.next().unwrap().parse().unwrap();
    let x: i32=itr.next().unwrap().parse().unwrap();
    let y: i32=itr.next().unwrap().parse().unwrap();
    let d: i32=t-tb-(x-xb).abs()-(y-yb).abs();
    if d<0 || d%2!=0 {
        println!("No");
        process::exit(0);
    }
}
println!("Yes");
}

おまけ

検索したら先人がいた(それはそう)
説明が詳しいのでこっちをみた方が勉強になるかも
AtCoder に登録したら解くべき精選過去問 10 問を Rust で解いてみた - Qiita