Search code examples
loopsjtacit-programming

Tacit function to multiply five consecutive number in a list: J, j701


I'm working on Project Euler, I'm on problem 8, and I'm trying a simple brute force: Multiply each consecutive 5 digit of the number, make a list with the results, and find the higher.

This is the code I'm currently trying to write in J:

   n =: 731671765313x
   NB. 'n' will be the complete 1000-digits number

   itl =: (".@;"0@":)
   NB. 'itl' transform an integer in a list of his digit

   N =: itl n
   NB. just for short writing

   takeFive =: 5 {. ] }.~ 1 -~ [
   NB. this is a dyad, I get this code thanks to '13 : '5{.(x-1)}.y'
   NB. that take a starting index and it's applied to a list

How I can use takeFive for all the index of N? I tried:

  (i.#N) takeFive N
|length error: takeFive
|   (i.#N)    takeFive N 

but it doesn't work and I don't know why. Thank you all.


Solution

  • 1. The reason that (i.#N) takeFive N is not working is that you are essentially trying to run 5{. ((i.#N)-1) }. Nbut you have to use x not as a list but as an atom. You can do that by setting the appropriate left-right rank " of the verb:

     (i.#N) (takeFive"0 _) N
    7 3 1 6 7
    7 3 1 6 7
    3 1 6 7 1
    1 6 7 1 7
    6 7 1 7 6
    7 1 7 6 5
    1 7 6 5 3
    7 6 5 3 1
    6 5 3 1 3
    5 3 1 3 0
    3 1 3 0 0
    1 3 0 0 0
    

    2. One other way is to bind (&) your list (N) to takeFive and then run the binded-verb through every i.#N. To do this, it's better to use the reverse version of takeFive: takeFive~:

    ((N&(takeFive~))"0) i.#N
    7 3 1 6 7
    7 3 1 6 7
    3 1 6 7 1
    1 6 7 1 7
    6 7 1 7 6
    7 1 7 6 5
    1 7 6 5 3
    7 6 5 3 1
    6 5 3 1 3
    5 3 1 3 0
    3 1 3 0 0
    1 3 0 0 0
    

    or (N&(takeFive~)) each i.#N.

    3. I think, though, that the infix dyad \ might serve you better:

    5 >\N
    7 3 1 6 7
    3 1 6 7 1
    1 6 7 1 7
    6 7 1 7 6
    7 1 7 6 5
    1 7 6 5 3
    7 6 5 3 1
    6 5 3 1 3