26
\$\begingroup\$

Defenestration is the act of throwing someone or something out of a window.
Wikipedia

Input

The input will consist of two parts:

  • A floor plan and a person inside the house/building.

    • v><^ represents a person, pointing in the direction signified by the arrow. The input will contain exactly one person.

    • - and | represent walls, and # represents a window. is empty space.

    This portion of the input may be taken as either a single string, or an array/list/etc. of lines. There will never be any trailing or leading spaces, and the input will always be a rectangle.

    Example:

    -----###---
    |         |
    |     ^   |
    -----------
    
  • An integer ≥ 1 signifying how far (in characters) the person travels.

Output

The output should be

  • 1 if the person ends up "inside" a window (i.e. after moving forwards the distance specified in the input, the person is on top of a #).

  • 2 if the person has been defenestrated (come into contact with a # and then continued further on).

  • 3 if the person has hit a wall (come into contact with a - or |. Once hitting the wall, the person stops and does not continue through it).

  • 0 if none of the above are true (and all the person has done is travel through empty space).

Assumptions

All of the following can be assumed to be true:

  • The person will never travel "out of bounds" of the input area.

  • After being defenestrated, the person will never come into contact with another # or a -/| (so you don't have to worry about if 2 and 1 or 3 are both true).

Test cases

For the following "floor plan":

-----
|   |
|###|
|   |
| ^ |
In   Out
1    0
2    1
3    2

For this floor plan:

> | # |
In   Out
1    0
2-99 3    * that is, any input 2-99 outputs 3

For this floor plan:

||####|#|#|##|<
In   Out
any  3

Final test case:

|v|
|#|
| |
| |
| |
| |
In   Out
1    1
2-5  2  
\$\endgroup\$
8
  • 7
    \$\begingroup\$ I propose the title of this challenge be changed to Defenestration testing. \$\endgroup\$
    – cat
    Commented Dec 15, 2015 at 1:07
  • 1
    \$\begingroup\$ Follow-up question: This, except with pit's. \$\endgroup\$ Commented Dec 15, 2015 at 1:19
  • 2
    \$\begingroup\$ @CᴏɴᴏʀO'Bʀɪᴇɴ Has someone been for-sparta'd? \$\endgroup\$
    – cat
    Commented Dec 15, 2015 at 1:24
  • \$\begingroup\$ Why did my edit get rejected ): \$\endgroup\$
    – cat
    Commented Dec 15, 2015 at 1:24
  • \$\begingroup\$ @cat Because it's an edit on someone else's question, that they must have input on. \$\endgroup\$ Commented Dec 15, 2015 at 1:25

1 Answer 1

11
\$\begingroup\$

JavaScript (ES6), 147 146 bytes

(p,n)=>eval('l=p.search`\n`+1;m=p.match`[<>v^]`;for(r=d=i=0;i++<n&r<3;r-1?0:d=2)r=(c=p[m.index+i*({v:l,"<":-1,">":1}[m]||-l)])>"#"?3:c>" ";+r||d')

Saved 1 byte thanks to @NinjaBearMonkey!

Explanation

Takes a floorplan as a string and the number of moves. Returns a number.

(p,n)=>                               // p = floor plan as string, n = number of moves
  eval(`                              // use eval to enable for loop without {} or return
    l=p.search\`\n\`+1;               // l = line length
    m=p.match\`[<>v^]\`;              // m = the position and orientation of the person
    for(
      r=                              // r = result at the current step
        d=                            // d = 2 if the person has been defenestrated
          i=0;                        // i = current step
      i++<n&r<3;                      // for each step while the person has not hit a wall
      r-1?0:d=2                       // set d to 2 once the person enters the window
    )
      r=(                             // r = 0 if on " ", 1 if on "#" or 3 if on "|" or "-"
        c=p[m.index+i*                // c = character after current step
          ({v:l,"<":-1,">":1}[m]||-l) // get the index offset of each step
        ]
      )>"#"?3:c>" ";
    +r||d                             // return the result of the current step or d
  `)

Test

var solution = (p,n)=>eval('l=p.search`\n`+1;m=p.match`[<>v^]`;for(r=d=i=0;i++<n&r<3;r-1?0:d=2)r=(c=p[m.index+i*({v:l,"<":-1,">":1}[m]||-l)])>"#"?3:c>" ";+r||d')
<textarea id="floorplan" rows="6" cols="30">-----
|   |
|###|
|   |
| ^ |</textarea><br />
Moves = <input type="text" id="moves" value="3" />
<button onclick="result.textContent=solution(floorplan.value,moves.value)">Go</button>
<pre id="result"></pre>

\$\endgroup\$
5
  • 3
    \$\begingroup\$ I like your testing snippet! \$\endgroup\$
    – GamrCorps
    Commented Dec 15, 2015 at 2:33
  • \$\begingroup\$ ಠ_ಠ I was just about to post pretty much the exact same thing. \$\endgroup\$ Commented Dec 15, 2015 at 2:43
  • \$\begingroup\$ @CᴏɴᴏʀO'Bʀɪᴇɴ Haha, I know that feeling all too well... \$\endgroup\$
    – user81655
    Commented Dec 15, 2015 at 2:46
  • \$\begingroup\$ Nice answer, btw! Very smart. \$\endgroup\$ Commented Dec 15, 2015 at 2:47
  • \$\begingroup\$ You can save two bytes by making it a curried function and using a regular function - p=>n=>{l=p.search`\n`+1;m=p.match`[<>v^]`;for(r=d=i=0;i++<n&r<3;r-1?0:d=2)r=(c=p[m.index+i*({v:l,"<":-1,">":1}[m]||-l)])>"#"?3:c>" ";return+r||d} \$\endgroup\$
    – emanresu A
    Commented Feb 22, 2022 at 8:04

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.