バーニングシップ・フラクタル

言語:Mathematica

burnp[c_, limit_, f_] := (
  n = 0;
  z = 0;
  While[n < limit,
   z = f[z, c];
   If[Abs[z] >= 2, out = False; Break[]]
    If[n == limit - 1, out = True; Break[]]
    n++;];
  out)
list[table_] := (
  Map[{Re[#], Im[#]} &, table])
clist[sample_] := 
 Flatten[Table[-2 + -2 I + i/sample*4 + j/sample*4 I, {i, 0, 
    sample}, {j, 0, sample}]]
main[sample_, limit_, f_] :=
 ListPlot[list[Select[clist[sample], burnp[#, limit, f] &]]]

実行例
f:id:mikuwaorenoyome:20170121174325p:plain

Emacsのデフォルトメジャーモードをlisp-interaction-modeにする方法(version 24.5.1)

Emacs-Lispを使っている人にとって、*scratch*バッファのlisp-interaction-modeは重要ですよね。(C-jでS式を評価できたりします)

デフォルトメジャーモードをlisp-interaction-modeにするのは簡単で、init.elに次の一文を加えるだけです。

場所:gnupack_basic-13.06-2015.11.08\home\.emacs.d\init.el

加える文:(setq default-major-mode 'lisp-interaction-mode)

これであなたもELISPERだ!

AIZU ONLINE JUDGEのELISP解答例(ITP1_1_A~ITP1_2_C)

ITP1_1_A:Hello World
(message "Hello World")
ITP1_1_B:X Cubic
(progn (defun cubic ()
	 (let ((x (read)))
	   (* x x x)))
       (cubic))
ITP1_1_C:Rectangle
(progn (defun rectangle ()
         (let ((a (read))
	       (b (read)))
           (cons (* a b) (* 2 (+ a b)))))
       (rectangle))
ITP1_1_D:Watch
(progn (defun watch ()
         (let ((x (read)))
           (let ((s (% x 60)))
             (let ((m (% (/ (- x s) 60) 60)))
	       (let ((h (/ (- (/ (- x s) 60) m) 60)))
	         (list h m s))))))
       (watch))
ITP1_2_A:Small, Large, or Equal
(progn (defun small ()
	 (let ((a (read))
	       (b (read)))
	   (if (< a b) (message "a<b")
	     (if (> a b) (message "a>b") (message "a=b")))))
       (small))
ITP1_2_B:Range
(progn (defun range ()
         (let ((a (read))
	       (b (read))
	       (c (read)))
           (if (and (< a b) (< b c)) (message "YES") (message "NO"))))
       (range))
ITP1_2_C:Sorting Three Numbers
(progn (defun swap (x a b)
         (let ((c (elt x a)))
           (setf (elt x a) (elt x b))
           (setf (elt x b) c)
           x))
       (defun sort ()
	 (let ((a (read)) (b (read)) (c (read)))
	   (let ((x (list a b c)))
             (dotimes (j (1- (length x)))
               (dotimes (i (1- (length x)))
                 (if (> (elt x i) (elt x (1+ i)))
	             (swap x i (1+ i)))))
	     x)))
       (sort))

Lispやってみた2

あれから少し経って、多少なりとも使えるようになりましたが、わからないことだらけです(^_^;)
例えば、文字列を出力しようとしても、カッコつきのまま出力されたり、複数の出力ができなかったり・・・
あとわかったことは、lispにもいろいろな方言があるということでしょうか。
私が使っているのは、Emacs Lisp(通称elisp)だと思います。
とりあえずは、少しでも良さげな解説サイトを探すことを
目標にしたいと思います(´-`)

Lispやってみた

Lispを学び始めたんですが、いかんせんLispの解説サイトが少ない・・・
やはりマイナーなのでしょうか?
素数判定のプログラムすらまともに動かない(´・ω・`)
なぜ興味を持ったかと言いますと、ラムダ計算ができそうなのが理由です。
良いと思った点は、とにかく簡潔に書けるということです。
カッコは"("と")"だけ使って、"{"や"}"は使いません。
あとは、Rubyと一緒で引数を区切る時に","を使いません。
ぜひLispが使える人のご教授を受けたいですね。

ドットボックス 3×3 必勝

Dots&Boxesという外国のゲームの3×3の必勝手順を調べました。
結果は後手必勝となったんですが、問題はプログラムを走らせるとあまりにも早く結果が出るんですよね(-_-;)
プログラムが間違ってるのか私が間違っているのか・・・

#include<stdio.h>

bool dotbox(int *c);
bool turn(int *c);
void calq(int *c, bool *q);
void calsq(int s, int *sq);
bool winlose(int *c);
void printc(int *c);

int main(){
	int i;
	int c[24];
	int result;
	
	for (i = 0; i < 24; i++){
		c[i] = -1;
	}
	
	result = dotbox(c);
	printf("%d\n", result);
	return 0;
}
bool dotbox(int *c){
	int i,j,k;
	bool t;
	for (k = 0; k < 24; k++){
		if (c[k] == -1) break;
	}
	if (k == 24){
		return winlose(c);
	}else{
		for (i = 0; i < 24; i++){
			for (j = 0; j < 24; j++){
				if (c[j] == i) break;
			}
			if (j == 24){
				t = turn(c);
				c[k] = i;
				//printc(c);
				if (t == dotbox(c)){
					c[k] = -1;
					return t;
				}
			}
		}
		return !turn(c);
	}
}
bool turn(int *c){
	int i, j;
	int sq[9] = {};
	bool turn = 0, turnflag = 0;

	for (i = 0; i < 24; i++){
		if (c[i] == -1) break;
		calsq(c[i], sq);
		for (j = 0; j < 9; j++){
			if (sq[j] == 4){
				sq[j]++;
				turnflag = 1;
			}
		}
		if (turnflag == 1){
			turn = !turn;
			turnflag = 0;
		}

		turn = !turn;
	}
	return turn;
}
void calq(int *c, bool *q){
	int i, j;
	int sq[9] = {};
	bool turn=0,turnflag=0;

	for (i = 0; i < 24; i++){
		calsq(c[i], sq);
		for (j = 0; j < 9; j++){
			if (sq[j] == 4){
				q[j] = turn;
				sq[j]++;
				turnflag = 1;
			}
		}
		if (turnflag == 1){
			turn = !turn;
			turnflag = 0;
		}

		turn = !turn;
	}
}
void calsq(int s, int *sq){
	if (s == 0 || s == 1 || s == 12 || s == 15)
		sq[0]++;
	if (s == 1 || s == 2 || s == 13 || s == 16)
		sq[1]++;
	if (s == 2 || s == 3 || s == 14 || s == 17)
		sq[2]++;
	if (s == 4 || s == 5 || s == 15 || s == 18)
		sq[3]++;
	if (s == 5 || s == 6 || s == 16 || s == 19)
		sq[4]++;
	if (s == 6 || s == 7 || s == 17 || s == 20)
		sq[5]++;
	if (s == 8 || s == 9 || s == 18 || s == 21)
		sq[6]++;
	if (s == 9 || s == 10 || s == 19 || s == 22)
		sq[7]++;
	if (s == 10 || s == 11 || s == 20 || s == 23)
		sq[8]++;
}
bool winlose(int *c){
	int i;
	bool q[9];
	calq(c, q);
	int sen=0, kou=0;
	for (i = 0; i < 9; i++){
		if (q[i] == 0)
			sen++;
		else
			kou++;
	}
	if (sen>kou)
		return 0;
	else
		return 1;
}
void printc(int *c){
	int i;
	for (i = 0; i < 24; i++){
		printf("%d,", c[i]);
	}
	printf("\n");
}

4つで10

Javaについて少し勉強したので、練習として4つの数字で10を作るプログラムを書きました。

4つで10を作る遊びはテンパズルとかメイクテンと呼ばれてるらしいです。

package fourtoten.com;

import java.io.*;
import java.util.ArrayList;

public class FourToTen{
	double[] input=new double[4];
	String s;
	boolean b;
	
	FourToTen() throws IOException{
		BufferedReader br=
				new BufferedReader(new InputStreamReader(System.in));
		System.out.println("4つの数を,で区切って入力");
		String moji=br.readLine();
		String[] inputmoji=moji.split(",");
		for(int i=0;i<4;i++){
			input[i]=Double.parseDouble(inputmoji[i]);
		}
	}
	
	public void maketen(FourToTen result){
		ArrayList<ArrayList<Tree>> treelist=new ArrayList<ArrayList<Tree>>();
		ArrayList<Tree> subtreelist=new ArrayList<Tree>();
		for(int i=0;i<result.input.length;i++){
			Tree tree=new Tree();
			tree.children=new Tree[0];
			tree.value=Double.toString(result.input[i]);
			subtreelist.add(tree);
		}
		treelist.add(subtreelist);
		while(treelist.get(0).size()>=2){
			ArrayList<ArrayList<Tree>> sublist=new ArrayList<ArrayList<Tree>>();
			int jmax=ketugou(treelist.get(0)).size();
			for(int i=0;i<treelist.size();i++){
				for(int j=0;j<jmax;j++){
					sublist.add(ketugou(treelist.get(i)).get(j));
				}
			}
			treelist=sublist;
		}
		
		for(int i=0;i<treelist.size();i++){
			if(treelist.get(i).get(0).calc(0)==10.0){
				result.b=true;
				result.s=treelist.get(i).get(0).dump();
				return;
			}
		}
		result.b=false;
		result.s="0";
		return;
	}
	
	public static ArrayList<ArrayList<Tree>> ketugou(ArrayList<Tree> b){
		ArrayList<ArrayList<Tree>> treelist=new ArrayList<ArrayList<Tree>>();
		ArrayList<Tree> subtreelist;
		Tree subtree;
		
		for(int i=0;i<b.size();i++){
			for(int j=0;j<b.size();j++){
				if(i==j) continue;
				for(int k=0;k<=3;k++){
					subtreelist=new ArrayList<Tree>();
					
					subtree=new Tree();
					subtree.value=func_to_op(k);
					subtree.children=new Tree[2];
					subtree.children[0]=b.get(i);
					subtree.children[1]=b.get(j);
					subtreelist.add(subtree);
					for(int m=0;m<b.size();m++){
						if(m==i||m==j) continue;
						subtreelist.add(b.get(m));
					}
					treelist.add(subtreelist);
				}
			}
		}
		return treelist;
	}
	
	static double func(int k,double a,double b){
		switch(k){
		case 0:return a+b;
		case 1:return a-b;
		case 2:return a*b;
		case 3:return a/b;
		default:return 0;
		}
	}
	
	static String func_to_op(int k){
		switch(k){
		case 0:return "+";
		case 1:return "-";
		case 2:return "*";
		case 3:return "/";
		default:return "?";
		}
	}
	
}
package 遺伝的プログラミング.com;

public class Tree {
    public String value;
    public Tree[] children;

    public String dump() {
        String result = value;
        for (int i = 0; i < children.length; i++)
            result += " " + children[i].dump();
        return result;
    }

    public double calc(double x) {
        switch (value.charAt(0)) {
        case '+': return children[0].calc(x) + children[1].calc(x);
        case '-': return children[0].calc(x) - children[1].calc(x);
        case '*': return children[0].calc(x) * children[1].calc(x);
        case '/': return children[0].calc(x) / children[1].calc(x);
        case '^': return Math.pow(children[0].calc(x), children[1].calc(x));
        case 'x': return x;
        }
        return Double.parseDouble(value);
    }
    
    static public Tree make(java.util.Random rand, int len) {
        Tree result = new Tree();
        switch(len >= 5 ? 6 : rand.nextInt(7)) {
        case 0: result.value = "+"; result.children = new Tree[2]; break;
        case 1: result.value = "-"; result.children = new Tree[2]; break;
        case 2: result.value = "*"; result.children = new Tree[2]; break;
        case 3: result.value = "/"; result.children = new Tree[2]; break;
        case 4: result.value = "^"; result.children = new Tree[2]; break;
        case 5: result.value = "x"; result.children = new Tree[0]; break;
        default: result.value = ((Integer)(rand.nextInt(10) + 1)).toString(); result.children = new Tree[0];
        }
        for (int i = 0; i < result.children.length; i++)
            result.children[i] = make(rand, len + 1);
        return result;
    }
}
package fourtoten.com;

import java.io.*;

class Test{
	public static void main(String[] args) throws IOException{
		FourToTen result=new FourToTen();
		result.maketen(result);
		System.out.println("結果:"+result.b);
		if(result.b==true) System.out.println("式:"+result.s);
	}
}

Treeクラスはこちらから借りました→http://shogo82148.github.io/blog/2012/10/04/6saiconf-3/

悩んだのはやはり、どう木構造を上手く定義するかと、4つの数字で何通り計算できるかですね。木構造の方は遺伝的プログラミングで検索したらすごいのが出てきたので迷わず使いました。
後、式の出力はポーランド記法なので少し解説すると、2+3を+23のように書きます。/*54-86は(5*4)/(8-6)ですね。
C++はまだ勉強してませんが、動的配列はCよりJavaのほうが使いやすいかなと思いました。ただ、プログラミング言語を複数学ぶと、どれを使っていいか迷っちゃいますよね。