15
\$\begingroup\$

The Language: Oppification

A funny language to speak is created by applying the following process to each word:

  1. Place op after each consonant. So Code becomes Copodope.

Yes, that's it. For the purpose of this challenge, y is always a consonant.

The Challenge: De-oppification

Given an oppified word, return the original word. Input will only contain letters. The first letter may be capitalized. The original word will never be empty and will always contain a vowel.

Test Cases:

Oppified      ->         Original 
a                        a
I                        I
itop                     it
opop                     op
Opop                     Op
popopop                  pop
Copopop                  Cop
opopopop                 opop
Kopicopkop               Kick
Asopia                   Asia
soptopopop               stop
hopoopopsop              hoops
hopoopopedop             hooped
ooooohop                 oooooh
aaaopopaaa               aaaopaaa
Popopopsopicoplope       Popsicle
gopaloplopopopinopgop    galloping
aopopbopopopcopopop      aopbopcop
\$\endgroup\$
  • 8
    \$\begingroup\$ None of your test cases contain a vowel followed by op, so an answer along the lines of replace(/(.)op/, '\1') won't fail any of them. I suggest that you add a word like hoop or looped to the test cases. \$\endgroup\$ – Doorknob Jun 5 '17 at 19:35
  • \$\begingroup\$ @mbomb007 I added some more tricky test cases. \$\endgroup\$ – xnor Jun 5 '17 at 20:09
  • \$\begingroup\$ Does the answer only have to work for preoppified inputs or all inputs? \$\endgroup\$ – CalculatorFeline Jun 6 '17 at 2:51
  • \$\begingroup\$ @CalculatorFeline "Given an oppified word" \$\endgroup\$ – mbomb007 Jun 6 '17 at 4:21
  • 2
    \$\begingroup\$ Can we add "mopmopmopbopopop" as a test case? :) \$\endgroup\$ – user2390246 Jun 6 '17 at 7:31

18 Answers 18

10
\$\begingroup\$

V, 12, 5 bytes

Í.“op

Try it online!

00000000: cd2e 936f 70                             ...op

Saved 7 bytes thanks to @Xnor's realization that since the input must always be opped, we don't have to check for vowels.

\$\endgroup\$
  • \$\begingroup\$ Hmm, this seems so hard to beat... \$\endgroup\$ – Erik the Outgolfer Jun 5 '17 at 20:08
  • 4
    \$\begingroup\$ The hex dump: ...op Is making me laugh way harder than it should \$\endgroup\$ – nmjcman101 Jun 6 '17 at 11:33
12
\$\begingroup\$

Retina, 9 bytes

(?!\G)op

Try it online!

Instead of checking that the preceding character is a consonant, we just make sure that the current op is not adjacent to either the beginning of the string or the previous match. The only case where we could match an incorrect op is if the original string contained an op (resulting in opop). But in that case we'll just remove the first op instead of the second and the result will be the same.

\$\endgroup\$
  • \$\begingroup\$ Wouldn't this give an incorrect answer for an input like loop? \$\endgroup\$ – Leo Jun 6 '17 at 7:27
  • 4
    \$\begingroup\$ @Leo loop is not a valid input because you can't obtain it from oppifying another word. \$\endgroup\$ – Martin Ender Jun 6 '17 at 7:39
  • \$\begingroup\$ @MartinEnder But lopoop (the oppified version of loop) is valid, and doesn't get de-oppified to loop. \$\endgroup\$ – Imus Jun 6 '17 at 11:48
  • \$\begingroup\$ @Imus no, the oppified version of loop is lopoopop. \$\endgroup\$ – Martin Ender Jun 6 '17 at 11:49
  • \$\begingroup\$ realised my mistake as well shortly after posting it :) was too slow in deleting. Good point. \$\endgroup\$ – Imus Jun 6 '17 at 11:50
10
\$\begingroup\$

Python, 42 bytes

lambda s:re.sub('(.)op',r'\1',s)
import re

Try it online!

If I'm not mistaken, you can just substitute all ?op with ? without caring about vowels. If the original string contains op, then it's oppified to opop, and the replacement returns it to op and no further. This is because the pattern matches for ?op cannot overlap, so only one op is removed.

A non-regex solution is 5 bytes longer.

Python, 47 bytes

f=lambda s:s and s[0]+f(s[1+2*(s[1:3]=='op'):])

Try it online

\$\endgroup\$
  • 3
    \$\begingroup\$ You can import re after you reference it‽ \$\endgroup\$ – Adám Jun 5 '17 at 20:57
  • 4
    \$\begingroup\$ @Adám Python doesn't evaluate it when the function is defined, only when it's called. \$\endgroup\$ – xnor Jun 5 '17 at 20:59
  • 4
    \$\begingroup\$ Wow, it's been a while since I've seen anyone use an interrobang. I guess that's a way to golf your comment a little. \$\endgroup\$ – Baldrickk Jun 6 '17 at 12:24
  • 1
    \$\begingroup\$ @Baldrickk But in bytes, the interrobang has >= bytes than just the string "?!" \$\endgroup\$ – MilkyWay90 2 days ago
5
\$\begingroup\$

Perl 5, 10 + 1 = 11 bytes

s/.\Kop//g

Try it online!

Run with -p (1 byte penalty); golfing languages might do implicit I/O automatically, but Perl needs an option for it.

When I saw @xnor's answer, I realised it could be improved using a Perl-specific regex feature; s/a\Kb/c/g is equivalent to s/ab/ac/g (in other words, the s/// only replaces the things after the first \K). So here's how it looks in Perl.

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

Retina, 15 8 bytes

(.)op
$1

Try it online!

-7 bytes thanks to Kevin Cruijssen

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

Go, 103 92 bytes

Must... compile... Go built-in functions have weird names. :P

import."regexp"
func f(s string)string{return MustCompile("(.)op").ReplaceAllString(s,"$1")}

Try it online!

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

Haskell (93 62 61 Bytes)

a(x:'o':'p':r)|notElem x"aeiouAEIOU"=x:a r
a(x:r)=x:a r
a x=x

thanks to @nimi suggestions in comments!

\$\endgroup\$
  • 2
    \$\begingroup\$ Some tips: as you are using v and o only once, you can inline it. notElem is shorter than not(...elem...). You can replace the && in a guard with a ,. The last case for a can be written as a x=x. No need for () in x:(a r). \$\endgroup\$ – nimi Jun 5 '17 at 20:56
  • 1
    \$\begingroup\$ ... oh, and the test for =="op" can be replaced with a literal pattern match: a(x:'o':'p':r)|notElem x"aeiouAEIOU"=x:a r \$\endgroup\$ – nimi Jun 5 '17 at 20:59
  • \$\begingroup\$ Updated. thanks @nimi \$\endgroup\$ – Davide Spataro Jun 5 '17 at 21:13
  • 1
    \$\begingroup\$ One more byte to save: you can omit the space between x and ". \$\endgroup\$ – nimi Jun 5 '17 at 21:21
3
\$\begingroup\$

PHP, 36 bytes

<?=preg_replace("#.\Kop#","",$argn);

Try it online!

\$\endgroup\$
  • \$\begingroup\$ How is this supposed to be run? \$\endgroup\$ – Titus Jun 6 '17 at 21:00
  • \$\begingroup\$ It fails for the first two test cases. Use preg_replace to fix. \$\endgroup\$ – Titus Jun 6 '17 at 21:03
  • \$\begingroup\$ You can save 3 bytes by renaming the variable to any single character, $a for instance \$\endgroup\$ – junkfoodjunkie Jun 7 '17 at 2:45
  • \$\begingroup\$ @junkfoodjunkie $argn is a reserved variable which is availbale when PHP is run with the -ROption from the command line \$\endgroup\$ – Jörg Hülsermann Jun 7 '17 at 9:30
  • \$\begingroup\$ Ah, okay, didn't know that. The online tester doesn't account for it. :-) \$\endgroup\$ – junkfoodjunkie Jun 7 '17 at 9:34
2
\$\begingroup\$

Japt, 9 bytes

r"%Vop"_g

Try it online

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

JavaScript (ES6), 35 bytes

Add f= at beginning and invoke like f(arg).

s=>s.replace(/([^aeiou])op/gi,"$1")

I am surprised no one posted a JavaScript solution yet....

Test Snippet

let f=
s=>s.replace(/([^aeiou])op/gi,"$1")

console.log("a" + " -> " + f("a"));
console.log("I" + " -> " + f("I"));
console.log("itop" + " -> " + f("itop"));
console.log("opop" + " -> " + f("opop"));
console.log("Opop" + " -> " + f("Opop"));
console.log("popopop" + " -> " + f("popopop"));
console.log("Copopop" + " -> " + f("Copopop"));
console.log("opopopop" + " -> " + f("opopopop"));
console.log("Kopicopkop" + " -> " + f("Kopicopkop"));
console.log("Asopia" + " -> " + f("Asopia"));
console.log("soptopopop" + " -> " + f("soptopopop"));
console.log("hopoopopsop" + " -> " + f("hopoopopsop"));
console.log("hopoopopedop" + " -> " + f("hopoopopedop"));
console.log("ooooohop" + " -> " + f("ooooohop"));
console.log("aaaopopaaa" + " -> " + f("aaaopopaaa"));
console.log("Popopopsopicoplope" + " -> " + f("Popopopsopicoplope"));
console.log("gopaloplopopopinopgop" + " -> " + f("gopaloplopopopinopgop"));
console.log("aopopbopopopcopopop" + " -> " + f("aopopbopopopcopopop"));

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

C (gcc), 83 bytes

main(c,v)char**v;{for(;*v[1];strchr("aAeEiIoOuU",putchar(*v[1]++))?:printf("op"));}

Try it online!

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

///, 18 bytes

/op/.//../o\p//.//

Try it online!

Note that this snippet wants to replace op with a ., but later on there is a replacement defined where op is being put back into the string. That second instruction would have the op replaced by a . (and thus insert a . into the end result), so I've used a \ between the o and p to break the pattern.

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

APL (Dyalog), 13 bytes

'(.)op'⎕R'\1'

Try it online!

Simply PCRE Replace any character followed by "op" with the character itself.

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

Crystal, 39 Bytes

def o(s)s.gsub(/([^aeiou])op/,"\\1")end

How it works

It simply searches for each consonant, followed by the sequence op. If so, replace that sequence only with the consonant found before: ([^aeiou]).

Try it online

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

Java 8, 36 26 bytes

s->s.replaceAll("(.)op","$1")

-10 bytes by replacing [^aeiou] with ., thanks to @xnor's explanation in his Python answer.

Try it here.

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

Ruby, 34 27 22 + 1 = 23 bytes

-4 bytes thanks to RJHunter.

+1 byte for the -p flag.

$_.gsub!(/(.)op/,'\1')

Try it online!

\$\endgroup\$
  • \$\begingroup\$ Using Ruby's -p option will cost a byte but allow your script to start directly with gsub. \$\endgroup\$ – RJHunter Jun 6 '17 at 1:08
0
\$\begingroup\$

sed, 22 bytes

sed -E 's/(.)op/\1/g'

Reads from STDIN until EOF and outputs de-oppified string
Uses same length reduction technique from @xnor's Python answer

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

R, 29 bytes

gsub("(.)op","\\1",scan(,''))

Try it online!

Much like most other solutions here, captures character followed by op, replaces it with character itself.

\$\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.