Jimmy has conquered the platform, performed in the circus, fought inequality and even battled against monsters. In fact, he's gone around the whole world on his travels. However, we need to look at the big picture: Jimmy was successful in this world, on this planet. But can he do the same on, let's say, a different planet? Or, is something as simple as the shape and terrain enough to stop him?
In this challenge, the input will be a 'planet' - (roughly) an ASCII circle made out of
= characters. The circle can be any size, and be shaped like the outputs in this challenge (except hollow), like the following:
===== = = = = = = = = = = = = = = = = =====
These circles are made with the Midpoint Circle algorithm, which computes the coordinates of each point of the discrete circle. You can find examples on how to implement this algorithm on this Wikipedia page. A
slightly less technical much simpler and clearer explanation, with code examples in common languages, is also available on GeeksForGeeks' website. You can assume all circles are made using this algorithm. See the 'Notes' section for a little more info on this, if you'd like.
The planet may also be (horizontally) thicker or thinner in places, but will always be justified by spaces to be circular. There can also be holes (where the wall is infinitely thin), in which case justification obviously doesn't make sense, but you can require that as part of your input if you wish (see near bottom of this question). Two opposite walls will never both extend so much that one wall will touch the other.
The top/bottom of the circle count as individual sections, so they can also be made 0-width.
An example circle:
== = == = ======== = === = = == ===== == === === ====
But here's the thing: there will also be a Jimmy in the image, somewhere. He might be on the circle, inside it, hanging off it, or floating around in space somewhere:
== = == = ======== = === = = /o\ == // Jimmy is standing safely ===== == === === ====
== = == = ======== = === = = == ===== == /o\ // Jimmy is balancing between two platforms === === ====
== = == = ======== = === = = /o\== // Jimmy will fall (only one body part on the ground) ===== == === === ====
== = == = ======== /o\ // Jimmy's very lost. :( = === = = == ===== == === === ====
The output should be a truthy/falsey value representing whether Jimmy can safely make it around the circle (not just whether he is safe in his starting position).
To clarify, 'get around the circle' means to get back to exactly your starting position, as in, your legs and head both need to be above the same blocks as they were when you started. This does also mean you cannot shift blocks that are below your feet. Further, to 'get around' means you've visited every 'column' (with a width of one character each, i.e he's visited each point along the X axis) within the bounds of the starting, unaltered circle at least once. For instance, if the circle looks like:
== = == = ======== = === = = == ===== == === === ====
at least one body part of Jimmy has to, at some point, touch each of these columns:
vvvvvvvvv == = == = ======== = === = = == ===== == === === ====
To do this, Jimmy has to be able to move. He can move in the following ways:
- Move up to (can move less if you wish) up to one block vertically and two blocks across, but he cannot go end up inside any blocks in either direction. He can go through blocks though:
Start (a _cropped_ section of a circle, obviously not a valid input): = = ===/o\ === Step 2: = = /o\ === === // Move up 1 and across two, and not colliding with anything in start or end position
- "Bump" the block directly beside Jimmy 1 horizontal layer, but:
- Jimmy has to be moving exclusively in that direction (e.g if he is trying to shift a block to the left, he has to be moving just left: not right or diagonally in any way).
- You can't bump blocks diagonally or vertically.
- You can't bump a block with another block immediately beside it (i.e you can only move one block at a time)
- Jimmy cannot move a block beyond the bounds of the current circle - see below
Start: == = =/o\ = == Step 2: == = =/o\ // Jimmy has moved himself, as well as the block beside him, to the left. = ==
Regarding the last bumping rule:
== =. // Jimmy cannot bump this block to the left as it would =/o\ // go out of the bounds of the original circle. = == // (also, Jimmy is stuck in this case)
Obviously, Jimmy can at no point be in such a position that less than two body parts are touching the ground - otherwise, he will tip over.
Your challenge is to state whether there is any possible set of moves in which Jimmy can get around the circle either clockwise or anticlockwise. You can use any valid truthy/falsey values, and take input in any valid format, such as a string with
\n (or even
\\n, if your language interprets them as literal characters) separators, or as an array of lines.
A circle should return a falsey value if and only if in every possible combination of moves, Jimmy eventually either:
- gets stuck, i.e cannot make any legal move before getting around the circle
- falls (i.e the only valid move is one that results in an invalid position)
This is code-golf, so shortest answer in bytes wins.
- If Jimmy starts in an invalid place, the answer is necessarily falsey. Such inputs do count as valid, but as no possible move can be made without falling, it will fail to condition 2.
- Outside the circle is not necessarily invalid, as long as his feet are touching the ground - e.g, this is valid:
/o\ == = == = ======== = === = = == ===== == === === ====
- You can assume the input will always be based on a valid circle, with no more than half (round down) of the wall segments being thickness-0.
- If you wish, you can define how you want inputs to be space-justified in the case that there are 0-width walls - e.g:
('@' is used to represent space) ===== ==@@@@= ====@@=== =@@@@@=== =@@@@@@@= =@@@@@@== =====@@@= // This is pretty straightforward ==@@@@@@= ===@=== ===== But what about: == = == = ======== = === = = /o\ == ===== == === === ==== You can choose between: ==@@= ==@@@@= ======== =@@@@@=== @@@@@@@@= =@/o\@@== ===== == ===@=== ==== or ==@@= ==@@@@= ========@ =@@@@@=== @@@@@@@@= =@/o\@@== =====@@@@ ==@@@@@@@ ===@=== ====
- Additional spaces in the input may also be requested, to ensure equal line length:
@@==@@=@@ @==@@@@=@ ========@ =@@@@@=== @@@@@@@@= =@/o\@@== // While this _is_ an option, it's likely less-than-ideal =====@@@@ // as you have to manually work out/guess the dimensions of ==@@@@@@@ // the circle in the case of 0-width edges (I'm not even sure if @===@===@ // this is always possible) @@====@@@ vs ==@@= ==@@@@= ========@ =@@@@@=== @@@@@@@@= =@/o\@@== =====@@@@ ==@@@@@@@ ===@=== ====
- Once again, remember that planets can not only vary in geology, but also radius! I've just arbitrarily used size-5 circles as they are not too big to fit on one line/make by hand, but the size can theoretically be anything between 2 and infinity. As to what the radius means, see this question for some examples, or look at a pseudocode writeup of the circle generation algorithm here.
- If you wish, you can take the radius as an additional argument/input.
- Default loopholes are forbidden!