23
\$\begingroup\$

Lighthouses on an island have blink codes that let ships know which lighthouse they are seeing. Input should be strings of S and L. Here is a (Python) example of codes for 4 lighthouses as a list of strings:

['SLS', 'SLL', 'SSS', 'LSL']

where:

S = short ON (1 sec)
L = long ON (3 sec)

Long and short ON's are both followed by 1 sec OFF, except the last in the code, which is followed by a 7-second LONG OFF pause to signify end of code. The code for the first lighthouse in the above example corresponds to this blink schedule in seconds :

1 ON, 1 OFF, 3 ON, 1 OFF, 1 ON, 7 OFF [repeat]

Challenge:

n Lighthouses come on simultaneously, each at the start of its schedule. Write a program that takes a series of blink codes (strings in the above format) and outputs the total number of seconds that exactly zero, one, two, three, ... n lighthouses were on at the same time after the first hour of lighthouse operation (So the output numbers will always total 3600.)

Test Cases:

Input -> Output
['SLS', 'SLL', 'SSS', 'LSL'] -> 1125, 890, 652, 590, 343  
['S', 'L', 'SS'] -> 2250, 630, 540, 180 
['SLSL', 'S'] -> 1850, 1450, 300  
['SLS'] -> 2314, 1286  
['SS', 'SS', 'L'] -> 2520, 360, 0, 720

Rules:

There can be one or more lighthouses (code strings).

All lighthouses come on simultaneously, each at the start of its code schedule.

Codes can be any length >= 1 and don't have to be unique (however off-shore mayhem may ensue).

Just for clarity, the 652 in the first example is the time in seconds that exactly 2 lighthouse (not 2 or more) were on.

The shortest code in bytes wins ().

\$\endgroup\$
12
  • 5
    \$\begingroup\$ @Makonede The user did post in the sandbox before, but unfortunately, no one pointed out these issues there. \$\endgroup\$
    – user
    Jul 12, 2021 at 18:37
  • 3
    \$\begingroup\$ @Djin Tonic I am sorry none of us mentioned these issues when you posted your draft in the Sandbox before, but 1. banning imports isn't a great idea. Not every language has them, it's unclear what you mean, and it's just unfair and doesn't add anything to the challenge. 2. We use bytes and include whitespace here. I would suggest modifying your question while there are no answers. \$\endgroup\$
    – user
    Jul 12, 2021 at 18:40
  • 2
    \$\begingroup\$ Welcome to Code Golf, by the way! \$\endgroup\$ Jul 12, 2021 at 18:47
  • 2
    \$\begingroup\$ Thanks for the suggestions. I've done some editing. Not sure how to specify the form the string inputs should take. \$\endgroup\$
    – DjinTonic
    Jul 12, 2021 at 18:49
  • 2
    \$\begingroup\$ @DjinTonic There are some default rules for input/output, so if you just specify something like "input should be a list of strings of S and L characters" any weird edge cases should be taken care of already \$\endgroup\$ Jul 12, 2021 at 18:54

8 Answers 8

5
\$\begingroup\$

Jelly,  24 22 21  20 bytes

O%9ÄṬ;Øỵ¬ṁ⁽½c)SċⱮLŻ$

A monadic Link that accepts the list of lists of S and/or L characters and yields the ascending list of multiplicity counts.

Try it online! Or see the test-suite.

How?

O%9ÄṬ;Øỵ¬ṁ⁽½c)SċⱮLŻ$ - Link: lighthouse patterns, P
             )       - for each pattern in P: say, 'SLSL'
O                    -   cast to ordnials     [83,76,83,76]
 %9                  -   modulo nine          [2,4,2,4]
   Ä                 -   cumulative sums      [2,6,8,12]
    Ṭ                -   untruth              [0,1,0,0,0,1,0,1,0,0,0,1]
     ;Øỵ             -   concatenate "aeiouy" [0,1,0,0,0,1,0,1,0,0,0,1,'a','e','i','o','u','y']
        ¬            -   logical NOT          [1,0,1,1,1,0,1,0,1,1,1,0,0,0,0,0,0,0]
                                              (the "full-pattern" of this lighthouse)
          ⁽½c        -   3600
         ṁ           -   (full-pattern) moulded-like (3600) -> above repeated to length 3600
              S      - sum (vectorises) -> counts at each second
                   $ - last two links as a monad, f(P):
                 L   -   length of P
                  Ż  -   zero-range -> [0..length(P)]
                Ɱ    - for each n in [0..length(P)]:
               ċ     -   count occurrences of n in the counts at each second
\$\endgroup\$
2
  • \$\begingroup\$ Really like the trick with Ṭ€ ... ¬--I got stuck on finding a good way of going from "SL" to [1, 3], then screwing around with joins from there... \$\endgroup\$ Jul 12, 2021 at 22:35
  • 1
    \$\begingroup\$ Thanks, I did start the same way (for the [1,3] I had OḤọ2) \$\endgroup\$ Jul 12, 2021 at 22:44
3
\$\begingroup\$

05AB1E, 25 bytes

ε€C9%Å10.ý˜7Å0«60n∍}øOZÝ¢

Try it online!

ε                  }        # for each lighthouse in the implicit input:
 €C                         #   convert each character from binary
   9%                       #   modulo 9: S -> 28 %9 = 1, L -> 21%9 = 3
     Å1                     #   for each number in the resulting list get a list of that many 1's
       0.ý                  #   intersperse with 0's 
          ˜                 #   flatten into a list of 1's and 0's
           7Å0«             #   append 7 0's
               60n∍         #   extend the list to length 60^2=3600 by cycling the values
                    ø       # after the loop: transpose the list of lists
                     O      # sum every one of the 3600 sublists
                      ZÝ    # get the range [0 .. max(a)]
                        ¢   # for each value in the range, count occurences in the long list

Try the S/L to 0/1 conversion with step-by-step output: Try it online!

\$\endgroup\$
1
  • \$\begingroup\$ 0.ý˜7Å0« to J0ý7°*S for -1 (or alternatively: 9%Å10.ý˜7Å0« to 13%<b0ý7°*S for -1). \$\endgroup\$ Aug 23, 2021 at 10:16
2
\$\begingroup\$

J, 60 53 52 bytes

_1+(0,#\)#/.~@,[:+/(3600$(6$0),~&;19<@#:@|14+3&u:)&>

Try it online!

-7 after reading Jonathan Allen's idea of doing arithmetic on the character codes, though I use a different method which converts S to 2 and L to 14, and then converts those to binary.

idea

  • For each pattern, convert it into a bitmask where 1 is on, 0 is off
  • Extend that bitmask cyclically to 3600. Now we have an n x 3600 matrix.
  • Sum columns. Now we have the numbers 0-n, each some number of times.
  • Prepend the numbers 0-n to that list, in case any happen to be missing, and so the result will be ordered from 0 to n.
  • Group and count.
  • Subtract 1 from each count.
\$\endgroup\$
2
\$\begingroup\$

JavaScript (ES6), 113 bytes

Expects an array of strings. Returns an object.

a=>(n=3600,g=L=>n--?g(o[a.map(s=>t+=~~(s=s.replace(/./g,c=>c>g?10:1110))[n%(s.length+6)],t=0),t]=-~o[t]):o)(o={})

Try it online!

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

Python 2, 125 117 bytes

lambda a:map(map(sum,zip(*[sum([2*(c<'S')*[1]+[1,0]for c in C],[0]*6)*500for C in a]))[6:3606].count,range(len(a)+1))

-8 thanks to Jonathan Allan.

\$\endgroup\$
4
  • \$\begingroup\$ m90, could you please show me the code needed to print out any of the test cases? Thanks \$\endgroup\$
    – DjinTonic
    Jul 12, 2021 at 23:55
  • \$\begingroup\$ @DjinTonic lambda produces a function, so you can call it directly by writing (lambda [etc.])(['SLSL', 'S']), or you can save it in a variable by writing f=lambda [etc.] and then call it as f(['SLSL', 'S']). \$\endgroup\$
    – m90
    Jul 13, 2021 at 5:23
  • \$\begingroup\$ Ah, Python 2. If only I could read! Thanks. \$\endgroup\$
    – DjinTonic
    Jul 13, 2021 at 7:50
  • \$\begingroup\$ One more use of map saves 8 bytes - Try it online! \$\endgroup\$ Jul 13, 2021 at 17:29
1
\$\begingroup\$

Python 3, 154 bytes

Very trivial approach: convert the code strings into sequences of 1s and 0s representing the seconds in which each lighthouse is ON or OFF; then cumulate the sum of seconds depending on how many lighthouses are on at the same time.

def f(h):
 t=[0]*(len(h)+1)
 for i in range(3600):t[[c[i]for c in[(x.replace('S','10').replace('L','1110')+'0'*6)*450for x in h]].count('1')]+=1
 print(t)

Try it online!


Un-golfed function with comments

def f(lighthouses):
    """
    function that takes as input the list of lighthouses' blink codes
    """

    # replace in the codes 'S' and 'L' with '1's
    # corresponding to the effective ON duration in seconds
    # '0' is needed for the OFF separation period
    lighthouses = [x.replace('S', '10') for x in lighthouses]
    lighthouses = [x.replace('L', '1110') for x in lighthouses]

    # LONG OFF period
    # only 6s because one '0' is already added on the last character
    lighthouses = [x + '0'*6 for x in lighthouses]

    # repeat the sequence for at least 1h
    # minimum code duration 'S' = 8s
    # 3600/8=450 then repeat 450 times to be sure to have at least 1h
    lighthouses = [x * 450 for x in lighthouses]

    # initialize the list to keep the total number of seconds
    tot = [0] * (len(lighthouses) + 1)
    
    # loop over 1h of repeated sequences
    for i in range(3600):
    
        # increase the counter
        # the index corresponds to how many lighthouses are ON at the same time
        # counting how many '1's there are at a given position in all the sequences
        tot[[c[i] for c in lighthouses].count('1')] += 1
    
    # outputs the list with total seconds
    print(tot)
\$\endgroup\$
0
1
\$\begingroup\$

R, 119 116 bytes

Edit: -3 bytes thanks to Giuseppe

function(a)table(c(rowSums(sapply(a,function(x)!1:3600%in%cumsum(rep(c(utf8ToInt(x)%%9,!!1:6),999)))),0:sum(a>0)))-1

Try it online!

\$\endgroup\$
2
  • 1
    \$\begingroup\$ !!1:6 instead of rep(1,6). \$\endgroup\$
    – Giuseppe
    Jul 14, 2021 at 17:24
  • \$\begingroup\$ @Giuseppe - Thanks! \$\endgroup\$ Jul 14, 2021 at 21:11
0
\$\begingroup\$

Charcoal, 32 bytes

IE⊕Lθ№E³⁶⁰⁰Σ⭆θ§⁺⪫Eν×1∨⁼πS³0×0⁷λι

Try it online! Link is to verbose version of code. Explanation: For each number of "on" lighthouses and each second of the hour, calculate the "on" pattern for each lighthouse and count how many of the seconds had that number of lighthouses "on".

    θ                               Input array
   L                                Length
  ⊕                                 Incremented
 E                                  Map over implicit range
       ³⁶⁰⁰                         Literal `3600` (seconds)
      E                             Map over implicit range
             θ                      Input array
            ⭆                       Map over elements and join
                  ν                 Current blink code
                 E                  Map over characters
                    1               Literal string `1`
                   ×                Repeated by
                       π            Current character
                      ⁼             Equals
                        S           Literal string `S`
                     ∨              Logical Or
                         ³          Literal `3`
                ⪫                   Join with
                          0         Literal string `0`
               ⁺                    Concatenated with
                            0       Literal string `0`
                           ×        Repeated by
                             ⁷      Literal `7`
              §                     Indexed by
                              λ     Current second
           Σ                        Sum i.e. count of "on" lighthouses
     №                              Count of
                               ι    Outer index
I                                   Cast to string
                                    Implicitly print
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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