アート・オブ・FizzBuzz

この記事はklis Advent Calendar 2016 - Adventar5日目の記事です。4日目の記事はこちら

みなさん、FizzBuzz書いてますか?

プレイヤーは円状に座る。最初のプレイヤーは「1」と数字を発言する。次のプレイヤーは直前のプレイヤーの次の数字を発言していく。ただし、3で割り切れる場合は「Fizz」(Bizz Buzzの場合は「Bizz」)、5で割り切れる場合は「Buzz」、両者で割り切れる場合(すなわち15で割り切れる場合)は「Fizz Buzz」(Bizz Buzzの場合は「Bizz Buzz」)を数の代わりに発言しなければならない。発言を間違えた者や、ためらった者は脱落となる。 このゲームをコンピュータ画面に表示させるプログラムとして作成させることで、コードが書けないプログラマ志願者を見分ける手法をJeff AtwoodがFizzBuzz問題 (FizzBuzz Question) として提唱した。その提唱はインターネットの様々な場所で議論の対象になっている。

Fizz Buzz - Wikipedia

今回はこのFizzBuzz問題でちょっとだけ遊んでみましょう。使用言語はC++です。

Case1: 一般的な解法

#include <bits/stdc++.h>
using namespace std;

int main() {
    for(int i=1; i<101;++i) {
        if(i%15==0) cout << "FizzBuzz" << endl;
        else if(i%3==0) cout << "Fizz" << endl;
        else if(i%5==0) cout << "Buzz" << endl;
        else cout << i << endl;
    }
}

特に説明不要ですね。ループを回して3と5で割り切れるときにはFizzBuzz、3で割り切れるときにはFizz,5で割り切れるときにはBuzz,それ以外の時は数字を出力します。

Case2: if-less

#include <bits/stdc++.h>
using namespace std;

int main() {
    for(int i=1; i<101; ++i) {
        (i%15<1&&puts("FizzBuzz"))
            ||(i%3<1&&puts("Fizz"))
            ||(i%5<1&&puts("Buzz"))
            ||printf("%d\n",i);
    }
}

if文を使わないパターンです。C/C++では&&と||はそれ以上評価が必要なくなるとそこで評価を終了することを利用しています。

Case3: for-less

#include <bits/stdc++.h>
using namespace std;

void fizzbuzz(int i) {
    if(i>100) return;
    (i%15<1&&puts("FizzBuzz"))
        ||(i%3<1&&puts("Fizz"))
        ||(i%5<1&&puts("Buzz"))
        ||printf("%d\n",i);

    fizzbuzz(++i);
}

int main() {
    fizzbuzz(1);
}

再帰を利用してループを使わずに実現しています。あとはさっきと同じです。

Case4: use template

#include <bits/stdc++.h>
using namespace std;

template<class T>
int p(T x) { puts(x); }

template<>
int p(int x) { printf("%d\n", x); }

template<int N>
void fizzbuzz() {
    (N%15<1&&p("FizzBuzz"))
        ||(N%3<1&&p("Fizz"))
        ||(N%5<1&&p("Buzz"))
        ||p(N);

    fizzbuzz<N+1>();
}

template<>
void fizzbuzz<101>() { return; }

int main() {
    fizzbuzz<1>();
}

C++のテンプレートを利用して書き換えています。やってることは同じです。

Case5: golf

#include<ios>
int main(int i){for(;i<101;){printf(i%3?i%5?"%d":"":"Fizz",i);puts(i++%5?"":"Buzz");}}

コードの短さを追求するcode golfという競技があるらしいです。このコードは100バイト強ですが、anarchy golf - FizzBuzzによると一番短いコードで90バイトらしいです。ちなみに、Rubyluaなどのスクリプト言語を利用すればぐっと短くなります。

おまけ: HQ9F+

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++f

HQ9+については各自調べるように。

以上です。

C/C++で行列演算クラスを書きました

行列演算が必要&外部ライブラリを使いたくないという状況ができましたので作成しました.

※以下ヘッダ部抜粋

#include <iostream>
#include <vector>

/*
 * 行列演算クラス
 */
class Ematrix
{
  private:
    int row;
    int col;
    std::vector< std::vector<long long> > value;
  public:
    // 1行1列の行列
    Ematrix();
    // 単位行列
    Ematrix(int);
    // 行数と列数を指定した行列
    Ematrix(int, int);
    // コピーコンストラクタ
    Ematrix(const Ematrix&);
    // 添字演算子
    inline std::vector<long long> operator [](int) const;
    inline std::vector<long long>& operator [](int);
    // 算術演算子
    const Ematrix operator +(const Ematrix&) const;
    const Ematrix operator -(const Ematrix&) const;
    const Ematrix operator *(const Ematrix&) const;
    const Ematrix operator *(const int&) const;
    // 行数ゲッタ
    int get_row() const;
    // 列数ゲッタ
    int get_col() const;
    // 要素ベクトルゲッタ
    std::vector< std::vector<long long> > get_value() const;
};

※実装部一部抜粋

Ematrix::Ematrix()
  :row(1), col(1),
   value(std::vector< std::vector<long long> >(1,
         std::vector<long long>(1,0)))
{
}

Ematrix::Ematrix(int row, int col)
  :row(row),
   col(col),
   value(std::vector< std::vector<long long> >(row,
         std::vector<long long>(col,0)))
{
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

inline std::vector<long long> Ematrix::operator [](int index) const
{
  return this->value[index];
}

inline std::vector<long long>& Ematrix::operator [](int index)
{
  return this->value[index];
}

行列の要素はstd::vectorで持っておき、添字演算を可能にしています. 引数なしで初期化した場合は1行1列の行列が生成されます.

  • 行列の実数倍
  • 行列の和
  • 行列の差
  • 行列の積
  • 単位行列 に対応しています.

もし使いたい方がいれば以下からどうぞ.

github.com

【Raspberry PI 3】ディスプレイなしで接続

先日Rasbery PI 3 Model Bをゲットしたので、そのセットアップをば。

環境

  • Rasbery PI 3 Model B
  • RASPBIAN 4.4
  • SUSE Linux Leap42.1
  • 有線LAN接続

microSDにRASPBIANをインストール

OSをダウンロードします。
RASPBIAN
ダウンロードしたら、imagewriterを使ってimgファイルを焼きます。

$ sudo apt-get install imagewriter
$ imagewriter

ラズパイ起動

LANケーブル、microSDを差し込み、電源を入れます。

IPアドレスを調べる

ラズパイのIPを調べます

$ sudo arp-scan -l --interface eth0

SSHログイン

調べたIPにSSHでログインします。

$ ssh pi@xxx.xxx.xxx.xxx
pi@xxx.xxx.xxx.xxx's password:

パスワードを聞かれるので初期パスワードraspberryを入力してログイン

これで無事接続完了です。お疲れ様でした。

C/C++用ヘッダオンリライブラリ管理ツール【chppl】

Qiitaでも書きましたが宣伝させていただきます。

qiita.com

github.com

C/C++PythonのpipやRubyのgemsのような操作感でライブラリを管理できます。 もっとヘッダオンリ・シングルファイルライブラリが流行って欲しいですね。

依存パッケージインストール

$ sudo apt-get install subversion subversion-tools postgresql postgresql-server-dev-9.3

インストール方法

$ cd  
$ git clone https://github.com/nocotan/chppl-tool  
$ cd chppl-tool/chppl-tool/src
$ make
$ echo "export PATH=$PATH:~/chppl-tool/chppl-tool/bin" >> ~/.bashrc

使い方

インストール

$ chppl install <packagename>

ヘルプ

$ chppl help

ライブラリの登録はこちら

chppL

誰でも登録・削除ができます。 自分だけで運用したい場合はDB設定変更して自身のherokuにデプロイしてみてください。