Jump to page: 1 2
Thread overview
appender!(dchar[]) put fail
Jun 13, 2015
kerdemdemir
Jun 13, 2015
Quentin Ladeveze
Jun 13, 2015
kerdemdemir
Jun 13, 2015
Quentin Ladeveze
Jun 13, 2015
kerdemdemir
Jun 13, 2015
Dennis Ritchie
Jun 13, 2015
kerdemdemir
Jun 13, 2015
Quentin Ladeveze
Jun 13, 2015
Dennis Ritchie
Jun 13, 2015
Ali Çehreli
June 13, 2015
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();
}
June 13, 2015
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.
June 13, 2015
> 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 ?
June 13, 2015
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[][].
June 13, 2015
> 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?
June 13, 2015
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);
June 13, 2015
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?
June 13, 2015
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 ?
June 13, 2015
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]]
June 13, 2015
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

« First   ‹ Prev
1 2