2009/08/31

SchemeとJsでしつこくYCombinator

しつこいことにまたもやYCombinator。
Schemeの方はTechEd2009中に、眠くなったときや話がわからなくなった時に書いた(w

download - ycombinator.scm.txt
download - ycombinator.js.txt

2009/08/24

Jsのfunctionで暇つぶし(ejax)

またもや眠気覚ましに少し遊んでみた。

意味のあるコードではない。

 

いつまでたってもScheme初級者から抜け出せない私はJavaScriptよくで遊ぶ。

 

functionはもうちょっと短くfunくらいにならないかな。まぁ改めてみるとlambdaもなかなか冗長だな。^でいんじゃね。

 

ところで、ejaxとjs2-modeはやはりかなり良い。この二つが完全に連携してくれると助かるけどなー。

(ejaxはemacs lispで書かれたECMA標準に準拠したJavaScriptインタプリタ)

 

download - 10times.recursive.helloworld.js

 

普通の再帰

(function f (n){
   if (0 < n)
   {
     print("Hello, world !");
     f(n - 1);
   }
})(10);

 

マッチポンプ的な再帰に変換。自分に自分を呼び出す自分を渡して・・・

(function (f){
   f(f, 10);
})(function (f, n){
      if (0 < n)
      {
        print("Hello, world !");
        f(f, n - 1);
      }
    });

 

リテラルを一つ外にくくりだしてみる。無名関数はローカル変数の変わりになるというあれ。Schemeのletはlambdaでくくり出すのと同じだよーっていうあれ。

(function (x){
   (function (f){
      f(f, x);
    })(function (f, n){
         if (0 < n)
         {
           print ("Hello, world !");
           f(f, n - 1);
         }
       });
})(10);

 

出力を行う部分を関数として外に出してみる。この辺から後はとくに面白みがない。

(function (y, action){
   (function (x){
      (function (f){
         f(f, x);
       })(function (f, n){
            if (0 < n)
            {
              action(n);
              f(f, n - 1);
            }
          });
    })(y);
})(10, function (v){
      print("Hello, world !");
    });

 

反復条件も関数として外に出してみる。pはpredicateのpということで。

(function (y, a, p){
   (function (x){
      (function (f){
         f(f, x);
       })(function (f, n){
            if (p(n))
            {
              a(n);
              f(f, n - 1);
            }
          });
    })(y);
})(10, function (v){
      print("Hello, world !");
    }, function(c){
      return 0 < c;
    });

 

ここで再帰のたびにデクリメントされる部分を関数として外に出したらfor文ぽいよねーなどと思いながら外にだしてみる。iはincrementのiかな。

(function (y, a, p, i){
   (function (x){
      (function (f){
         f(f, x);
       })(function (f, n){
            if (p(n))
            {
              a(n);
              f(f, i(n));
            }
          });
    })(y);
})(10, function (v){
      print("Hello, world !");
    }, function(c){
      return 0 < c;
    }, function (j){
      return j - 1;
    });

2009/08/12

[C#]再帰的四則演算(加減乗除)

KPF第四回勉強会でやったネタのC#版ですね。

The Little Schemerの4章のNumbers Gamesのコード片です。

 

download - NumbersGames.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

 

// The Little Schemer
// chapter 4
// ISBN:0262560992
namespace NumbersGames
{
    class Program
    {
        static void Main(string[] args)
        {
            /* 再帰で加減乗除(四足演算) */


            //インクリメント
            var inc = new Func<int, int>(n => ++n);
            Console.WriteLine("inc(1) -> {0}", inc(1));// -> 2

 

            //デクリメント
            var dec = new Func<int, int>(n => --n);
            Console.WriteLine("dec(1) -> {0}", dec(1));// -> 0

 

            //加算
            Func<int, int, int> add = null;
            add = (n, m) =>
                {
                    return m == 0
                        ? n
                        : inc(add(n, dec(m)));
                };
            Console.WriteLine("add(2, 3) -> {0}", add(2, 3));// -> 5

 

            //減算
            Func<int, int, int> sub = null;
            sub = (n, m) =>
                {
                    return m == 0
                        ? n
                        : dec(sub(n, dec(m)));
                };
            Console.WriteLine("sub(3, 2) -> {0}", sub(3, 2));// -> 1

 

            //大なり
            Func<int, int, bool> bgr = null;
            bgr = (n, m) =>
                {
                    return n == 0
                        ? false : m == 0
                        ? true : bgr(dec(n), dec(m));
                };
            Console.WriteLine("bgr(3, 2) -> {0}", bgr(3, 2));// -> True

 

            //小なり
            Func<int, int, bool> sml = null;
            sml = (n, m) =>
                {
                    return m == 0
                        ? false : n == 0
                        ? true : sml(dec(n), dec(m));
                };
            Console.WriteLine("sml(2, 3) -> {0}", sml(2, 3));// -> True

 

            //乗算
            Func<int, int, int> mul = null;
            mul = (n, m) =>
                {
                    return m == 0
                        ? m
                        : add(n, mul(n, dec(m)));
                };
            Console.WriteLine("mul(2, 3) -> {0}", mul(2, 3));// -> 6

 

            //除算
            Func<int, int, int> div = null;
            div = (n, m) =>
                {
                    return sml(n, m)
                        ? 0
                        : inc(div(sub(n, m), m));
                };
            Console.WriteLine("div(15, 3) -> {0}", div(15, 3));// -> 5

 

            Console.ReadLine();
        }
    }
}

[C#]九九テーブル

先日schemeで書いたものをC#で書いてみようかなーと。

型宣言でかなりごちゃごちゃ。varはいいな。

 

 

download - QxQ.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace QxQ
{
    class Program
    {
        static void Main(string[] args)
        {
            Func<IEnumerable<int>, IEnumerable<int>
                , List<List<KeyValuePair<KeyValuePair<int, int>, int>>>> tblmaker;

 

            tblmaker = new Func<IEnumerable<int>, IEnumerable<int>
                , List<List<KeyValuePair<KeyValuePair<int, int>, int>>>>(
                (IEnumerable<int> row, IEnumerable<int> col) =>
                {
                    List<List<KeyValuePair<KeyValuePair<int, int>, int>>> ret
                        = new List<List<KeyValuePair<KeyValuePair<int, int>, int>>>();
                    row.ToList().ForEach(i =>
                        {
                            List<KeyValuePair<KeyValuePair<int, int>, int>> rows
                                = new List<KeyValuePair<KeyValuePair<int, int>, int>>();

                            col.ToList().ForEach(j =>
                                {
                                    rows.Add(new KeyValuePair<KeyValuePair<int, int>, int>(
                                        new KeyValuePair<int, int>(i, j), i * j));
                                });
                            ret.Add(rows);
                        });
                    return ret;
                });

            List<List<KeyValuePair<KeyValuePair<int, int>, int>>> tbl
                 = tblmaker(Enumerable.Range(1, 10), Enumerable.Range(1, 9));

            Console.WriteLine(tbl);
            Display(tbl);
            Console.ReadLine();

            /*
System.Collections.Generic.List`1[System.Collections.Generic.List`1[System.Colle
ctions.Generic.KeyValuePair`2[System.Collections.Generic.KeyValuePair`2[System.I
nt32,System.Int32],System.Int32]]]
((1 . 1) 1)((1 . 2) 2)((1 . 3) 3)((1 . 4) 4)((1 . 5) 5)((1 . 6) 6)((1 . 7) 7)((1 . 8) 8)((1 . 9) 9)
((2 . 1) 2)((2 . 2) 4)((2 . 3) 6)((2 . 4) 8)((2 . 5) 10)((2 . 6) 12)((2 . 7) 14)((2 . 8) 16)((2 . 9) 18)
((3 . 1) 3)((3 . 2) 6)((3 . 3) 9)((3 . 4) 12)((3 . 5) 15)((3 . 6) 18)((3 . 7) 21)((3 . 8) 24)((3 . 9) 27)
((4 . 1) 4)((4 . 2) 8)((4 . 3) 12)((4 . 4) 16)((4 . 5) 20)((4 . 6) 24)((4 . 7) 28)((4 . 8) 32)((4 . 9) 36)
((5 . 1) 5)((5 . 2) 10)((5 . 3) 15)((5 . 4) 20)((5 . 5) 25)((5 . 6) 30)((5 . 7) 35)((5 . 8) 40)((5 . 9) 45)
((6 . 1) 6)((6 . 2) 12)((6 . 3) 18)((6 . 4) 24)((6 . 5) 30)((6 . 6) 36)((6 . 7) 42)((6 . 8) 48)((6 . 9) 54)
((7 . 1) 7)((7 . 2) 14)((7 . 3) 21)((7 . 4) 28)((7 . 5) 35)((7 . 6) 42)((7 . 7) 49)((7 . 8) 56)((7 . 9) 63)
((8 . 1) 8)((8 . 2) 16)((8 . 3) 24)((8 . 4) 32)((8 . 5) 40)((8 . 6) 48)((8 . 7) 56)((8 . 8) 64)((8 . 9) 72)
((9 . 1) 9)((9 . 2) 18)((9 . 3) 27)((9 . 4) 36)((9 . 5) 45)((9 . 6) 54)((9 . 7) 63)((9 . 8) 72)((9 . 9) 81)
((10 . 1) 10)((10 . 2) 20)((10 . 3) 30)((10 . 4) 40)((10 . 5) 50)((10 . 6) 60)((10 . 7) 70)((10 . 8) 80)((10 . 9) 90)           
            */

 

            var tablemaker2 = new Func<IEnumerable<int>, IEnumerable<int>
            , List<List<KeyValuePair<KeyValuePair<int, int>, int>>>>((row, col) =>
                {
                    var ret = new List<List<KeyValuePair<KeyValuePair<int, int>, int>>>();

                    row.ToList().ForEach(i =>
                    {
                        var rows = new List<KeyValuePair<KeyValuePair<int, int>, int>>();

                        col.ToList().ForEach(j =>
                        {
                            rows.Add(new KeyValuePair<KeyValuePair<int, int>, int>(
                                new KeyValuePair<int, int>(i, j), i * j));
                        });
                        ret.Add(rows);
                    });
                    return ret;
                });
        }

        private static void Display(List<List<KeyValuePair<KeyValuePair<int, int>, int>>> tbl)
        {
            tbl.ForEach(list =>
                {
                    list.ForEach(pair =>
                        {
                            Console.Write("(({0} . {1}) {2})"
                                , pair.Key.Key, pair.Key.Value, pair.Value);
                        });
                    Console.WriteLine();
                });
        }
    }
}

[C#]名前空間の外にクラスを定義する

というようなことができるということだったので、やってみた。

使いどころは思いつかない。

 

download - GlobalNamespaceClasss

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

 

namespace Sample.GlobalNamespaceClass
{
    class Program
    {
        static void Main(string[] args)
        {
            new GlobalClass<string>("hello").Print(
                s => { Console.WriteLine(s); return s; });
        }
    }
}

 

//グローバル名前空間に定義されたクラス(名前空間の指定無し)
public class GlobalClass<T>
{
    private T val;

 

    public T Value
    {
        get
        {
            return this.val;
        }
    }

 

    public GlobalClass(T val)
    {
        this.val = val;
    }

 

    public T Print(Func<T, T> printer)
    {
        return printer(this.val);
    }
}

2009/08/11

[js]map,iota,times

download - map.iota.times.js

 

map, iotaは何度か同じようなの書いてる。

timesはNumberクラスいじったらできるんじゃね?って思ったらできた。

 

// Arrayクラスのprototypeにmapを追加
Array.prototype.map = function (f)
{
  var ret = [];

  for (var i = 0; i < this.length; i++)
  {
    ret = f(this[i]);
  }
  return ret;
};

 

// Arrayクラスにiotaクラスメソッドを追加(したつもり)
Array.iota = function (cnt, init, inc)
{
  init = init || 0;
  inc = inc || 1;

  var ret = [];

  for (var i = 0, j = init; ret.length < cnt; i++, j = j + inc)
  {
    ret[i] = j;
  }

  return ret;
};

 

/*
js> Array.iota(10)
0,1,2,3,4,5,6,7,8,9


js> Array.iota(10, 10)
10,11,12,13,14,15,16,17,18,19


js> Array.iota(10, 2, 2)
2,4,6,8,10,12,14,16,18,20
*/

 

// 数値(Numberクラス?)のprototypeにtimesメソッドを追加
Number.prototype.times = function (f)
{
  var ret = [];
  for (var i = 0; i < Math.abs(this); i++)
  {
    ret[i] = f(i);
  }
  return ret;
};

/*
js> (10).times(function (i)
{
  print (i);
});
0
1
2
3
4
5
6
7
8
9
,,,,,,,,,

 

js> (10).times(function (i) { print ('hello'); })
hello
hello
hello
hello
hello
hello
hello
hello
hello
hello
,,,,,,,,,
js>
*/

[scheme]九九っぽい

(use srfi-1)
(define 9x9
  (lambda (row cnt inc mul)
    (append
     (cons
      (map (lambda (n)
             (cons (cons mul n)(cons (* n mul) '())))
           (iota cnt 1 inc))
      (if (zero? row)
          '()
          (9x9 (- row 1) cnt inc (+ mul 1)))))))



(9x9 9 9 1 1)
;; =>  ((((1 . 1) 1) ((1 . 2) 2) ((1 . 3) 3) ((1 . 4) 4) ((1 . 5) 5) ((1 . 6) 6) ((1 . 7) 7) ((1 . 8) 8) ((1 . 9) 9)) (((2 . 1) 2) ((2 . 2) 4) ((2 . 3) 6) ((2 . 4) 8) ((2 . 5) 10) ((2 . 6) 12) ((2 . 7) 14) ((2 . 8) 16) ((2 . 9) 18)) (((3 . 1) 3) ((3 . 2) 6) ((3 . 3) 9) ((3 . 4) 12) ((3 . 5) 15) ((3 . 6) 18) ((3 . 7) 21) ((3 . 8) 24) ((3 . 9) 27)) (((4 . 1) 4) ((4 . 2) 8) ((4 . 3) 12) ((4 . 4) 16) ((4 . 5) 20) ((4 . 6) 24) ((4 . 7) 28) ((4 . 8) 32) ((4 . 9) 36)) (((5 . 1) 5) ((5 . 2) 10) ((5 . 3) 15) ((5 . 4) 20) ((5 . 5) 25) ((5 . 6) 30) ((5 . 7) 35) ((5 . 8) 40) ((5 . 9) 45)) (((6 . 1) 6) ((6 . 2) 12) ((6 . 3) 18) ((6 . 4) 24) ((6 . 5) 30) ((6 . 6) 36) ((6 . 7) 42) ((6 . 8) 48) ((6 . 9) 54)) (((7 . 1) 7) ((7 . 2) 14) ((7 . 3) 21) ((7 . 4) 28) ((7 . 5) 35) ((7 . 6) 42) ((7 . 7) 49) ((7 . 8) 56) ((7 . 9) 63)) (((8 . 1) 8) ((8 . 2) 16) ((8 . 3) 24) ((8 . 4) 32) ((8 . 5) 40) ((8 . 6) 48) ((8 . 7) 56) ((8 . 8) 64) ((8 . 9) 72)) (((9 . 1) 9) ((9 . 2) 18) ((9 . 3) 27) ((9 . 4) 36) ((9 . 5) 45) ((9 . 6) 54) ((9 . 7) 63) ((9 . 8) 72) ((9 . 9) 81)) (((10 . 1) 10) ((10 . 2) 20) ((10 . 3) 30) ((10 . 4) 40) ((10 . 5) 50) ((10 . 6) 60) ((10 . 7) 70) ((10 . 8) 80) ((10 . 9) 90)))

Schemeによる記号処理入門

[scheme]iotaっぽいの書いてみた

昼過ぎは毎日猛烈に眠いので今日は眠気覚ましにsrfi-1のiota書いてみた。
(こんなんだったかなーと思い出しながら)
download


;; (iota cnt init inc
(define iota
  (lambda (cnt . opt)
    (letrec ((init (if (null? opt)
                       0
                       (car opt)))
             (inc (cond
                   ((or (null? opt)
                        (null? (cdr opt))) 1)
                   (else (cadr opt))))
             (iter (lambda (cnt init inc ret)
                     (if (zero? cnt)
                         '()
                         (cons ret
                               (iter (- cnt 1)
                                     init
                                     inc
                                     (+ ret inc)))))))
      (iter cnt init inc init))))

(iota 10 0 1)
;; => (0 1 2 3 4 5 6 7 8 9)
(iota 10 1)
;; => (1 2 3 4 5 6 7 8 9 10)
(iota 15)
;; => (0 1 2 3 4 5 6 7 8 9 10 11 12 13 14)
(iota 10 0 2)
;; => (0 2 4 6 8 10 12 14 16 18)

2009/08/10

9LISP

9lisp

kpf.logo.main

 

  • 9LISP
    • LISPの勉強会を始めます
    • ガチンコです
    • 月2回やります
  • KPF
    • 次は第五回目の勉強会
    • メンバーが40名を超えました

[Twitter]最近ブログを書いていなかったので

【近況】

  • 引っ越した
  • 転職した
  • しばらく家がオフラインだった
  • 転職した会社の椅子が全部アーロンチェア
  • MSの資格取った(MCP、MCTS)
    • 70-536 (C# 2005) Microsoft .NET Framework 2.0 Application Development Foundation
    • 70-528 Microsoft .NET Framework 2.0 Web-Based Client Development for C# 2005
    • 70-526 Microsoft .NET Framework 2.0 Windows-Based Client Development for C# 2005
    • 取得予定
      • 分散アプリケーション(C#)
      • Design Enterprise
  • 苦手なネットワーク分野の勉強を始めた(仕事で)
    • SNMP
    • TCP/IP
  • 新しく学ぶ必要があるものが増えた
    • SharePointServer
    • TeamFoundationServer
    • VMWare
    • Windows Communication Foundation
    • SNMP
  • 読書
    • 6月は14冊読んだ

[JavaScript]srfiのiota

今日は少し寝不足で仕事中に激しい睡魔に襲われたので気分転換に書いた。

download

 

Arrayに非破壊的なmap追加してiotaっぽいの書いてfizzbuzzってみた。

Array.prototype.map = function (f)
{
  var ret = [];
  for (var i = 0; i < this.length; i++)
  {
    ret[i] = f(this[i]);
  }
  return ret;
};

function iota(cnt, init, inc)
{
  var ret = [];
  init = init || 0;
  inc = inc || 1;

  for (var i = 0, j = init; j < cnt; i++, (j = j + inc))
  {
    ret[i] = j;
  }
  return ret;
}

iota(100, 1).map(function (n){
                   var ret = n;
                   var modulo = function (divider)
                   {
                     return n % divider;
                   };

                   if (modulo(3) == 0)
                   {
                     ret = "fizz";
                   }
                   if (modulo(5) == 0)
                   {
                     ret = "buzz";
                   }
                   if (modulo(15) == 0)
                   {
                     ret = "fizzbuzz";
                   }

                   return ret;
                 });

[KPF]第4回勉強会をやってきた

取り急ぎ。

「SchemeとJavaScriptで数字遊び」と題してライブコーディングをやるつもりでしたが、途中でテンパってしまって自ら強制終了というなんともヒドイ醜態をさらしてきましたorz

ライブコーディングも中途半端だったので取り急ぎコードをさらします。

 

download

 

 

var inc = function (n)
{
  return ++n;
};

var dec = function (n)
{
  return n - 1;
};

var add = function (n, m)
{
  return m == 0
    ? n
    : inc(add(n, dec(m)));
};

var sub = function (n, m)
{
  return m == 0
    ? n
    : dec(sub(n, dec(m)));
};

var bgr = function (n, m)
{
return m == 0
    ? true
    : (n == 0
       ? false
       : bgr(dec(n), dec(m)));
};

var sml = function (n, m)
{
  return m == 0
    ? false
    : (n == 0
       ? true
       : sml(dec(n), dec(m)));
};

var mul = function (n, m)
{
  return m == 0
    ? m
    : add(n, mul(n, dec(m)));
};

var div = function (n, m)
{
  return sml(n, m)
    ? 0
    : inc(div(sub(n, m), m));
};

function fact (n)
{
  return n == 0
    ? 1
    : n * fact(--n);
}

function tailCallFact(n)
{
  var recur = function (m, ret)
  {
    return m == 0
      ? ret
      : recur(m - 1, m * ret);
  };
  return recur(n, 1);
}

function tailCallFact(n)
{
  var recur = function (m, ret)
  {
    return [ret, m == 0
      ? ret
            : recur(m - 1, m * ret)];
  };
  return recur(n, 1);
}

var i = 10;
do { print ("hello"); i--; }while(0 < i)

(function () { var i = 10; do{ print("hello"); i--;}while(0 < i);})();

Array.prototype.each = function (f)
{
  for(var i = 0; i<this.length; i++)
  {
    f(this[i]);
  }
};

(function (f){
   f(f, 10);
})(function (f, n){
      if (0 < n)
      {
        print ("hello");
        f(f, n - 1);
      }
    });

(function (f){
   f(f, 10);
})(function (f, n){
      if (0 < n)
      {
        print("hello");
        f(f, n - 1);
      }
    });

(function (f){
   f(f, f, 10);
})(function (f, n){
      if (0 < n)
      {
        print("hello");
        f(f, n - 1);
      }
    });

function map (f, array)
{
  for (var i = 0; i < array.length; i++)
  {
    array[i] = f(array[i]);
  }
  return array;
}

map(function (v)
    {
      print(v);
      return v;
    },
    [1, 2, 3, 4, 5]);

Array.prototype.map = function (f)
{
  for (var i = 0; i < this.length; i++)
  {
    this[i] = f(this[i]);
  }
  return this;
};

[1,2,3,4,5].map(function(v){print(v);return v;});

 

(define inc
  (lambda (n)
    (+ n 1)))

(define dec
  (lambda (n)
    (- n 1)))

(define add
  (lambda (n m)
    (if (zero? m)
        n
        (inc (add n (dec m))))))

(define sub
  (lambda (n m)
    (if (zero? m)
        n
        (dec (sub n (dec m))))))

(define bgr
  (lambda (n m)
    (cond
     ((zero? n) #f)
     ((zero? m) #t)
     (else (bgr (dec n)(dec m))))))

(define sml
  (lambda (n m)
    (cond
     ((zero? m) #f)
     ((zero? n) #t)
     (else (sml (dec n)(dec m))))))

(define mul
  (lambda (n m)
    (if (zero? m)
        0
        (add n (mul n (dec m))))))

(define div
  (lambda (n m)
    (if (sml n m)
        0
        (inc (div (sub n m) m)))))

(define fact
  (lambda (n)
    (if (zero? n)
        1
        (* n (fact (- n 1))))))

(define tail-call-fact
  (lambda (n)
    (letrec ((iter (lambda (n ret)
                     (cons
                      ret
                      (if (zero? n)
                          '()
                          (iter (- n 1)
                                (* n ret)))))))
      (iter n 1))))

(do ((i 0 (+ i 1)))
    ((= i 10))
  (print "hello"))

(let loop ((s 0))
  (if (< s 10)
      (begin
        (print "hello")
        (loop (+ s 1)))))

(for-each
(lambda (i)
   (print "hello"))
'(1 2 3 4 5))

((lambda (f)
   (f f 10))
(lambda (f n)
   (if (< 0 n)
       (begin
         (print "hello")
         (f f (- n 1))))))

((lambda (f)
   (f f 10))
(lambda (f n)
   (if (< 0 n)
       (begin
         (print "hello")
         (f f (- n 1))))))

(define fact
  (lambda (n)
    (if (zero? n)
        1
        (* n (fact (- n 1))))))

(define tail-call-fact
  (lambda (n)
    (letrec ((iter (lambda (x ret)
                     (if (zero? x)
                         ret
                         (iter (- x 1)(* x ret))))))
      (iter n 1))))

(define e '(define (fact n)
             (if (zero? n)
                 1
                 (* n (fact (- n 1))))))

(car e)
(caadr e)
(cdadr e)
(caddr e)

(use srfi-1)
(map
(lambda (n)
   (cond
    ((zero? (modulo n 3)) "fizz")
    ((zero? (modulo n 5)) "buzz")
    ((zero? (modulo n 15)) "fizzbuzz")
    (else n)))
(iota 100 1))