水曜日, 5月 28, 2014

C++のラムダ

Java8でついにラムダ式が..というのは間違いなくビッグニュースではあるが,一方C++も既にラムダをC++0x以降で既にサポート済みであることを述べておかないのはある意味フェアではなかろう.

以下の例はinitializer_list経由でリストの 配列を取り,リストの値はラムダ式のpredを使いソート,そして指定された関数で出力する例.

#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;


class Tako {
private:
 vector<signed> v;
public:
 Tako(initializer_list<signed> listVal);
 virtual ~Tako() {}
 void dump(void (f)(const signed));
 void sort();
};

Tako::Tako(initializer_list<signed> listVal) {

 for (auto a : listVal) {
  v.push_back(a);
 }
}

void Tako::dump(void (f)(const signed)) {
 for (auto x : v) {
  f(x);
 }
}

void Tako::sort() {

 if (v.size() >= 2) {
  std::sort(v.begin(), v.end(), [](signed x, signed y)-> signed { return x > y; });
 }

}

void dump_to_stdout(const signed v) {
 cout << v << endl;
}

int main() {

 Tako t = { 32, 27, 30, 50, 64, 10 };
 void(*myfunc)(signed) = dump_to_stdout;
 t.sort();
 t.dump(myfunc);


}

日曜日, 5月 18, 2014

Java8 - コレクター マップ

問題

String型のリストをstreamを使用してマップに変換せよ.そのリストの各要素は変換されたマップの値とする.キーは任意の整数値を割り当ててよい.

ヒント

Collectors.map()メソッドの基本知識をただ問うているだけの問題.

解答

       Stream.of("tako", "pako")
                .collect( toMap( x -> ++ctx, y -> y, (a,b) -> a + b ) )
                .forEach( (x,y) -> System.out.println( x + ":" + y ) );


火曜日, 5月 13, 2014

走り書き - 草を生やす

草を生やす,緑豊かなコードである.
package org.tanuneko;

import java.util.Arrays;

public class Kusa {

    public static void main( String args[] ) {

        System.out.println(
            Arrays.asList( "This is a pen".split( " " ) ).stream()
                    .map( x -> "ww" + x + "ww" )
                    .reduce( "(^o^)", String::concat )
                    .toString()
        );

    }

}


日曜日, 5月 04, 2014

2次元配列から重複を検索

問題
In a 2-D matrix, every row is increasingly sorted from left to right, and the last number in each row is not greater than the first number of the next row. A sample matrix follows. Please implement a function to check whether a number is in such a matrix or not. It returns true if it tries to find the number 7 in the sample matrix, but it returns false if it tries to find the number 12.
1   3   5
7   9   11
13  15  17
(Coding Interviews: Questions, Analysis & Solutionsより引用)

ヒント
2次元配列である必要などない.


基本的には2次元配列である必要がないため,一次元配列にするか,このまま2次元配列に2分検索をするか.ここでは前者の方法をとっている.


package org.tanuneko;

import java.util.*;
import java.util.stream.Collectors;

/**
 * Created by morinoko on 5/3/2014.
 */
public class DupeFound {

    static int bsearch( List<Integer> l, int val ) {

        int s = 0;
        int e = l.size() - 1;
        int m = 0;
        while( s <= e ) {
            m = l.get((s + e) / 2);
            if (m == val)
                return (s + e) / 2;
            else if (m < val)
                s = ((s + e) / 2) + 1;
            else
                e = ((s + e) / 2) - 1;
        }
        return -1;
    }


    public static void main( String args[] ) {

     
    List<Integer> l = Arrays.asList( "1 3 5", "7 9 11", "13 15 17" )
            .stream()
            .flatMap(x -> Arrays.stream(x.split(" ")))
            .mapToInt(x -> Integer.parseInt(x))
            .collect(ArrayList::new, ArrayList::add, ArrayList::addAll);

    int m = l.get( l.size() / 2 );

    System.out.println( bsearch( l, 5 ) );
    System.out.println( bsearch( l, 14 ) );
}
}

土曜日, 5月 03, 2014

マルチスレッド - notifyとwait

問題
There are three threads in a process. The first thread prints 1 1 1 …, the second one prints 2 2 2 …, and the third one prints 3 3 3 … endlessly. How do you schedule these three threads in order to print 1 2 3 1 2 3 …?
(Coding Interviews, Analysis & Solutions より引用)

ヒント
各スレッド間でchain of responsibility的に連係動作させるか,マスタスレッドがnotify/waitを利用してオーケストレーションするか等,解法は色々ある.

解答

ここではヒントの後者の方法を実装してみた.

package org.tanuneko;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

/**
 * Created by morinoko on 5/3/2014.
 */
public class MyThread implements Runnable {

    private static final int NUM_TH = 3;
    private final int id;
    private final int val;
    private static Object[] objs = new Object[NUM_TH];

    static {
        for( int i = 0;i < objs.length;i++ ) {
            objs[i] = new Object();
        }
    }

    public MyThread( int id,int val ) {
        this.id = id;
        this.val = val;
    }

    public void run() {

        while( true ) {

            synchronized( objs[id] ) {

                try {
                    objs[id].wait();
                } catch ( InterruptedException iE ) {
                    iE.printStackTrace();
                }
            }
            System.out.println( val );

        }
    }

    public static void main( String args[] ) throws InterruptedException {

        ExecutorService s = Executors.newFixedThreadPool( NUM_TH );
        for( int i = 0;i < NUM_TH;i++ ) {
            s.execute( new MyThread( i, i + 1) );
        }

        int invokeTarget = 0;
        while( true ) {
            synchronized( objs[invokeTarget] ) {
                objs[invokeTarget].notify();
            }

            Thread.sleep( 1000 );
            invokeTarget = ++invokeTarget % NUM_TH;
        }

    }

}

Groovy - JsonSlurperとJsonBuilder

最近仕事でGroovyを選ぶことが多い.やはりスピードを最優先かつシェルスクリプトでは要求にこたえられない場合はGroovy又はPythonを選ぶことになる.

しかしGroovyは書けば書くほど,便利で病みつきになる言語である.Groovy JDKも便利なものばかりで,おそらく通常のJavaコードを書くより効率は倍,コード量も半分以下になっていると感じる.

とりわけ便利であると思ったものをいくつか紹介していきたい.

一つ目はJsonSlurperとJsonBuilder.JSonSlurperは,名前の通りJsonオブジェクトをずずっとパースしてGroovyオブジェクトにアンマーシャルしてくれる.JsonSlurperは多くのparseオーバロード メソッドを提供しているので,JsonSlurperの為に入力データを加工する手間も省けることも多いだろう.
一方JsonBuilderはGroovyオブジェクトからJSONデータへのマーシャリング機能を提供している.
以下の例はJSONメッセージをアンマーシャル後,再びマーシャルする例.


import groovy.json.JsonBuilder
import groovy.json.JsonSlurper

jsonMsg = "{\n" +
        "    \"title\": \"The Latin Bit\",\n" +
        "    \"Label\": \"BlueNote\",\n" +
        "    \"Janre\": \"Jazz\",\n" +
        "    \"Leader\": [\n" +
        "        \"Grant Green\"\n" +
        "    ],\n" +
        "    \"Release\": 1962,\n" +
        "    \"TrackRecords\": [\n" +
        "        {\n" +
        "            \"All Tracks\": [\n" +
        "                \"Grant Green(g)\",\n" +
        "                \"John Acea(p)\",\n" +
        "                \"Wendell Marshall(b)\",\n" +
        "                \"Willie Bobo(ds)\",\n" +
        "                \"Carlos 'Patato' Valdes(conga)\",\n" +
        "                \"Garvin Masseaux(chekere)\"\n" +
        "            ]\n" +
        "        }\n" +
        "    ]}"

def parseJson( jsonData ) {

    JsonSlurper json = new JsonSlurper()
    return json.parseText( jsonData )

}

def buildJson( obj ) {

    def builder = new JsonBuilder( obj )
    return builder.toPrettyString()
}

// main

def parsed = parseJson( jsonMsg )
println( parsed )
assert parsed.title == "The Latin Bit"
assert parsed.Release == 1962
assert parsed.Leader[0] == "Grant Green"
assert parsed.TrackRecords["All Tracks"][0].indexOf( "John Acea(p)" ) != -1

println( buildJson( parsed ) )