9
\$\begingroup\$

In a secret lab corridor, there are emitters and gates: A number represents a laser emitter with a certain frequency, a 0 represents an inactive gate. If two emitters of the same frequency face each other with only inactive gates (0) in between, their beams meet and activate the entire stretch of gates in between. But if any other emitter is in the way, the beam is blocked.

Your task

Write a program that simulates the beam activation.

Input

A list/array of nonnegative integers.

Output

The transformed list/array, with activated gates.

Winning Criteria

The shortest correct program (measured in bytes) wins. In the event of a tie, the earliest posted answer wins.

Sample data

Example 1 (Simple case)

[0,2,0,0,2]         
→ [0,2,2,2,2]

Example 2 (Gate between emitters)

[0,2,0,1,0,2]       
→ [0,2,0,1,0,2]

Example 3 (A more complex example)

[0,2,0,2,5,0,0,5,1] 
→ [0,2,2,2,5,5,5,5,1]

Example 4 (Consecutive emitters)

[3,0,0,3,0,3]       
→ [3,3,3,3,3,3]
\$\endgroup\$
0

10 Answers 10

4
\$\begingroup\$

Retina 0.8.2, 22 bytes

(?<=(.)0*)0(?=0*\1)
$1

Try it online! Link includes test cases. Uses strings of different printable Unicode characters to represent the emitters, except 0 represents an inactive gate, for ease of converting the test cases. Explanation: Uses lookarounds to find matching emitters surrounding inactive gates and replaces the latter with the former.

\$\endgroup\$
4
\$\begingroup\$

Jelly, 11 bytes

o@\
UÇU=Ç×Ç

Attempt This Online!

We left scan the array with the reversed logical OR function, causing all zeros to be replaced with the previous non-zero element:

[0,2,0,1,0,2,0,0,2,0]
[0,2,2,1,1,2,2,2,2,2]

Next we do the same thing, but in reverse:

[0,2,0,1,0,2,0,0,2,0]
[2,2,1,1,2,2,2,2,2,0]

Out of the two resulting arrays, we take equal elements and set all other elements to 0:

[0,2,2,1,1,2,2,2,2,2]
[2,2,1,1,2,2,2,2,2,0]
[0,2,0,1,0,2,2,2,2,0]

I haven’t used Jelly in a really long time, so there is probably a shorter way to express this algorithm.

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

JavaScript (ES6), 48 bytes

a=>a.map(p=(v,i)=>v|a.find(v=>i--*v<0)!=p?p=v:p)

Try it online!

Commented

a =>            // a[] = input array
a.map(p =       // start with p non-numeric
(v, i) =>       // for each value v at index i in a[]:
  v |           //   if v is not zero
  a.find(v =>   //   or the first non-zero value in a[]
    i-- * v < 0 //   at an index higher than i (1)
  ) != p ?      //   is not equal to p (2):
    p = v       //     set p to v
  :             //   else:
    p           //     use the current value of p
)               // end of map()

(1) The expression i-- * v < 0 is true if and only if i is negative and v is non-zero.
(2) If there's no such non-zero value at all, find() returns undefined, which cannot be equal to p.

\$\endgroup\$
2
\$\begingroup\$

05AB1E, 25 bytes

®.øγü3εÅsy˜ÔÀ`©Qs_*i0®:]˜

Try it online or verify all test cases.

Explanation:

®.ø           # Surround the (implicit) input-list with leading/trailing -1
   γ          # Adjacent-group all the same values together
    ü3        # Split it into overlapping triplets
ε             # Map over each triplet:
 Ås           #  Keep the middle list of the current triplet
 y            #  Push the triplet of three lists again
  ˜           #  Flatten it to a single list
   Ô          #  Connected-uniquify it to a triplet of integers [a,b,c]
    À         #  Rotate once towards the left: [b,c,a]
     `        #  Pop and push all its values to the stack
      ©       #  Store the top value in variable `®` (without popping)
       Q      #  Pop the top two and check if they're the same: c==a
      s       #  Swap so the third value is at the top
       _      #  Check that it's 0: b==0
        *i    #  If both are truthy:
          0®: #   Replace all 0s with value `®` in the middle list
]             # Close both the if-statement and map
 ˜            # Flatten the list of lists
              # (after which the result is output implicitly)
\$\endgroup\$
2
\$\begingroup\$

Python3, 135 bytes

def f(s):
 for i in range(len(s)):
  for I in range(i+1,len(s)):s[i:I]=[s[i:I],[s[i]]*(I-i)][s[i]==s[I]and not any(s[i+1:I])]
 return s

Try it online!

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

Python 3, 99 94 bytes

f=lambda a,v=0:[v:=x or v for x in a]
lambda a:[x*(x==y)for x,y in zip(f(a),f(a[::-1])[::-1])]

Attempt This Online!

Uses the same approach as my Jelly answer.

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

Google Sheets, 132 bytes

=let(d,A:A,r,lambda(a,sort(a,sequence(rows(a)),)),f,lambda(a,scan(0,a,lambda(a,n,if(n,n,+r(a))))),index(if(f(d)=r(f(r(d))),f(d),d)))

Uses Adamátor's method.

screenshot

Ungolfed:

=let(
  d, A1:A,
  reverse_, lambda(a, sort(a, sequence(rows(a)),)),
  fill_, lambda(a, scan(0, a, lambda(a, n, 
    if(n, n, single(reverse_(a)))
  ))),
  arrayformula(if(fill_(d) = reverse_(fill_(reverse_(d))), fill_(d), d))
)
\$\endgroup\$
1
\$\begingroup\$

Charcoal, 25 bytes

IEEθ↨Φ…θ⊕κλ⁰∧¬⌕Φ✂θκLθ¹λιι

Try it online! Link is to verbose version of code. Explanation: The inner Map performs a cumulative Or reduction on the array, while the outer map checks that each resulting value is the first non-zero value in the rest of the original array (which is equivalent to comparing against a reverse cumulative Or reduction), replacing invalid values with zero.

   θ                        Input array
  E                         Map over values
       θ                    Input array
      …                     Truncated to length
         κ                  Current index
        ⊕                   Incremented
     Φ                      Filtered on
          λ                 Non-zero values
    ↨      ⁰                Interpret as base `0` (take last element or `0` if none)
 E                          Map over values
              ⌕             Index of
                       ι    Current value in
                 θ          Input array
                ✂    ¹      Sliced from
                  κ         Current index to
                    θ       Input array
                   L        Length
               Φ            Filtered on
                      λ     Non-zero values
             ¬              Is zero
            ∧               Logical And
                        ι   Current value
I                           Cast to string
                            Implicitly print each value on its own line
\$\endgroup\$
0
\$\begingroup\$

Janet, 88 bytes

|(let[f|(accumulate|(case $1 0 $ $1)0 $)r reverse](map|(case $ $1 $ 0)(f $)(r(f(r $)))))

Uses the same approach as my Jelly answer.

\$\endgroup\$
0
\$\begingroup\$

Nibbles, 8.5 bytes

!`\$|\`\\@|~*==$_

Attempt This Online!

Uses the same approach as my Jelly answer.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.