26
\$\begingroup\$

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.

Leaderboard

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>

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

28 Answers 28

25
\$\begingroup\$

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)
\$\endgroup\$
3
  • \$\begingroup\$ Save three bytes: lambda l:'o'in map(max,l[:-1]) \$\endgroup\$ Jul 7, 2019 at 21:02
  • \$\begingroup\$ Oh, very astute - thanks! \$\endgroup\$ Jul 7, 2019 at 21:21
  • \$\begingroup\$ That's a very clever use of ASCII values. Nice. \$\endgroup\$
    – anon
    Jul 8, 2019 at 15:03
17
\$\begingroup\$

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"
\$\endgroup\$
6
  • 2
    \$\begingroup\$ 16 hours? Now that's dedication! \$\endgroup\$
    – moltarze
    Jul 7, 2019 at 9:08
  • 3
    \$\begingroup\$ Wait so it took you 16 hours to write down 5 bytes? ;-) \$\endgroup\$
    – Cullub
    Jul 9, 2019 at 17:41
  • \$\begingroup\$ Looks you like you need a break (same advice goes for little Jimmy!). \$\endgroup\$ Jul 9, 2019 at 20:52
  • \$\begingroup\$ @connectyourcharger, no, that's my life! Dedication would be doing it without a break. Which I did! \$\endgroup\$
    – Shaggy
    Jul 11, 2019 at 21:53
  • 3
    \$\begingroup\$ @ihavenoidea, Pfft! I'll sleep when I'm dead! \$\endgroup\$
    – Shaggy
    Jul 11, 2019 at 21:54
17
\$\begingroup\$

Python 2, 28 bytes

lambda x:"o', '|"in`zip(*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.

\$\endgroup\$
6
  • \$\begingroup\$ Can you do it without the check that the line has a "/"? \$\endgroup\$
    – xnor
    Jul 6, 2019 at 16:49
  • \$\begingroup\$ @xnor Yup! -11 bytes \$\endgroup\$ Jul 6, 2019 at 16:50
  • 1
    \$\begingroup\$ Save a couple like so: lambda x:1-all("|"in i for i in x[:-1]) \$\endgroup\$ Jul 6, 2019 at 17:12
  • 1
    \$\begingroup\$ Ouch, you was faster :) \$\endgroup\$ Jul 6, 2019 at 17:22
  • 1
    \$\begingroup\$ @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. \$\endgroup\$ Jul 7, 2019 at 19:55
8
\$\begingroup\$

Jelly,  9 7  6 bytes

Ṗ<”|ṀẠ

A monadic Link 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.

Ṗ<”|ṀẠ - Main Link: list of lines of characters
Ṗ      - remove last line
  ”|   - pipe character
 <     - less than? (vectorises) - Note that all other characters are
    Ṁ  - maximum
     Ạ - all?
\$\endgroup\$
5
  • 1
    \$\begingroup\$ 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. \$\endgroup\$
    – moltarze
    Jul 6, 2019 at 16:04
  • 1
    \$\begingroup\$ @connectyourcharger Foreshadowing? \$\endgroup\$ Jul 6, 2019 at 16:05
  • \$\begingroup\$ @negativeseven Possibly. I have already considered a meta community wiki to index all of the Jimmy posts. \$\endgroup\$
    – moltarze
    Jul 6, 2019 at 16:07
  • 1
    \$\begingroup\$ "Note that all other characters are [less than '|']"? \$\endgroup\$ Jul 6, 2019 at 19:06
  • \$\begingroup\$ @EriktheOutgolfer yeah, implicitly. \$\endgroup\$ Jul 6, 2019 at 19:08
8
\$\begingroup\$

Grime, 5 bytes

\o/\|

Try it online!

The right tool for the job.

\o        # match an "o"
  /       # above
   \|     # a "|"
\$\endgroup\$
6
\$\begingroup\$

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.

\$\endgroup\$
1
  • 1
    \$\begingroup\$ Very nice with the pairwise modulo. \$\endgroup\$ Jul 8, 2019 at 13:10
5
\$\begingroup\$

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
\$\endgroup\$
4
\$\begingroup\$

Stax, 6 bytes

é¿┤4╠q

Run and debug it

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

\$\endgroup\$
4
\$\begingroup\$

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?

\$\endgroup\$
3
\$\begingroup\$

Dyalog APL Extended, 14 13 11 9 bytes

3∊¯1+/⍤↓<

Try it online!

\$\endgroup\$
1
  • \$\begingroup\$ -2: 3∊¯1+/⍤↓< \$\endgroup\$
    – Adám
    Jul 7, 2019 at 1:42
3
\$\begingroup\$

Haskell, 19 bytes

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

Try it online!

\$\endgroup\$
2
\$\begingroup\$

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!

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

///, 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!

\$\endgroup\$
2
\$\begingroup\$

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.

\$\endgroup\$
2
\$\begingroup\$

Kotlin, 93 84 bytes

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

Try it online!

\$\endgroup\$
2
\$\begingroup\$

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.

\$\endgroup\$
1
  • 1
    \$\begingroup\$ List.any(not<<String.contains"|")<<List.drop 1<<List.reverse is a slightly shorter anonymous function. \$\endgroup\$
    – Lynn
    Oct 26, 2020 at 15:01
1
\$\begingroup\$

JavaScript, 38 37 bytes

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

Try it online!

\$\endgroup\$
1
\$\begingroup\$

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!

\$\endgroup\$
1
  • \$\begingroup\$ 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). \$\endgroup\$
    – Neil
    Jul 6, 2019 at 18:05
1
\$\begingroup\$

Perl 5 -p, 26 bytes

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

Try it online!

\$\endgroup\$
1
\$\begingroup\$

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
 and return to beginning

@
 Return with exit
 code 0
\$\endgroup\$
1
\$\begingroup\$

05AB1E (legacy), 6 bytes

ζJ„o|å

Port of @Shaggy's Japt answer.

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)
\$\endgroup\$
1
1
\$\begingroup\$

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.

\$\endgroup\$
1
\$\begingroup\$

Husk, 6 bytes

€'om▲h

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

\$\endgroup\$
1
\$\begingroup\$

Vyxal, 6 bytes

Ḣ\|vOA

Try it Online!

Takes a list of lines, returns a 1 if Jimmy can't hang on, 0 if he can.

\$\endgroup\$
0
\$\begingroup\$

Pyth, 9 bytes

sPm!sqR\|

Test suite!

\$\endgroup\$
0
\$\begingroup\$

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).

\$\endgroup\$
0
\$\begingroup\$

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
\$\endgroup\$
0
\$\begingroup\$

Rockstar, 147 146 137 bytes

Outputs 0 for false and 1 for true

listen to J
Y's 0
while J
cut J
listen to R
X's 0
while J
let S be R at X
let Y be+roll J's "o" and S's "|"
let X be+1

let J be R

say Y

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

listen to J     :Read first line of input into variable J
Y's 0           :Initialise Y as 0
while J         :While J exists
cut J           :  Split J into an array
listen to R     :  Read next line of input into variable R
X's 0           :  Initialise X as 0
while J         :  While J is not empty
let S be        :    Assign to variable S
  R at X        :      The character in R at 0-based index S
let Y be+       :    Increment Y by
  roll J        :      Pop the first element from J
  's "o"        :      Eqaul to "o"?
  and           :      Logical AND with
  S's "|"       :      S is equal to "|"
let X be+1      :    Increment X
                :  End while loop
let J be R      :  Reassign R to J
                :End while loop
say Y           :Output Y
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.