📜 ⬆️ ⬇️

Clojure and Project Euler, part 2

In the previous article ( Clojure and Project Euler, Part 1 ) I described the solution of the first 3 problems from the Euler project using clojure — a fairly young language, but with well-known parents.
In this article I will continue to acquaint the reader (and myself too) with this funny java-lisp. And I will show you the solution of 3 more simple tasks from Euler.


Task 4


The task
Find the maximum product of 2 three-digit numbers, which is a palindrome.

Algorithm
1. Create after-all works.
2. Filter, leaving only palindromes.
3. Find the maximum.
')
Code
First, we define a function that determines whether a palindrome is a string or not.
I decided to train willpower and try to write code with comments, at least f-tsii.
( defn palindrom?
"Returns true if x is palindrom,
false otherwise. "
[ x ]
( let [ s ( str x ) ]
( = ( seq s ) ( reverse s ) ) ) )

It is worth noting 4 things.
1. The description of the function is written after its name and before the list of arguments. This description will be displayed when you call (doc your-function).
2. In clojure, all predicates (I understand them as functions of one variable that return true or false) usually end with a question mark.
3. Because we pass the number, we have to convert it to the string first, this is done using the str function.
4. word is of type String, and (reverse word) already returns a sequence and with simple comparison it will always be false. Therefore, it is necessary to make the word from the post, too. This is what we do with the help of (seq word).

Now the main part:
( reduce max
( filter palindrom?
( for [ i ( range 100 1000 ) j ( range i 1000 ) ] ( * i j ) ) ) )


C (reduce max ...) should be more or less clear; it just takes the maximum from the whole it gets.
In (filter ...) we filter after-numbers and leave only palindromes, moreover, we immediately pass our palindrom predicate there, rather than an anonymous function, as in previous times.
( for [ i ( range 100 1000 ) j ( range i 1000 ) ] ( * i j ) )
it uses the for-function that returns after it. It contains local variables in brackets [], which are usually used in cycles (I don’t know how to name them correctly, but I think everyone knows where i and j are used). Itself is formed from the values ​​of the expression, standing after binding []. In our case, this is simply the product of i and j. There is still a slight improvement in the fact that j runs not from 100 to 1000, but from the current i, which speeds up the work.
A more graphic example for:
( for [ i ( range 1 5 ) j ( range i 5 ) ] [ i j ] )
; We get the following vectors: ([1 1] [1 2] [1 3] [1 4] [2 2] [2 3] [2 4] [3 3] [3 4] [4 4])


Task 5


The task
Print the minimum number that is divided into all numbers from 1 to 20 inclusive.

Algorithm
Take and find the smallest common multiple of 20 numbers.

Code
Of course, you can write your NOC, but we will not ... Better use ready-made functions, or rather libraries. Usually together with c clojure connect immediately and clojure-contrib ( http://clojure.org/libraries ) - the assembly of libraries, written, as I understand, by ordinary users. Clojure-contrib is just in the jar-file and is included in the path along with clojure.jar. There are all sorts of different utilities. It may be noted that in the library of lazy-seq there is a Fibonacci post and a prime number, which we wrote in the last article. But we will now be interested in the math library, in which there is a lcm function - NOC.
We connect:
( use 'clojure . contrib . math )

And decide:
( reduce lcm ( range 1 21 ) )


I will skip some tasks that do not require any special new knowledge of the language, but only implementation. So go straight to 8:

Task 8


The task
Given a number with 1000 characters, it is necessary to find 5 consecutive digits in it, which give the maximum product and output this product. The number itself can be found here: ( http://projecteuler.net/index.php?section=problems&id=8 )

Algorithm
1. First you need to enter this number into the program, I decided to save it to a file and read from there, because it's not very convenient to write it to the editor. At the same time we will work with the libraries of java itself.
2. Split the number into five groups of 5 digits.
3. Multiply and take the maximum.

Code
The number (20 lines of 50 characters) is stored in the file input.txt
( def number
( let [ reader ( new java . io . BufferedReader ( new java . io . FileReader "input.txt" ) ) ]]
( reduce str ( for [ i ( range 20 ) ] ( . readLine reader ) ) ) ) )

Here you can see the familiar classes BufferedReader and FileReader. It is possible to create a new instance of the class through the new function, in which the second parameter is the name of the class, the third, fourth, etc. - arguments for the constructor of this class. It is worth noting that we can also import a class in order not to write the full name, but we cannot import all the classes from the package at once, as in Java. Need one by one.
You can call methods on a class instance through a dot: (.methodName instance arg1 arg2 ...).

Let's write a method that will turn a string into digits:
( defn to-digit-seq
"Converts string st
to sequence of digits. "
[ st ]
( map # ( Character / getNumericValue % ) st ) )

It is worth noting here that static methods and class variables of Java can be accessed through ClassName / methodName.

And now the main part:
( reduce max
( map # ( reduce *% )
( partition 5 1 ( to-digit-seq number ) ) ) )

It uses a funny f-tion partition, which returns after-subsequences of this post :)
In general, in our case, he broke the post-digits, on post-th, elements of which are groups of 5 digits, in increments of 1.

That's probably all for now. In the end, I would like to give a link to saytik, which contains solutions for the task pool of tasks from Euler, he unexpectedly came across for himself. There really is not everything, but you can still see what are the options and learn, I think: http://clojure-euler.wikispaces.com/

Source: https://habr.com/ru/post/84791/


All Articles