[Jprogramming] Project Euler, problem 36
Mike Day
mike_liz.day at tiscali.co.uk
Sat Jun 30 18:02:06 HKT 2007
Raul's explained a lot overnight but, now I'm awake,
I'll try to expand on the working of my effort - appended
below your (Bruno's) note in case anyone is still trying
to do problem 36.
Mike
Bruno wrote:
> Thank you for the awnsers.
>
> I'm having some trouble understanding the codes tough.... In Roger's code
> what does the I. do? Here's how I read the code:
>
> +/ I. ((-:|.)@#: *. (-:|.)@":)"0 i.1e6
>
> from 1 to 1e6, check if the number is palyndrome in base 2 and in base
> 10.
> I. the bolean list // don't understand this part
> sum the elements
>
> In Mike's code, there's a nice speed boost, but I can't understand the
> code
> flow... How do you prevent from doing a test if the other test was
> false? I
> beleive it has to do with the * primitive...
>
> And if we wanted to do as Raul told and only test odd numbers, how do
> we go
> from 1 to 999999 jumping 2 numbers? That would cut the code execution
> time
> in half I beleive.
>
> #######################
>
> I tried going back to problem 1 and adapting your solutions to it, but
> failed =(
>
> +/ 1e3 #~ ((3|"0)) +. (5|"0)) i. 1e3
> NB. how do I access the current number from inside the ( ) ?
>
> Bruno
> ----------------------------------------------------------------------
> For information about J forums see http://www.jsoftware.com/forums.htm
>
>
(I've tried to anticipate line-unwraps, probably missed some)
My first offering was
+/(* ((-:|.)@#:"0)) (#~((-:|.)@":"0)) i. 1e6
You can construe this as 3 operations in series, given
the right argument as i. 1e6
Each operation is a tacit J expression, but the whole
is an explicit J expression.
(Raul's useful remark about odds only can be incorporated
by restating the right argument as >: +: i. 0.5e6)
Let's use a small set of numbers for exposition:
n =: 12 110 111 112 313
The first operation is
(#~((-:|.)@":"0))
Consider these fragments:
[sn =: ":"0 n NB. express each number as a string
12
110
111
112
313
[b =: (-: |.)"1 sn NB. are strings palindromes?
0 0 1 0 1
NB. this is a hook; see J dictionary
[n10 =: b#n NB. yield base-10 palindromes
111 313
NB. join these fragments together - we can now drop
NB. the "1 from the hook:
[n10 =: (#~(-:|.)@":"0)n NB.can drop a pair of brackets
111 313
NB. The second similar operation applies only to the results
NB. of the first. So in this approach you don't need to
NB. worry about "doing a test if the other test was false"
[n2 =: (* (-:|.)@#:"0) n10 NB.again drop a pair of brackets
0 313
NB. This is another hook f g where f is * and
NB. g is ((-:|.)@#:"0)
((-:|.)@#:"0) n10 NB. right monad side of hook
0 1
NB. The * just multiplies 0 1 by 111 313
NB. Alternatively we could have had
[n2 =: (#~ ((-:|.)@#:"0)) n10
313
NB. I think the latter (with #~) involves more
NB. restructuring while the former (with *) needs
NB. more multiplies. However, they time roughly equally
NB. on this problem.
NB. The last, third, operation +/ merely adds up the
NB. remaining numbers
My alternative solution just swaps the base-10 and
base-2 operations.
I hope that helps.
Mike
More information about the Programming
mailing list