20
\$\begingroup\$

The 80's TV series Knight Rider featured an intelligent, self-aware car called KITT. One distinctive aspect of the car was a front-mounted scanner bar that allowed KITT to "see" (and that looked suspiciously familiar to fans of another, earlier TV series).

The scanner had eight lights as seen in this picture:

enter image description here

The lights "moved" as shown in this animated image.

Your task, as you have guessed by now, it to recreate the scanner bar with the moving lights in ASCII art.

The challenge

Given an integer t, output the state of the scanner bar at that instant, defined as follows:

  • The scanner consists of eight lights.
  • At any instant one of the lights is active, and is shown as #. The lights that were active at times t-1 and t-2 are now dimmed, and are shown as +; unless they coincide with the current active one. The rest of the lights are off, and are shown as -.
  • The active light moves left to right, then right to left.

The exact output for each t is detailed below.

0  -->  #++-----   % The leftmost light is active, and it just came from the right.
                   % The two neighbouring lights are dimmed
1  -->  +#------   % The active light has bounced to the right, and it is covering
                   % one of the two lights that should be dimmed. So there is only
                   % one dimmed light
2  -->  ++#-----   % The active light has moved one more step to the right, and the
                   % two trailing dimmed lights are visible
3  -->  -++#----
7  -->  -----++#
8  -->  ------#+   % The active light has bounced to the left
9  -->  -----#++
10 -->  ----#++-
13 -->  -#++----
14 -->  #++-----   % Same as 0
15 -->  +#------   % Same as 1

For negative values of t the cycle is simply extended:

-1 -->  -#++----   % Same as 13
-2 -->  --#++---   % Same as 12

#Additional rules

You can write a program or function.

Output can contain trailing whitespace and a leading newline.

Shortest code in bytes wins.

\$\endgroup\$
1

13 Answers 13

6
\$\begingroup\$

JavaScript (ES6), 65 67 bytes

EDIT - Fixed for negative values. Now supporting N >= -8,000,000,000, which should provide a fairly good extended operating time in AUTO CRUISE mode. :-)

let f =

n=>[..."------#++-----".substr((n+=8e9)%7,8)].sort(_=>n/7&1).join``

// testing 28 frames
for(var i = -14; i < 14; i++) {
  console.log(f(i));
}

Animated version

let f =

n=>[..."------#++-----".substr((n+=8e9)%7,8)].sort(_=>n/7&1).join``

let n = 0;

setInterval(function() { document.getElementById("o").innerHTML = f(n++) }, 90);
<pre id="o"></pre>

\$\endgroup\$
2
  • \$\begingroup\$ You can save 1 byte with n>=7 instead of n/7&1 \$\endgroup\$
    – Hedi
    Oct 8, 2016 at 11:23
  • \$\begingroup\$ @Hedi - That would work if n was in [0 ... 13], but it's not. \$\endgroup\$
    – Arnauld
    Oct 8, 2016 at 13:43
4
\$\begingroup\$

Jelly, 28 22 bytes

-6 bytes thanks to the help of @Dennis! (upend first, then concatenate)

”-ẋ6;“#++”ṙ7Ḷ’¤Ḋ€U;$⁸ị

TryItOnline
Or perform four oscillations with a bonus easter egg!!

How?

”-ẋ6;“#++”ṙ7Ḷ’¤Ḋ€U;$⁸ị - Main link: n
”-   “#++”             - strings "-" and "#++"
  ẋ6                   - repeat six times: "------"
    ;                  - concatenate: "------#++"
              ¤        - nilad followed by atoms as a nilad (ie make a constant)
           7Ḷ’         -     range(7) decremented: [-1,0,1,2,3,4,5]
          ṙ            - rotate left by (makes)-----------> ["+------#+",
               Ḋ€      - Dequeue each                        "------#++",
                   $   - last two atoms as a monad           "-----#++-",
                 U     -     reverse (vectorises)            "----#++--",
                  ;    -     concatenate                     "---#++---",
                    ⁸  - left argument (n)                   "--#++----",
                     ị - index into (1 based and modular)    "-#++-----"])
\$\endgroup\$
4
\$\begingroup\$

JavaScript (ES6), 90 87 bytes

n=>"01234567".replace(/./g,i=>"-+##"[g=n=>!((+i+n)%14&&(n-i)%14),g(n)*2|g(n-1)|g(n-2)])

"-+##" is indexed by a bitmask, where bit 1 signifies an active light and bit 0 signifies a dimmed light. Active/dimmedness is now calculated by adding and subtracting the current position from the desired position and seeing if either result is divisible by 14.

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

Python, 53 bytes

lambda n:('-'*5+'++#'+'-'*6)[-n%7:][:8][::-n/7%2*2-1]

Creates the string -----++#------, takes a length-8 window depending on the input modulo 7, reverses for inputs modulo 14 that lie between 1 and 7 .

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

><>, 51+3 = 54 bytes

<v{"------#++"%7&(7%*27:-1
}>:?!\1-$
{~&?r\~
l?!;o>

Input is expected on the stack at program start, so +3 bytes for the -v flag.

Try it online!

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

MATL, 34 30 27 bytes

'++#-'I:7XyY+4LZ)t2&P&viY))

7 bytes saved thanks to @Luis

Try it Online!

Another example with the first 25 steps

Explanation

'++#-'      % Push the string literal to the stack
I:          % Create the array [1 2 3]
7Xy         % Create a 7 x 7 identity matrix
Y+          % Perform 2D convolution between the vector and this matrix
4LZ)        % Grab all but the first column. Yields the following matrix
            %
            %    2 3 0 0 0 0 0 0
            %    1 2 3 0 0 0 0 0
            %    0 1 2 3 0 0 0 0
            %    0 0 1 2 3 0 0 0
            %    0 0 0 1 2 3 0 0
            %    0 0 0 0 1 2 3 0
            %    0 0 0 0 0 1 2 3
            %
t2&P&v      % Copy this matrix, flip it horizontally and vertically concatenate
            % it with itself. 
i           % Explicitly grab the input (n)
Y)          % Get the n-th row of the above matrix (and use modular indexing)
)           % Index into the initial string literal to replace 2 with #, 1 and 3 with + 
            % and all 0's with -
            % Implicitly display the result
\$\endgroup\$
0
2
\$\begingroup\$

Pyth, 33 28 bytes

Saved 5 bytes by calculating all the lights the same way.

X:*8\-@LJ+U7_S7,-Q2tQ\+@JQ\#

Starts with the lights all off and turns them on one at a time.

Try it out online!

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

JavaScript, 204 bytes

function g(i){var a=(i%16+16)%16
if(!a)return g(2)
if(1==a%14)return(g(2)+'-').substr(1)
if((1<a)&&(a<8))return Array(a-1).join('-')+'++#'+Array(8-a).join('-')
return g(a-7).split("").reverse().join("")}

Test

function g(i){var a=(i%16+16)%16
if(!a)return g(2)
if(1==a%14)return(g(2)+'-').substr(1)
if((1<a)&&(a<8))return Array(a-1).join('-')+'++#'+Array(8-a).join('-')
return g(a-7).split("").reverse().join("")}

for (var i = 0; i < 16; ++i) {
    console.log(i + '-->' + g(i));
}

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

JavaScript (ES6), 72

t=>`------${(t=(13+t%14)%14)>6?'#++':'++#'}------`.substr(t>6?t%7:7-t,8)

Less golfed

t=>(
  pad = '------',
  t = (13+(t%14))%14,
  u = t % 7,
  t > 6 ? (pad + '#++' + pad).substr(u, 8)
        : (pad + '++#' + pad).substr(7 - u, 8)
)

Test

f=
t=>`------${(t=(13+t%14)%14)>6?'#++':'++#'}------`.substr(t>6?t%7:7-t,8)

T=_=>(
  O.textContent=f(++N.textContent),
  setTimeout(T, 150)
)

T()
<input id=I type=number value=0 oninput='N.textContent=this.value'>
<pre id=N>-100</pre>
<pre id=O></pre>

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

Vim, 95 bytes

D7i-<esc>7a_<esc>@=(<C-r>"%14+13)%14+1
|r#8|i
<esc>:v/#/d
:s/.#/+#
f#i+<esc>:s/\v^(_*)(\+*)#(_*)$/\3#\2\1
:s/_/-/g

Try it online!

Explanation

There might be a better way to do this...

D

Delete the input number into the " register.

7i-<esc>7a_<esc>

Insert the string -------_______.

@=...
|

Go to the character with the 1-based index given by this expression...

<C-r>"%14

The previously deleted number, mod 14. Unfortunately, Vim's mod operator gives negative results if the left-hand side was negative, so we have to correct for that...

(...+13)%14+1

... by adding 14 and taking the result mod 14. But at the same time, we can subtract 1, mod 14, and add 1 to give the 1-based mod (same as the regular mod, except it gives 14 instead of 0).

r#

Replace the character at that index (- or _) with #.

8|i
<esc>

Go to index 8 and insert a newline, putting the -s and the _s each on their own line.

:v/#/d

Whichever line doesn't contain the #, delete it.

:s/.#/+#

If there's a character before the #, replace it with +.

f#i+<esc>

Go to the # and insert another + before it.

:s/\v^(_*)(\+*)#(_*)$/\3#\2\1

If the line has _ instead of -, reverse it.

:s/_/-/g

Replace _ with -.

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

Perl, 65 bytes

Includes +1 for -n

Run with the number on STDIN:

for i in 0 `seq 14`; do perl -M5.010 kitt.pl <<< $i; done

kitt.pl:

#!/usr/bin/perl -n
$_="311e".--$_%14+4e16|0;s/.(.{8})/$&|reverse/e;y/013/-+#/;say//

Not very competitive but deserves a post for the strange method

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

Perl, 56 55 bytes

Includes +3 for -p

Run with the number on STDIN:

for i in 0 `seq 14`; do kitt.pl <<< $i; echo; done

kitt.pl:

#!/usr/bin/perl -p
$_=eval'1x8
|1x(7-abs$_--%14-7).++$^F#'x3;y;1537;-+#

Put this in a file without the final newline (add a final ; to the program if you don't want to bother with that). Unfortunately using a literal ^F doesn't work

This program contains 2 comment characters (ignore the #! line). One of them really is a comment and actually gains a byte....

Implements the actual afterglow algorithm

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

Canvas, 23 bytes

±7%╵-8×#++1╋8m⁸╷³╵%7<?↔

Try it here!

\$\endgroup\$

Your Answer

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

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