Note: the title was misspelled intentionally.
Given a string s, swap the first vowel runs of every 2 words. For this challenge, y is considered a vowel.
For example, given an input of "great day sir":
1. Input: "great day sir"
2. Identify pairs of words: "[great day] [sir]" (No word for sir to pair with)
3. Identify the first vowel runs in each word: "[gr[ea]t d[ay]] [s[i]r]"
4. Swap the vowel runs in each pair: "[gr[ay]t d[ea]] [s[i]r]"
5. Return/print: "grayt dea sir"
When there are vowel runs of different lengths, you still swap the whole runs. When a word has more than one vowel runs, you still only swap the first one. When the first or second word of a pair of words does not have a vowel, then you do not swap the vowels for those words.
You may assume that the input only consists of one case of alphabetic letters and the literal space or another constant delimiter.
Standard methods of I/O, standard loopholes apply. Leading/trailing whatevers are okay.
Test cases:
Input -> Output
"great day sir" -> "grayt dea sir"
"ppcg is the best" -> "ppcg is the best" (When there is no vowel to swap, don't swap vowels."
"this is a test case" -> "this is e tast case"
"loooooooooooooong word" -> "long woooooooooooooord"
"great night" -> "grit neaght"
"anything goes" -> "oenything gas"
"qwrtpsdfghjklzxcvbnm aaaaaaaa hi there" -> "qwrtpsdfghjklzxcvbnm aaaaaaaa he thire"
"this is a long test case in case you could not tell" -> "this is o lang tast cese an cise ou cyould net toll"
12 Answers 12
V, (削除) 42 (削除ここまで), 41 bytes
ò2Eá
òÍ ̈[aeiouy]«© ̈ © ̈[aeiouy]«©/32±
Íî
Hexdump:
00000000: f232 45e1 0af2 cda8 5b61 6569 6f75 795d .2E.....[aeiouy]
00000010: aba9 a883 2083 a9a8 5b61 6569 6f75 795d .... ...[aeiouy]
00000020: aba9 2fb3 b2b1 0acd ee ../......
Explanation:
ò ò " Recursively:
2E " Move to the end of two words forward
á<cr> " And append a newline
This will put all groups of two words on their own line, for example:
this is
a long
test case
in case
you could
not tell
Now we run some fancy regex-magic:
Í " Globally substitute
̈[aeiouy]«© " A vowel (capture group 1)
̈<131> " Followed by as few characters as possible, then a space
<131>© " Followed by as few characters as possible (capture group 2)
̈[aeiouy]«© " Followed by a vowel again
/ " With:
32± " Capture groups '3', '2', '1'
Í " Remove all:
î " Newlines
-
\$\begingroup\$ Your regex doesn't require the end of a word between your two vowel groups. Try it online! \$\endgroup\$nmjcman101– nmjcman1012017年06月14日 13:50:37 +00:00Commented Jun 14, 2017 at 13:50
-
\$\begingroup\$ @nmjcman101 Are you looking at my old revision? Because that's exactly what I have right now \$\endgroup\$DJMcMayhem– DJMcMayhem2017年06月14日 13:52:34 +00:00Commented Jun 14, 2017 at 13:52
-
\$\begingroup\$ My TIO link wasn't fixing anything, I just changed the input. It swaps the letters oddly. \$\endgroup\$nmjcman101– nmjcman1012017年06月14日 13:53:31 +00:00Commented Jun 14, 2017 at 13:53
-
\$\begingroup\$ @nmjcman101 Ah, I see. Fixed now! \$\endgroup\$DJMcMayhem– DJMcMayhem2017年06月14日 13:57:55 +00:00Commented Jun 14, 2017 at 13:57
Japt, (削除) 39 (削除ここまで) 37 bytes
They said it would be ugly, but I didn't listen... and it was:
̧ò ®efQ="%y+" ?Z£XrQZg°T fQP PÃ:ZÃc ̧
Explanation
̧ ò ® efQ="%y+" ?Z£ XrQ Zg° T fQ P PÃ :ZÃ c ̧
UqS ò mZ{Zef"%y+" ?ZmXYZ{Xr"%y+"Zg++T f"%y+"P P} :Z} c qS
Implicit: U = input string, such as "abc def ghi jkl mno"
UqS Split on spaces, splitting into words. ["abc","def","ghi","jkl","mno"]
ò Group into runs of two items. [["abc","def"],["ghi","jkl"],["mno"]]
mZ{ For each pair Z:
Zef"%y+"? If not every item contains a run of vowels (%y = [AEIOUYaeiouy]),
:Z return Z. [ ["ghi","jkl"] ]
ZmXYZ{ Otherwise, for each item X in Z:
Xr"%y+" Replace each run of vowels with
Zg++T the item at the next index in Z, [["def","abc"] ["mno"]]
f"%y+"P but only the first run of vowels. [["e", "a" ] ["o" ]]
P Replace only for the first match. [["ebc","daf"] ["mno"]]
}
} [["ebc","daf"],["ghi","jkl"],"mno"]]
c Flatten back into a single array. ["ebc","def","ghi","jkl","mno"]
qS Re-join on spaces. "ebc daf ghi jkl mno"
Implicit: output result of last expression
JavaScript (ES6), (削除) 62 (削除ここまで) (削除) 106 (削除ここまで) (削除) 98 (削除ここまで) 101 bytes
s=>s.match(/(\w+)( (\w+))?/g).map(m=>m.replace(/([aeiouy]+)(\w* \w*?)([aeiouy]+)/g,'3ドル2ドル1ドル')).join` `
f=
s=>s.match(/(\w+)( (\w+))?/g).map(m=>m.replace(/([aeiouy]+)(\w* \w*?)([aeiouy]+)/g,'3ドル2ドル1ドル')).join` `
;
[
"great day sir",
"ppcg is the best",
"this is a test case",
"loooooooooooooong word",
"great night",
"anything goes",
"qwrtpsdfghjklzxcvbnm aaaaaaaa hi there",
].map(f).map(s=>console.log(s))
Retina, 65 bytes
((\w*?)([aeiouy]+)(\w* \w*?)([aeiouy]+)|(\w+ ))(\w*)
2ドル5ドル4ドル3ドル6ドル7ドル
Try it online! Includes test cases. I wanted to use a conditional group reference but I couldn't get it to work in 66 bytes let alone 65 or less.
Retina, 50 bytes
\S+ \S+
$&¶
%O$^`(?<=\b[^aeiouy]*)[aeiouy]+
$`
¶
−2 bytes thanks to Martin.
- First step is splitting each word pair to its own line (
¶is newline). This allows us to use.*within a pair of words. - Next, for each line we find the first vowel block in each word, and sort them by position in descending order.
-
\$\begingroup\$ I tried removing the double
[aeiouy]+but couldn't get something economic. \$\endgroup\$Kobi– Kobi2017年06月14日 06:36:04 +00:00Commented Jun 14, 2017 at 6:36 -
1\$\begingroup\$ It's marginally shorter to swap the runs with a sort stage: tio.run/… \$\endgroup\$Martin Ender– Martin Ender2017年06月14日 07:58:45 +00:00Commented Jun 14, 2017 at 7:58
-
\$\begingroup\$ @MartinEnder - Nice one! I couldn't get sorting to work. I tried another version that removed the
[aeiouy]duplication, but I can't golf it down. I think It might work nicely with your suggestion: tio.run/… \$\endgroup\$Kobi– Kobi2017年06月14日 08:24:10 +00:00Commented Jun 14, 2017 at 8:24
Python 2, 148 bytes
from re import*
v="([aeiouy]+)"
print sub(r"(\w+)(?: (\w+))?",lambda m:sub(v+"(.* .*?)"+v,lambda g:''.join(g.groups()[::-1]),m.group()),raw_input())
Code Golfing is getting addictive!
Sections off pairs of words, then grabs the 2 groups of vowels and the string in between, reverses the order and uses that as the substitute.
Perl, 58 bytes
57 bytes code + 1 for -p.
$v="([aeiouy]+)";s!\w+ \w+!$&=~s/$v(.* .*?)$v/3ドル2ドル1ドル/r!ge
-2 bytes thanks to @Dada!
-
\$\begingroup\$ Just a couple of bytes to save by dropping a
?and storing([aeiouy]+)in a variable: Try it online! \$\endgroup\$Dada– Dada2017年06月22日 13:55:20 +00:00Commented Jun 22, 2017 at 13:55
Haskell, (削除) 177 (削除ここまで) (削除) 173 (削除ここまで) (削除) 171 (削除ここまで) 169 bytes
unwords.s.words
s(x:y:z)=maybe[x,y]id(do(a,b)<-k x;(c,d)<-k y;j[b c,d a])++s z
s x=x
v=(`elem`"aeiouy")
j=Just
k s=do(a,(x:y,r))<-j$span v<$>break v s;j(x:y,\n->a++n++r)
This is a direct shortening of the following naïve solution, so there should something much better around here:
swapvowels :: String -> String
swapvowels = unwords . swapPairs . words
swapPairs :: [String] -> [String]
swapPairs (word1:word2:rest) =
case (,) <$> extractVowels word1 <*> extractVowels word2 of
Just ((vowels1, rebuild1), (vowels2, rebuild2))
-> [rebuild1 vowels2, rebuild2 vowels1] ++ swapPairs rest
Nothing -> [word1,word2] ++ swapPairs rest
swapPairs rest = rest
extractVowels :: String -> Maybe (String, String -> String)
extractVowels s = do
let isVowel l = l `elem` "aeiouy"
(a,b) <- Just $ break isVowel s
(w@(_:_),r) <- Just $ span isVowel b
return (w, \n -> a ++ n ++ r)
Ruby, 87+1 = 88 bytes
Uses the -p flag.
gsub(/(\w+) (\w+)/){_,a,b=*$~;a[r=/[aeiouy]+/]&&b[r]?a.sub(r,b[r])+' '+b.sub(r,a[r]):_}
Java (OpenJDK 8), (削除) 363 (削除ここまで) 304+25 bytes
-34 bytes thanks to @KevinCruijssen
Golfed:
l->{String s[]=l.split(" "),a,b;Pattern p=Pattern.compile("[aeiouy]+");for(int i=0;i<s.length-1;i+=2){Matcher m=p.matcher(s[i]),n=p.matcher(s[i+1]);a=m.find()?m.group():null;b=n.find()?n.group():null;if(a!=null&b!=null){s[i]=s[i].replaceFirst(a,b);s[i+1]=s[i+1].replaceFirst(b,a);}}return l.join(" ",s);}
Ungolfed:
String swapVowels(String line) {
String[] parts = line.split(" ");
Pattern pattern = Pattern.compile("([aeiouy]+)");
for (int i = 0; i < parts.length - 1; i += 2) {
Matcher matcherL = pattern.matcher(parts[i]), matcherR = pattern.matcher(parts[i + 1]);
String vowelRunL = matcherL.find() ? matcherL.group() : null, vowelRunR = matcherR.find() ? matcherR.group() : null;
if (vowelRunL != null & vowelRunR != null) {
parts[i] = parts[i].replaceFirst(vowelRunL, vowelRunR);
parts[i + 1] = parts[i + 1].replaceFirst(vowelRunR, vowelRunL);
}
}
return String.join(" ", parts);
}
-
2\$\begingroup\$ You can remove the parenthesis around the input (
(l)->tol->). You can addimport java.util.regex.*;to the byte-count, and remove all otherjava.util.regex.. You can remove the parenthesis in the regex ("([aeiouy]+)"->"[aeiouy]+"). And you can changeString[]s=l.split(" ");toString s[]=l.split(" "),a,b;, then you can remove theStringinside the for-loop; And you can changeString.join(" ",s);tol.join(" ",s);. Here is it all combined. [329 bytes] \$\endgroup\$Kevin Cruijssen– Kevin Cruijssen2017年06月14日 06:54:30 +00:00Commented Jun 14, 2017 at 6:54
Python 3, (削除) 198 (削除ここまで) (削除) 196 (削除ここまで) 192 bytes
- Saved 6 bytes: thanks to Zachary T :
if(m and n)to if m and n & removed unwanted r for regex string, index i starting from 1 instead of 0
from re import*
s=search
a=input().split()
v="[aeiouy]+"
j=1
while j<len(a):
i=j-1;m=s(v,a[j]);n=s(v,a[i])
if m and n:a[i]=sub(v,m[0],a[i],1);a[j]=sub(v,n[0],a[j],1)
j+=2
print(' '.join(a))
-
1\$\begingroup\$ I think you can shave three bytes off your program: one by removing the r before your string, another by changing
i+1<len(a)toi<=len(a), and the third by changingif(m and n)toif m and n. \$\endgroup\$Adalynn– Adalynn2017年06月14日 15:37:26 +00:00Commented Jun 14, 2017 at 15:37 -
1\$\begingroup\$ Thanks. But the
i+1<len(a)cannot be changed toi<=len(a)or else it will try to evaluatea[j]i.e.a[i+1]fori=len(a)and causeindex out of rangeerror: \$\endgroup\$0xffcourse– 0xffcourse2017年06月14日 15:51:09 +00:00Commented Jun 14, 2017 at 15:51 -
\$\begingroup\$ Sorry, I was reading that as
i<len(a)+1, whoops! \$\endgroup\$Adalynn– Adalynn2017年06月14日 15:54:36 +00:00Commented Jun 14, 2017 at 15:54 -
1\$\begingroup\$ Would this work? repl.it/IlX1 \$\endgroup\$Adalynn– Adalynn2017年06月14日 16:00:39 +00:00Commented Jun 14, 2017 at 16:00
-
1\$\begingroup\$ You have extraneous spaces at the end of some of your lines, I counted 192 bytes. \$\endgroup\$Adalynn– Adalynn2017年06月18日 17:12:41 +00:00Commented Jun 18, 2017 at 17:12
ppcg is awesomebecomeppcg is awesomeorppcg as iwesome? \$\endgroup\$this is a long test case in case you could not tellshould bethis is o lang tast cese an cise ou cyould net toll, since the vowel runsyouandouwould be swapped. \$\endgroup\$