LoginSignup
2
1

More than 3 years have passed since last update.

競技プログラミング用のD言語でいい感じに入力を取るライブラリ

Posted at

まえがき

自分のために作ったのですが、
使ってて結構気持ちいいので記事にしました。
一番下に本体があるのでコピペして使ってください。

どんな感じか

例えばグラフだと、

//N
//An Bn
3
1 2
2 3
1 3

これを読もうとするコードはこんな感じになると思うんですけど結構冗長ですよね。

struct Edge{
    long a, b;
}
long N;
readf("%d", N);
Edge[] edges;
foreach(i;0..N){
    long x, y;
    readf("%d %d", x, y);
    edges ~= Edge(x, y);
}

このライブラリを使うとこんな感じで読めます。

struct Edge{
    long a, b;
}
auto N = scanElem;
Edge[] edges = scanElem!Edge(N);

機能

空白区切りで1つずつ読んでいきます
改行などもいい感じに処理してくれます

T scanElem!(T=long)
T[] scanElem!(T=long)(long size)
T scanElem(T)()if(is(T==struct))
Tuple!List[] scanElem(List...)(long size)
Tuple!List scanElem(List...)()

テンプレートに型を渡します。
構造体を渡すとメンバーを上から順番に読んでくれます。
構造体が入れ子になっていても再帰的に読んでいきます。
複数渡すとタプルにして返します。

scanElemの引数に読み込む個数を渡すと配列にいれてくれます。
引数なしならそのまま1つです。

文字列も取れます

//N
//NAMEn AGEn
3
harusann2 22
nako 3
tako 1
void main(){
    struct User{
       string name;
       long age;
    }
    long N = scanElem;
    User[] users = scanElem!User(N);
}

入れ子にも出来ます

//N
//Xn Yn Rn
2
1.2 2 0.3
3.8 4.2 0.9
void main(){
    struct Vector{
       real x, y; 
    }
    struct Cicle{
        Vector pos;
        real r;
    }
    long N = scanElem;
    Cicle[] cicle = scanElem!Cicle(N);
}

タプル

1 2
void main(){
    Tuple!(long,long) HW = scanElem!(long,long);
}

本体

コピペして使ってください

T[] scanElem(T=long)(long size)
{
    T[] list = new T[size];
    foreach(i;0..size)
    {
        list[i] = scanElem!T;
    }
    return list;
}

T scanElem(T)()
if(is(T==struct))
{
    T res;
    foreach(ref field; res.tupleof){
        field = scanElem!(typeof(field));
    }
    return res;
}

Tuple!List[] scanElem(List...)(long size)
{
    auto list = new Tuple!List[size];
    foreach(i;0..size)
    {
        list[i] = scanElem!List;
    }
    return list;
}
Tuple!List scanElem(List...)()
{
    List res;
    foreach(i, e; List){
        res[i] = scanElem!e;
    }
    return tuple(res);
}

T scanElem(T = long)()
if(isBasicType!T||isSomeString!T)
{
    import core.stdc.stdlib;
    static auto scanBuf = appender!(char[])([]);

    scanBuf.clear;

    int c = ' ';
    while (isWhite(c) && c != -1)
    {
        c = getchar;
    }
    while (!isWhite(c) && c != -1)
    {
        scanBuf ~= cast(char) c;
        c = getchar;
    }
    return scanBuf.data.to!T;
}

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1