2012年4月30日月曜日

Project Euler-Problem4をgroovyで解いてみる

問題

左右どちらから読んでも同じ値になる数を回文数という。 2桁の数の積で表される回文数のうち、最大のものは 9009 = 91 × 99 である。

では、3桁の数の積で表される回文数のうち最大のものはいくらになるか。

答えを求めたコード

999から回文数を求めて、最も大きい数字を最後に取り出すだけの単純なコードです。
private Boolean isPalindrome(int num) {
  num.toString() == num.toString().reverse()
}

private Integer getMaxPalindrome(int num) {
  (num .. 100).findResult {
    if (isPalindrome(num * it)) {
      num * it
    }
  }
}
def ret = (999..100).collect {
  getMaxPalindrome(it)
}
println "{ret.max()} = ${ret.max()}"

2012年4月25日水曜日

Project Euler-Problem3をgroovyで解いてみる

問題内容

The prime factors of 13195 are 5, 7, 13 and 29.

What is the largest prime factor of the number 600851475143 ?
和訳は・・・
13195 の素因数は 5、7、13、29 である。

600851475143 の素因数のうち最大のものを求めよ。

コード

単純に割り切れる値を求めて、その値が自分より小さい素数に含まれていないことをチェックしています。
def primes = []
(2..Math.sqrt(600851475143)).each {
  if (600851475143 % it == 0 && !(primes.find {prime -> it % prime == 0})) {
    primes << it
  }
}
println primes.max()

2012年4月22日日曜日

[groovy]正規表現パターンをコンパイルして使おう

正規表現パターンをコンパイルして使用する方法。
スラッシュでパターンを構築しても、単なる文字列なのでこれだと毎回コンパイルされるので、
コンパイルしてjava.util.regex.Patternにしてあげるのが良い。
def p = ~/\w/    // 正規表現文字列を「~」でコンパイルする
def s = /\w/

// 「~」でコンパイルしているのでPatternオブジェクトになる。
assert p instanceof java.util.regex.Pattern
// スラッシュで構築したパターンはStringオブジェクトのまま
assert s instanceof java.lang.String

2012年4月15日日曜日

[groovy]正規表現のパターン定義

パターン定義はjavaと同じ。
ただい、正規表現パターンの文字列を「"」ではなく「/」で定義すると余計なエスケープがいらなくなる。

assert "hoge." =~ /\./   // 余計なエスケープがいらない
assert "hoge." =~ "\\."    // 「\」のエスケープが必要

[groovy]Immutableなクラス

@ImmutableアノテーションをクラスにつけてあげるとImmutableなクラスが実現できる。

※Immutableアノテーションは、groovy.langパッケージにもあるけど、非推奨になっているのでgroovy.transformの方をしようする。

Immutableなクラスの例

import groovy.transform.Immutable

@Immutable
class Hoge {
  String hoge
  int num
}

Immutableなクラスを変更しようとするとどうなるか?

Hogeクラスをインスタンス化し、hogeプロパティを変更してみます。
def hoge = new Hoge(hoge: "hoge", num: 100)
hoge.hoge = "変更"

実行してみると、ReadOnlyPropertyExceptionが発生し、クラスの状態が変更できないことがわかります。
Caught: groovy.lang.ReadOnlyPropertyException: Cannot set readonly property: hoge for class: goovy.immutable.Hoge
groovy.lang.ReadOnlyPropertyException: Cannot set readonly property: hoge for class: goovy.immutable.Hoge
 at goovy.immutable.Hoge.setProperty(Hoge.groovy)
 at goovy.immutable.main.run(main.groovy:6)

==演算子

Immutableなクラスにしてあげると、「==」演算子をオーバライドしてくれます。

お試しコード。
def hoge = new Hoge(hoge: "hoge", num: 100)

// immutableなオブジェクトは、「==」をオーバライドしてくれるから、
// 同じあたいかどうかになる
assert hoge == new Hoge(hoge: "hoge", num: 100)
assert hoge != new Hoge(hoge: "hoge", num: 101)

def mutableHoge = new MutableHoge(hoge: "hoge", num : 100)
// mutableなオブジェクトは、==がオーバライドされないので同一インスタンスかの比較
assert mutableHoge != new MutableHoge(hoge: "hoge", num : 100)


ImmutableだとtoStringまで実装される

Immutableなクラスだと、toStringまで追加されるようです。

Immutableでないと、「hoge = goovy.immutable.Hoge@6c0089ab」な感じになりますが、Immutableだと「hoge = goovy.immutable.Hoge(hoge:hoge, num:100)」なります。


2012年4月12日木曜日

keytoolを使ってみた

keytoolを使用して、暗号化の鍵を生成してみよう。

※keytoolは、JAVA_HOME/bin配下にいます。

鍵を登録

keytoolの「-genseckey」を使用して暗号化の鍵を登録できます。 【ポイント】
  • storetypeには、「JCEKS」を指定する。
  • keyalgには、鍵を生成するためのアルゴリズムを指定する。
  • keysizeは、秘密鍵を生成する際には必須。今回は、AES暗号用の128ビットの鍵を生成している。
  • keystoreのファイル名。指定しない場合は、HOME/.keystoreとなる。
  • aliasには、鍵を識別するための任意の名前を指定する。 KeyStore#getKeyを使用して、鍵を取得する際に指定する名前となる。
  • storepassには、キーストアにアクセスするためのパスワードを設定する。
keytool -genseckey -storetype JCEKS -keyalg AES -keysize 128 -keystore ./.key -storepass password -alias key1 

上記コマンド実行後に、以下のメッセージが表示されます。 鍵ごとにパスワードを設定する場合には、新しいパスワードを入力します。 keysotreにアクセスする際に必要となるパスワードと同じにする場合には、なにも入力しなくて大丈夫です。
 の鍵パスワードを入力してください。 (キーストアのパスワードと同じ場合は RETURN を押してください): 

登録されている鍵をリスト表示

listを指定すると、登録されている鍵や証明書をリスト表示することが出来ます。

$ keytool -list -storepass password -keystore .key -storetype JCEKS

キーストアのタイプ: JCEKS キーストアのプロバイダ: SunJCE

キーストアには 2 エントリが含まれます。

key1, 2012/04/12, SecretKeyEntry, mykey, 2012/04/12, SecretKeyEntry, 

登録されている鍵を削除

deleteを指定すると登録されている鍵を削除できます。 deleteを実行後にlist表示してみると、鍵が上のlist表示の時から減っていることが分かります。
$ keytool -delete -alias mykey -keystore .key -storepass password -storetype JCEKS $ keytool -list -storepass password -keystore .key -storetype JCEKS

キーストアのタイプ: JCEKS キーストアのプロバイダ: SunJCE

キーストアには 1 エントリが含まれます。

key1, 2012/04/12, SecretKeyEntry, 

2012年4月5日木曜日

groovyの文字列操作

groovyの文字列操作。

基本的にJavaのStringにあるメソッドは使えるが、それが拡張されていて文字列をさらに扱いやすくなっている。

def str = 'Hello World.'

assert str.startsWith('Hello')

// 特定位置の文字を取得
assert str.charAt(0) == 'H'   // これは、java.lang.Stringのメソッド
assert str.getAt(0) == 'H'    // これは、groovyのメソッド
assert str[0] == 'H'

// 文字の存在チェック
assert str.contains("World")

// substring
assert str[0..4] == 'Hello'   // 0〜4文字目
assert str[0..<5] == 'Hello'  // 0〜4文字目
def range = (0..4)
assert str[range] == 'Hello'  // Rangeを指定してもOK

// 連結や除去
assert 'Hi' + str + '!' - 'Hello' - '.' == 'Hi World!'
assert "Hi${str}!" - 'Hello' - '.' == 'Hi World!'

// 文字数のカウント
assert str.count('l') == 3

// 整形
assert "100".padLeft(5, '0') == '00100'   // 先頭0埋め
assert "100".padLeft(5) == '  100'        // 先頭スペース埋め

// 増幅
assert "100" * 2 == '100100'

Project Euler-Problem 2をgroovyで解いてみる

問題はこちらを見てね。http://se-bikou.blogspot.jp/2012/03/project-euler-problem-2scala.html

単純にListに、フィボナッチ数列を詰めて行って、その値が400万を超えたらループを終えています。
で、求めた数列の中から偶数のものだけにフィルタかけて合計を求めてます。

def list = [0, 1]
while(list[-1] <= 4000000) {
  list << list[-2] + list[-1]
}
println "list.sum() = ${list.findAll{it % 2 == 0}.sum()}"