12
\$\begingroup\$

Rules

In this challenge, I'm going to redefine the definition of "quotes" a bit.

  • Quotation marks (AKA quotes) are any identical characters used in pairs in various writing systems to set off direct speech, a quotation, or a phrase. The pair consists of an opening quotation mark and a closing quotation mark, which is the same character(case-sensitive).

  • If there are quote-pairs overlapping each other,

    • If a pair nesting another, both pairs are still valid.
    • If a pair not nesting another, the first starting pair remains valid. The other is no longer considered as a pair.
  • When counting quoted characters(length of a pair of quotes),

    • The quotes themselves don't count.
    • Each pair's length is counted independently. Overlapping doesn't affect another.

Goal

Your goal is to print the total length of all valid quotes. This is code golf, therefore the code with the fewest bytes wins.

Examples

Legend:
    <foo>: Valid quotes
    ^    : Cannot be paired character

Input   : ABCDDCBA
`A`  (6): <BCDDCB>
`B`  (4):  <CDDC>
`C`  (2):   <DD>
`D`  (0):    <>
Output  : 12

Input   : ABCDABCD
`A`  (3): <BCD>
`B`  (0):  ^   ^
`C`  (0):   ^   ^
`D`  (0):    ^   ^
Output  : 3

Input   : AABBBBAAAABA
`A`  (0): <>    <><> ^
`B`  (0):   <><>    ^
Output  : 0

Input   : ABCDE
Output  : 0

Input   : Print the total length of all "quoted" characters
`r` (40):  <int the total length of all "quoted" cha>
`n` (14):    <t the total le>
`t` (15):     < >   <o>       <h of all "quo>
` `  (7):      ^   <total>      <of>   ^        ^
`h`  (0):        ^             ^                  ^
`e`  (8):         < total l>                 ^          ^
`o`  (0):            ^           ^         ^
`a`  (0):              ^            ^              ^ ^
`l`  (0):               ^ ^          <>
`"`  (0):                               ^      ^
`c`  (0):                                        ^    ^
Output  : 84

Input   : Peter Piper picked a peck of pickled peppers
`P`  (5): <eter >
`e`  (9):  <t>     ^      <d a p>           <d p>  ^
`r`  (0):     ^     ^
` `  (3):      ^     ^      <a>    <of>       ^
`i`  (5):        <per p>
`p`  (3):         <er >        ^       ^       ^ <>
`c`  (8):               <ked a pe>       ^
`k`  (7):                ^        < of pic>
`d`  (0):                  ^                 ^
Output  : 40

Input   : https://www.youtube.com/watch?v=dQw4w9WgXcQ
`h` (27): <ttps://www.youtube.com/watc>
`t`  (0):  <>            ^          ^
`/`  (0):       <>               ^
`w` (14):         <><.youtube.com/>         <4>
`.`  (7):            <youtube>
`o`  (0):              ^       ^
`u`  (1):               <t>
`c`  (0):                     ^      ^             ^
`Q`  (8):                                  <w4w9WgXc>
Output  : 57
\$\endgroup\$
  • \$\begingroup\$ @NickKennedy I fixed the rules to be more like actual quotes. I think this is what you expected. Can you review this? \$\endgroup\$ – user2286046 Jun 19 at 9:24
  • 1
    \$\begingroup\$ looks good! Thanks for listening to my feedback. \$\endgroup\$ – Nick Kennedy Jun 20 at 21:29
1
\$\begingroup\$

Jelly, 12 bytes

œṡ¹¡ḢṖẈ;߀ƲS

Try it online!

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

APL (Dyalog Unicode), 36 bytesSBCS

Full program. Prompts for input from stdin.

≢∊t⊣{t,←'(.)(.*?)\1'⎕S'\2'⊢⍵}⍣≡⍞⊣t←⍬

Try it online!

t←⍬ set up an accumulator t (for total)

⍞⊣ discard that in favour of string input from stdin (symbol: quote in console)

{}⍣≡ apply the following anonymous lambda until stable (fix-point; previous ≡ next)

⊢⍵ on the argument

 …⎕S'\2' PCRE Search for the following, returning group 2 for each match:

  (.) any character (we'll call this group 1)
  (.*?) as few characters as possible (we'll call this group 2)
  \1 the group 1 character

t,← update t by append that to t's current value

t⊣ discard that (the final list of no matches) in favour of t

 count the number of characters in that

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

JavaScript (ES6), 64 bytes

f=([c,...a],i=a.indexOf(c))=>c?(~i&&i+f(a.splice(0,i+1)))+f(a):0

Try it online!

Commented

f = (                       // f is a recursive function taking either the input string
                            // or an array of characters, split into
  [c, ...a],                // c = next character and a[] = all remaining characters
  i = a.indexOf(c)          // i = index of the 1st occurrence of c in a[] (-1 if not found)
) =>                        //
  c ?                       // if c is defined:
    ( ~i &&                 //   if i is not equal to -1:
      i +                   //     add i to the final result
      f(a.splice(0, i + 1)) //     remove the left part of a[] up to i (included) and
    )                       //     do a recursive call on it
    + f(a)                  //   add the result of a recursive call on a[]
  :                         // else:
    0                       //   stop recursion
\$\endgroup\$
1
\$\begingroup\$

Ruby, 49 bytes

Recursive solution. Find quote groups, count their lengths, and then recursively look for sub-group lengths and sum everything together.

f=->s{s.scan(/(.)(.*?)\1/).sum{|a,b|b.size+f[b]}}

Try it online!

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

Jelly, 17 bytes

œṡḢẈṖ$Ḣ+ɼṛƲ)Ẏ$F¿®

Try it online!

A full program that takes a single argument, the input string wrapped in a list, and returns the number of quotes characters as an integer.

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

JavaScript (Node.js), 65 64 62 bytes

f=s=>(s=/(.)(.*?)\1(.*)/.exec(s))?f(s[3])+f(s=s[2])+s.length:0

Try it online!

Original approach (64 bytes):

f=(s,r=/(.)(.*?)\1/g,t=r.exec(s))=>t?f(t=t[2])+t.length+f(s,r):0

Try it online!

f=s=>                              // Main function:
 (s=/(.)(.*?)\1(.*)/.exec(s))?     //  If a "quoted" segment can be found:
  f(s[3])                          //   Return the recursive result outside this segment,
  +f(s=s[2])                       //   plus the recursive result of this segment,
  +s.length                        //   plus the length of this segment
 :0                                //  If not: no quoted segment, return 0.
\$\endgroup\$
0
\$\begingroup\$

Brain-Flak, 100 bytes

({{<({}<>)<>(({<>(({}({})<>[({}<>)]))(){[{}()](<>)}{}}{}){(<>)})<>{}>{<>({}<<>({}<>)>)<>}<>[{}]}{}})

Try it online!

Commented

# Loop over each character in input and sum iterations:
({{

  # Evaluate matching quote search as zero
  <

    # Move opening "quote" to right stack
    ({}<>)<>

    # Until match or end of search string found:
    # Note that the character to search for is stored as the sum of the top two entries in the right stack.
    (

      ({

        <>((

          # Character to search for
          {}({})

          # Subtract and move next character
          <>[({}<>)]

        # Push difference twice
        ))

        # Add 1 to evaluation of this loop
        ()

        # If no match, cancel out both 1 and pushed difference to evaluate iteration as zero (keep one copy of difference for next iteration)
        # (compare to the standard "not" snippet, ((){[()](<{}>)}{}) )
        # Then move to other stack
        {[{}()](<>)}{}

        # If a match was found, this will instead pop a single zero and leave a zero to terminate the loop, evaluating this iteration as 0+1=1.

      # Push 1 if match found, 0 otherwise
      }{})

      # If match found, move to left stack and push 0 denote end of "quoted" area.
      {(<>)}

    # Push the same 1 or 0 as before
    )

    # Remove representation of opening "quote" searched for
    # The closing quote is *not* removed if there is a match, but this is not a problem because it will never match anything.
    <>{}

  >

  # Move searched text back to left stack, evaluating each iteration as either the 1 or 0 from before.
  # This counts characters enclosed in "quotes" if a match is found, and evaluates as 0 otherwise.
  {<>({}<<>({}<>)>)<>}

  # Remove 0/1 from stack; if 1, cancel out the 1 added by the closing "quote"
  <>[{}]

# Repeat until two consecutive zeroes show up, denoting the end of the stack.
# (Because closing quotes are not removed, it can be shown that all other zeroes are isolated on the stack.)
}{}})
\$\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.