硬貨の問題

fn main() {
   let C: [i32; 6] = [3, 2, 1, 3, 0, 2];
   let mut A = 620;

   let V: [i32; 6] = [1, 5, 10, 50, 100, 500];

   let mut ans: i32 = 0;

   for i in (0..6).rev() {
      let t = std::cmp::min(A / V[i], C[i]);
      A -= t * V[i];
      ans += t;
   }

   println!("{}", ans);
}

【Blockchain】Avalancheのノードの稼働

$ wget -nd -m https://raw.githubusercontent.com/ava-labs/avalanche-docs/master/scripts/avalanchego-installer.sh;\
chmod 755 avalanchego-installer.sh;\
./avalanchego-installer.sh

$ ./avalanchego –network-id=local –staking-enabled=false –snow-sample-size=1 –snow-quorum-size=1 –http-host=0.0.0.0

【Rust】スタックマシンでループ文を実装するための準備

ループで実行する処理文を記憶するために、”{ }”で囲まれている中身を取得してベクターで保存しておく。

fn main() {
    let mut stack = vec![];
    let mut instructions = vec![];

    let str = "1 2 + { 10 20 + }".to_string();
    let mut words: Vec<_> = str.split(" ").collect();

    while let Some((&word, mut rest)) = words.split_first() {
        if word.is_empty() {
            break;
        }
        if word == "{" {
            (instructions, rest) = parse_instruction(rest);
        } else if let Ok(parsed) = word.parse::<i32>() {
            stack.push(parsed.to_string());
        } else {
            match word {
              "+" => add(&mut stack),
              _ => panic!("{word:?} could not be parsed"),
            }
        }
        words = rest.to_vec();
    }
    println!("{:?}", stack);
    println!("{:?}", instructions);
}

fn parse_instruction<'src, 'a>(input: &'a [&'src str])-> (Vec<String>, &'a [&'src str]) {
    let mut tokens: Vec<String> = vec![];
    let mut words = input;

    while let Some((&word, mut rest)) = words.split_first() {
        if word.is_empty() {
            break;
        }
        if word == "}" {
            return (tokens, rest);
        } else {
            tokens.push(word.to_string())
        }
        words = rest;
    }
    (tokens, words)
}

fn add(stack: &mut Vec<String>) {
    let rhs: i32 = stack.pop().unwrap().parse::<i32>().unwrap();
    let lhs: i32 = stack.pop().unwrap().parse::<i32>().unwrap();
    stack.push((lhs + rhs).to_string());
}

Running `target/debug/sample`
[“3”]
[“10”, “20”, “+”]

【Rust】axumでcookieを取得する

routeにmiddlewareをくっつけます。
Requestのheadersからcookieを取得します。

#[tokio::main]
async fn main() {
    let app = axum::Router::new()
        .route("/", axum::routing::get(handle_index))
        .layer(middleware::from_fn(my_middleware));

    let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await.unwrap();
    axum::serve(listener, app).await.unwrap();
}
//
async fn my_middleware(req: Request,
    next: Next,) -> impl IntoResponse {

    let mut session_token = req
        .headers()
        .get_all("Cookie")
        .iter()
        .filter_map(|cookie| {
            cookie
                .to_str()
                .ok()
                .and_then(|cookie| cookie.parse::<cookie::Cookie>().ok())
        })
        .find_map(|cookie| {
            (cookie.name() == "hoge".to_string()).then(move || cookie.value().to_owned())
        });
    println!("{:?}", &session_token);

    let cookies = req.headers().get("cookie");
    println!("{:?}", &cookies);

    let mut res = next.run(req).await;
    res
}

Finished `dev` profile [unoptimized + debuginfo] target(s) in 3.60s
Running `target/debug/axum`
Some(“value”)
Some(“hoge=value”)
hoge=value; Max-Age=600

ほう、なるほど。middlewareにリダイレクトを追加したい。

【Rust】型エイリアス(type)

fn main(){

    let x = 123;
    println!("{}", type_of(x));
}

fn type_of<T>(_: T) -> &'static str {
    std::any::type_name::<T>()
}

c++だと、typeid

#include <iostream>
#include <typeinfo>

struct Base {};
struct Derived : public Base {};

struct PolyBase {virtual void member(){}};
struct PolyDerived : public PolyBase {};


int main() {
    int i;
    int* pi;
    std::cout << "int is: " << typeid(int).name() << std::endl;
    std::cout << "i is: " << typeid(i).name() << std::endl;
    std::cout << "pi is: " << typeid(pi).name() << std::endl;
    std::cout << "*pi is: " << typeid(*pi).name() << std::endl;
    std::cout << std::endl;

    Derived derived;
    Base *pbase = &derived;
    std::cout << "derived is: " << typeid(derived).name() << std::endl;
    std::cout << "*pbase is: " << typeid(*pbase).name() << std::endl;
    std::cout << std::boolalpha << "same type? " << (typeid(derived) == typeid(*pbase)) << std::endl;
    std::cout << std::endl;

    PolyDerived polyderived;
    PolyBase* ppolybase = &polyderived;
    std::cout << "polyderived is: " << typeid(polyderived).name() << std::endl;
    std::cout << "*ppolybase is: " << typeid(*ppolybase).name() << std::endl;
    std::cout << std::boolalpha << "same type? " << (typeid(polyderived) == typeid(*ppolybase)) << std::endl;
}
fn main(){
    let i = 10;
    let j = 3.14;
    println!("{}", type_of(i));
    println!("{}", type_of(j));
}

fn type_of<T>(_: T) -> &'static str {
    std::any::type_name::<T>()
}

derivedは派生。rustはclassがなくstructとimplなので、baseとderivedという概念があるか不明。。

【Rust】スライス


fn main(){
    let s = String::from("ABCDEFGH");
    let s1 = &s[0..3];
    let s2 = &s[3..6];
    println!("{} {}", s1, s2);


}

c++でsliceはないので、関数で書いている場合

#include <iostream>
#include <vector>

template<typename T>
void print(std::vector<T> const &v)
{
    for (auto i: v) {
        std::cout << i << ' ';
    }
    std::cout << std::endl;
}

template<typename T>
std::vector<T> slice(std::vector<T> const &v, int m, int n)
{
    auto first = v.cbegin() + m;
    auto last = v.cbegin() + n + 1;

    std::vector<T> vec(first, last);
    return vec;
}

int main()
{
    std::vector<int> v = {1, 2, 3, 4, 2, 2, 4, 6, 5};

    int m = 4, n = 7;
    std::vector<int> sub_vec = slice(v, m, n);
    print(sub_vec);
    return 0;
}
fn print(v: Vec<i32>) {
    for &i in & v {
        print!("{} ", &i);
    }
    print!("\n");
}

fn slicing(v: Vec<i32>, m: i32, n: i32) -> Vec<i32>
{
    let vec = &v[m..n];
    return vec.to_vec();
}

fn main(){
    let mut vect = vec![1, 2, 3, 4, 2, 2, 4, 6, 5];
    let v = slicing(vect, 4, 7);
    print(v);
}

>> slice indices are of type `usize` or ranges of `usize`

これでなぜ引数i32がエラーになるか理解できん…

[shell] コマンドを実行する

シェルでのコマンドの実行はevalで実行する

command="echo hoge"
eval $command

$ ./test.sh
hoge

終了コードで処理を変える

command="echo hoge"
eval $command

retval=$?

if [ $retval -eq 0 ]
then
    echo "成功しました!"
else
    echo "失敗しました"
fi

これをechoではなく、bitcoin-core.cli –getinfoにします。

command="bitcoin-core.cli --getinfo"
eval $command

retval=$?

if [ $retval -eq 0 ]
then
    echo "成功しました!"
else
    echo "失敗しました"
fi

値が1の時に起動するように書けばよさそうですね。

[bitcoin] Berkeley DB

Bitcoincoreで使用されているBerkeley DBについて

– Cで記述されたソフトウェアライブラリ
– Key/value API
– SQL APIとしてSQLiteが組み込まれている
– Bツリー、ハッシュ、キュー、RECNOストレージ
– C++, Java/JNI, C#, Python, Perlなど
– Java Direct Persistence Layer
– JavaコレクションAPI
– レプリケーション
– Berkeley DB is not a relational database, although it has database features including database transactions, multiversion concurrency control and write-ahead logging. BDB runs on a wide variety of operating systems including most Unix-like and Windows systems, and real-time operating systems.
– SQLのようなデータ操作言語を持たず、データベースへのアクセスは全てサブルーチン呼び出しによって行う。しかしdbmとは異なり、データ操作機能にトランザクションやレプリケーションに対応するインタフェースが備わっている
– Berkeley DB本体が対応するプログラミング言語はCおよびC++だけだが、Perl、Python、Tcl他多くの言語にバインディングが用意されており、それらから容易に利用することができる。

概要はわかったので、使い方ですな。