indexOf: -1.
-1 is
never reached.
Here
#indexOf: is standard, #- is defined on
sequences
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].
^a
This
is *not* coupled to the particular use we
have
in
mind for it; it is in no way tied to
characters
or
strings. It's quite general.
Note:
we do not need any new classes, except maybe
a
place to put one problem-specific method.
While
this answer, with no loop and no if in the
problem-specific
code, is quite pretty, it has a
problem.
Suppose the string to have M characters
and
the desired step to be number K. The CS101
approach
takes O(K) time and no allocations, but
the
higher level approach takes O(M) time and
allocates
three M-element Arrays. (In a non-strict
functional
language like Haskell, the higher level
version
*also* takes O(K) time, and with a good
enough
"deforesting" compiler should allocate no
data
structures.)
For
a problem like this, I really don't care
about
the
efficiency aspect. If I *do* care about
that,
then
starting from a higher level version gives
me
something
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, just
some
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
(left
parenthesis,
right parenthesis, others) differently.
You
need to treat members of the same class
(minus
one,
all other integers) differently.
Would
there be any gain in clarity or
maintainability
if
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 -2
instead of the
conventional 0 if the basement
is not reached,
and then *deeply confused* by
the fact that you
are returning a *string* in
this case.
Looking at your
code, I was further confused
by variables
called 'aSymbol' whose value is
always 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