【Rust】envファイルの設定方法

cargo.tomlと同じディレクトリに.envを作成します。

.env

APP_VERSION=1.0.0
APP_PROD=false
dotenv="0.15.0"
use dotenv::dotenv;
use std::env;

fn main() {
    dotenv();
    println!("{}", env::var("APP_VERSION").unwrap());
}

Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.28s
Running `target/debug/sample`
1.0.0

なるほどねー

【Rust】二分探索(binary search)

fn main() {
    let data = vec![10, 20, 30, 40, 50, 60, 70, 80, 90, 100];
    let target = 50;
    binary_search(data, target);
    
}

fn binary_search(data: Vec<u32>, target: u32) {
    let mut left = 0;
    let mut right = data.len() - 1;
    
    while left <= right {
        let mid = (left + right) / 2;
        if data[mid] == target {
            println!("ターゲットは要素の[{}]です。", mid);
            break;
        } else if data[mid] < target {
            left = mid + 1;
        } else {
            right = mid - 1;
        }
    }
}

Compiling rust v0.1.0 (/home/vagrant/dev/algorithm/rust)
Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.13s
Running `target/debug/rust`
ターゲットは要素の[4]です。

これは凄い面白いなあ

【Rust】線形探索

fn main() {
    let target = 40;
    let mut flg = format!("{}{}", target, "はデータの中にありません");
    let data = [50, 30, 90, 10, 20, 70, 60, 40, 80];
    for d in data {
        if d == 40 {
            flg = format!("{}{}", target, "はデータの中にあります!");
        }
    }
    println!("{}", flg);
}

Compiling rust v0.1.0 (/home/vagrant/dev/algorithm/rust)
Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.56s
Running `target/debug/rust`
40はデータの中にあります!

### 関数を定義
配列だと、data: [u32; 10] というように要素数を指定しなければならないので、Vectorの方が使い勝手が良い。

fn main() {
    let data = vec![50, 30, 90, 10, 20, 70, 60, 40, 80, 55];
    let target = 40;
    linear_search(data, target);
    
}

fn linear_search(data: Vec<u32>, target: u32) {
    let mut flg = format!("{}{}", target, "はデータの中にありません");
    for d in data {
        if d == 40 {
            flg = format!("{}{}", target, "はデータの中にあります!");
        }
    }
    println!("{}", flg);
}

【Blockchain】Walletの比較

人気のWallet比較

### coincheck(pc/mobile)
取引: 総資産、入金出金、購入、売却、送金、受取、積立、大口、NFT, チャート、トレードビュー
アカウント:アカウント変更、本人確認、電話番号、取引履歴、ログイン履歴
ログアウト

### bitcoin wallet(mobile)
btc amount, transaction, send, request, exchange rate, network monitor, block, peer情報

### Trust Crypto Wallet(mobile)
send, receive, buy, earn, crypt, NFT

### bitbank(pc/mobile)
総資産、現物、信用、保有銘柄、お気に入り、ピックアップ、入金、販売所、資産、お知らせ、メニュー、データ(履歴)、登録情報、設定、API

### SafePal wallet(app/hardware)
coin, Delfi, swap, bridge, exchange, market, favorite, deposit, Network

### coinbase wallet
Crypt, NFTs, DeFi,
Buy, swap, bridge, send, receive
Asset, Transaction, Browser, Explore, Setting

### blockchain.com
buy swap sell receive
Asset, price

### 楽天ウォレット
ホーム、運用状況、ニュース、お知らせ、メニュー

大体、どのような機能が必要かはわかりました。QRコードは必要ですね。

行列の計算

import random
from typing import List

Row = List[int]
Matrix = List[Row]

def matrix_multiply(matrix_a: Matrix, matrix_b: Matrix) -> Matrix:
    num_rows_a = len(matrix_a)
    num_cols_a = len(matrix_a[0])
    num_rows_b = len(matrix_b)
    num_cols_b = len(matrix_b[0])
    if num_cols_a != num_rows_b:
        raise ArithmeticError(
            f"Invalid dimensions; Cannot multiply "
            f"{num_rows_a}x{num_cols_a}*{num_rows_b}x{num_cols_b}"
        )
    solution_matrix = [[0] * num_cols_b for _ in range(num_rows_a)]
    for i in range(num_rows_a):
        for j in range(num_cols_b):
            for k in range(num_cols_a):
                solution_matrix[i][j] += matrix_a[i][k] * matrix_b[k][j]
    return solution_matrix

if __name__ == "__main__":
    cols = 3
    rows = 2
    A = [[random.randint(0, 10) for i in range(cols)]
        for j in range(rows)]
    print(f"matrix A: {A}")
    B = [[random.randint(0, 10) for i in range(rows)]
        for j in range(cols)]
    print(f"matrix B: {B}")
    C = matrix_multiply(A, B)
    print(f"matrix C: {C}")

$ python3 matmul_sequential.py
matrix A: [[9, 0, 0], [10, 6, 1]]
matrix B: [[9, 5], [1, 5], [10, 5]]
matrix C: [[81, 45], [106, 85]]

【Rust】fibonacci関数にcoroutineを組み合わせたい

関数の呼び出しの中でcoroutineを使用する。返り値にimpl Coroutineと書くと、期待通りの挙動になる。

#![feature(coroutines)]
#![feature(coroutine_trait)]
#![feature(stmt_expr_attributes)]

use std::ops::{Coroutine, CoroutineState};
use std::pin::Pin;

fn test() -> impl Coroutine{
    let mut coroutine = #[coroutine] || {
        println!("2");
        yield;
        println!("4");
    };
    return coroutine
}

fn main() {
    
    let mut coroutine = test();

    println!("1");
    Pin::new(&mut coroutine).resume(());
    println!("3");
    Pin::new(&mut coroutine).resume(());
    println!("5");
}

Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.22s
Running `target/debug/parallel`
1
2
3
4
5

fn fibonacci(n: u32)-> u32{
    if(n == 1) || (n == 2) {
        return 1;
    }
    return coroutines::spawn(move ||fibonacci(n - 2)).join().unwrap() + coroutines::spawn(move ||fibonacci(n - 1)).join().unwrap();
}

fn main() {
    println!("{}", fibonacci(8));
}

error: linking with `cc` failed: exit status: 1
|
= note: LC_ALL=”C” PATH=”/home/vagrant/.rustup/toolchains/nightly-aarch64-unknown-linux-gnu/lib/rustlib/aarch64-unknown-linux-gnu/bin:/home/vagrant/.vscode-server/cli/servers/Stable-fee1edb8d6d72a0ddff41e5f71a671c23ed924b9/server/bin/remote-cli:/home/vagrant/.local/bin:/home/vagrant/.cargo/bin:/home/vagrant/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin” VSLANG=”1033″ “cc” “/tmp/rustclduixt/symbols.o” “<71 object files omitted>” “-Wl,–as-needed” “-Wl,-Bstatic” “/home/vagrant/dev/rust/parallel/target/debug/deps/{libcoroutines-73d67594ef572d45.rlib,libspin-b921464275125a8a.rlib}” “/home/vagrant/.rustup/toolchains/nightly-aarch64-unknown-linux-gnu/lib/rustlib/aarch64-unknown-linux-gnu/lib/{libstd-37c91c156f70721a.rlib,libpanic_unwind-091ab8f68cc61686.rlib,libobject-e2f7a15061957456.rlib,libmemchr-c98c798b414d6437.rlib,libaddr2line-9aff78f201895d3e.rlib,libgimli-136ec4cd87684724.rlib,librustc_demangle-de97401acb73e7bd.rlib,libstd_detect-c05658b587ae52a4.rlib,libhashbrown-64cb6e685fd4789d.rlib,librustc_std_workspace_alloc-83e0c642422571d6.rlib,libminiz_oxide-37d00f2abcaa32e0.rlib,libadler2-4baacb3803247097.rlib,libunwind-7fc1e71b6d069b5b.rlib,libcfg_if-96e210777df10d05.rlib,liblibc-910d42f9f92e088d.rlib,liballoc-8d48e7538af467a9.rlib,librustc_std_workspace_core-1afa26d7618dba03.rlib,libcore-a40bbbb3fb06de3c.rlib,libcompiler_builtins-2b4a3d060745bb29.rlib}” “-Wl,-Bdynamic” “-lunblock_hook” “-lgcc_s” “-lutil” “-lrt” “-lpthread” “-lm” “-ldl” “-lc” “-Wl,–eh-frame-hdr” “-Wl,-z,noexecstack” “-L” “/home/vagrant/.rustup/toolchains/nightly-aarch64-unknown-linux-gnu/lib/rustlib/aarch64-unknown-linux-gnu/lib” “-o” “/home/vagrant/dev/rust/parallel/target/debug/deps/parallel-9e5acb293a2c78f7” “-Wl,–gc-sections” “-pie” “-Wl,-z,relro,-z,now” “-nodefaultlibs”
= note: some arguments are omitted. use `–verbose` to show all linker arguments
= note: /usr/bin/ld: cannot find -lunblock_hook: No such file or directory
collect2: error: ld returned 1 exit status

うーん、わからん…

【Rust】coroutineを使いたい

#![feature(coroutines)]
#![feature(coroutine_trait)]
#![feature(stmt_expr_attributes)]

use std::ops::{Coroutine, CoroutineState};
use std::pin::Pin;

fn main() {
    let mut coroutine = #[coroutine] || {
        yield 1;
        "foo"
    };

    match Pin::new(&mut coroutine).resume(()) {
        CoroutineState::Yielded(1) => {
            println!("yielded test");
        }
        _ => panic!("unexpected return from resume"),
    }
    match Pin::new(&mut coroutine).resume(()) {
        CoroutineState::Complete("foo") => {
            println!("foo test");
        }
        _ => panic!("unexpected return from resume"),
    }
}

error[E0554]: `#![feature]` may not be used on the stable release channel

$ rustup install nightly
$ cargo +nightly run
Compiling parallel v0.1.0 (/home/vagrant/dev/rust/parallel)
Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.28s
Running `target/debug/parallel`
yielded test
foo test

use std::ops::{Coroutine, CoroutineState};
use std::pin::Pin;

fn main() {
    let mut coroutine = #[coroutine] || {
        println!("2");
        yield;
        println!("4");
    };

    println!("1");
    Pin::new(&mut coroutine).resume(());
    println!("3");
    Pin::new(&mut coroutine).resume(());
    println!("5");
}

Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.27s
Running `target/debug/parallel`
1
2
3
4
5

Pin::new(&mut coroutine).resume(());で一旦停止するのか…

【Rust】フィボナッチ数列

フィボナッチは再起的に計算を行う。

6 の場合は、
6 -> (4,5)
4 -> (2,3)
5 -> (3,4)
2 -> 【1】
3 -> (1, 2) -> 【1】【1】

fn fibonacci(n: u32)-> u32{
    if(n == 1) || (n == 2) {
        return 1;
    }
    return fibonacci(n - 2) + fibonacci(n - 1);
}


fn main() {
    println!("{}", fibonacci(6));
}

Compiling rust v0.1.0 (/home/vagrant/dev/algorithm/rust)
Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.12s
Running `target/debug/rust`
8

8の時は21, 10は55となる。
なんか不思議な感じがする。

【Rust】素数の判定

まず、prime(平方根)を計算する。sqrt()はf64にする必要がある。

fn main() {
    let x = [1, 2, 3, 4, 5, 6, 7, 8, 9];
    for i in x {
        let y = (i as f64).sqrt();
        println!("{}", y);
    }
}

Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.29s
Running `target/debug/rust`
1
1.4142135623730951
1.7320508075688772
2
2.23606797749979
2.449489742783178
2.6457513110645907
2.8284271247461903
3

nが、2から平方根までの値で割り切れれば、素数ではない

fn main() {
    let x = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15];
    for i in x {
        let mut flag = true;
        let prime = (i as f64).sqrt();
        if prime >= 2.0 {
            for j in 2..((prime + 1.0) as u32){
                if i % j == 0 {
                    flag = false;
                    break;
                }
            }
        }
        if flag == true {
            println!("{}は素数です", i);}
    }
}

Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.14s
Running `target/debug/rust`
1は素数です
2は素数です
3は素数です
5は素数です
7は素数です
11は素数です
13は素数です

floatへの変換を書かなければならない分、コードが冗長になるが、もう少しエレガントに書きたいものだ。○○か否かはTrue or Falseが書きやすい。

【Rust】Eventとdeque

Eventを待ち受ける側はループで待機し、イベントキューに新しいEventが登録されるとコールバックする。

use std::collections::VecDeque;
use std::thread;
use std::sync::Mutex;

static deque: Mutex<VecDeque<String>> = Mutex::new(VecDeque::new());

fn main() {

    let handle = thread::spawn(move || {
        loop {
            if deque.lock().unwrap().len() > 0 {
                println!("Who' threre?");
                deque.lock().unwrap().pop_front();
            }
        }
    });

    let event1 = "Peter knock".to_string();
    deque.lock().unwrap().push_back(event1);
    println!("{:?}", deque);

    let event2 = "John knock".to_string();
    deque.lock().unwrap().push_back(event2);
    println!("{:?}", deque);
    handle.join().unwrap();
}

Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.22s
Running `target/debug/parallel`
Mutex { data: [“Peter knock”], poisoned: false, .. }
Mutex { data: [“Peter knock”, “John knock”], poisoned: false, .. }
Who’ threre?
Who’ threre?