# Can Jimmy hang on his rope?

Yet another Jimmy challenge by his original father. See these other lovely challenges.

As you all know, recently we've been seeing challenges related to Jimmy on platforms. Now, Jimmy is an acrobat as I mentioned before, and he's got other tricks up his sleeve.

One of these tricks is hanging by ropes. Here's an example of a rope Jimmy could hang from:

            ||
||
||
||
||
||


When Jimmy hangs on a rope, it looks like this:

            ||
||
/o\
||
||
||


He can hang on the left or the right of the rope, so this:

            ||
||
||
/o\
||
||


is also valid. But he cannot hang by just one body part, so anything like this:

            ||
||
||
/o\|
||
||


is invalid. Note that when he is hanging by one body part the other half of the rope is visible because Jimmy does not cover it up.

Also, Jimmy does not like hanging on the bottom of the rope - it scares him - so this:

            ||
||
||
||
||
/o\


is invalid.

# The challenge

Take input of a Jimmy situation like the ones above, and output whether Jimmy will hang on to the rope or not through a truthy or falsy value.

# The specifics

• Write a program that takes input. This can be through a function or any other appropriate input method.

1. The input should be a scene of one Jimmy and a rope as exemplified above.
• The program should output a truthy or falsy value to the console based on whether Jimmy can hang on to the rope or if he would fall off the rope, respectively.

• The criteria for Jimmy being able to hang on the rope:

1. Two of his body parts are on the rope.

2. He is not on the bottom of the rope.

3. He is not floating in mid-air.

• You can assume the rope will be straight, made up of || segments, and will be longer than one character in height.

• You can assume one whole rope and one singular Jimmy will be present in your scene, no more and no less.

• You can assume there will be no trailing newlines at the bottom of the rope.

• You must cover any amount of leading or trailing spaces before and after the rope.

# Test cases

           ||
||
||                 TRUTHY
/o\
||
||

||
||
/o\|                FALSY
||
||

||
/o\                    TRUTHY
||

||
/o\                FALSY

/o\
||                  TRUTHY

||
||
/o\  ||                FALSY
||
||


# Scoring

This is , so lowest score in bytes wins after about a week.

You can view the leaderboard for this post by expanding the widget/snippet below. In order for your post to be included in the rankings, you need a header (# header text) with the following info:

• The name of the language (end it with a comma , or dash -), followed by...

• The byte count, as the last number to appear in your header.

For example, JavaScript (ES6), 72 bytes is valid, but Fortran, 143 bytes (8-bit) is invalid because the byte count is not the last number in the header (your answer will be recognized as 8 bytes - don't take advantage of this).

<!-- Run the snippet to see the leaderboard. Report any bugs to @ozewski on Github. -->    <iframe src="https://ozewski.github.io/ppcg-leaderboard/?id=187759" width="100%" height="100%" style="border:none;">Oops, your browser is too old to view this content! Please upgrade to a newer version of your browser that supports HTML5.</iframe><style>html,body{margin:0;padding:0;height:100%;overflow:hidden}</style>

• Is the rope always going to have the same number of spaces before it, or can that vary? Jul 6 '19 at 15:53
• @Maxwell That can vary. Jul 6 '19 at 15:58
• Jimmy should really take a holiday Jul 6 '19 at 16:20
• @LuisMendo Jimmy is dedicated to what he does! Jul 6 '19 at 16:25
• Taking a page right of of your book here @connectyourcharger, Jimmy's not happy with you. Jul 8 '19 at 13:17

# Python 2 or 3,  33  30 bytes

-3 thanks to Maxwell

lambda l:'o'in map(max,l[:-1])


An unnamed function accepting a list of lines

Try it online!

### How?

There needs to be a section of rope obscured by Jimmy that is not the bottom one.

lambda l:'o'in map(max,l[:-1])
lambda l:                      # a function taking l (the lines as strings)
l[:-1]  # strip off the last line
map(max,      ) # maximum of each line (where '|'>'o'>'\'>'/'>' ')
'o'in                 # was 'o' one of them? (hence Jimmy obscured all the rope)

• Save three bytes: lambda l:'o'in map(max,l[:-1]) Jul 7 '19 at 21:02
• Oh, very astute - thanks! Jul 7 '19 at 21:21
• That's a very clever use of ASCII values. Nice.
– Nic
Jul 8 '19 at 15:03

# Japt, 5 bytes

I think this is right; I've been working for 16 hours straight and barely know my own name so I wouldn't be surprised if it's not!

Õø|io


Try it

Õø|io     :Implicit input
Õ         :Transpose
ø        :Contains?
|io     :  "|" prepended with "o"

• 16 hours? Now that's dedication! Jul 7 '19 at 9:08
• Wait so it took you 16 hours to write down 5 bytes? ;-) Jul 9 '19 at 17:41
• Looks you like you need a break (same advice goes for little Jimmy!). Jul 9 '19 at 20:52
• @connectyourcharger, no, that's my life! Dedication would be doing it without a break. Which I did! Jul 11 '19 at 21:53
• @ihavenoidea, Pfft! I'll sleep when I'm dead! Jul 11 '19 at 21:54

## Python 2, 28 bytes

lambda x:"o', '|"inzip(*x)


Try it online!

How does it work? It takes input as a list of strings, and zip joins the string. Jimmy stays on the rope if there is a "|" below an "o", so this code joins all the lines and checks if there is an "o" followed by a "|".

Annotated code:

lambda x: # Creates an anonymous function that takes one argument
"o', '|" # If this substring is in the zip object, then Jimmy's "o" is above a "|"
in
    # Back quotes change the object into its string representation
zip(*x) # Joins the lines together


## (Old Answer) Python 2 or 3, 39 bytes

lambda x:1-all("|"in i for i in x[:-1])


A function that takes input as a list of strings, each string being a different line.

-11 bytes thanks to xnor! -2 bytes thanks to Jonathan Allan!

Try it online! (If you want to try more test cases, just put a "." after each set of lines in the input box.)

How does this work? Well, if Jimmy is fully on the rope, then that line will not have any "|" characters. Therefore, we can check each line, and if we find any with no "|" characters, then we know that Jimmy can stay on the rope. However, Jimmy can not hang on to the bottom of the rope; therefore, we don't include the final line in our check. If the final line is just another part of the rope, than it won't matter, because we'll still find a valid row higher up, but if the final line is the one with Jimmy, then it won't find a line without "|" anywhere, and will return False.

• Can you do it without the check that the line has a "/"?
– xnor
Jul 6 '19 at 16:49
• @xnor Yup! -11 bytes Jul 6 '19 at 16:50
• Save a couple like so: lambda x:1-all("|"in i for i in x[:-1]) Jul 6 '19 at 17:12
• Ouch, you was faster :) Jul 6 '19 at 17:22
• @KlaymenDK The function iterates through x[:-1], not x. x[:-1] is all the elements of the list except the final element, because in Python you can use negative indices. Therefore, it (correctly) returns a falsy result if Jimmy is at the bottom of the rope. Jul 7 '19 at 19:55

# Jelly,  9 7  6 bytes

Ṗ<”|ṀẠ


Try it online!

### How?

There needs to be a section of rope obscured by Jimmy that is not the bottom one.

Ṗ<”|ṀẠ - Main Link: list of lines of characters
Ṗ      - remove last line
”|   - pipe character
<     - less than? (vectorises) - Note that all other characters are
Ṁ  - maximum
Ạ - all?

• I feel so weird writing these challenges about Jimmies. It starts to make you feel weird once you imagine multiple Jimmies hanging off of the same rope. Jul 6 '19 at 16:04
• @connectyourcharger Foreshadowing? Jul 6 '19 at 16:05
• @negativeseven Possibly. I have already considered a meta community wiki to index all of the Jimmy posts. Jul 6 '19 at 16:07
• "Note that all other characters are [less than '|']"? Jul 6 '19 at 19:06
• @EriktheOutgolfer yeah, implicitly. Jul 6 '19 at 19:08

# Grime, 5 bytes

\o/\|


Try it online!

The right tool for the job.

\o        # match an "o"
/       # above
\|     # a "|"


# 05AB1E, 5 bytes

Çü%àθ


Try it online!

Ç         # convert the input to a 2D array of codepoints
ü%       # pairwise modulo (vectorized)
à      # maximum (*not* vectorized, returns a single number)
θ     # tail (last digit)


The only characters that can appear in the input are \o/ |, with respective codepoints 92, 111, 47, 32, 124 (there are no newlines, since we chose to take input as an array of lines). The possible results by moduloing two of these numbers are 0, 13, 15, 17, 19, 28, 30, 32, 45, 47, 92, 111. 111 is the largest of those, and also the only one that ends with 1, so the code will output truthy if and only if 111 is present in the list (only 1 is truthy in 05AB1E). 111 is 111 (o) % 124 (|), and so only occurs if there's an o above a | in the input.

• Very nice with the pairwise modulo. Jul 8 '19 at 13:10

## brainfuck, 79 64 bytes

>>+<<,[----------[<]>>[.-]+<[>-]+[---------<-->]<[<]>>[-]<[>]<,]


Try it online!

Outputs the 0x01 byte for truthy and nothing for falsy.

Z: 0
A: input
B: 0
C: has no | been found on this line?

>>+<<                       initialize C to 1
,[                          loop over each char

----------                set A to 0 if input was \n
[<]>>                     move to C if input was \n; B otherwise
[                         if input was \n and C is true
.-                      output 1
]

+                         this will reinitialize C to 1 if input was \n
but also clobber B with 1 if it wasn't
now we have { 0   0   0  (1)} if input was \n;
{ 0   _  (1)  _ } otherwise
<[>-]                     clear own cell if the one to the left is positive
this yields { 0   0  (0)  1 } and
{ 0   _  (0)  _ } as desired

+[---------<-->]          set A to 0 if input was |
<[<]>>                    move to C if input was |; B otherwise
[-]                       zero out current cell: clears C if input was |
<[>]<                     realign pointer onto A

,]                          break on end of input


# Stax, 6 bytes

é¿┤4╠q


Run and debug it

Transposes the input, then searches for "o|".

# APL (Dyalog Unicode), 8 bytesSBCS

Anonymous tacit prefix function, taking a character matrix as argument.

1∊'o|'⍷⍉


Try it online!

⍉ transpose

'o|'⍷ mask for everywhere o is immediate followed by |

1∊ is one a member thereof?

# Dyalog APL Extended, 141311 9 bytes

3∊¯1+/⍤↓<


Try it online!

• -2: 3∊¯1+/⍤↓<
Jul 7 '19 at 1:42

any(all(<'|')).init


Try it online!

# JavaScript, 39 33 bytes

Thanks @Daniil Tutubalin for golfing off 2 bytes

x=>!!x.match(/^( *)\/[^|]*\n/m)


This matches any line which is not the line where his left arm shows up and none of the rope shows.

Try it online!

• It appears to fail if he is at the bottom of the rope Jul 6 '19 at 17:11
• It should fail if he is at the bottom, right? Because Jimmy falls if he is at the bottom fo the rope Jul 6 '19 at 17:13
• I mean that when I put him at the bottom of the rope your function for some reason returned 1 Jul 6 '19 at 17:28
• Hm, nevermind then. Jul 6 '19 at 17:33
• What about /^ *.o. *\n/?
– tsh
Jul 8 '19 at 2:08

# ///, 53 50 bytes

/~/\/\~/\/o\\/1~1 /1~ 1/1~|1~/1|~/|~/1.~/ ~/.~/
~.


Try it online!

Because there is no other way to take input in ///, it is hard-coded:

/~/\/\~/\/o\\/1~1 /1~ 1/1~|1~/1|~/|~/1.~/ ~/.~/
~<INPUT HERE>.


Explanation:

The general approach is to replace Jimmy with a unary 1, then remove him from all situations where he is in danger. If he survives, he is outputted. If he doesn't, then nothing is. The ~ in the code are a replacement for //, which allow the code to be shortened by 3 bytes here. They are omitted from the explanation.

/{/\//
/}/\/\//

{The top two lines allow me to leave comments without disturbing the code.}

/\/o\\/1/ {Replace Jimmy with a 1.}
/1 /1/    {Get rid of any spaces in front of Jimmy. This moves Jimmy towards the rope from the left.}
/ 1/1/    {Get rid of any spaces after Jimmy. This moves Jimmy towards the rope from the right.}

/|1//     {If Jimmy is touching the rope, remove him and the rope.}
/1|//     {This is based on the observation that in all cases where Jimmy is safe, there is no visible rope on his line.}

/|//      {Remove any remaining rope. If Jimmy was touching a rope, it's already too late for him.}
/1.//     {This handles the case where Jimmy is at the bottom of the rope (hence the period at the end).}

/ //      {The remaining lines clean up the output.}
/.//
/
//

||
||
||
/o\
||.


Try it online!

# Ruby 2.5.5, 22 bytes

->x{x.pop;!x.all? /\|/}


Expects an array of lines. Requires a minimum of version 2.5.5 because this is when Array#all?(pattern) was added.

Because of the constraints that the input will always be a valid scene of Jimmy and a rope, it boils down to whether any of the lines prior to the last line have the rope obscured.

# Kotlin, 93 84 bytes

fun j(a:List<String>){print(a.count{!it.contains("|")}==1&&!a.last().contains("o"))}


Try it online!

# Elm 0.19, 68 60 bytes

List.any(not<<String.contains"|")<<List.drop 1<<List.reverse


Anonymous, points-free function. Takes input as a list of lines. Disregarding the last line, it checks whether there are any with no '|' in them – implying the rope is fully covered by Jimmy.

Thanks to Lynn for golfing 8 bytes.

Verify all test cases here.

• List.any(not<<String.contains"|")<<List.drop 1<<List.reverse is a slightly shorter anonymous function.
– Lynn
Oct 26 '20 at 15:01

# JavaScript, 38 37 bytes

r=>r.some(x=>!~x.search\\|,r.pop())


Try it online!

## Retina, 9 bytes

m^[^|]+^


Try it online!

Now, I've never programmed in Retina before, but as far as I can tell this works. It is a regular expression that finds a string containing (1) the beginning of the input, (2) no "|" characters, and (3) a newline.

People more familiar with either regular expressions or Retina are encouraged to offer suggestions. -2 bytes thanks to Neil!

• Two alternatives: 1) Remove the \n because a new line is not a | and so that will match anyway, and the final ^ suffices to ensure that you actually matched a newline. 2) Use a pilcrow ¶ instead of \n and remove the trailing ^ (because that's always true after a newline in multiline mode).
– Neil
Jul 6 '19 at 18:05

# Perl 5-p, 26 bytes

$\||=!/\|/;$;=/o/}{$\&&=!$


Try it online!

# Befunge-98 (PyFunge), 26 24 bytes

]~:a-!#v_' +
^_-3q#$< @  Try it online! Exits with return code 3 if \n is encountered and the last line contained 3 non-space characters, otherwise exits with return code 0 on EOF. Thus, this relies on the last line not containing a trailing newline. ### Dissected ]~ :a-!#v_ ' + Read character, Branch downwards if Increment counter on branch up (and equal to 10 ('\n') the stack if greater loop around) if than 32 (' ') and end of stream implicitly loop ^_-3q#$<                    <
Return with code 3
if counter is equal to 3,
otherwise reset counter

@
Return with exit
code 0


# 05AB1E (legacy), 6 bytes

ζJ„o|å


Input as a list of lines.

Try it online.

Explanation:

ζ       # Zip/transpose the (implicit) strings in the input-list, with space as filler
# (NOTE: zip/transpose doesn't work on string-list in the new version of 05AB1E,
#  which is why we use the legacy version)
J      # Join these zipped/transposed lines together to a single string
„o|å  # And check if it contains the string "o|"
# (after which the result is output implicitly)


# PowerShell, 26 bytes

Port of Maxwell's answer for Retina.

"\$args"-match'(?m)^[^|]+^'


Try it online!

Explanation:

true if:

1. there is a line in a scene that does not contain the character |
2. and after this line there is a start of a new line.

false otherwise.

# Husk, 6 bytes

€'om▲h


Try it online! A port of Jonathan Allan's answer.

# Pyth, 9 bytes

sPm!sqR\|


Test suite!

# Pyret, 79 bytes

{(l):all2({(r,n):string-char-at(n,string-index-of(r,"o") == "|")},l,link(0,l))}


Expects an array of lines as strings. Makes a copy in link(0,l) where all rows shifted down by one. Goes through each row r and n where n is the row below r. Checks that if Jimmy's body "o" is at some position, then the row below it has a pipe there (i.e. Jimmy's hanging on the rope and isn't at the bottom).

# SnakeEx, 7 bytes

j:<R>o|


Try it here!

### Explanation

The only necessary and sufficient condition is that Jimmy's torso has to have a rope character below it.

j:       Define the main snake, j (for Jimmy)
<R>    Pivot right (i.e. downward, since the snake starts out moving to the right)
o   Match Jimmy's torso and move down
|  Match a rope character


# Rockstar, 147 bytes

listen to J
Y's0
while J
listen to R
X's0
while J at X
let H be J at X
let S be R at X
let Y be+H is "o" and S is "|"
let X be+1

let J be R

say Y
`

Try it here (Code will need to be pasted in)