*Mo and Larry have devised a way of encrypting messages. They first decide secretly on the number of columns and write the message (letters only) down the columns, padding with extra random letters so as to make a rectangular array of letters. For example, if the message is “There’s no place like home on a snowy night” and there are five columns, Mo would write down*

t o i o y

h p k n n

e l e a i

r a h s g

e c o n h

s e m o t

n l e w x

*Note that Mo includes only letters and writes them all in lower case. In this example, Mo used the character ‘x’ to pad the message out to make a rectangle, although he could have used any letter. Mo then sends the message to Larry by writing the letters in each row, alternating left-to-right and right-to-left. So, the above would be encrypted as*

toioynnkpheleaigshareconhtomesnlewx

*Your job is to recover for Larry the original message (along with any extra padding letters) from the encrypted one.*

Summarizing, we basically need to convert the string back to the character matrix, reverse every odd row, transpose the matrix and build the string again. This is pretty easy to do in factor:

: toandfro ( sequence n -- string ) group [ odd? [ reverse ] when ] map-index flip concat >string ;

( scratchpad ) "toioynnkpheleaigshareconhtomesnlewx" 5 toandfro --- Data stack: "theresnoplacelikehomeonasnowynightx"

Unfortunately, even if SPOJ provides a wide programming language support, it doesn’t support Factor. Factor has usually been compared to lisp, so I decided to translate the above code to Common Lisp and see how well it fits. This is the equivalent Common Lisp code:

(>string (concat (flip (map-index #'(lambda (s n) (if (oddp n) (reverse s) s)) (group sequence n)))))) => "theresnoplacelikehomeonasnowynightx"

For this to work, we should define some functions used in this sentence, since Common Lisp doesn’t include them in its standard library:

group:

(defun group (sequence n) (loop for i from 0 to (1- (/ (length sequence) n)) collect (subseq sequence (* i n) (+ (* i n) n))))

(group "toioynnkpheleaigshareconhtomesnlewx" 5) => ("toioy" "nnkph" "eleai" "gshar" "econh" "tomes" "nlewx")

map-index:

(defun map-index (function list) (labels ((m-i (fn l i) (unless (null l) (cons (apply fn (car l) (list i)) (m-i fn (cdr l) (1+ i)))))) (m-i function list 0)))

(map-index #'(lambda (s n) (if (oddp n) (reverse s) s)) '("toioy" "nnkph" "eleai" "gshar" "econh" "tomes" "nlewx")) => ("toioy" "hpknn" "eleai" "rahsg" "econh" "semot" "nlewx")

flip:

(defun flip (list) (when (> (length list) 0) (loop for i from 0 to (1- (length (car list))) collect (mapcar #'(lambda (seq) (elt seq i)) list))))

(flip '("toioy" "hpknn" "eleai" "rahsg" "econh" "semot" "nlewx")) => ((#\t #\h #\e #\r #\e #\s #\n) (#\o #\p #\l #\a #\c #\e #\l) (#\i #\k #\e #\h #\o #\m #\e) (#\o #\n #\a #\s #\n #\o #\w) (#\y #\n #\i #\g #\h #\t #\x))

concat:

(defun concat (sequence) (reduce #'append sequence))

(concat '((#\t #\h #\e #\r #\e #\s #\n) (#\o #\p #\l #\a #\c #\e #\l) (#\i #\k #\e #\h #\o #\m #\e) (#\o #\n #\a #\s #\n #\o #\w) (#\y #\n #\i #\g #\h #\t #\x))) => (#\t #\h #\e #\r #\e #\s #\n #\o #\p #\l #\a #\c #\e #\l #\i #\k #\e #\h #\o #\m #\e #\o #\n #\a #\s #\n #\o #\w #\y #\n #\i #\g #\h #\t #\x)

>string:

(defun >string (sequence) (concatenate 'string sequence))

(>string '(#\t #\h #\e #\r #\e #\s #\n #\o #\p #\l #\a #\c #\e #\l #\i #\k #\e #\h #\o #\m #\e #\o #\n #\a #\s #\n #\o #\w #\y #\n #\i #\g #\h #\t #\x)) => "theresnoplacelikehomeonasnowynightx"

Joining it all we have:

(defun group (sequence n) (loop for i from 0 to (1- (/ (length sequence) n)) collect (subseq sequence (* i n) (+ (* i n) n)))) (defun map-index (function list) (labels ((m-i (fn l i) (unless (null l) (cons (apply fn (car l) (list i)) (m-i fn (cdr l) (1+ i)))))) (m-i function list 0))) (defun flip (list) (when (> (length list) 0) (loop for i from 0 to (1- (length (car list))) collect (mapcar #'(lambda (seq) (elt seq i)) list)))) (defun concat (sequence) (reduce #'append sequence)) (defun >string (sequence) (concatenate 'string sequence)) (defun toandfro (sequence n) (>string (concat (flip (map-index #'(lambda (s n) (if (oddp n) (reverse s) s)) (group sequence n))))))

Some of the functions above require a list as a parameter instead of a sequence, yet it could be easily modified to support sequences in a more generic form.

I wonder how an independent Common Lisp implementation would compare to the above.

]]>The contest is divided in different rounds, the first one consisted in 3 puzzles. The first one is entitled Double Squares and says as follows:

`A double-square number is an integer X which can be expressed as the sum of two perfect squares. For example, 10 is a double-square because 10 = 3`

^{2} + 1^{2}. Your task in this problem is, given X, determine the number of ways in which it can be written as the sum of two squares. For example, 10 can only be written as 3^{2} + 1^{2} (we don't count 1^{2} + 3^{2} as being different). On the other hand, 25 can be written as 5^{2} + 0^{2} or as 4^{2} + 3^{2}.

**Input**

You should first read an integer N, the number of test cases. The next N lines will contain N values of X.

**Constraints**

0 ≤ X ≤ 2147483647

1 ≤ N ≤ 100

```
```**Output**

For each value of X, you should output the number of ways to write X as the sum of two squares.

**Example input**

5
10
25
3
0
1

**Example output**

1
2
0
1
1

So basically this means that we need to check for each number n how many distinct x, y combinations are to satisfy: y^{2} + z^{2} = x

I decided to implement it in Factor. Since the program is going to be a script that parses a file whose name is provided as a command line argument, let’s begin with the boring stuff:

: (double-squares) ( path -- ) utf8 file-lines 1 tail [ string>number count ] each ; : double-squares ( -- ) command-line get first (double-squares) ;

`(double-squares)`

parses the input file, removes the first line (which provides the number of test cases) and counts the amount of double squares (with the yet to be defined word `count`

).

`double-squares`

takes care of command line argument parsing and calls `(double-squares)`

. This separation helps us during the development process, since we can call `(double-squares)`

from the listener and use `double-squares`

as a mere wrapper for the script.

So, now that we have the boring stuff done, let’s solve the core of the problem and implement `count`

. We’ll use a dynamic variable `counter`

to make the code more readable:

SYMBOL: counter : count ( x -- ) 0 counter set [ 2 / floor >integer 1 + ] keep [ check-double ] curry each-integer counter get . ;

What happens here? The counter is initialized, and we loop from 0 to x/2 to set the value of y^{2} in y^{2} + z^{2} = x. So if we know both x and y, we just need to check whether both y = sqrt(y^{2}) and z = sqrt(x – y^{2}) are natural numbers. That’s exactly the task of `check-double`

:

: root? ( x -- ? ) sqrt dup >fixnum number= ; inline : check-double ( x y z -- w ) [ drop root? ] [ swap - root? ] 2bi and [ counter inc ] when

As you can see, `check-double`

also increments the counter in case a double square is found. The loop iterates in range [0,x/2] and not in range [0,x] since 3^{2} + 1^{2} and 1^{2} + 3^{2} don’t count as different double squares.

So, we’re done. Let’s try our code:

$ ./double-squares.factor input.txt 1 2 0 1 1

Everything seems ok, right? Well, that’s what I thought at least. So I downloaded input file, ran the script again and waited… and waited… and waited… until I decided it was enough and took a look. The input files had some big numbers and the script was taking forever. The reason? I was looping for each integer instead of each valid root, which increases the number of iterations exponentially… how lame. So let’s fix the affected words:

: check-double ( x y z -- w ) swap sq - root? [ counter inc ] when ; inline : count ( x -- ) 0 counter set [ 2 / sqrt floor >integer 1 + ] keep [ check-double ] curry each-integer counter get . ;

Now it works fine… unfortunately (for me) facebook guys decided that a 6′ deadline from input file downloading to output submission was a good idea, so i failed this one due to timeout.

Here you have the whole program:

#! /usr/bin/env factor USING: kernel math math.functions command-line namespaces sequences io.encodings.utf8 io io.files prettyprint math.parser ; IN: double-squares SYMBOL: counter : root? ( x -- ? ) sqrt dup >fixnum number= ; inline : check-double ( x y z -- w ) swap sq - root? [ counter inc ] when ; inline : count ( x -- ) 0 counter set [ 2 / sqrt floor 1 + ] keep [ check-double ] curry each-integer counter get . ; : (double-squares) ( path -- ) utf8 file-lines 1 tail [ string>number count ] each ; : double-squares ( -- ) command-line get first (double-squares) ; double-squares]]>

`prime-counting(n)`

function, that returns the number of primes to`n`

`nth-prime(n)`

function, that returns the nth prime number

A day before Samuel Tardieu wrote an article about Positional factoring which included information about the math.primes vocabulary in Factor. He also included a solution on J which is also used to provide a solution to the Programming Praxis problem (see the first comment). So I decided to write an implementation in Factor, which is a very easy task.

`primes-upto`

takes a number and returns a sequence of prime numbers up to that one, so we just need to count the sequence length to get intended result:

USING: sequences math.primes ; : prime-counting ( x -- y ) primes-upto length ;

Testing it, works as expected:

( scratchpad ) 100 prime-counting . 25 ( scratchpad ) { 100 101 102 103 104 } [ prime-counting ] map . { 25 26 26 27 27 }

This problem is a bit more complex, yet Factor provides a great solution in math.primes.lists making use of Lazy lists: `lprimes`

provides an infinite stream of prime numbers, so we just need to take as many prime numbers as needed and return the last:

USING: sequences math.primes lists lists.lazy math.primes.lists ; : nth-prime ( x -- y ) lprimes ltake list>array last ;

Testing it, works as expected:

( scratchpad ) 25 nth-prime . 97 ( scratchpad ) { 24 25 26 27 28 } [ nth-prime ] map . { 89 97 101 103 107 }

And that’s pretty much about it. Here you have the whole counting-primes vocabulary:

USING: sequences math.primes lists lists.lazy math.primes.lists ; IN: counting-primes : prime-counting ( x -- y ) primes-upto length ; : nth-prime ( x -- y ) lprimes ltake list>array last ;]]>

Gertaera berezia izango da niretzat hainbat arrazoiengatik. Alde batetik, ikasle, ikertzaile eta irakasle moduan ibilitako Ingenieritza Eskolara itzuliko naiz, nahiko denbora pasa ostean.

Bestalde, pozten nau ITSAS hartu duen indarra ikusteak, eta nola lagundu duten antolaketa lanetan hainbat ikasle, irakasle eta baita unibertsitateko beste langile (IISIZ, etab.).

Orain hilabeteak pasa ondoren dana ia prest dago, antolaketan parte hartu duten guztiei zorionak eta eskerrak eman baino ez (batez ere, Dani errudun nagusiari). Bertaratzea baino ez da falta, anima zaitezte!

]]>So, my data is lost, but my site is up again with a new hosting provider. A new time for my blog. This time i expect to be a bit different. I expect to write about more broad topics and probably in different languages. My blog engine now supports tags, so you’ll be able to select by posts by language if you wish (supposing there’s someone reading! )

]]>