phpの関数の大文字小文字の区別

これをみて欲しいんですが、、、

<?php
function userLog(){
    echo "log書いたよ!";
}

UserLog();

みたいなコードが本番コードにあって
関数名が違う!ログ取れてなくねっとなって調べてみましたが、
ちゃんと関数を呼べてるようです。

調べてみると、
phpは変数は大文字小文字を区別しますが、
関数名は大文字小文字を区別しないようです。

これは知らないと何か起きそうですね。。。

lispでキャラメルフラペチーノ

lisp遺伝的アルゴリズムでキャラメルフラペチーノ作ってみました。
クラスのメンバのアクセスの仕方、loopマクロの使い方を学びました。

;定数
(defconstant *gene_count* 18)
(defconstant *correct* '(c a r a m e l f r a p p u c h i n o))
(defconstant *alphabet* '(a b c d e f g h i j k l m n o p q r s t u))
(defconstant *generations* 20)
(defconstant *destroy* 5)
(defconstant *mutation_ratio* 25)

(defparameter *flag* nil)

;個体クラス-------------------------------------------------
(defclass individual ()
  ((gene
     :accessor gene)
   (point
     :accessor point)))

(defmethod init ((ind individual))
  (setf (point ind) 0)
  (setf (gene ind) '())
  (loop for i from 0 to (- *gene_count*  1)
        do
        (push (get_alphabet) (gene ind)))
  ind )

(defmethod review ((ind individual))
  (setf (point ind) 0)
  (loop for i from 0 to (- (list-length (gene ind)) 1)
        do
        (when (equal (nth i (gene ind)) (nth i *correct*))
          (setf (point ind) (+ (point ind) 1))))
  (when (>= (point ind) *gene_count*) (setf *flag* t)))

(defmethod mutation ((ind individual))
  (setf (nth (random *gene_count*) (gene ind)) (get_alphabet))
  (setf (nth (random *gene_count*) (gene ind)) (get_alphabet)))

(defun make_child (father mother)
  (let ((child (make-instance 'individual))
        (rnd (random *gene_count*)))
    (init child)
    (loop for i from 0 to (- *gene_count* 1)
          do
          (if (< i rnd)
              (setf (nth i (gene child)) (nth i (gene mother)))
              (setf (nth i (gene child)) (nth i (gene father)))))
    child))

(defun get_alphabet ()
  (nth (random (list-length *alphabet*)) *alphabet*))


;コロニークラス-------------------------------------------------
(defclass colony ()
  ((generation
     :accessor generation)))

(defmethod init ((c colony))
  (setf (generation c) nil)
  (loop for i from 0 to (- *generations*  1)
        do
        (push (init (make-instance 'individual)) (generation c))))

(defmethod reviews ((c colony))
  (dolist (g (generation c))
    (review g)))

(defmethod destroy ((c colony))
  (loop for i from 0 to (- *destroy* 1)
        do
        (let ((s_key 0)
              (s_point 0)
              (j 0))
          (terpri)
          (dolist (g (generation c))
            (cond ((= j 0)
                   (setf s_point (point g)))
                  ((> s_point (point g))
                   (setf s_key j)
                   (setf s_point (point g))))
            (setf j (+ j 1)))
          (setf (generation c) (delete_at (generation  c) s_key)))))

(defmethod make_children ((c colony))
  (loop for i from 0 to (- *destroy* 1)
        do
        (push (make_child (nth (random (- *generations* *destroy* 1)) (generation c))
                          (nth (random (- *generations* *destroy* 1)) (generation c)))
              (generation c))))

(defmethod mutations ((c colony))
  (dolist (g (generation c))
    (when (= 1 (random *mutation_ratio*))
      (mutation g))))

(defun delete_at (l index)
  (let ((tmp '()))
    (loop for i from 0 to (- (list-length l) 1)
          do
          (unless (= i index) (push (nth i l) tmp)))
    tmp))


;-------------------------------------------------------
(defun main ()
  (let ((generations (make-instance 'colony))
        (i 0))
    (init generations)
    (loop
          (reviews generations)
          (dolist (g (generation generations))
            (print (gene g))
            (princ (point g)))
          (when *flag*
            (print i)
            (print "finish")
            (return))
          (destroy generations)
          (make_children generations)
          (mutations generations)
          (setf i (+ i 1)))))
(main)

次回は実用的なものを作っていきたいと思います。
lisp面白い!

地味に使えそうなcatをクリップボードに流し込む方法

terminalで作業していてそれをブログに貼りたい時とか困りますよね?

そういう時は
pbcopy
を使いましょう。

cat memo.txt | pbcopy

クリップボードにコピーされるので
ctrl + vでどこにでも貼れますね!

qiita.com
(ありがとうございました)

lispで8クイーン実装して見た

最近common lispに入門しようとして頑張っているのですが、
lispはすごく楽しいですね!
かっこの中に処理がハマった時にテトリスのような快感がありますね。

(defclass queen ()
  ( num
    count
    result))

(defmethod init ((q queen) n)
  (setf (slot-value q 'num) n)
  (setf (slot-value q 'count) 0)
  (setf (slot-value q 'result) nil)
  (let ((i 0))
    (loop
      (push 'nil (slot-value q 'result))
      (setf i (+ i 1))
      (when (>= i n) (return)))))

(defmethod run ((q queen) y)
  (let ((x 0))
    (loop
      (init_array q y)
      (when (can_put q x y)
        (progn
          (put q x y)
          (if (>=  y (- (slot-value q 'num) 1))
              (progn
                (setf (slot-value q 'count) (+ (slot-value q 'count) 1))
                (write_field q))
              (run q (+ y 1))) ) )
      (setf x (+ x 1))
      (when (>= x (slot-value q 'num)) (return))))
  nil)

(defmethod init_array ((q queen) y)
  (let ((i 0))
    (loop
      (when (>= i y)
        (setf (nth i (slot-value q 'result)) nil))
      (setf i (+ i 1))
      (when (>= i (slot-value q 'num)) (return)))))

(defmethod can_put ((q queen) x y)
  (if (and (null (nth y (slot-value q 'result)))
           (null (is_include q x))
           (slant_check q x y))
      t
      nil))

(defmethod slant_check ((q queen) x y)
  (let ((tmp1 (- y x))
        (tmp2 (+ y x))
        (i 0)
        (tmp t))
    (loop
      (when (and (not (null (nth i (slot-value q 'result))))
                 (or (= i (+ (nth i (slot-value q 'result))  tmp1)) (= i (+ (* (nth i (slot-value q 'result))  -1) tmp2))))
        (setf tmp nil))
      (setf i (+ i 1))
      (when (>= i (slot-value q 'num)) (return)))
    tmp ))

(defmethod write_field ((q queen))
  (let ((i 0)
        (j 0))
    (loop
      (setf j 0 )
      (loop
        (if (and (not (null (nth i (slot-value q 'result))))
                 (= (nth i (slot-value q 'result)) j))
            (princ "Q ")
            (princ "_ "))
        (setf j (+ j 1))
        (when (>= j (slot-value q 'num)) (return)))
      (terpri)
      (setf i (+ i 1))
      (when (>= i (slot-value q 'num)) (return)))
    (print (slot-value q 'count))
    (terpri)))

(defmethod is_include ((q queen) x)
  (let ((i 0)
        (tmp nil))
    (loop
      (when (and (not (null (nth i (slot-value q 'result))))
                 (= (nth i (slot-value q 'result)) x))
        (setf tmp t))
      (setf i (+ i 1))
      (when (>= i (slot-value q 'num)) (return)))
    tmp ))

(defmethod put ((q queen) x y)
  (setf (nth y (slot-value q 'result)) x))


(defun main ()
  (let ((qu (make-instance 'queen)))
    (init qu 8)
    (run qu 0)))

(main)

マクロとかはまだわからないし、
クラスのメンバにアクセスできるもう少し綺麗な書き方とかあるかもしれないですけど、
とりあえず動いたことがとても嬉しいですね!

lispのS式を書いていると、
日本人は英語できるようになったり、するんでしょうか?
全然英語できないですが、関数を頭に持ってくる感じが
動詞を前に持ってくるのと似ているような気がします笑

※Rustでも描きたいけど型の厳密さが難しい

C++で8クイーン

Rubyと同じように
C++でも描いて見ました。

#include <iostream>
using namespace std;

class queen{
      private:
            int n;
            int count;
            int result[];
            void init_array(int y);
            bool can_put(int x, int y);
            bool slant_check(int x, int y);
            bool is_include(int x);
            void write();
            void put(int x, int y);

      public:
            queen();
            queen(int n);
            void run(int y = 0);
            ~queen(){ };
};

queen::queen(){
      n = 8;
      count = 0;
      for(int i = 0; i < n; i++){
            result[i] = -1;
      }
}
queen::queen(int _n){
      n = _n;
      count = 0;
      for(int i = 0; i < n; i++){
            result[i] = -1;
      }
}

void queen::run(int y){
      for(int x = 0; x < n; x++){
            init_array(y);
            if(!can_put(x, y)){ continue; }
            put(x, y);
            if(y == n - 1){
                  count++;
                  write();
            }else{
                  run(y + 1);
            }
      }
}

void queen::init_array(int y){
      int i = 0;
      for(int i = 0; i < n; i++){
            if(i >= y){ result[i] = -1; }
      }
}

bool queen::can_put(int x, int y){
      return result[y] == -1 && !is_include(x) && slant_check(x, y);
}

bool queen::slant_check(int x, int y){
      int tmp1 = y - x;
      int tmp2 = y + x;
      for(int i = 0; i < n; i++){
            if (result[i] == -1){
                  continue;
            }else if(i == result[i] + tmp1 || i == -(result[i]) + tmp2) {
                  return false;
            }
      }
      return true;
}

bool queen::is_include(int x){
      for(int i = 0; i < n; i++){
            if(result[i] == x){
                  return true;
            }
      }
      return false;
}

void queen::write(){
      for(int y = 0; y < n; y++){
            for(int x = 0; x < n; x++){
                  if(result[y] == x){
                        cout << "Q ";
                  }else{
                        cout << "_ ";
                  }
            }
            cout <<  "\n";
      }
      cout << count << "\n";
}

void queen::put(int x, int y){
      result[y] = x;
}

int main(){
      queen q(11);
      q.run();
      cout << "hi\n";
      return 0;
}

勉強がてらC++描いて見ました。
もっとガシガシかけるようになりたいな!

rubyで8クイーン実装してみた

プログラミング言語の勉強でアルゴリズム実装しようと思いまして、
8クイーン実装して見ました。
先ずはrubyで実装しました。回転、裏返し省いてません。

class Queen
      def initialize(_queen)
            @queen = _queen
            @count = 0
            @result = Array.new(_queen, nil)
      end

      def queen(y = 0)
            @queen.times do |x|
                  init_array(y)
                  next if !can_put?(x, y)
                  put(x, y)
                  if y == @queen - 1
                        @count += 1
                        write()
                  else
                        queen(y + 1)
                  end
            end
      end

      private
      #自分がいる行以下のqueen初期化
      def init_array(y)
            i = 0
            while i < @queen
                  @result[i] = nil if i >= y
                  i += 1
            end
      end

      #置けるか確認
      def can_put?(x, y)
            return @result[y].nil? && !@result.include?(x) && slant_check(x, y)
      end

      #斜めのチェック
      def slant_check(x, y)
            tmp1 = y - x
            tmp2 = y + x
            @result.each_with_index do |_x, _y|
                  next if _x.nil?
                  if _y == _x + tmp1 ||  _y == (-_x) + tmp2
                        return false
                  end
            end
            return true
      end

      def write()
            @queen.times do |y|
                  line = ""
                  @queen.times do |x|
                        line +=  @result[y] == x ? "Q " : ". "
                  end
                  puts line
            end
            p @count
      end

      def put(x, y)
            @result[y] = x
      end
end

q = Queen.new(8)
q.queen()

次の言語で実装する時は
もう少しシンプルにして、回転、裏返しも無くしていきたいと思います。

C++でキャラメルフラペチーノ

仕事でC++を使うことがありそうなので
キャラメルフラペチーノ作ってみました。
ポインタとか、参照とかの使い方がいまいちパッとしないです。
C++とかをうまく使えるようになればもう少しRustも使えるようになるだろうという
モチベーションで頑張ります。

#include <iostream>
#include <vector>
#include <random>

using namespace std;

const int GENE_COUNT = 18;
const int GENERATIONS = 20;
const int DESTROY = 5;
const char* ALPHABET = "abcdefghijklmnopqrstuvwxyz";
const char* CORRECT_GENE = "caramelfrappuchino";

//random関数
random_device r;
mt19937 mt(r());
uniform_int_distribution<int> rand_alphabet(0,25);
uniform_int_distribution<int> rand_gene_count(0, GENE_COUNT - 1);
uniform_int_distribution<int> rand_mutation(0, 15);

bool Flag = false;

class indivisual {
      private:
            char gene[GENE_COUNT];
            int point;
            void create_gene();
      public:
            indivisual(){
                  point = 0;
                  create_gene();
            };
            int get_point(){ return point; }
            char *get_gene(){ return gene; }
            void set_gene_with_index(int index, char g){ gene[index] = g; }
            char get_gene_with_index(int index){ return gene[index]; }
            void review();
            void mutation();
            static void make_child(indivisual &child, indivisual &mother, indivisual &father){
                  int rnd = rand_gene_count(mt);
                  int i = 0;
                  while( i < GENE_COUNT){
                        if( i < rnd){
                              child.set_gene_with_index(i, mother.get_gene_with_index(i));
                        }else{
                              child.set_gene_with_index(i, father.get_gene_with_index(i));
                        }
                        i++;
                  }
            }
            ~indivisual(){ }
};

void indivisual::create_gene(){
      int i = 0;
      while (i < GENE_COUNT) {
            gene[i] = ALPHABET[rand_alphabet(mt)];
            i++;
      }
}
void indivisual::review(){
      point = 0;
      int i = 0;
      while(i < sizeof(gene) / sizeof(gene[0])){
            if(gene[i] == CORRECT_GENE[i]){ point++; }
            i++;
      }
      if(point >= GENE_COUNT){
            Flag = true;
      }
}

void indivisual::mutation(){
      gene[rand_gene_count(mt)] = ALPHABET[rand_alphabet(mt)];
      gene[rand_gene_count(mt)] = ALPHABET[rand_alphabet(mt)];
}

class colony {
      private:
            vector<indivisual> genes;
      public:
            colony(){
                  int i = 0;
                  while(i < GENERATIONS){
                        indivisual ind;
                        genes.push_back(ind);
                        i++;
                  }
            }
            void write_gene();
            void reviews();
            void destroy();
            void make_children();
            void mutations();
            ~colony(){ };
};
void colony::reviews(){
      for(indivisual& i : genes){
            i.review();
      }
}

void colony::destroy(){
      int i = 0;
      while (i < DESTROY) {
            int s_key = 0;
            int s_point = 0;
            int j = 0;
            for(indivisual& ind : genes){
                  if(j == 0){
                        s_point = ind.get_point();
                  } else if( s_point > ind.get_point()) {
                        s_key = j;
                        s_point = ind.get_point();
                  }
                  j++;
            }
            genes.erase(genes.begin() + s_key);
            i++;
      }
}
void colony::make_children(){
      int i = 0;
      while(i < DESTROY) {
            int rnd1 = 1;
            int rnd2 = 2;
            indivisual child;
            indivisual::make_child(child, genes[rnd1], genes[rnd2]);
            genes.push_back(child);
            i++;
      }
}
void colony::mutations(){
      for(indivisual& i : genes){
            if(rand_mutation(mt) == 1){
                  i.mutation();
            }
      }
}
void colony::write_gene(){
      for(indivisual& i : genes){
            cout << i.get_gene() << " " << i.get_point() << "\n";
      }
      cout << "\n";
}

int main(){

      colony c;
      int i = 0;
      while (i < 50000){
            cout << "generation: " << i << "\n";
            c.reviews();
            c.write_gene();
            c.destroy();
            c.make_children();
            c.mutations();
            if(Flag){
                  cout << "finish" << "\n";
                  break;
            }
            i++;
      }
      return 0;
}


Rust, lisp全然書けないけど楽しいです。
仕事に導入できるぐらいかけるようになりたいなぁ!