ClojureとProject Euler、パート2

前の記事( ClojureとProject Euler、パート1 )で、clojureを使用したEulerプロジェクトの最初の3つのタスクの解決策について説明しました。clojureはかなり若い言語ですが、親はよく知られています。

この記事では、読者(および私も)にこの面白いjava lispを紹介し続けます。 そして、オイラーの3つの簡単なタスクのソリューションを紹介します。





タスク4



タスク

回文である2つの3桁の数字の最大積を求めます。



アルゴリズム

1.すべての作品の投稿を作成します。

2.パリンドロームのみを残してフィルターします。

3.最大値を見つけます。



コード

まず、文字列が回文であるかどうかを決定する関数を決定します。

私は意志力を訓練し、少なくともf-tionでコメント付きのコードを書くことにしました。

defind palindrom?

「xが回文であればtrueを返し、

そうでなければfalse。

[ x ]

let [ s str x ]

= seq s reverse s ))


4つのことに注意する価値があります。

1.関数の説明は、名前の後、引数のリストの前に記述されます。 この説明は、電話をかけると表示されます(doc your-function)。

2. clojureでは、すべての述語(それらを1つの変数からtrueまたはfalseを返す関数として理解します)は通常、疑問符で終わります。

3.以来 数値を渡すため、最初に文字列に変換する必要があります。これはstr関数を使用して行われます。

4. wordはString型で、(reverse word)はシーケンスを返し、単純な比較では常にfalseになります。 そのため、単語も単語から作る必要があります。 これが私たちが行うことです(シーケンスワード)。



ここで主要な部分:

最大値を減らす

フィルターパリンドロム?

for [ i range 100 1000 j range i 1000 ] * i j




C(reduce max ...)は多かれ少なかれ明確である必要があり、受け取った8個から最大値を取ります。

(フィルター...)では、数字の数をフィルター処理してパリンドロームのみを残し、すぐに述語パリンドロームを渡しますか?前の例のように、匿名関数ではなく、そこにあります。

[[ i range 100 1000 j range i 1000 ] * i j
ここでは、for関数が使用され、ctが返されます。 これは、通常ループで使用される角括弧[]でローカル変数を示します(正しい名前の付け方はわかりませんが、iとjの使用場所は誰でも知っていると思います)。 実際のアイテムは、バインディング[]に続く式の値から形成されます。 私たちの場合、これは単にiとjの積です。 jが100から1000ではなく、現在のiから実行されるという事実には、まだわずかな改善があります。これにより、作業が高速化されます。

より具体的な例:

for [ i range 1 5 j range i 5 ] [ i j ]

; ベクトルの数を取得します:([1 1] [1 2] [1 3] [1 4] [2 2] [2 3] [2 4] [3 3] [3 4] [4 4])




タスク5



タスク

1から20までのすべての数で除算された最小数を出力します。



アルゴリズム

20個の数字の最小公倍数を取得します。



コード

もちろん、独自のNOCを作成することはできますが、私たちは...既製の関数を使用するのではなく、ライブラリを使用する方がよいでしょう。 通常、clojure-contrib( http://clojure.org/libraries )、私が理解しているように、普通のユーザーによって書かれたライブラリのアセンブリは、clojureにすぐに接続されます。 Clojure-contribは単純にjarファイルに含まれ、clojure.jarとともにパスに含まれています。 さまざまな種類のユーティリティがあります。 lazy-seqライブラリには、前の記事で書いたフィボナッチポストと素数の素数があることに注意してください。 しかし、今は数学ライブラリに興味があるでしょう。そこにはlcm関数-NOCがあります。

接続します:

'clojure。contrib。mathを使用


そして、私たちは決定します:

lcmを減らします範囲1 21




言語の特別な新しい知識を必要とせず、実装のみを必要とするいくつかのタスクをスキップします。 8に直行します。



タスク8



タスク

1000文字の数字を指定すると、最大の製品を提供する5桁の連続した数字を見つけて、この製品を印刷する必要があります。 ここで番号を見ることができます:( http://projecteuler.net/index.php?section=problems&id=8



アルゴリズム

1.最初に、この番号をプログラムに入力する必要があります。エディターに書き込むのはあまり便利ではないため、ファイルに保存してそこから読み取ることにしました。 同時に、Java自体のライブラリを使用します。

2.数字を5桁の5つのグループに分けます。

3.乗算して最大値を取ります。



コード

番号(各50文字の20行)は、ファイルinput.txtに保存されます。

定義番号

let [ reader new java。io。BufferedReader new java。io。FileReader "input.txt" ]

str for [ i range 20 ] . readLine reader )を減らす


ここでは、おなじみのBufferedReaderクラスとFileReaderクラスを見ることができます。 新しい関数を使用して新しいクラスインスタンスを作成できます。2番目のパラメーターはクラス名、3番目、4番目などです。 -このクラスのコンストラクターの引数。 フルネームを記述しないようにクラスをインポートできることは注目に値しますが、Javaのようにパッケージからすべてのクラスを一度にインポートすることはできません。 ひとつずつ。

ドットを介してクラスのインスタンスのメソッドを呼び出すことができます:(.methodName instance arg1 arg2 ...)。



文字列をいくつかの数字に変換するメソッドを作成します。

defn to-digit-seq

「文字列stを変換します

数字のシーケンスに。」

[ st ]

マップ# Character / getNumericValue st


静的メソッドとJavaクラス変数は、ClassName / methodNameを介してアクセスできることに注意してください。



そして今、主要部分:

最大値を減らす

マップ番号 reduce *%

パーティション5 1 to-digit-seq number


ここでは、面白いパーティション関数が使用されます。これは、指定された部分のサブシーケンスの数を返します:)

一般的に、私たちの場合、彼は8桁を1に分割しました。その要素は5桁のグループで、1ずつ増加します。



おそらく今のところすべてです。 最後に、オイラーからのタスクのポートフォリオに関する決定を含むウェブサイトへのリンクを提供したいと思います。私は思いがけず偶然に出会いました。 すべてが揃っているわけではありませんが、どのオプションが存在するかを確認して学ぶことができます。http//clojure-euler.wikispaces.com/



All Articles