Fastest Gun in the West

23

You are the roughest, toughest, coolest cowboy west of the Mississippi. However, some weird guy on a wacky nerd website decided that it would be cool to plop you into random unfinished landscapes and fight. No matter, you'll still win. However, to help you win those grueling gunfights you'll write home about, it's helpful to know how many bullets the coward lurking in the landscape has.

How about you help this poor guy out. Given an ASCII landscape, find the gun inside it and tell him how many bullets are loaded into it. This is the gun:

  (X)
(X\ /X)
 (XVX)
  \X/

Each X in the above picture is a potential slot for a bullet. The slot will either contain a space or one of 0,O,o (may not be consistent - the cowboy may have loaded different types of bullets in his gun).

There will always be exactly one gun, matching the above description, in the landscape. However, please note that the spaces around and inside the gun can contain anything.

Input

You will be given a string containing printable ASCII (so not tabs) and newlines to separate lines. You may also take a list of strings, if you wish. Strings will all be padded with spaces, so they will all be the same length. The input will be at least 4 rows high and 7 columns wide.

There will always be exactly one gun in the landscape.

Output

You will output how many bullets (0, O, o) there are in the gun, so your output will always between 0 and 6.

Test Cases

  (0)   ( )
(o\ /o( \ / )
 (oVo) ( V )
  \o/   \ /

0

----------------------------
////////////////////////////
////////////////////////////
/////////////(o)////////////
///////////(0\// )//////////
////////////( Vo)///////////
/////////////\ /////////////
////////////////////////////
----------------------------

3

()()()()()()()()()()()()()()()()\)/)()()()()()()()()()()()()
()()()()()()()()()()()()()()()()(V)()()()()()()()()()()()()(
()()()()()()()(\0/)()()()()()()()()()()()()()()()()()()()()(
()()()()()()()()()()()()()()()()()()()()()()()( )()()()()()(
()()()()()()(o)()()()()()()()(00)()()()()()(( \(/0)()()()()(
()()()()()()()()()()()()()()()()()()()()()()(( V )()()()()()
()()()()()()()()()()()()()()()()()()()()()()()\O/()()()()()(

2

------(0)---
||||(0\|/0)
-----(0V0)--
||||||\0/
-------_------
|||||||-|
------|-|
|||||||-|
------|-|

6

00ooOO(0)/\\/V

  ( )
( \\/ )
 ( V )
 \\ /

00OOoo()()()())))

0

  (\)     (0)
(0\\/0) ( \0/ )
 (0V0)   ( V )
 \\0/     \ /

1 (left gun is invalid because of the `\` in the bullet slot)

-00(0)00\0
-(O\0/o)\ 
- (OVo)o\0
-o \ /oo/ 

5

This is , so shortest answer in bytes wins.

Stephen

Posted 2017-07-01T17:45:14.673

Reputation: 12 293

Sandbox – Stephen – 2017-07-01T17:45:22.050

10+1 If someone FGITWs this challenge ;) – Beta Decay – 2017-07-01T18:02:00.990

2You should add a test case where there's a 0 inside the gun's bounding box but outside the gun. – Martin Ender – 2017-07-01T18:20:03.147

@StepHen Oh right, there's the one zero inside the gun that doesn't belong to it. It would be good to have zeros outside the gun but within its bounding box as well though. – Martin Ender – 2017-07-01T18:21:03.093

"The input will be at least 4 rows high and 5 columns wide." - if there is always a gun then the input must be at least 7 columns wide. – manassehkatz-Moving 2 Codidact – 2017-07-02T14:30:36.263

Answers

19

Snails, 71 bytes

Try it online.

A
\/a=\)2w\V={\\u\(}c=\/b={\\c\(2}u!{(nb|.|.n.)=^o=^O=^0^ }{nb|.|.n.}^ 

feersum

Posted 2017-07-01T17:45:14.673

Reputation: 29 566

4Programming language for 2-dimensional pattern matching. you must be glad I made this challenge then :P – Stephen – 2017-07-01T18:35:34.640

25Do you have a link to this language? It's pretty funny that the fastest gun in the west is a snail. – PyRulez – 2017-07-01T20:24:02.610

1

@PyRulez Here is a link for you

– ovs – 2017-07-01T20:32:59.573

6@PyRulez you can click the language name on the TIO page – Stephen – 2017-07-01T20:59:58.950

I am interested in how this works. – user41805 – 2017-07-02T06:09:12.483

@KritixiLithos You can check out the documentation.

– feersum – 2017-07-03T06:49:54.297

6

Mathematica, 170 bytes

Catch@BlockMap[b="O"|"o"|"0";MatchQ[#,p=Characters@{"  (X)  ","(X\\ /X)"," (XVX) ","  \\X/  "}/." "->_/."X"->$;p/.$->b|"X"|" "]&&Throw@Count[Pick[#,p,$],b,2]&,#,{4,7},1]&

Takes an array of strings/chars. Returns the number of bullets.

JungHwan Min

Posted 2017-07-01T17:45:14.673

Reputation: 13 290

4

JavaScript, 215 211 209 bytes

Thanks to Shaggy for -4 bytes!

f=

i=>[...i].map((_,x)=>eval(String.raw`a=i.match(/(\n|^).{${x}}..\(${Z='([oO0 ])'}\).*\n.{${x}}\(${Z}\\.\/${Z}\).*\n.{${x}}.\(${Z}V${Z}\).*\n.{${x}}..\\${Z}\//);a&&alert(a.filter(i=>/^[oO0]$/.test(i)).length)`))

tests = [["  (0)   ( )\n(o\\ /o( \\ / )\n (oVo) ( V )\n  \\o/   \\ /",0],["----------------------------\n////////////////////////////\n////////////////////////////\n/////////////(o)////////////\n///////////(0\\// )//////////\n////////////( Vo)///////////\n/////////////\\ /////////////\n////////////////////////////\n----------------------------",3],["()()()()()()()()()()()()()()()()\\)/)()()()()()()()()()()()()\n()()()()()()()()()()()()()()()()(V)()()()()()()()()()()()()(\n()()()()()()()(\\0/)()()()()()()()()()()()()()()()()()()()()(\n()()()()()()()()()()()()()()()()()()()()()()()( )()()()()()(\n()()()()()()(o)()()()()()()()(00)()()()()()(( \\(/0)()()()()(\n()()()()()()()()()()()()()()()()()()()()()()(( V )()()()()()\n()()()()()()()()()()()()()()()()()()()()()()()\\O/()()()()()(",2],["------(0)---\n||||(0\\|/0)\n-----(0V0)--\n||||||\\0/\n-------_------\n|||||||-|\n------|-|\n|||||||-|\n------|-|",6],["00ooOO(0)/\\\\/V\n\n  ( )\n( \\\\/ )\n ( V )\n \\\\ /\n\n00OOoo()()()())))",0],["  (\\)     (0)\n(0\\\\/0) ( \\0/ )\n (0V0)   ( V )\n \\\\0/     \\ /",1]]

alert = x => i = x;

tests.forEach((t, index) => {
    i = 'Not Found'
    f(t[0]);
    document.getElementById('a').textContent += t[0] + '\n\n' + i + '\n\n';
    if (i != t[1]) {
        document.getElementById('a').textContent += 'Failed test ' + index + '! Expected '  + t[1] + '\n\n';
        document.getElementById('a').style = 'color: red'
    }
})
<pre id="a"></pre>

Basically, tries to match a gun n characters after a line break, for n from 0 to the length of the string.

Artyer

Posted 2017-07-01T17:45:14.673

Reputation: 1 697

Save a few bytes by assigning to Z within the literal, the first time you use it and getting rid of the {}. – Shaggy – 2017-07-03T16:52:53.280

@Shaggy Thanks! – Artyer – 2017-07-03T17:53:44.073

3

Python 2, 219 224 227 bytes

import re
f=lambda s:sum(sum(g>' 'for g in m.groups())for m in[re.match(r'.*@..\(X\)..@\(X\\./X\)@.\(XVX\).@..\\X/.*'.replace('X','([0Oo ])').replace('@',r'[^\n]*\n.{%d}'%i),'\n'+s,re.DOTALL)for i in range(0,s.find('\n'))]if m)

EDIT: Fixed a bug which cost me 5 bytes :(... found 3 bytes of extra r''s that weren't needed. And then Grrr!! Was not counting \ chars in my code correctly, so added 6...

Takes a string with newlines; retuns the number of bullets found.

Basically, applies a regex that looks for the gun pattern with 0, 1, ... lineLength characters of pad at the beginning of the lines.

Chas Brown

Posted 2017-07-01T17:45:14.673

Reputation: 8 959

3

C (gcc), 357 351 bytes

#define M(F,C)F(i){i=s[i]==C;}
b,i;char*s,c;M(L,'(')M(R,')')M(A,'/')M(D,'\\')M(V,'V')B(i){i=b=(c=s[i])==32?b:c==111?b+1:c==79?b+1:c==48?b+1:0;}(*t[])(int)={L,B,R,L,B,D,A,B,R,L,B,V,B,R,D,B,A};main(j,v,k,l)char**v;{for(s=v[1];s[l++]!=10;);for(;k=i,s[i++];){for(j=17;j--;)if(!(t[j])(k-=j==13?l-3:j==8?l-5:j==5?2:j==2?l-4:1))break;b=j<0?putchar(b+47):1;}}

Try it online! (golfed) (expanded) (357 golfed) (357 expanded)

I wondered how bad a solution would be in a language without built-in pattern matching. It came out a lot smaller than I feared.

Basically, this approach breaks the gun down into a series of individual parts it expects to see in specific locations relative to a specific index. If all parts are found where they are expected, it's a gun! The bullet test increments a global counter to keep track of how many bullets were in it, which we print when we have found the one and only gun in the landscape.

Note 1: I padded the test cases with spaces to ensure consistent row widths.

Note 2: Add 10 bytes if you don't like the assign instead of return trick. For clarity, I used actual return statements in the expanded code.

jiv

Posted 2017-07-01T17:45:14.673

Reputation: 81

Three minor optimizations:

  • Use putchar with b's value directly instead of printf (3 bytes).
  • Use ternary operator instead of if statement to print bullet count (1 byte).
  • Roll bullet count initialization into print ternary (2 bytes).

The last one is a bit smelly since it means b is zero when testing the first index, but since no gun could be at index 0 anyway, I think it's a fair change. – jiv – 2017-07-03T16:42:14.317