Why does reduce operator does not work the way I expect it to? - fold

I am trying to solve Euler 18 in Dyalog APL, and I am not able to understand why my solution does not work.
The problem is as follow:
By starting at the top of the triangle below and moving to adjacent
numbers on the row below, the maximum total from top to bottom is 23.
3
7 4
2 4 6
8 5 9 3
That is, 3 + 7 + 4 + 9 = 23.
Taking the example that I represent this way:
d ← (3 0 0 0) (7 4 0 0) (2 4 6 0) (8 5 9 3)
I am trying to solve it this way:
{⍵+((2⌈/⍺)),0}/⌽d
Which gives me this array: 22 19 15 0, where the bigger number is 22, which is not the right answer for the problem, which would be 23.
I am getting this behavior (left to right for ease of reading):
(2⌈/(8 5 9 3),0)+(2⌈/(2 4 6 0),0)+(2⌈/(7 4 0 0),0)+(2⌈/(3 0 0 0),0)
Which gives me the same result as the function.
What I would expect is this behavior (where each statement is substituted directly in the next line):
(2⌈/(8 5 9 3)),0
(2 4 6 0)+8 9 9 0
(2⌈/(10 13 15 0)),0
(7 4 0 0)+13 15 15 0
(2⌈/(20 19 15 0)),0
(3 0 0 0) + 20 19 15 0
23 19 15 0
Am I wondering where I am misunderstanding something in the APL process that leads to a different result than the one I am expecting.
Thank you!

/ works in the reverse way to what you expected - it evaluates through the array right-to-left.
F/a b c d is ⊂a F b F c F d, or, with parentheses, ⊂(a F (b F (c F d))).
After removing the ⌽ and swapping ⍺ and ⍵, you get {⍺+(2⌈/⍵),0}/d, which gives the result you want.

Related

What will be the output of the following pseudo code for input 7?

Please help me to understand the following code and what will be the possiable output.
What will be the output of the following pseudo code for input 7?
1.Input n
2.Set m = 1, T = 0
3.if (m > n)
Go to step 9
5.else
T = T + m
m = m + 1
8.Go to step 3
9.Print T
0
n is less than n so go to step 9 which is print T which is equal to 0 as set in step 2.
T should be 28. It will loop till m>7 (since n=7) and in each iteration T adds m to itself, since T is 0 initially it is only summing up m after incrementing it by 1 in each iteration.So if you add 1+2+3.....+7 you get 28 and that is when the loop breaks since m is now equal to 8.
for m = 1 2 3 4 5 6 7 and for 8 m>n will be true and it will go to step 9
T=(T+M)= 1 3 6 10 15 21 28 basically T is a series where next is added as 2,3,4,5,6,7 to prev number 2 3 4 5 6 7 if one look from other angle

Reversed iterator from top to bottom, right to left, instead of completely reversed

I have a std::vector that goes in the following order:
0 3 6
1 4 7
2 5 8
using a reverse iterator I get the following output:
8 5 2
7 4 1
6 3 0
The output I need is:
6 3 0
7 4 1
8 5 2
how would i go about getting that required ordering, at first it seems like i would be able to get a reverse iterator position - vertical size but that gets tricky when my vector is something like this:
0 6 12
1 7 13
2 8 14
3 9 15
4 10 16
5 11 17...

_mm_cmpistri in reverse

Let's say I have these strings:
char ref[30] = "1234567891234567891";
char oth[30] = "1234567891234567891";
I want to use the SSE 4.2 _mm_cmpistri function in C++; Normally the string is parsed from left to right. Is there a way to tell the function to search in reverse (compare from right to left instead of left to right?
Instead of searching
--------------->
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1
to search this way <-----------------
Later edit:
Here's what i want to do:
I have two strings and I need a function with this header:
int sse_cmp(const char *a, int posA, const char *b, int posB);
This function must compare the strings "backwords":
from posA to 0 or until posB == 0.
The function must return the number of of common chars from back.
Ex:
<--------- posA
a : 1 2 3 4 5 6 7 8 9
b : a b c d 7 8 9
<---- posB
will return 3 ( 987 )
What's the most efficient way to do it? ( with SSE )
You can use _SIDD_MOST_SIGNIFICANT as part of the mode parameter to _mm_cmpistri.
See Intel SSE4 programming reference

Can I use regular expressions to search for multiples of a number?

I'm trying to search a big project for all examples of where I've declared an array with [48] as the size or any multiples of 48.
Can I use a regular expression function to find matches of 48 * n?
Thanks.
Here you go (In PHP's PCRE syntax):
^(0*|(1(01*?0)*?1|0)+?0{4})$
Usage:
preg_match('/^(0*|(1(01*?0)*?1|0)+?0{4})$/', decbin($number));
Now, why it works:
Well we know that 48 is really just 3 * 16. And 16 is just 2*2*2*2. So, any number divisible by 2^4 will have the 4 most bits in its binary representation 0. So by ending the regexp with 0{4}$ is equivalent to saying that the number is divisible by 2^4 (or 16). So then, the bits to the left need to be divisible by 3. So using the regexp from this answer, we can tell if they are divisible by 3. So if the whole regexp matches, the number is divisible by both 3 and 16, and hence 48...
QED...
(Note, the leading 0| case handles the failed match when $number is 0). I've tested this on all numbers from 0 to 48^5, and it correctly matches each time...
A generalization of your question is asking whether x is a string representing a multiple of n in base b. This is the same thing as asking whether the remainder of x divided by n is 0. You can easily create a DFA to compute this.
Create a DFA with n states, numbered from 0 to n - 1. State 0 is both the initial state and the sole accepting state. Each state will have b outgoing transitions, one for each symbol in the alphabet (since base-b gives you b digits to work with).
Each state represents the remainder of the portion of x we've seen so far, divided by n. This is why we have n of them (dividing a number by n yields a remainder in the range 0 to n - 1), and also why state 0 is the accepting state.
Since the digits of x are processed from left to right, if we have a number y from the first few digits of x and read the digit d, we get the new value of y from yb + d. But more importantly, the remainder r changes to (rb + d) mod n. So we now know how to connect the transition arcs and complete the DFA.
You can do this for any n and b. Here, for example, is one that accepts multiples of 18 in base-10 (states on the rows, inputs on the columns):
| 0 1 2 3 4 5 6 7 8 9
---+-------------------------------
→0 | 0 1 2 3 4 5 6 7 8 9 ←accept
1 | 10 11 12 13 14 15 16 17 0 1
2 | 2 3 4 5 6 7 8 9 10 11
3 | 12 13 14 15 16 17 0 1 2 3
4 | 4 5 6 7 8 9 10 11 12 13
5 | 14 15 16 17 0 1 2 3 4 5
6 | 6 7 8 9 10 11 12 13 14 15
7 | 16 17 0 1 2 3 4 5 6 7
8 | 8 9 10 11 12 13 14 15 16 17
9 | 0 1 2 3 4 5 6 7 8 9
10 | 10 11 12 13 14 15 16 17 0 1
11 | 2 3 4 5 6 7 8 9 10 11
12 | 12 13 14 15 16 17 0 1 2 3
13 | 4 5 6 7 8 9 10 11 12 13
14 | 14 15 16 17 0 1 2 3 4 5
15 | 6 7 8 9 10 11 12 13 14 15
16 | 16 17 0 1 2 3 4 5 6 7
17 | 8 9 10 11 12 13 14 15 16 17
These get really tedious as n and b get larger, but you can obviously write a program to generate them for you no problem.
1|48|2304|110592|5308416
You are unlikely to have declared an array of size 48^5 or larger.
No, regular expressions can't calculate multiples (except in the unary number system: decimal 4 = unary 1111; decimal 8 = unary 11111111, so the regex ^(1111)+$ matches multiples of 4).
import re
# For real example,
# construction of a chain with integers multiples of 48
# and integers not multiple of 48.
from random import *
w = [ 48*randint( 1,10) for j in xrange(10) ]
w.extend( 48*randint(11,20) for j in xrange(10) )
w.extend( 48*randint(21,70) for j in xrange(10) )
a = [ el if el%48!=0 else el+1 for el in sample(xrange(1000),40) ]
w.extend(a)
shuffle(w)
texte = [ ''.join(sample(' abcdefghijklmonopqrstuvwxyz',randint(1,7))) for i in xrange(40) ]
X = ''.join(texte[i]+str(w[i]) for i in xrange(40))
# Searching the multiples of 48 in the chain X
def mult48(match):
g1 = match.group()
if int(g1)%48==0:
return ( g1, X[0:match.end()] )
else:
return ( g1, 'not multiple')
for match in re.finditer('\d+',X):
print '%s %s\n' % mult48(match)
Any multiple is difficult, but here's a (python-style) regexp that matches the first 200 multiples of 48.
0$|1(?:0(?:08$|56$)|1(?:04$|52$)|2(?:00$|48$|96$)|3(?:44$|92$)|4(?:4(?:$|0$)|88$\
)|5(?:36$|84$)|6(?:32$|80$)|7(?:28$|76$)|8(?:24$|72$)|9(?:2(?:$|0$)|68$))|2(?:0(\
?:16$|64$)|1(?:12$|60$)|2(?:08$|56$)|3(?:04$|52$)|4(?:0(?:$|0$)|48$|96$)|5(?:44$\
|92$)|6(?:40$|88$)|7(?:36$|84$)|8(?:32$|8(?:$|0$))|9(?:28$|76$))|3(?:0(?:24$|72$\
)|1(?:20$|68$)|2(?:16$|64$)|3(?:12$|6(?:$|0$))|4(?:08$|56$)|5(?:04$|52$)|6(?:00$\
|48$|96$)|7(?:44$|92$)|8(?:4(?:$|0$)|88$)|9(?:36$|84$))|4(?:0(?:32$|80$)|1(?:28$\
|76$)|2(?:24$|72$)|3(?:2(?:$|0$)|68$)|4(?:16$|64$)|5(?:12$|60$)|6(?:08$|56$)|7(?\
:04$|52$)|8(?:$|0(?:$|0$)|48$|96$)|9(?:44$|92$))|5(?:0(?:40$|88$)|1(?:36$|84$)|2\
(?:32$|8(?:$|0$))|3(?:28$|76$)|4(?:24$|72$)|5(?:20$|68$)|6(?:16$|64$)|7(?:12$|6(\
?:$|0$))|8(?:08$|56$)|9(?:04$|52$))|6(?:0(?:00$|48$|96$)|1(?:44$|92$)|2(?:4(?:$|\
0$)|88$)|3(?:36$|84$)|4(?:32$|80$)|5(?:28$|76$)|6(?:24$|72$)|7(?:2(?:$|0$)|68$)|\
8(?:16$|64$)|9(?:12$|60$))|7(?:0(?:08$|56$)|1(?:04$|52$)|2(?:0(?:$|0$)|48$|96$)|\
3(?:44$|92$)|4(?:40$|88$)|5(?:36$|84$)|6(?:32$|8(?:$|0$))|7(?:28$|76$)|8(?:24$|7\
2$)|9(?:20$|68$))|8(?:0(?:16$|64$)|1(?:12$|6(?:$|0$))|2(?:08$|56$)|3(?:04$|52$)|\
4(?:00$|48$|96$)|5(?:44$|92$)|6(?:4(?:$|0$)|88$)|7(?:36$|84$)|8(?:32$|80$)|9(?:2\
8$|76$))|9(?:0(?:24$|72$)|1(?:2(?:$|0$)|68$)|2(?:16$|64$)|3(?:12$|60$)|4(?:08$|5\
6$)|5(?:04$|52$)|6(?:$|0$))

ROUNDUP? what does it do? in C++

Can someone explain to me what this does?
#define ROUNDUP(n,width) (((n) + (width) - 1) & ~unsigned((width) - 1))
Providing width is an even power of 2 (so 2,4,8,16,32 etc), it will return a number equal to or greater than n, which is a multiple of width, and which is the smallest value meeting that criteria.
So width = 16; 5->16, 7->16, 15->16, 16->16, 17->32, 18->32 etc.
EDIT I started out on providing an explanation of why this works as it does, as I sense that's really what the OP wants, but it turned into a rather convoluted story. If the OP is still confused, I'd suggest working through a few simple examples, say width = 16, n=15,16,17. Remember that & = bitwise AND, ~ = bitwise complement, and to use binary representation exclusively as you work through the examples.
It rounds n up to the next 'width' - but I think width needs to be a power of 2.
For example width == 8, n = 5:
(5 + 8 - 1) & ~(7)
= 12 & ~7
= 8
So 5 rounds to 8. Anything 1 - 8 rounds to 8. 9 to 16 rounds to 16. Etc. (0 rounds to 0)
It defines a macro called ROUNDUP which takes two parameters, n and width, and returns the value (n + width - 1) & ~unsigned(width - 1).
:)
Try this if you think you know what it does:
std::string s("WTF");
std::complex<double> c(-11,5);
ROUNDUP(s, c);
It won't work in C because of the unsigned. Here is what is does, as long as width is confined to powers of 2:
n width ROUNDUP(n,width)
----------------
0 4 0
1 4 4
2 4 4
3 4 4
4 4 4
5 4 8
6 4 8
7 4 8
8 4 8
9 4 12
10 4 12
11 4 12
12 4 12
13 4 16
14 4 16
15 4 16
16 4 16
17 4 20
18 4 20
19 4 20