Go言語で8クイーン

久しぶりにGo言語が書いて見たくなって
8クイーン実装して見ました。

package main

import "fmt"

type Queen struct {
	num    int
	count  int
	result []int
}

func new(_num int) *Queen {
	_result := make([]int, _num)
	i := 0
	for i < _num {
		_result[i] = -1
		i++
	}
	return &Queen{
		num:    _num,
		count:  0,
		result: _result,
	}
}

func (queen *Queen) queen(y int) {
	for x := 0; x < queen.num; x++ {
		queen.init_array(y)
		if !queen.can_putp(x, y) {
			continue
		}
		queen.put(x, y)
		if y == queen.num-1 {
			queen.count++
			queen.write()
		} else {
			queen.queen(y + 1)
		}
	}
}

func (queen *Queen) init_array(y int) {
	for i := 0; i < queen.num; i++ {
		if i >= y {
			queen.result[i] = -1
		}
	}
}

func (queen Queen) can_putp(x int, y int) bool {
	return queen.result[y] == -1 && !queen.is_includep(x) && queen.slant_checkp(x, y)
}

func (queen Queen) is_includep(x int) bool {
	b := false
	for _, value := range queen.result {
		if value == x {
			b = true
		}
	}
	return b
}

func (queen Queen) slant_checkp(x int, y int) bool {
	tmp1 := y - x
	tmp2 := y + x
	b := true
	for _y, _x := range queen.result {
		if _x == -1 {
			continue
		}
		if _y == _x+tmp1 || _y == (-_x)+tmp2 {
			b = false
		}
	}
	return b
}

func (queen Queen) write() {
	for y := 0; y < queen.num; y++ {
		for x := 0; x < queen.num; x++ {
			if queen.result[y] == x {
				fmt.Print("Q ")
			} else {
				fmt.Print(". ")
			}
		}
		fmt.Print("\n")
	}
	fmt.Println(queen.count)
	fmt.Print("\n")
}

func (queen *Queen) put(x int, y int) {
	queen.result[y] = x
}

func main() {
	q := new(8)
	q.queen(0)
}

Go言語はとても見やすいですよね。

私は飽き性で色々な言語を触ってみるのですが、
Rubyはノリノリで書けますし、
Goは誰でも読めると思うし、
Lispテトリスのような気持ちでかけるし、
phpはすぐになんでも書けちゃうし、
それぞれいいところがありますよね。プログラマーになってよかったです笑

pythonでlifegameしてみた

pythonでlifegameして見ました。
lisppythonってめっちゃ目を細めてみると似ていますね。

import random

COUNT = 20
LIVE = 'o '
DEATH = '_ '
PIONEER = 100

class Field:
    def __init__(self):
        self._cells = [[DEATH for i in range(COUNT)] for j in range(COUNT)]

    def random_birthday(self):
        for i in range(PIONEER):
            self._cells[random.randint(0, COUNT - 1)][random.randint(0, COUNT - 1)] = LIVE

    def decide_life(self, x, y):
        neighbor_count = self._get_neighbors_count(x, y)
        if self._is_exists(x, y):
            if self._is_under_population(neighbor_count) or self._is_over_population(neighbor_count):
                self._death_cell(x, y)
        else:
            if self._is_just_population(neighbor_count):
                self._live_cell(x, y)

    def write(self):
        for line in self._cells:
            for l in line:
                print(l, end="")
            print("")
        print("")


    def _is_under_population(self, count):
        return count == 0 or count == 1

    def _is_over_population(self, count):
        return count >= 4

    def _is_just_population(self, count):
        return count == 3

    def _live_cell(self, x, y):
        self._cells[x][y] = LIVE

    def _death_cell(self, x, y):
        self._cells[x][y] = DEATH

    def _is_exists(self, x, y):
        return self._cells[x][y] == LIVE

    def _get_neighbors_count(self, x, y):
        result = 0
        if self._over0(x-1) and self._over0(y-1) and self._is_exists(x-1, y-1): result += 1
        if self._over0(y-1) and self._is_exists(x, y-1): result += 1
        if self._under_count(x+1) and self._over0(y-1) and self._is_exists(x+1, y-1): result += 1
        if self._over0(x-1) and self._is_exists(x-1, y): result += 1
        if self._under_count(x+1) and self._is_exists(x+1, y): result += 1
        if self._over0(x-1) and self._under_count(y+1) and self._is_exists(x-1, y+1): result += 1
        if self._under_count(y+1) and self._is_exists(x, y+1): result += 1
        if self._under_count(x+1) and self. _under_count(y+1) and self._is_exists(x+1, y+1): result += 1
        return result

    def _over0(self, num):
        return num >= 0

    def _under_count(self, num):
        return num < COUNT


def main():
    field = Field()
    field.random_birthday()
    field.write()
    i = 0
    while i < 500:
        for x in range(COUNT - 1):
            for y in range(COUNT - 1):
                field.decide_life(x, y)
        field.write()
        i += 1

if __name__ == "__main__":
    main()

CommonLispでMysqlのDATETIME型を作る

common lispmysqlのDATETIME型の作り方が見当たりませんでした。
phpでは

<?php
echo date('Y-m-d H:i:s');

のように書きますよね?


common lispでDBを触るときに使いたかったのですが
探しても全然見つからないです。。。

みなさんどうやって作っているのでしょうか?

私は

(ql:quickload :trivial-shell)
(trivial-shell:shell-command "date +'%Y-%m-%d %I:%M:%S'")

でshellを叩くことでいけるんじゃないかなと思ったところです。
まだ試していないのでいけるか分からないので
今からやってみようと思います。

CommonlispでCRUDして見た。

いつかlispを使える職場に行くことを夢見て
common lidpでCRUDを実装して見ました。

(ql:quickload :cl-dbi)
#| mysql
CREATE DATABASE test;
USE test;
CREATE TABLE tests(id int(5), name varchar(20), created timestamp);
INSERT INTO tests(id, name, created) VALUES(0, "aaa", "2017-07-31 00:00:00");
INSERT INTO tests(id, name, created) VALUES(1, "bbb", "2017-07-31 00:00:00");
INSERT INTO tests(id, name, created) VALUES(2, "ccc", "2017-07-31 00:00:00");
|#

(defvar *db*
    (dbi:connect :mysql
                 :database-name "test"
                 :username "root"
                 :password ""))

(defun reader ()
  (let* ((query (dbi:prepare *db* "SELECT * FROM tests"))
         (result (dbi:execute query)))
    (loop for row = (dbi:fetch result) ;変数を更新しながらloop
          while row ;条件が真の間だけloop
          do
          (print row)
          (print (getf row :|id|))
          (print (getf row :|name|))
          (print (getf row :|created|))
          (terpri))))

(defun updater ()
  (let* ((query (dbi:prepare *db* "UPDATE tests SET name = ? WHERE id = ?"))
         (result (dbi:execute query "eee" 1)))))

(defun deleter ()
  (let* ((query (dbi:prepare *db* "DELETE FROM tests WHERE id = ?"))
         (result (dbi:execute query 0)))))

(defun creater ()
  (let* ((query (dbi:prepare *db* "INSERT INTO tests(id, name, created) VALUES(?, ?, ?)"))
         (result (dbi:execute query 4 "fff" "2017-07-31 00:00:00")))))


(defun main ()
  (print "before read ----------------------------")
  (reader)
  (print "create")
  (creater)
  (print "update")
  (updater)
  (print "delete")
  (deleter)
  (print "after read -----------------------------")
  (reader))

(main)

Common Lisp用のデータベースライブラリ「CL-DBI」を作りました - 八発白中
参考にしました。ありがとうございます。

cppでlifegameして見た。

先日common lispで書いたものをc++で書いて見ました。
最近common lispを書きすぎて四則演算とか条件演算とかが
前にないと、頭が混乱して逆に読みにくくなって来ました笑

#include <iostream>
#include <random>
#include <unistd.h>

using namespace std;

const int COUNT = 20;
const char LIVE = 'o';
const char DEATH = '_';
const int pioneer = 100;

random_device rnd;
mt19937 mt(rnd());
uniform_int_distribution<> rand_0_to_count(0, COUNT);

class Field {
      private:
           char cells[COUNT][COUNT];
           void live_cell(int x, int y){
                 cells[x][y] = LIVE;
           }
           void death_cell(int x, int y){
                 cells[x][y] = DEATH;
           }
           bool is_exists(int x, int y){
                 bool result = false;
                 if(cells[x][y] == LIVE)
                       result = true;
                 return result;
           }
           int get_neighbors_count(int x, int y){
                 int result = 0;
                 if(over0(x-1) && over0(y-1) && is_exists(x-1, y-1)) result++;
                 if(over0(y-1) && is_exists(x, y-1)) result++;
                 if(underCount(x+1) && over0(y-1) && is_exists(x+1, y-1)) result++;
                 if(over0(x-1) && is_exists(x-1, y)) result++;
                 if(underCount(x+1) && is_exists(x+1, y)) result++;
                 if(over0(x-1) && underCount(y+1) && is_exists(x-1, y+1)) result++;
                 if(underCount(y+1) && is_exists(x, y+1)) result++;
                 if(underCount(x+1) && underCount(y+1) && is_exists(x+1, y+1)) result++;
                 return result;
           }
           bool over0(int num){
                 return ( num >= 0);
           }
           bool underCount(int num){
                 return (num < COUNT);
           }

      public:
           Field();
           void random_birthday();
           void decide_life(int, int);
           void write();
};

Field::Field(){
      for(int i = 0; i < COUNT; i++){
            for(int j = 0; j < COUNT; j++){
                  cells[i][j] = DEATH;
            }
      }
}

void Field::random_birthday(){
      for(int i = 0; i < pioneer; i++){
            cells[rand_0_to_count(mt)][rand_0_to_count(mt)] = LIVE;
      }
}

void Field::decide_life(int x, int y){
      int neighbor_count = get_neighbors_count(x, y);
      if(is_exists(x, y)){
            if(neighbor_count == 0 || neighbor_count == 1){
                  death_cell(x, y); //過疎死
            }else if(neighbor_count >= 4){
                  death_cell(x, y); //過密死
            }
      }else{
            if(neighbor_count == 3){
                  live_cell(x, y); //誕生
            }
      }
}

void Field::write(){
      for(int i = 0; i < COUNT; i++){
            for(int j = 0; j < COUNT; j++){
                  cout << cells[i][j] << ' ';
            }
            cout << "\n";
      }
      cout << "\n";
}

int main(){
      Field field;
      field.random_birthday();
      field.write();
      int i = 0;
      while(i < 500){
            for(int x = 0; x < COUNT - 1; x++){
                  for(int y = 0; y < COUNT - 1; y++){
                        field.decide_life(x, y);
                  }
            }
            field.write();
            usleep(500000);
            i++;
      }
      return 0;
}

お盆中にでも初のオープンソースの参加とかして見たいなぁ。。。
common lispが書きたいですね!

common lispでlife gameしてみた。

lifegame自体が人生初で組んだので
間違っているところがあるかもしれませんがご了承ください。

lispたのしいです。
lifegameも動いた時は興奮しますね。

今回はlispで初めて配列を使って見ました。

(defconstant +count+ 50)
(defconstant +live+ "o ")
(defconstant +death+ "_ ")

(defvar *pioneers* (/ (* +count+ +count+) 4))

(defclass field ()
  ((cells
     :accessor cells)))

;初期化
(defmethod init ((f field))
  (setf (cells f) (make-array (list +count+ +count+) :initial-element +death+)))

;randomに最初の生物を入れる
(defmethod random-birthday ((f field))
  (loop for i from 0 to *pioneers*
       do
       (setf (aref (cells f) (random +count+) (random +count+)) +live+)))

;そのセルは生きているか確認
(defmethod is_exists ((f field) x y)
  (let ((result nil))
      (when (equal (aref (cells f) x  y) +live+)
        (setf result t))
      result))


;周辺8セルを調べて合計値を返す
(defmethod get-neighbors-count ((f field) x y)
  (let ((result 0))
    (when (and (>= (- x 1) 0) (>= (- y 1) 0)
               (is_exists f (- x 1) (- y 1))) (incf result))
    (when (and (>= (- y 1) 0)
               (is_exists f x (- y 1)))  (incf result))
    (when (and (< (+ x 1) +count+) (>= (- y 1) 0)
               (is_exists f (+ x 1) (- y 1))) (incf result))
    (when (and (>= (- x 1) 0)
               (is_exists f (- x 1) y)) (incf result))
    (when (and (< (+ x 1) +count+)
               (is_exists f (+ x 1) y)) (incf result))
    (when (and (>= (- x 1) 0) (< (+ y 1) +count+)
               (is_exists f (- x 1) (+ y 1))) (incf result))
    (when (and (< (+ y 1) +count+)
               (is_exists f x (+ y 1)))  (incf result))
    (when (and
            (< (+ x 1) +count+) (< (+ y 1) +count+)
               (is_exists f (+ x 1) (+ y 1))  (incf result)))
    result ))

;生きるか死ぬかを決める
(defmethod decide-life ((f field) x y)
  (let ((neighbor-count (get-neighbors-count f x y)))
    (if (is_exists f x y)
      (cond ((or (= neighbor-count 0) (= neighbor-count 1)) (death-cell f x y)) ;過疎死
            ; ((or (= neighbor-count 2) (= neighbor-count 3)) ()) ;何もしない
            ((>= neighbor-count 4) (death-cell f x y))) ;過密死
      (when (= neighbor-count 3) (live-cell f x y))))) ;生殖、誕生

;セルに生物を発生させる
(defmethod live-cell ((f field) x y)
  (setf (aref (cells f) x y) +live+))

;せるの生物を殺す
(defmethod death-cell ((f field) x y)
  (setf (aref (cells f) x y) +death+))

;fieldの描画
(defmethod write-field ((f field))
  (loop for x from 0 to (- +count+ 1)
        do
        (loop for y from 0 to (- +count+ 1)
              do
              (princ (aref (cells f) x y)))
        (fresh-line))
  (terpri))

(defun main ()
     (let ((field (make-instance 'field)))
       (labels ((lifetime (field)
                          (loop for x from 0 to (- +count+ 1)
                                do
                                (loop for y from 0 to (- +count+ 1)
                                      do
                                      (decide-life field x y)))))
         (init field)
         (random-birthday field)
         (write-field field)
         (loop for i from 0 to 500
               do
               (lifetime field)
               (write-field field)
               (sleep 0.05)))))

(main)

commonlispでwebapi叩いてみた

lispapiを叩くのに色々頑張ったので初心者の方にshareです。

(ql:quickload :drakma)
(ql:quickload :babel)
(ql:quickload :cl-json)

(defun send (endpoint)
  (let* (
         ;drakmaを使ってendpointをgetで叩く
         (encoded-json (drakma:http-request endpoint))

         ;babelに渡すために決まった形があるらしい
         (vec (make-array (length encoded-json)
                             :initial-contents encoded-json
                             :element-type '(unsigned-byte 8)))

         ;babelでutf-8指定して文字列に戻す
         (json (babel:octets-to-string vec :encoding :utf-8))

         ;cl-jsonでjsonをdecodeしてlistにする
         (result (json:decode-json-from-string json)))

    ; (print encoded-json)
    ; (print "---------------------------------------")
    ; (print vec)
    ; (print "---------------------------------------")
    ; (print json)
    ; (print "---------------------------------------")
    ; (print result)
    ; (print "---------------------------------------")

    result))

(send "http://weather.livedoor.com/forecast/webservice/json/v1?city=400040")

最近lispばかり書いていますが、
lisp楽しいまだマクロとか書いていないのでlispはこれからもっと楽しくなりそうです。

lispの仕事があれば紹介してほしいです笑

(参考にしたURL ありがとうございました!)
http://cl.cddddr.org/index.cgi?Babel
http://qiita.com/zeptometer/items/175b97844046b83fc5f2
https://common-lisp.net/project/cl-json/