25
\$\begingroup\$

This challenge is inspired by the meme Men of Culture.

The meme involves blanking out parts of the original caption,

Ah, I see you're a man of culture as well.

to make it appear as if the character is saying something else.

Your challenge is to write a program that, given an input, show how the original sentence can be blanked out to achieve the input string.

Rules:

  • Use a - character to represent a blanked out character.
  • You must not add additional letters to achieve the input string
  • You may treat string comparisons as case-insensitive
  • You may ignore whitespace in string comparisions
  • If no substitution is possible, output a falsy value.
  • You may substitute redundant whitespace with a - as well, although not required.
  • Where multiple solutions are possible, you may output any of them.

Test cases:

Basic:

Example Meme 1

Ah, I see you're a well.
> Ah, I see you're a --- -- ------- -- well.

Example Meme 2

Ah, I see well.
> Ah, I see ------ - --- -- ------- -- well.

Edge case 1:

What did you just say about me, you little
> false

Edge case 2 (edited):

*no input*
> --- - --- ------ - --- -- ------- -- -----

Intermediate:

Example Meme 3

Ah, I see you're Orwell.
> Ah, I see you're - --- o- -----r- -- well.

Example Meme 4

Ah, ymca.
> Ah, - --- y----- - m-- -- c------ a- ----.

Example Meme 5

Ah, a manual.
> Ah, - --- ------ a man -- -u----- a- --l-.
OR: > Ah, - --- ------ a man -- -u----- a- ---l.

Harder:

Example Meme 6

tea.
> --- - --- ------ - --- -- ---t--e a- ----.

Example Meme 7

eeeee
> --- - -ee -----e - --- -- ------e -- -e---

TL;DR: Given an input string, output a string which represents how the original string should be modified to fit the input string, by using a "-" to represent a blanked out character. If a substitution is not possible, output a falsy value.

Code golf, so shortest code in bytes wins.

Edit: Clarifications

  • Ignore whitespace in string comparisions means you can strip away whitespace before you compare strings. For instance, the inputs Ah, a manual and Ah , a manual are treated as equal. Other punctuation , ' . must be preserved. Similarly for output, Ah, a manual is equal to Ah, amanual.

  • substitute redundant whitespace refers to the spaces present in the original caption. You don't need to replace them with "-", but if replacing nets you more points then go ahead.

\$\endgroup\$
12
  • \$\begingroup\$ Your "Orwell" output seems wrong: you've changed an 'f' to an 'r' in the first one. \$\endgroup\$
    – Draconis
    Commented Apr 15, 2018 at 6:22
  • 2
    \$\begingroup\$ What output should "Ah,<5 SPACES HERE>a manual." yield? \$\endgroup\$
    – lynn
    Commented Apr 15, 2018 at 9:53
  • 3
    \$\begingroup\$ If a substitution is not possible, output a falsy value. Well, requiring input validation is highly discouraged. \$\endgroup\$ Commented Apr 15, 2018 at 9:57
  • 2
    \$\begingroup\$ You may treat string comparisons as case-insensitive does that mean we must treat the input as case-insensitive or that we're able to take input in whatever case we want? Also, by You may ignore whitespace in string comparisions, do you mean we must ignore spaces? And what is "redundant whitespace"? \$\endgroup\$ Commented Apr 15, 2018 at 9:59
  • 1
    \$\begingroup\$ I think "input validation," if you could call it that, makes sense here @EriktheOutgolfer \$\endgroup\$ Commented Apr 15, 2018 at 14:34

12 Answers 12

6
\$\begingroup\$

><>, 94 bytes

"vAh, I see you're a Man of Culture as well.
0/i~ <r
!\:?!^:}=0={:@*:@"-"$?$~}$:@?
<>~i+0)?;>o

Try it online!

Case-sensitive, doesn't ignore whitespace or punctuation and outputs an empty string if the input is invalid. If you want to try other strings, you can just modify the first line after the "v, as long as it doesn't contain a " or a null byte.

\$\endgroup\$
5
\$\begingroup\$

Retina 0.8.2, 117 bytes

^.
¶Ah, I see you're a Man of Culture as well.¶$&
{+i`¶(\W|(\w))(.*¶)(?(2)\W*\2)
$1¶$3
}1`¶\w
-¶
.*¶.*¶.*\w.*|¶.*¶.*

Try it online! Could save 1 byte by requiring case-sensitivity. Could save 3 bytes by returning --, - --- ---'-- - --- -- ------- -- ----. on empty input. Explanation:

^.
¶Ah, I see you're a Man of Culture as well.¶$&

Prepend the desired text to the input.

{+i`¶(\W|(\w))(.*¶)(?(2)\W*\2)
$1¶$3

Move as many characters from the desired text to the result as possible. If the character is a letter then it also needs to match the next letter in the input, which is then deleted.

}1`¶\w
-¶

If there is no matching letter in the input, change it to a - and try again.

.*¶.*¶.*\w.*|¶.*¶.*

If there are still letters left in the input, delete everything, otherwise delete the remainder of the input.

\$\endgroup\$
5
\$\begingroup\$

Jelly, 58 55 48 45 bytes

“¬²Ẉ,ȷCIbƝɼeỴƤ/ɓIŒ;ṫṚS⁶_ŀỤ ṂB⁾÷ƈ»Ḣ”-1ị⁼ɗ?@€xṆ

Try it online!


More readable version:

“Ah, I see you're a man of culture as well.”Ḣ”-1ị⁼ɗ?@€xṆ

String compression breakdown:

Ah, I{short: see}{short: you}'re a{short: man} of{long: culture} as{short: we}ll.
\$\endgroup\$
3
\$\begingroup\$

Python 2, 126 114 bytes

i=input()
r=''
for c in"Ah, I see you're a man of culture as well.":x=c==i[:1];r+=c*x or'-';i=i[x:]
print(i=='')*r

Try it online!


Python 2, 108 106 bytes

Input is a list of chars.

lambda i:''.join(c==`i`[2:3]and i.pop(0)or'-'for c in"Ah, I see you're a man of culture as well.")*(i==[])

Try it online!

\$\endgroup\$
3
  • \$\begingroup\$ Could (i=='') not be (i<' ') (using a tab, the lowest printable character)? \$\endgroup\$ Commented Apr 16, 2018 at 9:06
  • \$\begingroup\$ @JonathanFrech this is possible, but it is both 7 bytes \$\endgroup\$
    – ovs
    Commented Apr 16, 2018 at 11:33
  • \$\begingroup\$ Well, you have got a point there ... \$\endgroup\$ Commented Apr 16, 2018 at 18:03
2
\$\begingroup\$

JavaScript (Node.js), 122 120 bytes

x=>"Ah, I see you're a Man of Culture as well.".replace(/./g,c=>c>' '?/^(.)\1/i.test(c+x)?(x=x.slice(1).trim``,c):'-':c)

Try it online!

Explanation :

x =>                 // It takes in 'x' as parameter for function a string
    "Ah, I see you're a Man of Culture as well.". // What the actual is 
            .replace(                             // Now we are gonna replace 
                    /./g,     // selects everything 
                    c =>      // lambda function with param c
                        c > ' ' ?                 
                        /^(.)\1/i.test(           // does it all
                            c + x ) ?            // checks if there is a match
                            (x=x.slice(1). // returns everything from 1 to end in an array
                                trim`` ,   // removes whitespaces
                            c : '-' : c)   // and done

Can be reduced further but replaces whitespaces with '-' as well. If this is acceptable then

JavaScript (Node.js), 112 bytes

x=>"Ah, I see you're a Man of Culture as well.".replace(/./g,c=>/^(.)\1/i.test(c+x)?(x=x.slice(1).trim``,c):'-')

Try it online!

Reduced even further , only replaces whitespaces that are after the given string with '-'.

JavaScript (Node.js), 105 bytes

x=>"Ah, I see you're a Man of Culture as well.".replace(/./g,c=>/^(.)\1/i.test(c+x)?(x=x.slice(1),c):'-')

Try it online!

\$\endgroup\$
2
  • 1
    \$\begingroup\$ Don't pass What did you just say about me, you little \$\endgroup\$
    – l4m2
    Commented Apr 15, 2018 at 15:52
  • \$\begingroup\$ I'm not getting correct output for your code for the What did you just say about me, you little test case. Your program produces --- - --- ------ - --- -- ------- -- w---- as output which is not what the challenge spec requires. \$\endgroup\$
    – 0 '
    Commented Apr 16, 2018 at 6:47
2
\$\begingroup\$

JavaScript (Node.js), 135 bytes

x=>!!x&&(t="Ah, I see you're a Man of Culture as well.".replace(/./g,c=>c>' '?/^(.)\1/i.test(c+x)?(x=x.slice(1).trim(),c):'-':c),!x&&t)

Try it online!

If "may" mean either do or not do is okay, then

JavaScript (Node.js), 106 bytes

x=>x&&(t="Ah, I see you're a Man of Culture as well.".replace(/./g,c=>c==x[0]?(x=x.slice(1),c):'-'),!x&&t)

Try it online!

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

Brain-Flak, 764 600 bytes

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

Try it online!

Big improvements thanks to Jo King, especially in the string construction but also a few logical tweaks in the main body. Explanation from him

It's case-sensitive (so "Ah, I see you're Orwell." doesn't match but "Ah, I see you're orwell." does), whitespace in input is not ignored, and unmatched whitespace in original string is converted to -. By my understanding, all of those are valid options.

Explanation:

(476 bytes of much improved stack manipulation) #Push string

{ #While string
  ([{}]<>({})) #Check whether the top characters are equal
  {(<{}(((((()()()()())){}{})){}{})>)}{}  #If characters are not equal, push - on top of input
  (<({}<(<()>)<>{({}<>)<>}>{})>)<>{({}<>)<>}{}<>  #Take top of input (either - or matched char) and add to output
}{}
<>{{{}}<>} #Pop both stacks if input is left over
<>{({}<>)<>}<> #Reverse output
\$\endgroup\$
5
  • \$\begingroup\$ You know, there was a question earlier to help automate producing arbitrary test for Brain-Flak. My own submission can (with a couple of modifications) get the text down to 506 bytes \$\endgroup\$
    – Jo King
    Commented Apr 17, 2018 at 6:12
  • \$\begingroup\$ With a couple of other improvements, I got the total down to 604 bytes \$\endgroup\$
    – Jo King
    Commented Apr 17, 2018 at 6:43
  • \$\begingroup\$ Explanation \$\endgroup\$
    – Jo King
    Commented Apr 17, 2018 at 6:49
  • \$\begingroup\$ A nice and round 600 bytes \$\endgroup\$
    – Jo King
    Commented Apr 17, 2018 at 7:01
  • \$\begingroup\$ @JoKing you're very good at improving my Brain-Flak it seems \$\endgroup\$ Commented Apr 17, 2018 at 13:57
2
\$\begingroup\$

Haskell, 182 174 172 171 170 169 bytes

import Data.Char
t=toLower
a!b=(b:)<$>a
""%l=Just$'-'<$l
l@(a:b)%(c:d)|t a==t c=b%d!c|1>0=l%d!'-'
_%_=mempty
(%"Ah, I see you're a man of culture as well.").concat.words

Try it online!

Ungolfed:

import Data.Char

template = "Ah, I see you're a man of culture as well."

-- strip spaces
preprocess :: String -> String
preprocess = filter (/=' ')

-- case-insensitive character comparison
a#b = (toLower a) == (toLower b)

strike' :: String -> String -> Maybe String
strike' "" "" = Just ""  -- base case
strike' _ "" = Nothing   -- chars are exhausted, impossible to convert
strike' "" rem = Just $ '-' <$ rem  -- full match, strike rest of chars
strike' cur@(x:xs) (r:rs)
    | x # r     =   (r:) <$> strike' xs rs  -- character matches; pop a char
    | otherwise = ('-':) <$> strike' cur rs -- no match; strike char, don't pop

strike :: String -> Maybe String
strike xs = strike' (preprocess xs) template
\$\endgroup\$
1
\$\begingroup\$

Prolog (SWI), 109 bytes

[]+[]+[].
I+[B|X]+[C|O]:-(I=[B|J],B=C;I=J,C=45),J+X+O.
I-O:-I+`Ah, I see you're a man of culture as well.`+O.

Try it online!

Case-sensitive and whitespace sensitive. The -/2 predicate is the main predicate with its first argument being the input string and the second argument being the output string.

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

JavaScript (Node.js), 103 bytes

s=>!s[i=0,r="Ah, I see you're a man of culture as well.".replace(/./g,c=>c==s[i]&&++i||c-1?c:'-'),i]&&r

Try it online!

Case sensitive.

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

Pyth, 78 bytesSBCS

V." y°äz µÿéiSs¾ýØC[ócõ!ó5§n"=b.x@zZkIqbN=+kN=hZ.?=+k\-))I<Zlz!z.?k

Test suite
Unprintable characters present in code, see link for correct version.
Case sensitive, does not ignore whitespace.

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

Perl 5 -F, 192 bytes

@q="Ah, I see you're a man of culture as well."=~/./g;while($x=shift@F){$x=~/\w/||next;while($_=shift@q){push@r,/\W/?$_:/\Q$x/i?$_:'-';$r[-1]=~/\w/i&&last}@q||last}say!$x&&@r,map/\w/?'-':$_,@q

Try it online!

\$\endgroup\$

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.