I wrote this Code to complete the exercise without implementing a “canTurnRight”, “canTurnLeft” or “canMove” function and it worked perfectly, but I still didnt pass the “A complex maze testing the full algorithm” scenario, even though the maze was completed correctly. The error messages were “Implement a “canTurnRight” function”, “Implement a “canTurnLeft” function” and “Implement a “canMove” function”. To solve this, I just implemented all of the functions without any output, which seems nonsensical to me to be required to solve the exercise.
To solve this, I just implemented all of the functions without any output, which seems nonsensical to me to be required to solve the exercise.
I agree, so why did you choose to not implement the functions? The instructions ask you to implement those functions - that’s the point of the exercise.
I think it’s to beat the “add 13 lines of codes“ challenge
I’ve completed every scenario except the last one (add only 13 lines of code)
I just couldn’t wrap my head around completing that while implementing the 3 functions
I did implement the functions but took so many lines.
I think It will help if there’s some sort of highlighter to show how many lines I added. Then I believe I can work through my code & look for ways to reduce lines while implementing the functions
I did implement those functions, but later deleted them and replaced them with “canGo” as a way to beat both of the “13 lines of code” challenge and the “Only use look once” challenge. But I now also see the solution that also implements all of the functions! Still, after beating the exercise, I felt this was kind of restricting, but I get if you want to keep it that way due to the way the exercise is set up.
Cool! You were able to beat the 13 lines rules even when implementing the functions!!!
Could you walk me through your mental model of how you structured your solution to make this possible?
Just a little code review:
if (canGo("left") === true) {...
The canGo(direction) function already returns a boolean true/false value. It’s not necessary to explicitly compare it to true.
This is sufficient:
if (canGo("left")) {...
I looked at it this way: I know that I have to implement the “canTurnLeft”, “canTurnRight” and “canMove” functions. Those should all check if the specified direction is either a “start”, “target” or “empty” space and if so, they should return true. Because this is the basis for all of those functions, I made a helper function called investigate(direction), which firstly uses look(direction) to set a variable called “space” to the type of space it has looked at (so look(direction) only gets used once). Then, it checks if the variable “space” is set to “start”, “target” or “empty” and if so, it returns true. Lastly, I used the investigate(direction) function with the specified direction in all of the functions I needed to implement to either return true or false. I hope this makes sense!
@elzda All this logic is fantastic. The only bit you missed is that these canTurnLeft() etc should be the ones that call you’re canGo("left") functions.
In coding, we have the concept of “magic strings”. These are strings that have meaning ("left", "ahead", etc). We really want to avoid scattering these throughout our codebase because if one of them needs to change (e.g. an API changes its rules, or we rename something elsewhere in our code) we have to change them in lots of places.
So because of that it’s better to use those just once in a place specifically designed for them (e.g. canTurnLeft()). This means that the rest of the code doesn’t need to know about the internals or the magic strings - it just gets a single, well named function it can use.
That’s the bit that I think you missed in the purpose of the exercise.
Now, to solve it in 13 lines…
In code we have the concept of “Expressions”. An expression is the ... in if(...) or in let seen = ... or many other places. Generally whenever we’re using values (1, "foo", true) or comparisons (x === true), etc that’s an expression. Expressions are always things that are “evaluated”. So we evaluated x === true and get true or false. Or we evaluated 5 + 3 and get 8.
Often, we can make our code tidier and simpler by using an expression more intelligently. And the key rule is that you can replace any expression with another expression and the code is still valid (not necessarily correct, but valid). So if you have a 5 in your code, you can replace it with 2 + 3. And if you have x === true you could replace it with false (or vis-versa). If you KNOW x will be true, you can write true not x === true.
In your canGo function, you have three expressions:
seen === "empty" ...truefalse
Lines 4-7 can be reduced into 1 line. You don’t need an if statement at all. Thinking about expressions, can you think about how that might be possible?
I already solved the exercise earlier the way you describe it, but the way you described it makes it really easy to understand why this is the correct way and how to think about using expressions efficiently. Thank you!
Yes! Makes a lot of sense!
Thanks!
That line 4 - 7 bit is what I’ve been missing! ![]()
Instead of an if block, just return something === something OR ….
That’s one line of code!
Thanks for the edge cases in the challenges. ![]()
