www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - appender!(dchar[]) put fail

reply "kerdemdemir" <kerdemdemir hotmail.com> writes:
I have two strings(stringB,stringC) which I need to repeat(bCount 
times, cCountTimes) and then chain.

auto charAppender = appender!(dchar[]);
auto totalStr = 
stringB.repeat(bCount).chain(stringC.repeat(cCount));

This compiles and works ok,
But when I try to append new string to charAppender :

charAppender.put(totalStr);	
Error: template std.array.join cannot deduce function from 
argument types

I tried:
charAppender.put(totalStr.array());
charAppender.data.chain(totalStr);
charAppender.data.chain(totalStr.array()); etc...

I always get compile errors.
Do you have any idea or fix about that?

Also what is the difference between algorithm.joiner without 
seperator and range.chain?

////////////////////////////////////////////////////////////////////////////
As requested before, this time I will copy full code,
////////////////////////////////////////////////////////////////////////////
int[dchar] mapA;
int includeCounter(T)(T tuple)
{
	int curMax = 100000;
	
	foreach ( elem ; tuple )	
	{
		int numberInA = 0;
		if (elem[0] in mapA)
			numberInA = mapA[elem[0]] ;
		else
		{
			curMax = 0;
			break;
		}
		
		if (  numberInA < elem[1] )
		{
			curMax = 0;
			break;
		}
		else
		{
			auto newCount = numberInA / elem[1];
			if ( newCount < curMax )
				curMax = newCount;
		}
	}
	if (curMax > 0)
	{
		foreach (  elem ; tuple )	
		{
			mapA[elem[0]] -= curMax;
		}
	}
	
	return curMax;	
}

void readInput()
{
	size_t lineSize;

	auto stringA = stdin.readln.chomp().map!( a => 
to!dchar(a)).array();
	auto stringB = stdin.readln.chomp().map!( a => 
to!dchar(a)).array();
	auto stringC = stdin.readln.chomp().map!( a => 
to!dchar(a)).array();
	
	foreach ( elem ; stringA)
		mapA[elem]++;
	
	auto tupleB = stringB.group();
	auto tupleC = stringC.group();

	auto bCount = includeCounter( tupleB );
	auto cCount = includeCounter( tupleC );

	auto charAppender = appender!(dchar[]);
	foreach ( elem ; mapA.keys)
	{
		int* count = &mapA[elem];
		if ( *count > 0)
		{
			while((*count)--)
				charAppender.put(elem) ;
		}
	}

	auto totalStr = 
stringB.repeat(bCount).chain(stringC.repeat(cCount));
	charAppender.put(totalStr);	
}

void main(  string[] args )
{
	readInput();
}
Jun 13 2015
next sibling parent reply "Quentin Ladeveze" <ladeveze.quentin openmailbox.org> writes:
On Saturday, 13 June 2015 at 10:45:58 UTC, kerdemdemir wrote:
 I have two strings(stringB,stringC) which I need to 
 repeat(bCount times, cCountTimes) and then chain.

 auto charAppender = appender!(dchar[]);
 auto totalStr = 
 stringB.repeat(bCount).chain(stringC.repeat(cCount));

 This compiles and works ok,
 But when I try to append new string to charAppender :

 charAppender.put(totalStr);	
 Error: template std.array.join cannot deduce function from 
 argument types

 I tried:
 charAppender.put(totalStr.array());
 charAppender.data.chain(totalStr);
 charAppender.data.chain(totalStr.array()); etc...

 I always get compile errors.
 Do you have any idea or fix about that?

 Also what is the difference between algorithm.joiner without 
 seperator and range.chain?

 ////////////////////////////////////////////////////////////////////////////
 As requested before, this time I will copy full code,
 ////////////////////////////////////////////////////////////////////////////
 int[dchar] mapA;
 int includeCounter(T)(T tuple)
 {
 	int curMax = 100000;
 	
 	foreach ( elem ; tuple )	
 	{
 		int numberInA = 0;
 		if (elem[0] in mapA)
 			numberInA = mapA[elem[0]] ;
 		else
 		{
 			curMax = 0;
 			break;
 		}
 		
 		if (  numberInA < elem[1] )
 		{
 			curMax = 0;
 			break;
 		}
 		else
 		{
 			auto newCount = numberInA / elem[1];
 			if ( newCount < curMax )
 				curMax = newCount;
 		}
 	}
 	if (curMax > 0)
 	{
 		foreach (  elem ; tuple )	
 		{
 			mapA[elem[0]] -= curMax;
 		}
 	}
 	
 	return curMax;	
 }

 void readInput()
 {
 	size_t lineSize;

 	auto stringA = stdin.readln.chomp().map!( a => 
 to!dchar(a)).array();
 	auto stringB = stdin.readln.chomp().map!( a => 
 to!dchar(a)).array();
 	auto stringC = stdin.readln.chomp().map!( a => 
 to!dchar(a)).array();
 	
 	foreach ( elem ; stringA)
 		mapA[elem]++;
 	
 	auto tupleB = stringB.group();
 	auto tupleC = stringC.group();

 	auto bCount = includeCounter( tupleB );
 	auto cCount = includeCounter( tupleC );

 	auto charAppender = appender!(dchar[]);
 	foreach ( elem ; mapA.keys)
 	{
 		int* count = &mapA[elem];
 		if ( *count > 0)
 		{
 			while((*count)--)
 				charAppender.put(elem) ;
 		}
 	}

 	auto totalStr = 
 stringB.repeat(bCount).chain(stringC.repeat(cCount));
 	charAppender.put(totalStr);	
 }

 void main(  string[] args )
 {
 	readInput();
 }
The problem is that your appender is a char appender, and you try to put a dstring into it. Replace : charAppender.put(totalStr); by : foreach(elem; totalStr){ charAppender.put(elem); } elem will be a dchar, so it will work.
Jun 13 2015
next sibling parent reply "kerdemdemir" <kerdemdemir hotmail.com> writes:
 The problem is that your appender is a char appender, and you 
 try to put a dstring into it. Replace :

 charAppender.put(totalStr);

 by :

 foreach(elem; totalStr){
    charAppender.put(elem);
 }

 elem will be a dchar, so it will work.
But I can see in the example of array.appander(http://dlang.org/phobos/std_array.html#appender) int[] a = [ 1, 2 ]; auto app2 = appender(a); app2.put(3); app2.put([ 4, 5, 6 ]); ---> appender accepts another array. Why this is not same with dchar ?
Jun 13 2015
parent reply "Quentin Ladeveze" <ladeveze.quentin openmailbox.org> writes:
On Saturday, 13 June 2015 at 12:02:10 UTC, kerdemdemir wrote:
 The problem is that your appender is a char appender, and you 
 try to put a dstring into it. Replace :

 charAppender.put(totalStr);

 by :

 foreach(elem; totalStr){
   charAppender.put(elem);
 }

 elem will be a dchar, so it will work.
But I can see in the example of array.appander(http://dlang.org/phobos/std_array.html#appender) int[] a = [ 1, 2 ]; auto app2 = appender(a); app2.put(3); app2.put([ 4, 5, 6 ]); ---> appender accepts another array. Why this is not same with dchar ?
It is the same, but totalStr is not a dchar[]. It's a Result (a type internal to the chain function ) which is a range. The foreach loop iterates over Result, which returns dchar[]. So if you try to do something like that : charAppender.put(totalStr.array), it won't work because totalStr.array is a dchar[][].
Jun 13 2015
parent reply "kerdemdemir" <kerdemdemir hotmail.com> writes:
 It is the same, but totalStr is not a dchar[]. It's a Result (a 
 type internal to the chain function ) which is a range. The 
 foreach loop iterates over Result, which returns dchar[].

 So if you try to do something like that :

 charAppender.put(totalStr.array), it won't work because 
 totalStr.array is a dchar[][].
Sorry to making the discussion longer and wasting your times. But I am looking for a way without for loops. Also looping every element one by one does not seems very efficient to me. Any advices for that?
Jun 13 2015
parent reply "Dennis Ritchie" <dennis.ritchie mail.ru> writes:
On Saturday, 13 June 2015 at 13:01:29 UTC, kerdemdemir wrote:
 Sorry to making the discussion longer and wasting your times.

 But I am looking for a way without for loops. Also looping 
 every element one by one does not seems very efficient to me. 
 Any advices for that?
Maybe it fit? auto stringB = readln.chomp.map!(to!dchar).array; auto stringC = readln.chomp.map!(to!dchar).array; auto charAppender = appender!(dchar[][]); auto totalStr = stringB.repeat(3).chain(stringC.repeat(5)); charAppender.put(totalStr); writeln(charAppender); charAppender.put("c"d.dup); charAppender.put("test"d.dup); writeln(charAppender);
Jun 13 2015
parent reply "kerdemdemir" <kerdemdemir hotmail.com> writes:
On Saturday, 13 June 2015 at 13:09:20 UTC, Dennis Ritchie wrote:

 auto stringB = readln.chomp.map!(to!dchar).array;
 auto stringC = readln.chomp.map!(to!dchar).array;

 auto charAppender = appender!(dchar[][]);

 auto totalStr = stringB.repeat(3).chain(stringC.repeat(5));

 charAppender.put(totalStr);

 writeln(charAppender);

 charAppender.put("c"d.dup);
 charAppender.put("test"d.dup);

 writeln(charAppender);
Thanks lot that is really good. One more question I am asking those kind of questions to understand and not ask same stuff over and over, : auto totalStr = chain(stringB.replicate(bCount), stringC.replicate(cCount)); writeln(typeof(totalStr.array()).stringof); ---->dchar[] But auto totalStr = chain(stringB.repeat(bCount), stringC.repeat(cCount)); writeln(typeof(totalStr.array()).stringof); ---->dchar[][] It seems to me a little inconsistent. range.repeat and array.replicate gives result in difference dimension. Is there any explanation or logic that I am missing which results this behaviour?
Jun 13 2015
next sibling parent "Quentin Ladeveze" <ladeveze.quentin openmailbox.org> writes:
On Saturday, 13 June 2015 at 13:32:19 UTC, kerdemdemir wrote:
 Thanks lot that is really good.

 One more question I am asking those kind of questions to 
 understand and not ask same stuff over and over, :
Don't worry, there is "learn" in "D.learn"
 auto totalStr = chain(stringB.replicate(bCount), 
 stringC.replicate(cCount));
 writeln(typeof(totalStr.array()).stringof);
 ---->dchar[]

 But
 auto totalStr = chain(stringB.repeat(bCount), 
 stringC.repeat(cCount));
 writeln(typeof(totalStr.array()).stringof);
 ---->dchar[][]

 It seems to me a little inconsistent. range.repeat and 
 array.replicate gives result in difference dimension.

 Is there any explanation or logic that I am missing which 
 results this behaviour?
Two functions doing the same thing would be the illogical thing, no ?
Jun 13 2015
prev sibling parent "Dennis Ritchie" <dennis.ritchie mail.ru> writes:
On Saturday, 13 June 2015 at 13:32:19 UTC, kerdemdemir wrote:
 One more question I am asking those kind of questions to 
 understand and not ask same stuff over and over, :

 auto totalStr = chain(stringB.replicate(bCount), 
 stringC.replicate(cCount));
 writeln(typeof(totalStr.array()).stringof);
 ---->dchar[]

 But
 auto totalStr = chain(stringB.repeat(bCount), 
 stringC.repeat(cCount));
 writeln(typeof(totalStr.array()).stringof);
 ---->dchar[][]

 It seems to me a little inconsistent. range.repeat and 
 array.replicate gives result in difference dimension.

 Is there any explanation or logic that I am missing which 
 results this behaviour?
std.range.repeat is a lazy version unlike std.array.replicate: 5.repeat(3).writeln; // a lazy version // [5, 5, 5] [5].replicate(3).writeln; // [5, 5, 5] // but [5].repeat(3).writeln; // a lazy version // [[5], [5], [5]]
Jun 13 2015
prev sibling parent =?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> writes:
On 06/13/2015 04:23 AM, Quentin Ladeveze wrote:

 The problem is that your appender is a char appender, and you try to put
 a dstring into it. Replace :

 charAppender.put(totalStr);

 by :

 foreach(elem; totalStr){
     charAppender.put(elem);
 }

 elem will be a dchar, so it will work.
To answer Erdem's later question, loops with side effects can be replaced with std.algorithm.each: totalStr.each!(elem => charAppender.put(elem)); One issue with that method that I am frequently reminded of is that although the lambda's => syntax is by definition a return statement, 'each' does not do anything with the returned value. (Regardless of whether the lambda returns anything or not.) Ali
Jun 13 2015
prev sibling parent Steven Schveighoffer <schveiguy yahoo.com> writes:
On 6/13/15 6:45 AM, kerdemdemir wrote:
 I have two strings(stringB,stringC) which I need to repeat(bCount times,
 cCountTimes) and then chain.

 auto charAppender = appender!(dchar[]);
 auto totalStr = stringB.repeat(bCount).chain(stringC.repeat(cCount));

 This compiles and works ok,
 But when I try to append new string to charAppender :

 charAppender.put(totalStr);
 Error: template std.array.join cannot deduce function from argument types

 I tried:
 charAppender.put(totalStr.array());
 charAppender.data.chain(totalStr);
 charAppender.data.chain(totalStr.array()); etc...

 I always get compile errors.
 Do you have any idea or fix about that?
Have you tried: put(charAppender, totalStr); It is not recommended to use charAppender.put directly, unless you know it will work. This is a frequent cause of problems (using .put on an output range directly). -Steve
Jun 13 2015