10
\$\begingroup\$

The city defines a dog as any living entity with four legs and a tail. So raccoons, bears, mountain lions, mice, these are all just different sizes of dog.

Given an ASCII-art image of an animal, determine if that animal is a dog.

Rules

An animal is a dog if it has four legs and a tail.

The foot of a leg starts with one of \ (backslash), | (pipe), or / (slash), has one or more _ in between, and another \, |, or /. Each foot will hit the last line of the string. The feet may not share a common border.

\ \  |   /   /    |  |     /  |   |  / /     <-- These are all just
|_|  |___|  |_____|  |_____|  |___|  |_|         different sizes of leg.

A tail is a line coming out of the left side of the figure and touching the leftmost part of the multiline string. The tail is made up of either - or = characters. The tail must be at least one character long, and can optionally end with a o or *.

o---  *--  *==  --  ==  -  =  o===  *-      <-- These are all just
                                                different sizes of tail.

You can take input as a multiline string, or array of lines. Output a truthy or falsy value to determine if the figure is a dog, or any two distinct values.

Truthy test cases:

      ______/\__/\
    _/    (  U U  )
*--/____. ,\_ w _/
    \  /| |\ |\ \
    /_/ \_/|_| \_\
    _________/\
o==/         ''>
   |_||_||_||_|
        /\__/\
       (  o O)
       /   m/ 
      |    |      don't ask
o-----|    \__
      |   ___ \_______
      //\ \  \___ ___ \
     /_/ \_\    /_|  \_|

Falsy test cases:

        __________          _
 ______/ ________ \________/o)<
(_______/        \__________/
     ____/)(\
    /   \o >o
   (     \_./
o--\ \_.  / 
    \____/
    ||  ||
    \/  \/
   /\/\/\/\/\
o-/       o.o
   /_/_/_/_/
\$\endgroup\$
14
  • 3
    \$\begingroup\$ Are these dogs? \$\endgroup\$
    – tsh
    Feb 7 at 3:17
  • 3
    \$\begingroup\$ @Jonah I assume it's because "the feet may not share a common border." \$\endgroup\$
    – chunes
    Feb 7 at 3:23
  • 1
    \$\begingroup\$ @tsh It must have exactly 4 legs. So in the ones you sent, the first, second, fourth, and last figures are dogs \$\endgroup\$
    – noodle man
    Feb 7 at 3:24
  • 1
    \$\begingroup\$ @Jacob are there any restrictions on the connectedness of the figure? eg, in tsh's first dog, the legs are not connected. Could I have 4 free floating legs and a tail to the left of them, also free floating, and be a dog? \$\endgroup\$
    – Jonah
    Feb 7 at 5:31
  • 3
    \$\begingroup\$ Is there any restriction on the height of the tail, e.g. is -|_||_||_||_| a dog? \$\endgroup\$
    – Neil
    Feb 7 at 9:49

7 Answers 7

6
\$\begingroup\$

Python, 102 bytes

lambda x:any(re.match("[\*o]?[\-=]+",r)for r in x)*len(re.split(r"[\\|/]_+[\\|/]",x[-1]))==5
import re

Attempt This Online!

Takes in a list of lines.

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

Retina 0.8.2, 59 bytes

^((.*¶)*[*o][-=])?(.*¶)*(.*?[\\|/]_+[\\|/])*.*$
$#4$#1
^41$

Try it online! Link is to test suite that splits on blank lines for convenience. Explanation:

^((.*¶)*[*o][-=])?(.*¶)*(.*?[\\|/]_+[\\|/])*.*$

Optionally match a tail, then match any number of legs.

$#4$#1

Replace with the count of legs and whether a tail was matched.

^41$

Check for exactly four legs and a tail.

\$\endgroup\$
1
  • \$\begingroup\$ Right tool for the job \$\endgroup\$
    – noodle man
    Feb 9 at 21:50
3
\$\begingroup\$

05AB1E, 43 41 bytes

ε„*oõš„-=âJÅ?}àIθ„__¬:.œε…\|/Sã'_ý¢O}à4Q*

Input as a list of lines.

Try it online or verify all test cases. (NOTE: I've added a remove spaces ðK before the partition builtin, to speed it up significantly. So should you test a 'dog' which has a space in one of its feet (e.g. |_ |, the ðK should be removed to test it properly.)

Explanation:

Step 1: Validate the tail:

ε              # Map over each line of the (implicit) input-list:
 „*o           #  Push string "*o"
    õš         #  Convert it to a list of characters and append an empty string:
               #   ["*","o",""]
      „-=      #  Push string "-="
         â     #  Get all combinations of the two with the cartesian product:
               #   [["","-"],["","="],["*","-"],["*","="],["o","-"],["o","="]]
          J    #  Join each inner pair together to a string:
               #   ["-","=","*-","*=","o-","o="]
           Å?  #  Check for each whether the current line starts with it
}à             # After the map: pop and push the maximum to check if any was truthy

Step 2: Validate the feet:

I              # Push the input-list again
 θ             # Leave just its last line
  „__          # Push string "__"
     ¬         # Push its first character (without popping): "_"
      :        # Keep replacing all "__" with "_" until there are no "__" left
.œ             # Get all partitions of this string
  ε            # Map over each partition:
   …\|/S       #  Push triplet-list ["\","|","/"]
        ã      #  Get all pairs with the cartesian power of 2:
               #   [["\","\"],["\","|"],["\","/"],["|","\"],["|","|"],["|","/"],["/","\"],["/","|"],["/","/"]]
         '_ý  '#  Join each inner pair with "_" delimiter:
               #   ["\_\","\_|","\_/","|_\","|_|","|_/","/_\","/_|","/_/"]
            ¢  #  Count how many times each foot occurs in the parts
             O #  Sum the counts of each type of foot together
  }à           # After the map: pop and leave the maximum sum of counts
    4Q         # Check if this is equal to 4

Step 3: Combine the checks and output:

*              # Multiply the two checks together
               # (after which the result is output implicitly)
\$\endgroup\$
2
  • 1
    \$\begingroup\$ Nice, didn't think finding all possible feet and tails would be shorter than a regex \$\endgroup\$
    – noodle man
    Feb 9 at 21:49
  • \$\begingroup\$ @Jacob Yeah, I was surprised as well when I saw my answer was shorter than the Retina answer (or the JavaScript regex-based answer). :) \$\endgroup\$ Feb 10 at 7:20
3
\$\begingroup\$

Factor, 62 101 bytes

[ dup R/ ^[*o]?[-=]+/m re-contains? swap
"\n" split last R/ [\\|\/]_+[\\|\/]/ count-matches 4 = and ]

+39 bytes to disallow dogs with more than four legs. Ouch. :\

enter image description here

\$\endgroup\$
1
  • 1
    \$\begingroup\$ Love the names lol. They could have their own show or book or something together \$\endgroup\$
    – noodle man
    Feb 9 at 22:09
3
\$\begingroup\$

Bash, 77 bytes

Though it's using core tools, so should work on other shells.

Edit: 7 bytes saved because I was being brain dead about how to test in TIO. Thanks for the nudge, @Neil.

Edit: just added more test cases

grep -Eqo ^[o*]?[=-] $1&&[ `tail -1 $1|grep -Eo "[/\\|]_+[/\\|]"|wc -l` = 4 ]

Try it online!

\$\endgroup\$
2
  • \$\begingroup\$ Wouldn't this be 7 bytes shorter as a full program rather than a function? \$\endgroup\$
    – Neil
    Feb 8 at 0:40
  • \$\begingroup\$ Thanks for the nudge, fixed. \$\endgroup\$
    – bxm
    Feb 8 at 9:15
3
\$\begingroup\$

JavaScript (Node.js), 65 bytes

x=>x.match(/[\\|\/]_+[\\|\/](?=.*$)|$/g)[4]</^[*o]?[-=]/m.test(x)

Try it online!

'' < true
'' ≮ false
undefined ≮ true
'|_|' ≮ true
\$\endgroup\$
4
  • \$\begingroup\$ Why do you need this part (?=.*$)|$ in the first regex? \$\endgroup\$
    – noodle man
    Feb 9 at 21:46
  • \$\begingroup\$ Also, you can save one byte in the second regex: /^[*o]?-|=/m \$\endgroup\$
    – noodle man
    Feb 9 at 21:47
  • \$\begingroup\$ @Jacob Make it at last line \$\endgroup\$
    – l4m2
    Feb 10 at 2:29
  • \$\begingroup\$ @Jacob Fail o= \$\endgroup\$
    – l4m2
    Feb 10 at 2:29
1
\$\begingroup\$

awk, 57 bytes

/^[o*]?[=-]/{t=1}END{exit t&&gsub(/[/\\|]_+[/\\|]/,0)==4}

Try it online!

\$\endgroup\$

Your Answer

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

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