23
\$\begingroup\$

Given a string of space delimited words, find the longest word such that, when that word is replaced with spaces, it is still a subsequence of the remaining string. Then, replace everything, except for one such subsequence, with spaces. Print the result

Example:

input:

that was esoteric and awesome man dope

longest applicable word: awesome

output:

a w eso m e

Test cases:

For inputs with multiple solutions, your mileage may vary, but these examples only have one solution each.

"a simple example" => "           a    "
"chores or emails" => "  or            "
"one tricky case on a set" => "       c           a se "
"scream dream care" => " c  a   re       "
"why only read one word" => "w   o    r  d         "
"stressed desserts seeddee" => "s  e  ed de  e           "

Here is an additional test case with multiple possible solutions, to ensure that you only return one solution: and an anon should output exactly one of the following:

an         
a       n  
a         n
       an  
       a  n

Rules / Clarifications

  • You may always assume a solution exists
  • The solution word will always appear exactly once in the string, so example example will never be an input
  • If there are multiple solutions, you may pick any one of them
  • Input will only be ascii letters a-z and spaces
  • Input will be either all uppercase or all lowercase, whichever is most convenient for the solver
  • You must output leading spaces unless that is absolutely impossible for your language in general, but trailing spaces may be removed
  • This is , so shortest code in bytes wins
\$\endgroup\$
7
  • 2
    \$\begingroup\$ Can a word appear twice in the input? If so, is " one" a valid solution for "one to one"? \$\endgroup\$ Commented Dec 14, 2024 at 19:34
  • 2
    \$\begingroup\$ @UriGranta oh good question. I'm going to say that it doesn't appear in the input, because ruling that either way just complicates the challenge. Edited spec, thanks for the comment. \$\endgroup\$ Commented Dec 14, 2024 at 19:40
  • \$\begingroup\$ Your test cases all suggest that the first occurrence of each letter in the target word will appear in the order they appear in the word. Can you please edit to clarify whether that is the case or not? And, if not, add 1 or more test cases to illustrate? e.g. Is wawe awesome some a vlaid input? And what would the expected output be? \$\endgroup\$ Commented Dec 15, 2024 at 3:31
  • 2
    \$\begingroup\$ @Shaggy I assumed that suggestion was made explicit by the word "subsequence", correct me if I'm wrong. I can add clarifying detail in the body if it helps, but the test case stressed desserts seeddee also covers it, seeing as both stressed and desserts are longer than seeddee. wawe awesome some works and the result is awe some (with a leading space, ideally) \$\endgroup\$ Commented Dec 15, 2024 at 3:38
  • \$\begingroup\$ "Given a string of space delimited words, find the longest word such that, when that word is replaced with spaces, it is still a subsequence of the remaining string." Replaced with spaces in the original string? \$\endgroup\$ Commented Dec 16, 2024 at 17:01

16 Answers 16

5
\$\begingroup\$

Google Sheets, 269 bytes 313 bytes

=let(b,"(.*)",w,tocol(split(A1," ")),sort(reduce(,sort(w,len(w),0),lambda(a,t,let(l,len(t),s,substitute(A1,t,rept(" ",l),1),p,b&join(b,mid(t,sequence(l),1))&b,o,join("_",regexextract(s,p)),i,sequence(len(o)),if(a=0,ifna(join(,if(mid(o,i,1)="_",mid(s,i,1)," "))),a))))))

Put the phrase in cell A1 and the formula in B1.

screenshot

The formula uses simple regexes only and doesn't rely on lookaround or backtracking. Bonus: works for outruled repetitions like one to one and example example as well.

Ungolfed:

=let( 
  words, tocol(split(A1, " ")), 
  sorted, sort(words, len(words), 0), 
  sort(reduce(, sorted, lambda(a, t, let( 
    length, len(t), 
    stripped, substitute(A1, t, rept(" ", length), 1), 
    letters, mid(t, sequence(length), 1), 
    pattern, "(.*)" & join("(.*)", letters) & "(.*)", 
    opposite, join("_", regexextract(stripped, pattern)), 
    i, sequence(len(opposite)), 
    if(a = 0, 
      ifna(join(, if(mid(opposite, i, 1) = "_", mid(stripped, i, 1), " "))), 
      a 
    ) 
  ))))
)
\$\endgroup\$
5
\$\begingroup\$

05AB1E, 24 23 bytes

ā<DæéR.ΔÎrǝð¡IyèJå}Kðsǝ

-1 byte fixing a bug found by @JonathanAllan (yes, -1 byte, not +1 😅)

(Don't) try it online.
To speed it up slightly, so it can at least output some test cases: try it online or verify multiple smaller test cases at once.

Explanation:

ā<              # Push a list in the range [0, (implicit) input-length)
  D             # Duplicate this indices-list
æ               # Pop and get the powerset of the copy
 éR             # Sort the from longest to shortest
   .Δ           # Pop and find the first that's truthy for:
     Î          #  Push 0 and the input-string
      r         #  Reverse the stack order
       ǝ        #  Insert the 0 at the current indices into the input
        ð¡      #  Then split on spaces
          I     #  Push the input-string again
           yè   #  Get the characters at the current indices
             J  #  Join this list of characters to a string
              å #  Check if it's in the list
    }K          # After the find_first: remove those indices from the full indices-list
      ðsǝ       # Insert spaces at all remaining indices in the (implicit) input 
                # (after which the result is output implicitly)

The (slightly) faster version has éR replaced with I#€gêù€`R:

 I              # Push the input-string
  #             # Split it on spaces
   €g           # Get the length of each word
     ê          # Uniquify and sort those lengths (smallest to largest)
      ù         # Only keep the powerset-lists of those lengths
       €`       # Flatten the list one level down
         R      # Reverse the list, so the order is from longest to shortest
\$\endgroup\$
5
  • 1
    \$\begingroup\$ You've fallen foul of the kind of edge case I was worried about trying to avoid when using powersets and the like (due to taking time to run longish tests), e.g.: "sets reset r" returns " s et " rather than " r " TIO \$\endgroup\$ Commented Dec 17, 2024 at 13:03
  • \$\begingroup\$ Maybe replacing õ with would work, although I'm not 100% sure. \$\endgroup\$ Commented Dec 17, 2024 at 13:10
  • 1
    \$\begingroup\$ @JonathanAllan Ah, I purposely left the ð¡ instead of checking for a substring inside the full string, but I guess that test case of sets reset r with [3,8,9] removes that second s, then splits by spaces, and then incorrectly finds set. Thanks for finding the bug. And yes, replacing the õ with would indeed have worked, since "set"≠"set/n". But replacing õI with Î or $ works similar and is even a -1. So thanks for finding that bug and also thanks for an indirect -1. 😅 \$\endgroup\$ Commented Dec 17, 2024 at 13:26
  • 1
    \$\begingroup\$ ...and thanks to you for -7 to mine ;) \$\endgroup\$ Commented Dec 17, 2024 at 14:43
  • 1
    \$\begingroup\$ @JonathanAllan Nice. Always great to help each other golf answers, even if it's sometimes indirect. :D (And in case I forget later on, happy holidays.) \$\endgroup\$ Commented Dec 17, 2024 at 16:57
5
\$\begingroup\$

Jelly,  30 29 28 21 19  17 bytes

-7 porting Kevin Cruijssen's approach in their 05AB1E answer (as proposed in the "Could probably be..." note above my original answer, below). Also -4 more golfing this.

JŒPṬoḲix@ʋƇo¬ao⁶

A monadic Link that accepts a list of characters and yields a list of characters.

Try it online! (although it's too slow for the longer test cases).

How?

JŒPṬoḲix@ʋƇo¬Ṫao⁶ - Link: Plaintext
J                 - indices of {Plaintext} -> AllIndices
 ŒP               - powerset of {AllIndices} (shortest to longest)
   Ṭ              - untruth -> AllMasks (each with ones at the chosen indices and
                                         zeros elsewhere up to the last chosen index)
          Ƈ       - keep those of {AllMasks} for which:
         ʋ        -   last four links as a dyad - f(Mask, Plaintext):
    o             -     {Mask} logical OR {Plaintext} (vectorises) 
                        -> Masked (Plaintext with ones in place of chosen indices)
     Ḳ            -     split {Masked} at space characters -> WordsOfMasked
       x@         -     {Plaintext} repeat {Mask} (vectorises)
                        -> Substring (i.e. the characters at the chosen indices)
      i           -     first 1-indexed index of {Substring} in {WordsOfMasked}
                        ...or 0 if not found
                    -> ValidMasks (ordered from fewest to most set bits)
            ¬     - {Plaintext} logical NOT -> Zeros = [0,0,...,0] (Plaintext's length)
           o      - {ValidMasks} logical OR {Zeros} (vectorises)
                    (right pads each mask with zeros to the length of Plaintext)
             Ṫ    - tail -> ValidMaskWithMaximalSetBits
              a   - {ValidMaskWithMaximalSetBits} logical AND {Plaintext} (vectorises)
                    -> X = Plaintext with zeros where we want spaces
               o⁶ - {X} logical OR with a space character (vectorises)
                    (replaces the zeros with spaces)

Original, 28 bytes

-1 inspired by Niel's comment about the original having two helper Links :)

Could probably be slightly terser by using a more bute-force approach (think partitions or powersets) - EDIT: yep, see above.

⁶µḲ¬i¦KẹⱮŒpʋⱮ`ẎQṢ$ƑƇLÞṪḟ@Jµ¦

A monadic Link that accepts a list of characters and yields a list of characters.

Try it online!

How?

⁶µ...µ¦ - Link: Plaintext         e.g: "a word is missing mate"
      ¦ - sparse application to {Plaintext}...
 µ   µ  - ...to indices: monadic chain - f(Plaintext) -> SpaceIndices
⁶       - ...apply: space character -> "           i s        "

Ḳ¬i¦KẹⱮŒpʋⱮ` - start of the monadic chain: Plaintext
Ḳ            - split {Plaintext} at space characters -> PlaintextAsWords
          Ɱ` - map across TrialWord in {PlaintextAsWords} with:
         ʋ   -   last four links as a dyad - f(PlaintextAsWords, TrialWord}
                 e.g. f(["a","word","is","missing","mate"], "is")
   ¦         -     sparse application to {PlaintextAsWords}...
  i          -     ...at indices: first index of {TrialWord} in {PlaintextAsWords}
 ¬           -     ...apply: logical NOT (vectorises)
    K        -     join with space characters -> RedactedPlaintext, e.g:
                   ['a',' ','w','o','r','d',' ',0,0,' ','m','i','s','s','i','n','g',' ','m','a','t','e']
      Ɱ      -     map across Character in {TrialWord} with:
     ẹ       -       indices of {Character} in {RedactedPlaintext}
                   [[12,15],[13,14]]
       Œp    -     Caterisan product -> AllIndexPicksMakingTrialWord
                   [[12,13],[12,14],[15,13],[15,14]]
               -> AllIndexPicksMakingTrialWordForEachWord
                  [[[20]],[],[[12,13],[12,14],[15,13],[15,14]],[],[]]

ẎQṢ$ƑƇLÞṪḟ@J - the rest of the monadic chain: AllIndexPicksMakingTrialWordForEachWord
Ẏ            - tighten
               [[20],[12,13],[12,14],[15,13],[15,14]]
     Ƈ       - keep those for which:
    Ƒ        -   is invariant under?:
   $         -     last two links as a monad:
 Q           -       deduplicate
  Ṣ          -       sort
               [[20],[12,13],[12,14]
      LÞ     - sort by length (to place the longest ones on the right)
        Ṫ    - tail -> KeepCharactersAt
               [12,14]
           J - indices {Plaintext} -> AllIndices
         ḟ@  - {AllIndices} filter discard {KeepCharactersAt}
               -> SpaceIndices
               [1,2,3,4,5,6,7,8,9,10,11,13,15,16,17,18,19,20,21,22]
\$\endgroup\$
7
  • \$\begingroup\$ Wow, two helper links: how often have you needed that before? \$\endgroup\$ Commented Dec 16, 2024 at 14:37
  • \$\begingroup\$ We don't actually need them here, it could all be inlined and still be the same byte count in this instance - with something like ⁶JḟḲ¬⁼¡€KẹⱮŒpʋQṢ$ƑƇ¥Ɱ`ẎLÞƲṪ$Ɗ¦ TIO - but it's certainly easier to grok with the two helper Links! \$\endgroup\$ Commented Dec 16, 2024 at 17:59
  • 1
    \$\begingroup\$ ...I found a one byte save inlining another way - so thanks :) \$\endgroup\$ Commented Dec 16, 2024 at 18:31
  • 1
    \$\begingroup\$ @UnrelatedString Nah, we'd need to sort them by bit-count (i.e. sum). Problematic examples: tail (should be trailing xy) or head (should be xy a). \$\endgroup\$ Commented Dec 18, 2024 at 22:08
  • 1
    \$\begingroup\$ Ah, TIL that ŒP is in size order and not just binary! All I can ever remember about its order is that the complements are the same list reversed. \$\endgroup\$ Commented Dec 18, 2024 at 22:28
4
\$\begingroup\$

JavaScript (ES6), 128 bytes

-3 thanks to @l4m2

s=>s[R="replace"](/\w+/g,n=w=>w[q=s[R](RegExp(`\\b${w}\\b`),w[R](e=/./g,i=0))[R](e,c=>c==w[i]?++i&&c:" "),i]||n>i||(n=i,b=q))&&b

Try it online!

Commented

s =>                 // s = input string
s[R = "replace"](    // replace in s
  /\w+/g,            // look for words
  n =                // n = best length so far, initially NaN'ish
  w =>               // for each word w in s:
  w[                 //   test w[i]:
    q =              //     q is the string obtained by
    s[R](            //     replacing in s:
      RegExp(        //       the (only) occurrence of w
        `\\b${w}\\b` //       surrounded by word boundaries
      ),             //
      w[R](          //       with w where ...
        e = /./g,    //         each character
        i = 0        //         is replaced with '0'
      )              //       end of replace()
    )                //     end of replace()
    [R](             //     replace again:
      e,             //       each ...
      c =>           //       ... character c with:
      c == w[i] ?    //         if c is w[i]:
        ++i && c     //           c itself (and increment i)
      :              //         else:
        " "          //           a space
    ),               //     end of replace()
    i                //     i is the actual index for our test
  ] ||               //   do nothing if w[i] is defined
                     //   (i.e. the subsequence is incomplete)
  n > i ||           //   or n is greater than i
                     //   (i.e. the best word b is longer)
  (n = i, b = q)     //   otherwise, set n to i and b to q
) && b               // end of replace(); return b
\$\endgroup\$
2
3
\$\begingroup\$

Japt v2.0a0 -h, 45 39 35 31 30 bytes

¸£¸hYXç)¸Ë¶XÎ?X=ÅD:SÃpÂ!XÃñè\a

Try it or run all test cases

¸£¸hYXç)¸Ë¶XÎ?X=ÅD:SÃpÂ!XÃñè\a     :Implicit input of string U
¸                                  :Split on spaces
 £                                 :Map each X at index Y
  ¸                                :  Split U on spaces
   hY                              :  Replace the element at index Y with
     Xç                            :    Fill X with spaces
       )                           :  End replace
        ¸                          :  Join with spaces
         Ë                         :  Map each D
          ¶                        :    Is equal to
           XÎ                      :      First character of X
             ?                     :    If true
              X=                   :      Reassign to X
                Å                  :        Remove first character from X
                 D                 :      Return D
                  :                :    Else return
                   S               :      Space
                    Ã              :  End inner map
                     p             :  Repeat
                      Â            :    Bitwise NOT of bitwise NOT of
                       !X          :    Logical NOT of X
                         Ã         :End outer map
                          ñ        :Sort by
                           è       :  Count of
                            \a     :    RegEx /[a-z]/g
                                   :Implicit output of last element
\$\endgroup\$
3
\$\begingroup\$

Retina, 189 180 162 bytes

L$`\b((\w)+)\b(?=(.)*(?<=(?(2)$)((?<-2>\2)|.)*\1(?<-3>(?<-2>\2)|.)*))
$& $`$.&* $'
N^$`
$.&
0G`
|""L$`\G(?<=(.)*)(\w)(?=\w* ((?<-1>\1)|.)*?(?(1)$)(.*?)\2)
$.4* $2

Try it online! Link includes test cases. Explanation:

L$`\b((\w)+)\b(?=(.)*(?<=(?(2)$)((?<-2>\2)|.)*\1(?<-3>(?<-2>\2)|.)*))
$& $`$.&* $'

Find all of the words that are subsequences of the remaining string. .NET balancing groups are used twice, firstly ?<-2> matches the subsequence and secondly ?<-3> ensures that the original word is skipped at the right place when matching the subsequence. (Note that the lookbehind is processed right-to-left, so that the (?(2)$) is actually the last part of the regex.) For each word, prefix it to the input with that word replaced with spaces.

N^$`
$.&
0G`

Sort in reverse order of length and keep only the longest word.

|""L$`\G(?<=(.)*)(\w)(?=\w* ((?<-1>\1)|.)*?(?(1)$)(.*?)\2)
$.4* $2

Find the subsequence and output only those letters with the appropriate amount of spacing.

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

Maple, 221 bytes

proc(s)uses StringTools;b:=" ";for u in sort(Words(s),length)do L:=length(u);t:=Substitute(cat(s,b),cat(u,b),cat(b$L+1));j:=1;c:=cat([for i in t do if i=u[j] then j++;i else b fi od][]);`if`(j-1=L,(g:=c[..-2]),x)od;g end;
proc(s) uses StringTools;                # input string s
 b:=" ";  
 for u in sort(Words(s),length) do       # sort words in increasing length
                                         # so last and longest success is returned
  L:=length(u);  
  t:=Substitute(cat(s,b),cat(u,b),cat(b$L+1)); # replace word with spaces;
                                         # pad word and s with space so doesn't
                                         # substitute within a longer word
  j:=1;  
  c:=cat([for i in t do if i=u[j] then j++;i else b fi od][]); # scan with i
                                         # pointing in string and j in word
  `if`(j-1=L,(g:=c[..-2]),x)             # success recorded in g if word was
                                         # finished (strip previously added space)
 od;  
 g                                       # return g  
end;  

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

K (ngn/k), 70 bytes

{*<c!+/'^c:a{(,'y)@'(#*|b)|x~':b:x{(*x=y)_x}\y}'x/'+(,'a)@'=#a:x\y}" "

Try it online!

Wonder if there's a non-brute-force better way.

                                                            a:x\y  words
                                               x/'+(,'a)@'=#       each whited out in input
          a{                                 }'                    subsequences:
            (,'y)@'       x~':b:x{(*x=y)_x}\y                        fill in a subsequence
                   (#*|b)|                                           only if all chars present
*<c!+/'^c:                                                         min by #spaces
\$\endgroup\$
3
\$\begingroup\$

Python, 143 bytes

lambda s:max([(j:=0)or''.join(w[j:(j:=j+(z==w[j:j+(v!=w)]))]or' 'for v in s.split()for z in v+' ')[:0-j//len(w)]for w in s.split()],key=sorted)

Attempt This Online!

Still feels like there is some slack left.

History:

Python, 147 bytes

lambda s:max([(j:=0)or''.join(' '*(z!=w[j:j+1]or v==w)or z[:(j:=j+1)]for v in s.split()for z in v+' ')[:-(w[:j]==w)]for w in s.split()],key=sorted)

Attempt This Online!

This one avoids the super-expensive substring replacement. Turns out that is worth jumping through a hoop or two.

Python, 151 bytes

lambda s:max([''.join(D[c==w[j:j+1]and(j:=j+1)]for c in f' {s} '.replace(D,D.upper()))[1:-(w[j:]<D)]for w in s.split()if[j:=0,D:=f' {w} ']],key=sorted)

Attempt This Online!

Python, 152 bytes

lambda s:max([''.join(D[c==[*w,0][j]and(j:=j+1)]for c in f' {s} '.replace(D,D.upper()))[1:-(w[j:]<D)]for w in s.split()if[j:=0,D:=f' {w} ']],key=sorted)

Attempt This Online!

Python, 153 bytes

lambda s:max([''.join(D[c==[*w,0][j]and(j:=j+1)]for c in f' {s} '.replace(D,len(D)*' '))[1:-(w[j:]<D)]for w in s.split()if[j:=0,D:=f' {w} ']],key=sorted)

Attempt This Online!

Python, 160 bytes

lambda s:max([''.join(c*(c==D[j-1:j]!=[j:=j+1])or' 'for c in f' {s} ~'.replace(D,len(D)*' '))[1:j//len(D)*-2]for w in s.split()if[j:=1,D:=' %s '%w]],key=sorted)

Attempt This Online!

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

K (ngn/k), 56 bytes

{r@*<+/'1+^r:w@'<'>'w{y_x,y~:*x}/'x/'+(,'w)@'=#w:x\y}" "

Try it online!

Hat-tip @tubular for trimming a bunch off.

Another adaptation of my Speed of Lobsters golf, with pieces lifted from @att's answer.

  • {...x/'+(,'w)@'=#w:x\y}" " fix x as " " and generate strings, each replacing a single word with spaces (this is taken directly from @att's answer)
  • r:w@'<'>'w{y_x,y~:*x}/' do the Speed of Lobsters thing, storing results in r
  • r@*<+/'1+^r identify the result that contains the longest valid word (and return it)
\$\endgroup\$
1
  • \$\begingroup\$ LMAO speed of lobsters i didnt even think of that \$\endgroup\$ Commented Jan 4 at 19:34
3
\$\begingroup\$

Python, 162 bytes

lambda s:min((g:=lambda p,a,b:a and g(p+f' {a}'[t:=a[0]==b[:1]],a[1:],b[t:])or[b,-len(w),p])('',re.sub(fr'\b{w}\b',w.upper(),s),w)for w in s.split())[2];import re

Attempt This Online!

-5 bytes by Jonathan Allan -2 bytes by STerliakov

\$\endgroup\$
8
  • 1
    \$\begingroup\$ w.upper() saves a byte over ' '*len(w) (and maybe there is something even terser?). \$\endgroup\$ Commented Dec 18, 2024 at 11:51
  • 1
    \$\begingroup\$ Two more by inlining the sort order. \$\endgroup\$ Commented Dec 18, 2024 at 12:51
  • 1
    \$\begingroup\$ ...actually make that four more \$\endgroup\$ Commented Dec 18, 2024 at 14:12
  • \$\begingroup\$ @JonathanAllan Changed to len(b or w+s) seems shorter. And we use [1] instead of [-1] to save one more. \$\endgroup\$ Commented Dec 19, 2024 at 2:24
  • 1
    \$\begingroup\$ @JonathanAllan Nice idea. So maybe min of [b,-len(w),p] \$\endgroup\$ Commented Dec 19, 2024 at 11:12
2
\$\begingroup\$

Perl 5 -ap, 110 bytes

$"=".*";map{@;=/./g;$m=$_,@l=@;if"@F"=~s/\b$_\b//r=~@;&@;>@l}@F;s/\b$m\b/' 'x@l/e;s/./$&eq$l[0]?shift@l:' '/ge

Try it online!

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

Charcoal, 59 49 bytes

F⪪θ «≔⪪⮌ι¹ηP×⭆⪫E⪪θ ⎇⁼ικ⭆κ κ ⎇∧η⁼κ§η±¹⊟ηψ∧¬η›LιLKA

Try it online! Link is to verbose version of code. Explanation:

F⪪θ «

Split the input into words and loop over each word.

≔⪪⮌ι¹η

Start with all letters remaining to be matched. (The letters are reversed so that they can be easily removed as they are matched.)

P×⭆⪫E⪪θ ⎇⁼ικ⭆κ κ ⎇∧η⁼κ§η±¹⊟ηψ∧¬η›LιLKA

Replace the word in the original string with spaces, then replace all of the characters with nulls (which print as spaces but don't count as being printed, so the length of the previous result can be counted as the number of printed characters) except the letters from the word which are kept as they are matched. If this matched all of the letters, and this word is longer than any previously output word, then output the result, overwriting any previous result.

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

Wolfram Language (Mathematica), 302 bytes

f[i_]:=(s=StringSplit[i];c=First@MaximalBy[Cases[s,Alternatives@@LongestCommonSequence@@@Transpose@{StringRiffle@Delete[s,#]&/@Range@Length@s,s}],StringLength];j=1;StringJoin@@Select[Map[If[#==(Characters@c)[[j]],j+=1;#," "]&,Characters@StringRiffle@(s/.c->StringRepeat[" ",StringLength[c]])],StringQ])

Try it online!

\$\endgroup\$
6
  • \$\begingroup\$ Could you update the TIO link so that this shows how the code is used? Note that submissions should be either a callable function or a full program and not a "snippet" (that expects prepopulated variables for example). I am unfamiliar with Mathematica so can't tell which of those this is, but I suspect it is a snippet and the TIO link doesn't appear to have any input. (see this meta answer and, perhaps this meta too) \$\endgroup\$ Commented Dec 18, 2024 at 11:50
  • \$\begingroup\$ Thank you @JonathanAllan. Those links were very helpful. You addressed two problems I had, not knowing the correct format for an answer in Wolfram and also how to correctly use TIO! I have one question: You will see that my code for the second test case throws an error, but still goes on to produce the correct answer, is this acceptable in code golf? Thank you for your effort on my behalf. \$\endgroup\$ Commented Dec 19, 2024 at 5:23
  • \$\begingroup\$ I have seen other users add a "Quiet" function before the "Print" statement to suppress the Error messages from output \$\endgroup\$ Commented Dec 19, 2024 at 5:28
  • 1
    \$\begingroup\$ It is usually acceptable, although error messages usually go to stderr (in TIO, the "Debug" section), while these seem to be written to stdout. From this meta I see that this is what Mathematica does, so maybe the quiet function should be included; I don't see a specific meta question about it though, so perhaps ask one and reference this answer and users more familiar with Mathematica golfing can opine. \$\endgroup\$ Commented Dec 19, 2024 at 10:21
  • 1
    \$\begingroup\$ 180 bytes \$\endgroup\$ Commented Dec 20, 2024 at 2:15
2
\$\begingroup\$

Python 3, 186 174 bytes

A quick not-very-golfed solution; I expect it's possible to do much better. Might try again if I get some time. (PS Thanks @tsh for saving 11 bytes, and @jonathan-allan for saving 1 more.)

import re
def f(s):
 for w in sorted(s.split(),key=len)[::-1]:
  t=re.sub(fr"\b{w}\b",w.upper(),s);o=""
  for c in w:n=t.find(c);o+=" "*n+c;t=t[n+1or len(t):]
  if~n:return o

Try it online!

\$\endgroup\$
7
  • 2
    \$\begingroup\$ if you do try again, might i recommend def test(s): print(s,"\n"+f(s)) in the footer instead? lets you visually compare input and output :D \$\endgroup\$ Commented Dec 14, 2024 at 20:50
  • \$\begingroup\$ 173 bytes by removing the regex dependency. \$\endgroup\$ Commented Dec 15, 2024 at 19:30
  • 1
    \$\begingroup\$ @movatica unfortunately that doesn't handle the first two test cases, where the longest word is also a substring of one of the other words \$\endgroup\$ Commented Dec 15, 2024 at 22:19
  • \$\begingroup\$ ah, you're right! \$\endgroup\$ Commented Dec 15, 2024 at 23:55
  • 1
    \$\begingroup\$ w.upper() saves a byte over " "*len(w) (and maybe there is something even terser?). \$\endgroup\$ Commented Dec 18, 2024 at 11:52
0
\$\begingroup\$

Java , 472 bytes


> edit : addition of lastIndexmatcher so it ensures wd in orderr. 

import java.util.Scanner;

class Subsequenc {
    public static void main(String args[]) {
        Scanner sc = new Scanner(System.in);

        // Input the string and the word
        System.out.print("Enter the string: ");
        String str = sc.nextLine();

        System.out.print("Enter the word: ");
        String wd = sc.nextLine();

        // Result array initialized with spaces
        char ch[] = new char[str.length()];
        for (int i = 0; i < ch.length; i++) {
            ch[i] = ' ';
        }

        // Track the position of the last matched character
        int lastMatchedIndex = -1;

        // Match logic
        for (int i = 0; i < wd.length(); i++) {
            char currentChar = wd.charAt(i);
            boolean found = false;
            for (int j = lastMatchedIndex + 1; j < str.length(); j++) {
                if (str.charAt(j) == currentChar) {
                    ch[j] = currentChar; // Add the matched character
                    lastMatchedIndex = j; // Update the last matched index
                    found = true;
                    break; // Move to the next character in wd
                }
            }
            if (!found) {
                // If a character in wd isn't found after lastMatchedIndex, stop processing
                break;
            }
        }

        // Print the result
        for (char c : ch) {
            System.out.print(c);
        }
    }
}
\$\endgroup\$
4
  • 2
    \$\begingroup\$ Welcome to CGCC. I think you misunderstood the challenge. You only get one input (e.g. scream dream care), and you'd have to find the valid word yourself before replacing them with spaces. Also, it seems you're currently replacing the first occurrence of each character with a space instead of replacing them in order (e.g. input scream dream care with word care currently results in " crea " instead of " c a re " in your program). Feel free to delete your answer; fix it; and then undelete it again. \$\endgroup\$ Commented Dec 17, 2024 at 8:36
  • \$\begingroup\$ Also, Tips for golfing in Java and Tips for golfing in <all languages> might both be interesting to read through. :) \$\endgroup\$ Commented Dec 17, 2024 at 8:36
  • \$\begingroup\$ thanks kevin i'll fix it \$\endgroup\$ Commented Dec 22, 2024 at 12:31
  • \$\begingroup\$ sry idk there was a edit box already provided so i wrote it right there , and i hope the comments arent misleading \$\endgroup\$ Commented Dec 22, 2024 at 12:48

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.