9
\$\begingroup\$

This challenge is from a game, Keep Talking And Nobody Explodes.

This is like one of those toys you played with as a kid where you have to match the pattern that appears, except this one is a knockoff that was probably purchased at a dollar store. – From the manual

Objective

The Simon Says module consists of 4 colored buttons: Red, Blue, Green, and Yellow. Given a sequence of button flashes and a sequence of button presses, decide whether it would disarm the module.

In the original game, the module consists of multiple stages, but in this challenge, only one stage will be considered.

How To Disarm

  • The buttons will flash in a sequence. These buttons shall be mapped accordingly to the chart below, and shall be pressed.

  • You may press the wrong button in cost of a strike. Then the mapping will change. Only up to 2 strikes are tolerable because a 3rd strike will detonate the bomb.

  • You must not press buttons anymore after the module is disarmed.

The chart:

Strikes\Flash Red    Blue   Green  Yellow
0             Blue   Red    Yellow Green
1             Yellow Green  Blue   Red
2             Green  Red    Yellow Blue

(This chart is for a bomb whose serial number has a vowel. It is assumed for the purpose of this code-golf challange.)

I/O format

The input shall be two strings consisting of R, B, G, and Y, indicating the colors. Case sensitive.

Though in the game, a stage consists of up to 5 flashes, in this challenge, there may be an arbitrary nonzero number of flashes.

An input not fitting to this format falls in don't care situation.

The output format is flexible.

Examples

Let's say the button flash sequence is GRYBB. The followings are examples of button press sequences:

Truthy

  • YBGRR
  • RBYRGG (in cost of 1 strike)
  • YBGRBG (in cost of 1 strike)
  • YBGBGRR (in cost of 2 strikes)

Falsy

  • YBG (The module isn't disarmed yet)
  • RRR (The 3rd strike detonated the bomb)
  • YBGRRB (You cannot press buttons anymore after the module is disarmed)
  • RRRY (You cannot press buttons after the bomb detonates)
\$\endgroup\$
2
  • \$\begingroup\$ Can you assume the two strings are equal length? Also, can we use, say 0 1 2 3 instead of RBGY? \$\endgroup\$
    – Jonah
    Mar 26, 2023 at 16:32
  • 4
    \$\begingroup\$ @Jonah The examples already include strings of inequal length, so you probably shouldn't assume they are equal length. \$\endgroup\$ Mar 26, 2023 at 18:45

5 Answers 5

4
\$\begingroup\$

JavaScript (Node.js), 83 bytes

Expects (a)(b). Returns 0 or 1.

a=>b=>Buffer(a).every(g=c=>"BRGR_GYBY"[c%s%12]==b[i++]||s++%5&&g(c),s=63,i=0)&!b[i]

Try it online!

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

JavaScript (Node.js), 111 bytes

Didn't do any more testing beyond the sample test cases.

f=(a,b,c=0)=>[...b].every((x,i)=>a[c]&&(c+="BRYGYGBRGRYB"[(i-c)*4+"RBGY".indexOf(a[c])]==x,i-c<2))&&c==a.length

Try it online!

Explanation:

  • Init counter to 0
  • For each character in b, check if counter is less than length of a
  • Increment counter if the button is pressed correctly
  • Exit early if there are 3 strikes
  • Check whether the counter is equal to the length of a
\$\endgroup\$
2
\$\begingroup\$

05AB1E, 40 bytes

ε.•B¸}îÑu`öVÏ•u4ôćs¾ès‡IN¾-©èʽ®}ÔèQ¾3‹*

Inputs in the order button-press sequence, flash sequence, where the flash sequence is a list of characters (button-press sequence can be either a string or character-list, doesn't matter too much).

Try it online or verify all test cases.

Explanation:

ε        # Map over the characters of the first (implicit) button-press sequence input:
 .•B¸}îÑu`öVÏ•
         #  Push compressed string "rbgybrygygbrgryb"
   u     #  Uppercase it
    4ô   #  Split it into parts of size 4
 ć       #  Extract head; pop and push remainder-list and first item separately
  s      #  Swap so the remainder-list is at the top
   ¾è    #  Index the strikes-counter `¾` into it,
         #  which is 0 by default
     s   #  Swap so the extracted head "RBGY" is at the top again
      ‡  #  Transliterate the current character according to these two strings
 I       #  Push the second flash sequence input-list
  N      #  Push the current map-index
   ¾-    #  Subtract the strikes-counter `¾` from it
     ©   #  Store this index in variable `®` (without popping)
      è  #  Pop and index it into the flash sequence input
 Ê       #  Check whether the two characters are NOT equal
  ½      #  If they aren't equal: increase the strikes-counter `¾` by 1
 ®       #  Push index `®`
}Ô       # After the map: connected-uniquify the list of indices
  è      # Index each into the second (implicit) input-list
   Q     # Check if it's equal to the second (implicit) input-list
       * # AND
    ¾3‹  # The strike-counter is smaller than 3
         # (after which the result is output implicitly)

See this 05AB1E tip of mine (section How to compress strings not part of the dictionary?) to understand why .•B¸}îÑu`öVÏ• is "rbgybrygygbrgryb".

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

Retina 0.8.2, 97 bytes

T`RGYB`Ro`.+,
^(.+)(.*,)\1
$2
\b,.
,
T`BRGY`Ro`.+,
^(.+)(.*,)\1
$2
\b,.
,
T`Yo`GRBY`.+,
^(.*),\1$

Try it online! Link includes test cases. Explanation:

T`RGYB`Ro`.+,

Translate the flashes according to the first row of the chart. Ro here stands for the reverse of the other pattern; the R in that pattern is literal because it does not precede a range or special character.

^(.+)(.*,)\1
$2

Remove all correct button presses.

\b,.
,

Remove a strike, but only if there are still more buttons to press.

T`BRGY`Ro`.+,

Update the flashes so that they match the second row of the chart. Note that this means translating from the first row to the second row.

^(.+)(.*,)\1
$2
\b,.
,

Remove any further correct button presses and strike.

T`Yo`GRBY`.+,

Update the flashes so that they match the third row of the chart. Here o has no R so it just expands to YGRBY, where the final Y is ignored because it's a duplicate.

^(.*),\1$

Check that the exact correct button presses remain.

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

Charcoal, 54 bytes

≔±Lθζ≔⁰εFη¿ζ¿⁼⌕RBGY§θζ⌕§⪪”$⌊η²<↑ΣG≧”⁴ει≦⊕ζ≦⊕ε≔³ε∧¬ζ‹ε³

Try it online! Link is to verbose version of code. Explanation:

≔±Lθζ

Start at the first button flash, but use the negated length as this makes the win condition easier to test and cyclic indexing means that it doesn't matter.

≔⁰ε

Start with no strikes.

Fη

Loop over each button press.

¿ζ

If the bomb has not yet been disarmed, then:

¿⁼⌕RBGY§θζ⌕§⪪”$⌊η²<↑ΣG≧”⁴ει

If the current flash matches the current button press (according to the number of strikes), then...

≦⊕ζ

... increment the flash index, otherwise...

≦⊕ε

... increment the number of strikes.

≔³ε

Otherwise, set the number of strikes to 3.

∧¬ζ‹ε³

Check that the bomb was disarmed without needing three strikes.

\$\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.