# Busy Letters & Evil CEOs

Imagine you are given an array/string containing $$\5\$$ letters of the English alphabet, with each letter having any value from A to Z (inclusive).

Every day, each letter will perform a job, which can affect itself or other letters in the array. The letter's job is determined by the letter itself.

Most letters are, due to unemployment rates, jobless. However, a key few still have unique tasks they can perform each day:

• $$\A\$$: Yells at the letter to its right, forcing that letter to change to the next letter in the alphabet. If there is no letter to its right, does nothing.
• $$\Z\$$: Yells at the letter to its left, forcing that letter to change to the previous letter in the alphabet. If there is no letter to its left, does nothing.
• $$\L\$$: This one's pushy. It rotates the array by 1 element to the left, wrapping around so the first element becomes the last.

The final letter is $$\X\$$, The CEO. If it shows up at any point, that means everyone is in trouble. However, if $$\X\$$ does not show up within 30 days (30th day included), that means everything is alright and the busy letters are safe.

A single day concludes once every letter has finished doing its job. A configuration like AJLF will evolve like this over the course of 3 days:

AJLF    at start of Day 1
KLFA    at start of Day 2
LFAL    at start of Day 3
FAML    at start of Day 4


A couple of important things to remember:

• Any letter that is not part of those mentioned earlier does nothing.

• The letters themselves overflow. If a letter increases past Z, it becomes A. Similarly, decreasing past A will turn the letter to Z.

• Letters on the left do their job first. For example, if you have A Z, after a day the result is A A since the Z gets yelled at before it does its job. Another example is that A K will be L A at the start of the next day, as the K turns into an L and then does its job.

• A letter that wraps around due to $$\L\$$ will not do anything until the day is over, but the letter may still be changed.

• $$\X\$$ can appear even in the middle of the day, so a configuration like AWZ is not safe.

Your job is, given an array containing an arbitrary configuration of $$\5\$$ letters, find out if the letters are safe (that is, $$\X\$$ does not show up before 30 days pass). This initial configuration corresponds to the start of day $$\1\$$.

# Input

An array containing $$\5\$$ valid letters. You may assume $$\X\$$ will never be part of this initial array. If it makes things easier, you are allowed to treat the letters as case insensitive, and you may use any representation for those letters you want, as long as it is consistent and it does not affect your results.

# Output

Whether or not the busy letters are safe after 30 days. If they are, output true (or any equivalent value that indicates it). If they are not safe, output the day at which $$\X\$$ appeared.

## Rules

This is , so shortest number of bytes wins.

## Test Cases

Input     Safe?
------------------
RABOA     No: Day 15
HAWPE     No: Day 1
ZHLFF     Safe
EALZJ     Safe
KWLFZ     No: Day 30
AZVLB     No: Day 2
LLLEA     No: Day 12

• are we allowed to take input as an array of numbers (ie. A is 1, B is 2, etc.)? Jan 29 at 20:26
• yep. edited the post Jan 29 at 20:29
• Is the input 5 characters long or 10? Jan 29 at 20:31
• Five - good catch. It was originally 10 but it felt excessive Jan 29 at 20:33
• Can we output a negative number instead of true? Jan 29 at 20:57

# Perl 5-pa, 148 bytes

for$;(1..30){map{$_&&$F[$_]==26?--$F[$_-1]:$_<4&&$F[$_]==1?++$F[$_+1]:$F[$_]-12||push@F,shift@F;$\||=$;if grep/24/,@F}0..4;@F=map$_%26,@F[-5..-1]}}{


Try it online!

Input as integers (A=1, B=2, etc.). Output is the day of the CEO's arrival or Perl's undef which appears as blank.

# Python 3, 156 bytes

An incredible 13-bytes reduction by @JonathanAllan:

def g(x):
for m in range(150):
if 23in x:return m//5+1
K=m%5and K;i=m%5-K;c=x[i];j=c==11;x=x[j:]+x[:j];K+=j;C=(c<1<4>i)-(c>24>0<i);x[C+i]=(x[C+i]+C)%26


Try it online!

A function that receives a list of integers $$\0 \leq n \lt 26\$$ of length 5, representing the letters from the alphabet. It returns None if the CEO does not appears, otherwise it returns the day it appeared.

This version removes nearly all if-statements from the previous implementation by taking advantage of the short-circuiting behavior of and and the relationship between bools and ints. It also uses some dark magic regarding chained comparisons when calculating C.

Using if-statements inside a loop (or any indentation block) is expensive, since it requires a new-line and therefore including more indentation to match the outer block.

# Python 3, 169 bytes (original version)

def g(x):
for m in range(150):
if m%5<1:K=0
if 23in x:return m//5+1
i=m%5-K;c=x[i]
if c==11:x=x[1:]+x[:1];K+=1
C=(c<1)*(i<4)-(c>24)*(i>0);x[i+C]=(x[i+C]+C)%26


Try it online!

How does it work?

The loop iterates $$\150\$$ times: $$\30\$$ days $$\\times\$$ $$\5\$$ letters.

Variable K contains the number of rotations happened in the current day, according to

A letter that wraps around due to $$\L\$$ will not do anything until the day is over, but the letter may still be changed.

The condition if m%5<1:K=0 implements the "until the day is over" part.

We then check whether X is present in the array. If it is, m//5 + 1 is returned. Since $$\0 \leq m \lt 150\$$, then $$\0 \leq m/5 \lt 30\$$, the current day (where the CEO appeared).

Variable i stores the index of the current letter (0-4) and variable c stores the current letter. Since whenever a rotation occurs, the current letter should be shifted back, a subtraction by K is made.

The condition if c==11: checks if the current letter is L. If it is, it rotates the array (x=x[1:]+x[:1]) and increments K.

The next line is a bit more complex. It evaluates two conditions: i) whether the current letter is A (c<1) and it's not the last letter (i<4); and ii) whether the current letter is Z (c>24) and it's not the first letter (i>0). Then, a subtraction is evaluated between i) and ii):

• If i) is true (1) and ii) is false (0), C will be +1, implementing "Yells at the letter to its right, forcing that letter to change to the next letter in the alphabet"
• If i) is false (0) and ii) is true (1), C will be -1, implementing "Yells at the letter to its left, forcing that letter to change to the previous letter in the alphabet"
• Otherwise, if i) and ii) are equal, C will be 0, implementing "Any letter that is not part of those mentioned earlier does nothing"

The next statement changes the previous or the next element on the array (i+C) and forces it to the previous or the next letter on the alphabet, handling the overflow ((x[...]+C)%26).

• A few golfs gives 156. Jan 31 at 13:31
• @JonathanAllan This is the most creative golfing I've ever seen, thanks!
– enzo
Jan 31 at 14:07
• A note about the "dark magic" - a concatenation of (in)equality checks like c<1<4>i evaluates as c<1 and 1<4 and 4>i. Jan 31 at 18:55
• A bit more for 152 (now gives False rather than None) Jan 31 at 18:57

# Charcoal, 93 bytes

ＦＳ⊞υ⌕αιＦ³⁰«≔⁰θＦＬυ«≔§υκη§≔υ⊕κ⁺§υ⊕κ∧¬η‹⊕κ⁺Ｌυθ≧⁺⁼η¹¹θ§≔υ⊖κ⁻§υ⊖κ∧⁼η²⁵›κ⁰≧﹪²⁶υ¿∧¬ⅈ№υ²³Ｉ⊕ι»ＵＭυ§υ⁺λθ


Try it online! Link is to verbose version of code. Outputs nothing if the input is safe. Explanation:

ＦＳ⊞υ⌕αι


Convert the input from a string of letters to a list of integers.

Ｆ³⁰«


Check for 30 days.

≔⁰θ


Start with no Ls on any given day.

ＦＬυ«≔§υκη


Loop through the letters and their original indices.

§≔υ⊕κ⁺§υ⊕κ∧¬η‹⊕κ⁺Ｌυθ


Increment the next letter if this letter is an A and it is not currently the rightmost letter.

≧⁺⁼η¹¹θ


Keep track of any Ls.

§≔υ⊖κ⁻§υ⊖κ∧⁼η²⁵›κ⁰


Increment the previous letter if this letter is a Z and is not the leftmost letter.

≧﹪²⁶υ


Overflow any increments from Z to A or decrements from A to Z.

¿∧¬ⅈ№υ²³Ｉ⊕ι


If this is the first appearance of X then output the day number.

»ＵＭυ§υ⁺λθ


Actually rotate the letters as necessary.

# Funge-98, 200 bytes

"HTRF"4("RBUS"4(4k&'v00pfa*10p020p
>10g:[email protected]_1-10p4L20g10g5%!3jJ21_20g1-20p
^:0w4L10g5%!!+'%:051C$4L4L4L4L ^ [:'\ w4L4L4L4L410g5%-'%:051C$4L
^#_^#!-b:<>j#'p02+1g02p01+1g01
'-3jR11_'10g5/-.@


Try it online!

Takes input as a list of 5 integers between 0 and 25. Outputs 0 if the letters are safe, and a number between 1 and 30 if they are not.

Contains non-printable characters, so here is a hex dump:

00000000: 2248 5452 4622 3428 2252 4255 5322 3428  "HTRF"4("RBUS"4(
00000010: 346b 2627 7630 3070 6661 2a31 3070 3032  4k&'v00pfa*10p02
00000020: 3070 0a3e 3130 673a 2133 6a40 2e30 5f31  0p.>10g:[email protected]_1
00000030: 2d31 3070 344c 3230 6731 3067 3525 6021  -10p4L20g10g5%!
00000040: 336a 4a32 315f 3230 6731 2d32 3070 0a5e  3jJ21_20g1-20p.^
00000050: 3a30 7734 4c31 3067 3525 2121 2b27 1a25  :0w4L10g5%!!+'.%
00000060: 3a30 3531 4324 344c 344c 344c 344c 0a5e  :051C$4L4L4L4L.^ 00000070: 2020 5b3a 2719 5c20 7734 4c34 4c34 4c34 [:'.\ w4L4L4L4 00000080: 4c34 3130 6735 2560 2d27 1a25 3a30 3531 L410g5%-'.%:051 00000090: 4324 344c 0a5e 235f 5e23 212d 623a 3c3e C$4L.^#_^#!-b:<>
000000a0: 6a23 1327 7030 322b 3167 3032 7030 312b  j#.'p02+1g02p01+
000000b0: 3167 3031 0a27 172d 336a 5231 315f 271e  1g01.'.-3jR11_'.
000000c0: 3130 6735 2f2d 2e40                      10g5/-.@

• Just curious: What does "HTRF" do? Jan 31 at 16:19
• @Fmbalbuena: "HTRF"4( includes the "FRTH" fingerprint, which gives the program access to some useful stack manipulation commands. Feb 1 at 1:42