DRAT!�� What (genius negated) designed gmail's interface?
If I am wrong that the canHandleInput: class method ofIllegalMoveSanta should return false, not true (becausethe order of the elements of #subclasses is not defined,so that IllegalMoveSanta might *always* be selected),then that is further evidence that avoiding "if" madethe code LESS readable.
You are a beginner at this, doing all the right thingsfor a beginner to do.�� One of the things you have to dois to develop a sense of "smell" for code.�� Each classought to "pull its weight".�� Four classes -- which itreally does not make sense to instantiate, just put theinstance methods on the class side and drop the #new --just to avoid a couple of very clear "ifs"?�� I don'tthink so.�� IF THESE CLASSES NEEDED TO EXIST FOR SOMEOTHER REASON, if they had real work to do, sure.�� Butthey don't.�� They only bloat and obscure the code.
On Wed, 28 Nov 2018 at 20:54, Richard O'Keefe <raoknz@gmail.com> wrote:
In Advent-of-Code 2015, the first problem isreally quite simple.�� There are at least twoways to think about it."CS101":�� ��set a counter to 0�� ��for each character of the string�� �� ��if it is '(' increment the counter�� �� ��if it is ')' decrement the counter�� ��report the counter
"Higher level":�� ��report the difference between�� �� ��(the number of '(' characters in the string) and�� �� ��(the number of ')' characters in the string).
Expressed in Smalltalk this looks something like�� Transcript print:�� �� (s occurrencesOf: $() - (s occurrencesOf: $)); cr.
Make no mistake: you *cannot* tell the differencebetween $( and $) using class-based dispatch becausethey belong to the same class.�� There has to be an"if" somewhere, the question is not whether but where.In this case, counting the number of occurrences of anobject in a collection is has been a standard Collectionmethod for nearly 40 years; it's one of the basicoperations you need to learn.
The "higher level" approach can be less efficient thatthe "CS101" approach, but in a case like this we reallydo not care.�� We want the code to be *clear*.
What about the second part of the problem?Not having submitted any answers, I can't actuallysee the second part on the AOC site, but luckily youhave included it in your program.
We want to�� ��[find the first place] where�� �� �� [the cumulative sum] of (c=$()�� �� �� [minus]�� �� �� [the cumulative sum] of (c=$))�� �� �� equals -1.
The "CS101" approach is�� ��n := i := 0.�� ��while n >= 0 and i < size(s) do�� �� �� i��+:= 1�� �� �� if s[i] = $( then n := n��+ 1�� �� �� if s[i] = $) then n := n - 1�� ��report n
The "higher level" approach looks something like�� n := (s cumCount: [:each | each = $(]) -�� �� �� ��(s cumCount: [:each | each = $)])�� �� �� ��indexOf: -1.-- although it gives 0 instead of s size��+ 1 when-1 is never reached.
Here #indexOf: is standard, #- is defined on sequencesin Squeak and Pharo, but #cumCount: does notexist.�� So we need something like
�� �� cumCount: aBlock�� �� �� ���� �� �� |c a|�� �� �� ���� �� �� a := Array new: self size.�� �� �� c := 0.�� �� �� self withIndexDo: [:each :i |�� �� �� �� (aBlock value: each) ifTrue: [c := c + 1].�� �� �� �� a at: i put: c].�� �� �� ^aThis is *not* coupled to the particular use we havein mind for it; it is in no way tied to charactersor strings.�� It's quite general.
Note: we do not need any new classes, except maybea place to put one problem-specific method.
While this answer, with no loop and no if in theproblem-specific code, is quite pretty, it has aproblem.�� Suppose the string to have M charactersand the desired step to be number K.�� The CS101approach takes O(K) time and no allocations, butthe higher level approach takes O(M) time andallocates three M-element Arrays.�� (In a non-strictfunctional language like Haskell, the higher levelversion *also* takes O(K) time, and with a goodenough "deforesting" compiler should allocate nodata structures.)
For a problem like this, I really don't care aboutthe efficiency aspect.�� If I *do* care about that,then starting from a higher level version gives mesomething to test a lower level version against.
To get an efficient answer to the second part,we still don't need a new semantic class, justsome place to put the code.
Day1�� class methods:�� �� indexOfFirstBasementTime: steps�� �� �� |floor|�� �� �� floor := 0.�� �� �� steps keysAndValuesDo: [:i :each |�� �� �� �� each = $( ifTrue: [floor := floor��+ 1].�� �� �� �� each = $) ifTrue: [floor := floor - 1].�� �� �� �� floor = -1 ifTrue: [^i]].�� �� �� ^0 "same convention as #indexOf:"
Does this contain "if"?�� Why yes, it does.Is there any problem with that?�� Why no, there isn't.You need to treat members of the same class (leftparenthesis, right parenthesis, others) differently.You need to treat members of the same class (minusone, all other integers) differently.Would there be any gain in clarity or maintainabilityif these ifs were somehow eliminated?�� Certainly NOT.
Quite the reverse, in fact.input2 withIndexDo: [ :element :index | |action|��action:= SantaAction getActionFor: element. floor := action�� doMovementFor: floor .self hasReachedBasement��ifTrue: [^ index]].�� �� ^ '-2'.
There is only one word for this: obfuscated.I was initially puzzled by your returning -2instead of the conventional 0 if the basementis not reached, and then *deeply confused* bythe fact that you are returning a *string* inthis case.
Looking at your code, I was further confusedby variables called 'aSymbol' whose value isalways and only a Character, never a Symbol.And if I am wrong that
IllegalMoveSanta class>> canHandleInput: in Smalltalk is to return 0 when something is�� �� ����approach
We want to find the first place where somethingbecomes true.�� There are again at least to approaches.��
On Wed, 28 Nov 2018 at 05:41, Roelof Wobben <r.wobben@home.nl> wrote:
Hello,
Yesterday I had a talk with luc frabresse about using if then.
He said if I understand it right, Its the best to not using a if then or
a ifTrue/ifFalse.
Can anyone help me figure out how to rewrite this project so I will not
use the ifTrue in the basement function.
my code so far can be found here : https://github.com/RoelofWobben/AOC2015
Roelof