Two sum: Difference between revisions

Content added Content deleted
(→‎{{header|Perl 6}}: Added Perl 6 solution)
(J draft...)
Line 29: Line 29:
{{out}}
{{out}}
<pre>[0,3]</pre>
<pre>[0,3]</pre>

=={{header|J}}==

So, first off, our basic approach will be to find the sums:
<lang J> =+/~0 2 11 19 90
0 2 11 19 90
2 4 13 21 92
11 13 22 30 101
19 21 30 38 109
90 92 101 109 180</lang>

And, check if any of them are our desired value:
<lang J> 21=+/~0 2 11 19 90
0 0 0 0 0
0 0 0 1 0
0 0 0 0 0
0 1 0 0 0
0 0 0 0 0</lang>

Except, we want indices here, so let's toss the structure so we can get those:
<lang J> ,21=+/~0 2 11 19 90
0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0
I.,21=+/~0 2 11 19 90
8 16</lang>

Except, we really needed that structure - in this case, since we had a five by five table, we want to interpret this result as a base five pair of numbers:

<lang J> $21=+/~0 2 11 19 90
5 5
5 5#:I.,21=+/~0 2 11 19 90
1 3
3 1</lang>

Or, taking advantage of being able to use verbs to represent combining their results, when we use three of them:
($ #: I.@,)21=+/~0 2 11 19 90
1 3
3 1</lang>

But to be more like the other task implementations here, we don't want all the results, we just want zero or one result. We can't just take the first result, though, because that would fill in a 0 0 result if there were none, and 0 0 could have been a valid result which does not make sense for the failure case. So, instead, let's package things up so we can add an empty to the end and take the first of those:

<lang J> ($ <@#: I.@,)21=+/~0 2 11 19 90
┌───┬───┐
│1 3│3 1│
└───┴───┘
a:,~($ <@#: I.@,)21=+/~0 2 11 19 90
┌───┬───┬┐
│1 3│3 1││
└───┴───┴┘
{.a:,~($ <@#: I.@,)21=+/~0 2 11 19 90
┌───┐
│1 3│
└───┘
;{.a:,~($ <@#: I.@,)21=+/~0 2 11 19 90
1 3</lang>

Finally, let's start pulling our arguments out using that three verbs combining form:

<lang J> ;{.a:,~($ <@#: I.@,) 21([ = +/~@])0 2 11 19 90
1 3
;{.a:,~21 ($ <@#: I.@,)@([ = +/~@])0 2 11 19 90
1 3</lang>

a: is not a verb, but we can use a noun as the left verb of three as an implied constant verb whose result is itself:
<lang J> ;{. 21 (a:,~ ($ <@#: I.@,)@([ = +/~@]))0 2 11 19 90
1 3</lang>

And, let's finish the job, give this a name, and test it out:
<lang J> twosum=: ;@{.@(a:,~ ($ <@#: I.@,)@([ = +/~@]))
21 twosum 0 2 11 19 90
1 3</lang>

Except that looks like a bit of a mess. A lot of the reason for this is that ascii is ugly to look at. (Another issue, though, is that a lot of people are not used to architecting control flow as expressions.)

So... let's do this over again, using a more traditional implementation where we name intermediate results. (We're going to stick with our architecture, though, because changing the architecture to the more traditional approach would change the space/time tradeoff to require more time.)

<lang J>two_sum=:dyad define
sums=. +/~ y
matches=. x = sums
sum_inds=. I. , matches
pair_inds=. ($matches) #: sum_inds
; {. a: ,~ <"1 pair_inds
)</lang>

And, testing:

<lang J> 21 two_sum 0 2 11 19 90
1 3</lang>

Or, we could go slightly more traditional and instead of doing that boxing at the end, use an if/else statement:

<lang J>two_sum=:dyad define
sums=. +/~ y
matches=. x = sums
sum_inds=. I. , matches
pair_inds=. ($matches) #: sum_inds
if. #pair_inds do.
{.pair_inds
else.
i.0
fi.
)</lang>

Then again, most people don't read J anyways, so maybe just stick with the earlier implementation:

<lang J>twosum=: ;@{.@(a:,~ ($ <@#: I.@,)@([ = +/~@]))</lang>


=={{header|Lua}}==
=={{header|Lua}}==