digitalmars.D.learn - Compute in one pass 3 tokens position

• bioinfornatics (12/12) Apr 30 2012 Hi,
• bioinfornatics (28/43) Apr 30 2012 Anyone know how to know the position of 3 token in one sequence in one
• Era Scarecrow (22/35) Apr 30 2012 I would say you are trying to way overcomplicated the solution.
• bioinfornatics (53/68) May 03 2012 ----------------- CODE -----------------------
• bioinfornatics (60/75) May 03 2012 update code for add attribute poure notrhow nd safe :)
• Jesse Phillips (6/20) May 04 2012 It doesn't give your answer directly, but I requested that
```Hi,
I would like to know how compute in on pass 3 tokens position in a
sequence.
curently i do:
File f =3D File( "reader.d", "r" );
scope(exit) f.close();
char buffer;
char[sizediff_t] token =3D ['(', '{', ';'];
auto position =3D map!( a =3D> content.countUntil( a ) )( [ ['('], ['{'],
[';'] ] );

if i use reduce instead map the build fail
```
Apr 30 2012
```Le lundi 30 avril 2012 =C3=A0 14:52 +0200, bioinfornatics a =C3=A9crit :
Hi,
I would like to know how compute in on pass 3 tokens position in a
sequence.
curently i do:
File f =3D File( "reader.d", "r" );
scope(exit) f.close();
char buffer;
char[sizediff_t] token =3D ['(', '{', ';'];
auto position =3D map!( a =3D> content.countUntil( a ) )( [ ['('], ['{'],
[';'] ] );
=20
=20
if i use reduce instead map the build fail
=20

Anyone know how to know the position of 3 token in one sequence in one
pass?

tok1 =3D a
tok2 =3D b
tok3 =3D c
seq =3D  blah count me
b=3D> 0 a=3D>2 c=3D>5
iterate over sequence if token not yet seen count the number of
iteration for know in which column it is located. Example own written on
the fly)

sizediiff_t[] countUntil( in char[] seq; char[] tokens ){
bool isSearching =3D true;
size_t index =3D 0;
sizediiff_t[] position =3D new sizediiff_t[](tokens.length);
while (isSearching){
if (index >=E2=81=BC seq.length)
isSearching =3D false;
else if (! find( position, -1) // al token found we can stop;
isSearching =3D false;
else{
sizediiff_t tmp =3D countUntil( tokens, [seq[index]]);
if (countUntil( tmp !=3D -1 && position[tmp] !=3D -1)
position[tmp] =3D index;
index++;
}
}
}
```
Apr 30 2012
```On Tuesday, 1 May 2012 at 02:49:19 UTC, bioinfornatics wrote:
Le lundi 30 avril 2012 à 14:52 +0200, bioinfornatics a écrit :
Anyone know how to know the position of 3 token in one sequence
in one
pass?

tok1 = a
tok2 = b
tok3 = c
seq =  blah count me
b=> 0 a=>2 c=>5
iterate over sequence if token not yet seen count the number of
iteration for know in which column it is located. Example own
written on
the fly)

I would say you are trying to way overcomplicated the solution.
For simplicity I would use an AA, then a foreach and it will do
it in 1 pass (2 if you count the inner ones). I'm not sure if
there's a better solution already in phobos, so I can't refer to
that :( This could be modified to be more generic so..

//returns AA of tokens that were found and the offset of their
first occurrence.
int[char] findTokens(const char[] input, char[] tok ...) {
int[char] offs;
foreach(i, ch; input) {
foreach(t; tok) {
if (ch == t && t !in offs)
offs[t] = i;
}
}
return offs;
}
unittest {
assert(findTokens("blah count me", 'a', 'b', 'c')  == ['a':2,
'b' : 0, 'c':5]);
}
```
Apr 30 2012
```Le lundi 30 avril 2012 =C3=A0 14:52 +0200, bioinfornatics a =C3=A9crit :
Hi,
I would like to know how compute in on pass 3 tokens position in a
sequence.
curently i do:
File f =3D File( "reader.d", "r" );
scope(exit) f.close();
char buffer;
char[sizediff_t] token =3D ['(', '{', ';'];
auto position =3D map!( a =3D> content.countUntil( a ) )( [ ['('], ['{'],
[';'] ] );
=20
=20
if i use reduce instead map the build fail
=20

----------------- CODE -----------------------
import std.stdio;
import std.conv;
import std.c.process;

sizediff_t[string] counter( in char[] sequence, string[] token...)
in{
assert(sequence !is null, "Error given sequence is null");
}
body{
bool   isComputing =3D true;
size_t index       =3D 0;
size_t flag        =3D 0;
sizediff_t[string] result;

foreach( tok; token)
result[tok] =3D -1;

while(isComputing){
if( index >=3D sequence.length )
isComputing =3D false;
else if( flag =3D=3D token.length )
isComputing =3D false;
else{
foreach( tok; token){
if( sequence.length - index >=3D tok.length ){
string currentToken =3D to!string(sequence[index .. index +
tok.length]);
if( currentToken in result && result[currentToken] =3D=3D -1 ){
result[currentToken] =3D index;
flag++;
}
}
}
index++;
}
}
return result;
}

void main( string[] args ){
if( args.length =3D=3D 1 ){
writefln( "Usage %s <token1> <token2> <token3> <token4>...", args
);
exit(0);
}
writeln( counter( "This a cool statement such as D is fun. Use it and
ot the D power. Oh yeah! Are you ready? Try it!! Have fun.", args[1..\$])
);

}
---------------------------------- END CODE -----------------------

\$ ./test This D !
["D":30, "!":74, "This":0] import std.string;

if all token is found befoore reach end sequence it stop and save us
from some loop
it works too if token do not has same length as shown in example
```
May 03 2012
```Le lundi 30 avril 2012 =C3=A0 14:52 +0200, bioinfornatics a =C3=A9crit :
Hi,
I would like to know how compute in on pass 3 tokens position in a
sequence.
curently i do:
File f =3D File( "reader.d", "r" );
scope(exit) f.close();
char buffer;
char[sizediff_t] token =3D ['(', '{', ';'];
auto position =3D map!( a =3D> content.countUntil( a ) )( [ ['('], ['{'],
[';'] ] );
=20
=20
if i use reduce instead map the build fail
=20

update code for add attribute poure notrhow nd safe :)

------------------
import std.string;
import std.stdio;
import std.conv;
import std.c.process;
/**
* searchIndex
* search at wich index is located each token in given sequence.
* It compute it in one pass.
* Returns:
* An ssociative array:
*  key =3D token and value first index where is found
*/
safe nothrow pure
sizediff_t[char[]] searchIndex( in char[] sequence, in char[][]
token...)
in{
assert(sequence !is null, "Error given sequence is null");
}
body{
bool   isComputing =3D true;
size_t index       =3D 0;
size_t flag        =3D 0;
sizediff_t[char[]] result;

foreach( tok; token)
result[tok] =3D -1;

while(isComputing){
if( index >=3D sequence.length )
isComputing =3D false;
else if( flag =3D=3D token.length )
isComputing =3D false;
else{
foreach( tok; token){
if( sequence.length - index >=3D tok.length ){
const(char)[] currentToken =3D (tok.length > 1) ?
sequence[index .. index + tok.length] : [sequence[index]];
if( currentToken in result && result[currentToken] =3D=3D -1 ){
result[currentToken] =3D index;
flag++;
}
}
}
index++;
}
}
return result;
}

void main( string[] args ){
if( args.length =3D=3D 1 ){
writefln( "Usage %s <token1> <token2> <token3> <token4>...", args
);
exit(0);
}
writeln( searchIndex( "This a cool statement such as D is fun. Use it
and got the D power. Oh yeah! Are you ready? Try it!! Have fun.",
args[1..\$]) );

}
```
May 03 2012    "Jesse Phillips" <Jessekphillips+D gmail.com> writes:
```On Monday, 30 April 2012 at 12:53:16 UTC, bioinfornatics wrote:
Hi,
I would like to know how compute in on pass 3 tokens position
in a
sequence.
curently i do:
File f = File( "reader.d", "r" );
scope(exit) f.close();
char buffer;
char[sizediff_t] token = ['(', '{', ';'];
auto position = map!( a => content.countUntil( a ) )( [ ['('],
['{'],
[';'] ] );

if i use reduce instead map the build fail