Thread overview | |||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
June 13, 2015 appender!(dchar[]) put fail | ||||
---|---|---|---|---|
| ||||
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 Re: appender!(dchar[]) put fail | ||||
---|---|---|---|---|
| ||||
Posted in reply to kerdemdemir | 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 Re: appender!(dchar[]) put fail | ||||
---|---|---|---|---|
| ||||
Posted in reply to Quentin Ladeveze | > 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 Re: appender!(dchar[]) put fail | ||||
---|---|---|---|---|
| ||||
Posted in reply to kerdemdemir | 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 Re: appender!(dchar[]) put fail | ||||
---|---|---|---|---|
| ||||
Posted in reply to Quentin Ladeveze | > 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 Re: appender!(dchar[]) put fail | ||||
---|---|---|---|---|
| ||||
Posted in reply to kerdemdemir | 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 Re: appender!(dchar[]) put fail | ||||
---|---|---|---|---|
| ||||
Posted in reply to Dennis Ritchie | 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 Re: appender!(dchar[]) put fail | ||||
---|---|---|---|---|
| ||||
Posted in reply to kerdemdemir | 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 Re: appender!(dchar[]) put fail | ||||
---|---|---|---|---|
| ||||
Posted in reply to kerdemdemir | 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 Re: appender!(dchar[]) put fail | ||||
---|---|---|---|---|
| ||||
Posted in reply to Quentin Ladeveze | 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 |
Copyright © 1999-2021 by the D Language Foundation