# Invert Some Switches on a Switchboard

Inspired by this challenge.

## Goal:

Given a pre-configured switchboard and a list of indexes, invert the switches at the given indexes.

A switchboard is made up of some number of switches (v or ^) wrapped in -'s and arranged into rows of varying length. Here is an example switchboard:

-v-^-v-
-^-v-
-v-^-v-


To invert/flip a switch means changing it from v to ^, or from ^ to v.

The switches are indexed left-to-right, top-to-bottom. E.g., in the example above, the last v in the first row would be in position 3 and the ^ in the middle row would be at 4 (using 1-indexing).

## Input:

• A string (or list of strings) representing the switchboard. It is guaranteed to match the regex ((-[v^])+-)(\n(-[v^])+-)*.
• A possibly empty list of numbers representing indexes, may be 0 or 1 (or some arbitrary number if you want) indexed. These are the switches that need to be flipped.

## Output:

• A switchboard in the same shape as the input with the specified switches inverted. Any unspecified switches should retain their initial state.

## Rules:

• Input will always be correctly formatted and no given indexes will be out of bounds.
• The list of indexes will be sorted and will have no duplicates.
• State in your answer what indexing you use, be it 0, 1, or some arbitrary one.
• Trailing whitespace is fine as long as the output looks like the input.
• This is so shortest code wins.

## Examples:

#Using 1-indexing
input: #Empty Case
[],
-v-^-v-

output:
-v-^-v-

input: #Single switch
,
-v-

output:
-^-

input: #Skip a line
[3,5],
-^-v-v-
-v-
-^-^-

output:
-^-v-^-
-v-
-v-^-

input: #Flip one in each line + number wrap
[3,4,6],
-^-v-v-
-v-
-^-^-

output:
-^-v-^-
-^-
-^-v-

input: #Flip 'em all
[1,2,3,4,5,6],
-^-v-v-
-v-
-^-^-

output:
-v-^-^-
-^-
-v-v-

• Can we output a rectangular char array, right-padding the shorter lines with spaces? Also, can we take input in that form? Jul 24, 2019 at 15:50
• @LuisMendo I'm going to say No on taking that as input. Trailing white space is fine as long as it looks like the input. Jul 24, 2019 at 15:57
• Hint to those checking if characters are >"-": As the input string is guaranteed to start with -, you can check against the parameter/argument/variable name you're using for that instead. Jul 25, 2019 at 22:31

# Vim, 60, 46, 38, 37 bytes/keystrokes

qq/\d
ggDJ@"/[v^]
sv^<esc>l?\V<C-r>"
x@qq4u@q


<esc> and <C-r> are both 1 byte/keystroke. Byte Counter

Test Case 1 (Verbose mode)

Test Case 2 (Verbose mode)

Thanks to Grimy for the ideas that led to a reduction of 22 bytes :)

• @Veskah ughhhhhh vim is super finicky about "do something 0 times" edge cases. See edit Jul 24, 2019 at 16:32
• Couldn't :s/\%V./\='v^'[submatch(0)=='v'] be cl<C-R>='v^'['<C-R>"'=='v'] for -13 bytes? (each <C-R> is only one byte). Jul 24, 2019 at 16:36
• @Grimy Ooh, good idea. Also s == cl, so -14 overall. Jul 24, 2019 at 16:42
• Other ideas: s^v!<Esc>?\<C-R>"<CR>xhf!x or s<CR>^v<Esc>:s/\V<C-R>"<CR>kgJ. Jul 24, 2019 at 16:51
• I thought about that, but it fails if the character to be inverted is at the end of a line… but then the input spec guarantees it’s followed by a -, so it actually works! Duh. Jul 24, 2019 at 18:13

# JavaScript, 63 59 bytes

a=>s=>s.replace(/v|\^/g,x=>"^v"[a.includes(n++)^x>"^"],n=0)


Try it online!

Saved 4 bytes thanks to Arnauld.

# K (oK), 31 27 bytes

Solution:

0:{@[x;(&x>93)y;"^v"94=]};


Try it online!

Explanation:

Quick answer, will try to golf it. 0-indexed.

0:{@[x;(&x>93)y;"^v"94=]}; / the solution
0:                       ; / print to stdout
{                     }  / lambda taking 2 implicit args x & y
@[ ;        ;       ]   / apply @[var;index;function]
94=    / 94 (ASCII "v") equal to? returns 0 or 1
"v^"       / index into "v^" (ie flip switch)
y            / index into
(     )             / do this together
x>93              / x greater than 93 (ASCII "]")
&                  / indices where true
x                     / apply to x


Notes:

• -4 bytes thanks to >93 trick

# Python 3, 140134 103 bytes

(-30 thanks to DJMcMayhem♦, -1 more thanks to Black Owl Kai)

def f(i,y,x=1):
for c in y:q=c>'-';p=len(i)and x==i*q;print([c,"v^"[c>'^']][p],end='');x+=q;i=i[p:]


Try it online!

Oof, second try at golfing anything at all. This just uses a rather unsophisticated loop over the string, using x to keep track of the current switch index. Uses 1-indexing.

Ungolfed:

def f(i,y):
x = 1
for c in y:
nextchar = c # nextchar gets golfed out completely within the print
if c in 'v^': # golfed as c>'-'
if len(i) and x==i:
nextchar = 'v' if c=='^' else '^'
i = i[1:]
x += 1
print(nextchar, end='')

• 107 bytes Jul 24, 2019 at 17:49
• 106 bytes Jul 24, 2019 at 18:11
• Or 104 if python 3 is acceptable Jul 24, 2019 at 18:22
• @DJMcMayhem Ooh, thanks for that replace catch xd Would you want to post the Python 3 as a separate answer, or do you think it's similar enough to add as an edit to this? Jul 24, 2019 at 18:52
• Feel free to add it :) I might post a python 3 answer, but I'd probably try to come up with my own approach first. Jul 24, 2019 at 19:14

# Jelly, 12 bytes

O^%5T⁴ịƲ¦40Ọ


A full program accepting a string and a list of integers which prints the result.

Try it online!

### How?

O^%5T⁴ịƲ¦40Ọ - Main Link: list of characters, S; inversion indices, I
O            - to ordinals   ('\n':10, '-':45, '^':94, 'v':118)
¦    - sparse application...
%5         -   modulo 5   (10:0, 45:0, 94:4, 118:3)
T        -   truthy indices (giving, X, indices of '^' and 'v' in S)
⁴       -   4th command line argument = I
ị      -   index into X   (giving indices of '^' and 'v' to invert in S)
^       40  - ...action: XOR with 40   (94:118, 118:94)
Ọ - from ordinals
- implicit print


# Python 3.8 (pre-release), 80, 78, 77, 71, 70 bytes

lambda x,s,i=0:''.join([c,'^v'[c<'v']][c>s and(i:=i+1)in x]for c in s)


-1 byte, thanks to @Shaggy

Try it online!

• c>s  saves a byte. Jul 25, 2019 at 22:36

# Perl 6, 31 bytes

->$_,\s{S:nth(s){\^|v}=$/~^'('}


Try it online!

(-2 bytes thanks to Jo King)

Perl 6's substitution operator S conveniently takes an nth adverb that accepts not only a single index at which to make the replacement, but a list of them, exactly as needed here.

The replacement is $/ ~^ '(', where $/ is the matched text (either v or ^), ~^ is the stringwise exclusive-or operator, and ( is the character whose bits turn v into ^ and vice versa.

• 31 bytes
– Jo King
Jul 25, 2019 at 2:24

# MATL, 29 bytes

c!tt45>o2yfi)(2=XK)t106-E-K(!


Input is a cell array of strings and a row vector of numbers, with 1-based indexing. Output is right-padded with spaces.

# Python 2, 10597 91 bytes

lambda a,s:reduce(lambda(t,i),c:(t+[c,'^v'[c<'v']][c>'-'and i in a],i+(c>'-')),s,('',0))


Try it online!

6 bytes saved by stealing using Rin's Fourier transform's c>'-' instead of c in'^v'.

0-indexed.

⁾^vḟ$€>”-T⁹ịƲ¦  Try it online! Full program. This feels too overlong... • I don't know Jelly so can't figure out how to try it myself but could you replace ”- with the name of the first argument (³?), which is guaranteed to start with a -, instead? Jul 25, 2019 at 22:34 • @Shaggy Nope, because > vectorizes. You can see that it doesn't work. Jul 25, 2019 at 23:24 • ah, that's exactly what I tried :) Didn't know if it was my lack of Jelly knowledge that was the cause or not, though. Don't suppose there's a single character built-in to get the first character of the first argument? Jul 25, 2019 at 23:41 • @Shaggy Erm... the only built-ins for command-line arguments are ³, ⁴, ⁵, ⁶ and ⁷, for the first to the fifth CLAs respectively. You can read the Atoms page to find out if a specific built-in function exists. Jul 25, 2019 at 23:48 • Ah, well, was worth a shot. One day, I will dive into Jelly properly. Jul 25, 2019 at 23:50 # Stax, 13 bytes ¿╫╦ÜΦ1▌X○!ΩTæ  Run and debug it This uses 0-based indices. 1. Find all indices of the regex [v^]. 2. Index into the index array using the input. 3. At each result, xor the input's ascii code with 40. This is xor('v', '^'). # Clean, 93 bytes import StdEnv$i=foldl(\s c=s++[if(any((==)(sum[1\\k<-s|k>'-']))i&&c>'-')if(c>'^')'^''v'c])[]


Try it online!

Defines the function $:: [Int] -> [Char] -> [Char] taking a zero-indexed list of indices and returning a function that takes the string and returns the altered string. # JavaScript (Node.js), 10198939177 67 bytes a=>s=>[...s].map(c=>t+=c>s?"^v"[a.includes(i++)^c>"^"]:c,t=i=)&&t  Try it online! 10 bytes, thx to suggestions by Shaggy. Port of my Python answer. Not used to golfing javascript! • A few quick tweaks Jul 25, 2019 at 9:17 • Or 67 bytes by paying forward the saving Arnauld gave me. Jul 25, 2019 at 22:27 • @Shaggy: Tips appreciated! Reading now... Jul 26, 2019 at 5:29 # V, 20 bytes ÑñÀ/vüÞ sv^l?Ö" xH  Try it online! Uses some new features, such as Ñ which is incredibly useful. # JavaScript, 111 bytes ### Code x=>y=>{x.map(i=>eval(y=y.replace(/(((v|\\^)[^^v]*){${i}})(v|\\^)/,(a,b,c,d,e)=>b+(e<"v"?"v":"^"))));return y}


Takes input in format f(x)(y) where x is the indices and y is the switchboard. Indices are 0 indexed

Try it online!

### Explanation

For each index

x.map(i=>...


construct the regex that finds the index+1 th "^" or "v"

.../(((v|\\^)[^^v]*){${i}})(v|\\^)/...  insert it into a string to replace it with the opposite symbol "v"<->"^" y=y.replace(...,(a,b,c,d,e)=>b+(e<"v"?"v":"^"))  then evaluate the string as a function eval(...)  After iterating through the indices to switch, return the switchboard return y  # Jelly, 17 bytes ⁾^vK;©⁹e€ky@€⁸¦®  Try it online! A full program taking the indices as first and string as second argument. Prints the output with the indicated switches flipped. # Retina 0.8.2, 66 62 bytes \d+$*
Tv^^v.(?<=\b(?(3)$)(?<-3>1)+(,1+)*(-|¶|(v|\^))+) 1A  Try it online! Link includes test case. 1-indexed. Explanation: \d+$*


Convert the input numbers to unary.

Tv^^v.(?<=\b(?(3)$)(?<-3>1)+(,1+)*(-|¶|(v|\^))+)  Transliterate between v and ^ all characters with the property that the number of vs and ^s so far (inclusive) equals one of the input numbers. 1A  Delete the input numbers. # Charcoal, 23 bytes ⭆η⎇№θ⌕ΦＬη№v^§ηλκ§v^⁼vιι  Try it online! Link is to verbose version of code. 0-indexed. Explanation:  η Input string ⭆ Map over characters and join ⎇ If № Count of (i.e. exists) ⌕ Index of κ Current index in Ｌ Length of η Input string Φ Implicit range filtered by № Count of (i.e. exists) η Input string § Indexed by λ Current value v^ In literal string v^ θ In input list v^ Then literal v^ § Indexed by ι Current character ⁼ Equal to v Literal v ι Else current character  # Ruby, 56 bytes 1-indexed. ->s,i{j=0;s.gsub(/[v^]/){i==i-[j+=1]?$&:"v^".tr(\$&,'')}}


Try it online!

# C# (Visual C# Interactive Compiler), 73 bytes

a=>b=>{int i=0;return a.Select(x=>x>45&&b.Contains(++i)?(char)(x^40):x);}


Try it online!

• @Veskah Updated to include empty case Jul 26, 2019 at 13:50

# Japt, 15 bytes

®c^(Z>V©øT° *#(


Try it

®c^(Z>V©ø°T *#(    U = Input String, V = Array of Indices
®                  Map each Z in U
c^                   XOR Z's charcode by
(Z>V                 Z is 'v' or '^'
øT°              The current Z's index is in V
*#(        Multiply the boolean with 40 (false = 0, true = 1)


# Japt, 16 14 bytes

Ëc^#(*(D>V©øT°


Try it

Ë>V©øT° ?Dc^#(:D     :Implicit input of multi-line string U & integer array V
Ë                    :Map each D in U
>V                  :  Greater than V? (Coerces V to a string and, conveniently, all digits are > "\n" & "-" and < "^" & "v")

• Aw, your code is no longer happy (it lost the :D) Jul 31, 2019 at 12:14