24
\$\begingroup\$

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
[1],
-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-
\$\endgroup\$
3
  • \$\begingroup\$ Can we output a rectangular char array, right-padding the shorter lines with spaces? Also, can we take input in that form? \$\endgroup\$
    – Luis Mendo
    Commented Jul 24, 2019 at 15:50
  • \$\begingroup\$ @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. \$\endgroup\$
    – Veskah
    Commented Jul 24, 2019 at 15:57
  • 2
    \$\begingroup\$ 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. \$\endgroup\$
    – Shaggy
    Commented Jul 25, 2019 at 22:31

22 Answers 22

11
\$\begingroup\$

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 :)

\$\endgroup\$
6
  • 2
    \$\begingroup\$ @Veskah ughhhhhh vim is super finicky about "do something 0 times" edge cases. See edit \$\endgroup\$
    – DJMcMayhem
    Commented Jul 24, 2019 at 16:32
  • \$\begingroup\$ 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). \$\endgroup\$
    – Grimmy
    Commented Jul 24, 2019 at 16:36
  • 2
    \$\begingroup\$ @Grimy Ooh, good idea. Also s == cl, so -14 overall. \$\endgroup\$
    – DJMcMayhem
    Commented Jul 24, 2019 at 16:42
  • \$\begingroup\$ Other ideas: s^v!<Esc>?\<C-R>"<CR>xhf!x or s<CR>^v<Esc>:s/\V<C-R>"<CR>kgJ. \$\endgroup\$
    – Grimmy
    Commented Jul 24, 2019 at 16:51
  • 1
    \$\begingroup\$ 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. \$\endgroup\$
    – Grimmy
    Commented Jul 24, 2019 at 18:13
6
\$\begingroup\$

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.

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

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
\$\endgroup\$
3
\$\begingroup\$

Python 3, 140 134 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[0]*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[0]:
                nextchar = 'v' if c=='^' else '^'
                i = i[1:]
             x += 1
         print(nextchar, end='')
\$\endgroup\$
5
  • \$\begingroup\$ 107 bytes \$\endgroup\$
    – DJMcMayhem
    Commented Jul 24, 2019 at 17:49
  • \$\begingroup\$ 106 bytes \$\endgroup\$
    – Kateba
    Commented Jul 24, 2019 at 18:11
  • \$\begingroup\$ Or 104 if python 3 is acceptable \$\endgroup\$
    – DJMcMayhem
    Commented Jul 24, 2019 at 18:22
  • \$\begingroup\$ @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? \$\endgroup\$ Commented Jul 24, 2019 at 18:52
  • 1
    \$\begingroup\$ 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. \$\endgroup\$
    – DJMcMayhem
    Commented Jul 24, 2019 at 19:14
3
\$\begingroup\$

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...
       Ʋ     - ...to indices: last four links as a monad: f(O(S))
  %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
\$\endgroup\$
3
\$\begingroup\$

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!

\$\endgroup\$
1
  • 1
    \$\begingroup\$ c>s saves a byte. \$\endgroup\$
    – Shaggy
    Commented Jul 25, 2019 at 22:36
3
\$\begingroup\$

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.

\$\endgroup\$
1
  • \$\begingroup\$ 31 bytes \$\endgroup\$
    – Jo King
    Commented Jul 25, 2019 at 2:24
2
\$\begingroup\$

MATL, 29 bytes

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

Try it online! Or verify all text cases.

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

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

Python 2, 105 97 91 bytes

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

Try it online!

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

0-indexed.

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

Jelly, 14 bytes

⁾^vḟ$€>”-T⁹ịƲ¦

Try it online!

Full program.

This feels too overlong...

\$\endgroup\$
5
  • \$\begingroup\$ 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? \$\endgroup\$
    – Shaggy
    Commented Jul 25, 2019 at 22:34
  • \$\begingroup\$ @Shaggy Nope, because > vectorizes. You can see that it doesn't work. \$\endgroup\$ Commented Jul 25, 2019 at 23:24
  • \$\begingroup\$ 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? \$\endgroup\$
    – Shaggy
    Commented Jul 25, 2019 at 23:41
  • \$\begingroup\$ @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. \$\endgroup\$ Commented Jul 25, 2019 at 23:48
  • \$\begingroup\$ Ah, well, was worth a shot. One day, I will dive into Jelly properly. \$\endgroup\$
    – Shaggy
    Commented Jul 25, 2019 at 23:50
2
\$\begingroup\$

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', '^').
\$\endgroup\$
2
\$\begingroup\$

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.

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

JavaScript (Node.js), 101 98 93 91 77 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!

\$\endgroup\$
3
  • \$\begingroup\$ A few quick tweaks \$\endgroup\$
    – Shaggy
    Commented Jul 25, 2019 at 9:17
  • \$\begingroup\$ Or 67 bytes by paying forward the saving Arnauld gave me. \$\endgroup\$
    – Shaggy
    Commented Jul 25, 2019 at 22:27
  • \$\begingroup\$ @Shaggy: Tips appreciated! Reading now... \$\endgroup\$
    – Chas Brown
    Commented Jul 26, 2019 at 5:29
2
\$\begingroup\$

V, 20 bytes

ÑñÀ/vüÞ
sv^l?Ö"
xH

Try it online!

Uses some new features, such as Ñ which is incredibly useful.

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

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
\$\endgroup\$
1
\$\begingroup\$

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.

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

Retina 0.8.2, 66 62 bytes

\d+
$*
T`v^`^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.

T`v^`^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.

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

Charcoal, 23 bytes

⭆η⎇№θ⌕ΦLη№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
       L                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
\$\endgroup\$
1
\$\begingroup\$

Ruby, 56 bytes

1-indexed.

->s,i{j=0;s.gsub(/[v^]/){i==i-[j+=1]?$&:"v^".tr($&,'')}}

Try it online!

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

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!

\$\endgroup\$
1
  • 1
    \$\begingroup\$ @Veskah Updated to include empty case \$\endgroup\$
    – Gymhgy
    Commented Jul 26, 2019 at 13:50
1
\$\begingroup\$

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 '^'
      ©                 Short-circuiting Logical and
       øT°              The current Z's index is in V
             *#(        Multiply the boolean with 40 (false = 0, true = 1)
\$\endgroup\$
1
\$\begingroup\$

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")
   ©                 :  Logical AND with
    ø                :  Does V contain
     T°              :    T (initially 0) postfix incremented
        ?            :  If true
         Dc          :  Charcode of D
           ^#(       :  XOR with 40
              :D     :  Else D
\$\endgroup\$
1
  • \$\begingroup\$ Aw, your code is no longer happy (it lost the :D) \$\endgroup\$
    – Veskah
    Commented Jul 31, 2019 at 12:14

Your Answer

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

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