Every word from babab to zyzyz

38

2

Your task is to write a program that will output a readable list of every five letter words with the structure:

consonant - vowel - consonant - vowel - consonant

The output should be sorted alphabetically with one word per line and no words repeated twice. It can be lowercase or uppercase but not mixed. So the list could start and end like this:

babab  
babac  
babad  
...  
zyzyw  
zyzyx  
zyzyz 

Vowels are a-e-i-o-u-y, the other 20 English-alphabet letters are consonants.
Words don't have to be actual dictionary words.
Shortest code wins.

Note: A few years ago I stumbled upon a program on a university website that did exactly that. Turns out my first and last name fit the c-v-c-v-c constraint, and i'd been googling myself.

wilks

Posted 2017-01-12T11:52:46.923

Reputation: 471

7I see two things here. First, there are a ridiculous amount of words like this. How do you expect to test the entries? Also, there are many names that fit that constraint. The first that comes to mind is Jacob, although others like Lucas also fit – TrojanByAccident – 2017-01-12T12:10:06.007

9@TrojanByAccident I believe the challenge requires all possible matching letter combinations, regardless of whether they are names/English words. "Words don't have to be actual dictionary words." – trichoplax – 2017-01-12T12:22:58.177

@trichoplax if you mean my second point, I was referring to the OP's Note at the bottom – TrojanByAccident – 2017-01-12T12:24:03.970

@TrojanByAccident My apologies - I didn't realise they were separate points. In that case, I guess a program to test the outputs would be helpful. I make it 20620620=288,000 words in total, around 1,728,000 characters including delimiters. I'm not sure if a Stack Snippet can handle strings that long. – trichoplax – 2017-01-12T12:28:51.067

@TrojanByAccident The note was just to point out how I had the idea for the question, not an extra challenge. Also, my first name is Kevin :) – wilks – 2017-01-12T12:39:14.047

Does the order in which the names are output, matter? If so, can you please explain that order in more detail? – smls – 2017-01-12T12:48:05.380

@smls By incremental I mean that after babaz comes babeb, not babob or babib. So we work our way through vowels and consonants in the order they come in the alphabet. – wilks – 2017-01-12T12:50:11.987

Can we use uppercase instead of lowercase? – Adám – 2017-01-12T13:28:52.583

Can we return a list of strings instead? – Adám – 2017-01-12T13:29:57.590

@Adám The output should be formatted like in the example, lowercase, each word to its line, no repeats. – wilks – 2017-01-12T13:40:17.007

3

@wilks Relevant meta post -- Strict i/o formats aren't appreciated in this SE community. This challenge is focusing on generating c-v-c-v-c words, not inserting newlines between words, no?

– JungHwan Min – 2017-01-12T14:41:37.933

1@JungHwanMin Thanks for the link, first time here and I didn't know about this. I saw it as a readable and alphabetical list of all the c-v-c-v-c words. So I agree that upper or lowercase really doesn't matter, but I also think that one very long string or, say some nested arrays, whilst technically valid wouldn't be a great answer. – wilks – 2017-01-12T15:30:32.413

2Having run a few of the upvoted answers to this question, they obviously do not comply with "The output should be incremental with each word on its own line". Has this requirement been relaxed and if so can you edit the question to reflect this? I reckon I could lose quite a few bytes if my answer wasn't restricted by the format. – ElPedro – 2017-01-12T18:33:26.250

Answers

28

Mathematica, 72 65 61 bytes

Print@@@Tuples@{a=##/(b=#5#9#15#21#25#)&@@Alphabet[],b,a,b,a}

For testing, I recommend replacing Print@@@ with ""<>#&/@. Mathematica will then display a truncated form showing the first few and last few words, instead of taking forever to print 288,000 lines.

Explanation

I finally found a use for dividing strings. :)

I've been intrigued by the possibility of adding or multiplying strings for a while, but the actual use cases are fairly limited. The main point is that something like "foo"+"bar" or "foo"*"bar" (and consequently, the short form "foo""bar") is completely valid in Mathematica. However, it doesn't really know what to do with the strings in arithmetic expressions, so these things remain unevaluated. Mathematica does apply generally applicable simplifications though. In particular, the strings will be sorted into canonical order (which is fairly messed up in Mathematica, once you start sorting strings containing letters of various cases, digits and non-letters), which is often a dealbreaker, but doesn't matter here. Furthermore, "abc""abc" will be simplified to "abc"^2 (which is a problem when you have repeated strings, but we don't have that either), and something like "abc"/"abc" will actually cancel (which we'll be even making use of).

So what are we trying to golf here. We need a list of vowels and a list of consonants, so we can feed them to Tuples to generate all possible combinations. My first approach was the naive solution:

Characters@{a="bcdfghjklmnpqrstvwxz",b="aeiouy",a,b,a}

That hardcoded list of consonants does hurt a bit. Mathematica does have an Alphabet built-in which would allow me to avoid it, if I were able to remove the vowels in a cheap way. This is where it gets tricky though. The simplest way to remove elements is Complement, but that ends up being longer, using one of the following options:

{a=Complement[Alphabet[],b=Characters@"aeiouy"],b,a,b,a}
{a=Complement[x=Alphabet[],b=x[[{1,5,9,15,21,25}]]],b,a,b,a}

(Note that we don't need to apply Characters to the whole thing any more, because Alphabet[] gives a list of letters, not a string.)

So let's try that arithmetic business. If we represent the entire alphabet as a product of letters instead of a list, then we can remove letters by simple division, due to the cancelling rule. That saves a lot of bytes because we won't need Complement. Furthermore, "a""e""i""o""u""y" is actually a byte shorter than Characters@"aeiouy". So we do this with:

a=##/(b="a""e""i""o""u""y")&@@Alphabet[]

Where we're storing the consonant and vowel products in a and b, respectively. This works by writing a function which multiplies all its arguments with ## and divides them by the product of vowels. This function is applied to the alphabet list, which passes each letter in as a separate argument.

So far so good, but now we have

{a=##/(b="a""e""i""o""u""y")&@@Alphabet[],b,a,b,a}

as the argument to Tuples, and those things are still products, not lists. Normally, the shortest way to fix that is putting a List@@@ at the front, which turns the products into lists again. Unfortunately, adding those 7 bytes makes it longer than the naive approach.

However, it turns out that Tuples doesn't care about the heads of the inner lists at all. If you do

Tuples[{f[1, 2], f[3, 4]}]

(Yes, for an undefined f.) You'll get:

{{1, 3}, {1, 4}, {2, 3}, {2, 4}}

Just as if you had used a List instead of f. So we can actually pass those products straight to Tuples and still get the right result. This saves 5 bytes over the naive approach using two hardcoded strings.

Now the "a""e""i""o""u""y" is still fairly annoying. But wait, we can save a few bytes here as well! The arguments of our function are the individual letters. So if we just pick out the right arguments, we can reuse those instead of the string literals, which is shorter for three of them. We want arguments # (short for #1), #5, #9, #15, #21 and #25. If we put # at the end, then we also don't need to add any * to multiply them together, because (regex) #\d+ is a complete token that can't have any non-digit appended to it. Hence we end up with #5#9#15#21#25#, saving another 4 bytes.

Martin Ender

Posted 2017-01-12T11:52:46.923

Reputation: 184 808

11Reads explanation. So... basically magic. – Tally – 2017-01-12T14:57:06.257

I'm surprised and impressed by your Tuples trick. That's entirely undocumented, right? And unexpected given how the two-input form Tuples[list,n] deals with list not having the List head (to me at least)! – A Simmons – 2017-01-12T17:26:02.383

1@ngenisis I find that wording very confusing. Because it's not clear that this refers to the outer list when using multiple lists. Indeed Tuples[f[{1,2}, {3,4}]] gives {f[1, 3], f[1, 4], f[2, 3], f[2, 4]} instead. It's not documented that the inner head is completely ignored. – Martin Ender – 2017-01-12T21:45:02.137

@ASimmons cc. ^ – Martin Ender – 2017-01-12T21:45:12.113

Ah, I misunderstood – ngenisis – 2017-01-12T21:53:45.240

Possibly the one-argument form of Tuples was added later than the two-argument form? That would explain the confusing documentation. – A Simmons – 2017-01-16T11:39:16.683

16

Perl, 47 bytes

#!perl -l
/((^|[aeiouy])[^aeiouy]){3}/&&print for a..1x5

Counting the shebang as one.

Try it online!

primo

Posted 2017-01-12T11:52:46.923

Reputation: 30 891

2This is nice, well done! Any reasons you're not using say ? – Dada – 2017-01-12T12:57:37.027

Thanks. I disagree that -M5.01 should be 'free'.

– primo – 2017-01-12T13:02:37.320

1I like your opinion on -M5.010. And the intersting part in the golfing isn't to replace print with say... – Dada – 2017-01-12T13:05:44.017

Isn't -E (and subsequently say) a freebie? – Zaid – 2017-01-12T18:20:05.310

@Zaid See Primo's first comment

– Dada – 2017-01-12T19:12:12.123

11

Python 3 - 110 bytes

a,b="bcdfghjklmnpqrstvwxz","aeiouy";print(*(c+d+e+f+g for c in a for d in b for e in a for f in b for g in a))

Straightforward looping fun :)

Carra

Posted 2017-01-12T11:52:46.923

Reputation: 301

Think our ideas are the same but you beat me by 10 with Python 3! – ElPedro – 2017-01-12T16:03:23.653

I was just about to post a python2 equivalent using this approach. Too slow, a vote for you instead. – Chris H – 2017-01-12T16:15:01.880

8

Ruby, 72 71 52 bytes

puts (?z..?z*5).grep /#{["[^aeiouy]"]*3*"[aeiouy]"}/

Thanks to Value Ink for the basic idea, which brought that down to 60 bytes.

G B

Posted 2017-01-12T11:52:46.923

Reputation: 11 099

1It's shorter to generate a list of 5-letter words and using grep. If you generate a range that uses lower-case strings, you get a sequence of the lower-case words only. puts ("babab".."zyzyz").grep /#{["[^aeiouy]"]*3*"[aeiouy]"}/ for 60 bytes – Value Ink – 2017-01-13T02:20:00.337

7

05AB1E, 18 16 bytes

05AB1E uses CP-1252 encoding.

žP3ãžO3ãâ€øJ€¨ê»

Explanation

žP3ã                # push all combinations of 3 consonants
    žO3ã            # push all combinations of 3 vowels
        â           # cartesian product
         €ø         # zip each pair of [ccc,vvv] (c=consonant,v=vowel)
           J        # join to list of strings ['cvcvcv','cvcvcv' ...]
            ۬      # remove last vowel from each
              ê     # sort and remove duplicates
              »     # join on newlines

For testing purposes I recommend replacing žP with a few consonants and žO with a few vowels.

Example using 5 consonants and 3 vowels

Emigna

Posted 2017-01-12T11:52:46.923

Reputation: 50 798

nice use of Cartesian product. Wouldn't've thought of that. – Magic Octopus Urn – 2017-01-12T14:45:48.003

7

Python 2, 120 102 94 bytes

from itertools import*
lambda:map(''.join,product(*(('AEIOUY','BCDFGHJKLMNPQRSTVWXZ')*3)[1:]))

Try it online!

Rod

Posted 2017-01-12T11:52:46.923

Reputation: 17 588

7

PHP, 88 86 84 80 bytes

pretty string increment :)
6 bytes saved by @Christoph

for($s=$v=aeiouy;++$s<zyzza;preg_match("#[^$v]([$v][^$v]){2}#",$s)&&print"$s
");

loops through all strings from bababa to zyzyz and tests if they match the pattern. Run with -nr.

Titus

Posted 2017-01-12T11:52:46.923

Reputation: 13 814

Lol, golfing with a buggy language spec, I like it – Patrick Roberts – 2017-01-12T16:48:34.270

1@PatrickRoberts It´s not a bug. It´s a feature. :D I am sad they embedded an implicit cast to integer into $a="001";$a++; some day. That was a very unconvenient change. – Titus – 2017-01-12T16:52:13.880

I didn't say the "feature" was a bug, I said the specification was a bug. Sort of like how in JavaScript, typeof null == "object" – Patrick Roberts – 2017-01-12T17:18:02.810

1for($s=$v=aeiouy;++$s<zyzza;)preg_match("#[^$v][$v][^$v][$v][^$v]#",$s)&&print"$s\n"; saves you 1 char. Sadly you have to change echo to print to use &&. Replacing \n with a real line break saves another. – Christoph – 2017-01-13T11:04:18.767

1you might save some chars using "#([^$v][$v]){2}​[^$v]#" but I haven't tested it. – Christoph – 2017-01-13T13:08:09.213

1@Christoph: Idk why, but ([^$v][$v]​){2}[^$v] does not work in the loop, while [^$v]([$v]​[^$v]){2} does. Both work standalone (even with the variable) though. – Titus – 2017-01-13T14:01:13.623

7

Pure Bash, 74

v={a,e,i,o,u,y}
c={b,c,d,f,g,h,{j..n},{p..t},v,w,x,z}
eval echo $c$v$c$v$c

Straightforward brace expansion.

Try it online.


If each item must be on its own line, then we have:

Pure Bash, 84

v={a,e,i,o,u,y}
c={b,c,d,f,g,h,{j..n},{p..t},v,w,x,z}
eval printf '%s\\n' $c$v$c$v$c

Digital Trauma

Posted 2017-01-12T11:52:46.923

Reputation: 64 644

6

MATL, 21 bytes

11Y2'y'h2Y2X~6Myyy&Z*

Try it online! (but output is truncated).

11Y2   % Push 'aeiou' (predefined literal)
'y'    % Push 'y'
h      % Concatenate: gives 'aeiouy'
2Y2    % Push 'abcdefghijklmnopqrstuvwxyz' (predefined literal)
X~     % Set symmetric difference: gives 'bcdfghjklmnpqrstvwxz'
6M     % Push 'aeiouy' again
yyy    % Duplicate the second-top element three times onto the top. The stack now
       % contains 'bcdfghjklmnpqrstvwxz', 'aeiouy', 'bcdfghjklmnpqrstvwxz',
       % 'aeiouy', 'bcdfghjklmnpqrstvwxz'
&Z*    % Cartesian product of all arrays present in the stack. Implicity display

Luis Mendo

Posted 2017-01-12T11:52:46.923

Reputation: 87 464

I think this should work, shaving a byte: 11Y2'y'h2Y2yX~yyy&Z* (Try it online!)

– Conor O'Brien – 2017-01-12T16:45:23.827

@ConorO'Brien Unfortunately, that creates the vcvcv pattern, not cvcvc as required. Thanks though! – Luis Mendo – 2017-01-12T16:55:34.523

6

Haskell, 54 51 bytes

l="bcdfghjklmnpqrstvwxz":"aeiouy":l
mapM(l!!)[0..4]

mapM func list builds all words by taking the possible characters for index i from the list returned by func (list!!i).

Edit: @xnor found 2 bytes to save and looking at his solution, I found another one.

nimi

Posted 2017-01-12T11:52:46.923

Reputation: 34 639

mapM id$take 5$cycle["bcdfghjklmnpqrstvwxz","aeiouy"] saves a byte. – xnor – 2017-01-12T21:47:31.990

Better yet, mapM(cycle["bcdfghjklmnpqrstvwxz","aeiouy"]!!)[0..4] or mapM(["bcdfghjklmnpqrstvwxz","aeiouy"]!!)[0,1,0,1,0]. It would be nice not to hardcode the vowels and consonants, but mapM(\n->[x|x<-['a'..'z'],elem x"aeiou"==odd n])[0..4] doesn't quite make it. – xnor – 2017-01-12T21:55:25.123

@xnor: Thanks! Replacing cycle from your first variant with explicit recursion saves an additional byte. – nimi – 2017-01-13T01:03:55.197

6

Python, 92 bytes

f=lambda i=-4,s='':i*[s]or sum([f(i+1,s+c)for c in i%2*'AEIOUY'or'BCDFGHJKLMNPQRSTVWXZ'],[])

Can't let itertools win out. Iterative is 1 byte longer in Python 2.

W='',
for s in(['AEIOUY','BCDFGHJKLMNPQRSTVWXZ']*3)[1:]:W=[w+c for w in W for c in s]
print W

xnor

Posted 2017-01-12T11:52:46.923

Reputation: 115 687

This is awesome ^_^ – ABcDexter – 2017-01-13T09:09:24.183

5

JavaScript (ES6), 91 90 bytes

f=(s='',i=4)=>{for(c of i%2?'aeiouy':'bcdfghjklmnpqrstvwxz')i?f(s+c,i-1):console.log(s+c)}

Edits

  • ETHproductions: -1 byte by removing extraneous group around ternary operator in for statement

Explanation

This defines a 5-deep recursive function that uses the parity of its depth of call to determine whether to iterate vowels or consonants. On each iteration, it checks to see whether to recurse or print by checking the amount of recursions left, and concatenates the letter of its current iteration to the end of the 5 character string that is currently being built depth-first.

Alternative 89 byte solution assuming ISO8859-1 encoding:

f=(s='',i=4)=>{for(c of i%2?'aeiouy':btoa`mÇ_äi骻-¿s`)i?f(s+c,i-1):console.log(s+c)}

Alternative 96 byte solution that returns entire output as single string:

f=(s='',i=4,o='')=>eval("for(c of i%2?'aeiouy':'bcdfghjklmnpqrstvwxz')o+=i?f(s+c,i-1):s+c+`\n`")

Run at your own risk. For the 91 byte solution, just use f() and for the 97 byte alternative, use console.log(f()).

Patrick Roberts

Posted 2017-01-12T11:52:46.923

Reputation: 2 475

I tried turning the solution into a generator in two different ways. Using the shorthand form supported only by Firefox is the same length: f=(s='',i=2)=>(for(c of(i%2?'aeiouy':'bcdfghjklmnpqrstvwxz'))for(q of i?f(s+c,i-1):[s+c])q) Using the standard form is unfortunately a byte longer: function*f(s='',i=2){for(c of(i%2?'aeiouy':'bcdfghjklmnpqrstvwxz'))yield*i?f(s+c,i-1):[s+c]} Still waiting for the day when a generator is the shortest option...

– ETHproductions – 2017-01-12T19:30:21.127

1btw, you can remove the inner parens in the for...of statement to save a byte – ETHproductions – 2017-01-12T19:30:49.563

5

Brachylog, 18 bytes

@W:@Dg:2jcb:eac@w\

Try it online!

Explanation

@W:@D                 The list ["aeiouy", "bcdfghjklmnpqrstvwxz"]
     g:2jcb           The list ["bcdfghjklmnpqrstvwxz", "aeiouy", "bcdfghjklmnpqrstvwxz", "aeiouy", "bcdfghjklmnpqrstvwxz"]
           :ea        Take one character of each string
              c       Concatenate into a single string
               @w     Write to STDOUT followed by a newline
                 \    Backtrack: try other characters of the string

Fatalize

Posted 2017-01-12T11:52:46.923

Reputation: 32 976

I was surprised at the need for the g and b, but testing it, this is because j seems to refuse to take a list of strings as input? :ea really shows off the strengths of Prolog/Brachylog, though, and is a step that most other languages find much more difficult. – None – 2017-01-12T18:46:46.480

@ais523 Yes, I was also suprised that the g and b were needed. j seems to be bugged and this is due once again to the difficulty of distinguishing a list of arguments from just a list. I might fix this though this will once again complexify the implementation. I might as well just not fix it and invest my time on fixing the core problem in a new version of Brachylog. – Fatalize – 2017-01-13T09:26:45.593

5

C, 201 199 186 184 183 169 163 bytes

Doing it a bit differently than with the previous basic counting method:

f(){for(char*c="bcdfghjklmnpqrstvwxz",*v="aeiouy",i[5]={0},*s[]={c,v,c,v,c},j=0;j<5;puts("")){for(j=5;j--;putchar(s[j][i[j]]));for(;j++<5&&!s[j][++i[j]];i[j]=0);}}

Ungolfed:

f() {
    for(char *c="bcdfghjklmnpqrstvwxz", *v="aeiouy", i[5]={0}, *s[]={c,v,c,v,c}, j=0; j<5; puts("")) {
        for (j=5; j--; putchar(s[j][i[j]])) ;
        for (; j++ < 5 && !s[j][++i[j]]; i[j]=0) ;
    }
}

And written in a bit more conventional way:

f() {
    char *c="bcdfghjklmnpqrstvwxz", *v="aeiouy", i[]={0,0,0,0,0}, *s[]={c,v,c,v,c}, j=0;
    while (j>=0) {
        for (j=0; j<5; j++) putchar(s[j][i[j]]); // output the word
        while (--j>=0 && !s[j][++i[j]]) i[j]=0; // increment the counters
        puts("");
    }
}

Basically, i are the counters, and s the array of strings containing all the chars over which we should iterate, for each counter. The trick is the inner while loop: it is used to increment the counters, starting from the rightmost one. If we see that the next character we should display is the ending null char, we restart the counter to zero and the "carry" will be propagated to the next counter.

Thanks Cristoph!

dim lost faith in SE

Posted 2017-01-12T11:52:46.923

Reputation: 7 018

Welcome to PPCG! – Martin Ender – 2017-01-13T10:50:33.310

1char *c I think the space is unnecessary. – Christoph – 2017-01-13T12:09:16.027

@Christoph You're right, thanks. – dim lost faith in SE – 2017-01-13T12:10:16.560

1f(){char*c="bcdfghjklmnpqrstvwxz",*v="aeiouy",i[]={0,0,0,0,0},*s[]={c,v,c,v,c},j=0;while(j>=0){for(j=0;j<5;++j)putchar(s[j][i[j]]);for(;--j>=0&&!s[j][++i[j]];)i[j]=0;puts("");}} gets you to 177. Come on you can do even better ;). – Christoph – 2017-01-13T12:21:46.213

2Using i[5]={0} instead of i[]={0,0,0,0,0} saves 7 bytes. – Falken – 2017-01-13T12:24:40.910

char*c="bcdfghjklmnpqrstvwxz",*v="aeiouy",i[5]={0},*s[]={c,v,c,v,c};f(int j=0){for(;j<5;)putchar(s[j][i[j++]]);for(;j-->0&&!s[j][++i[j]];)i[j]=0;puts("");j<0||f();} 164. Note that in general to get those versions compile I need int f() not sure if some compilers allow it without. – Christoph – 2017-01-13T12:44:47.640

@Christoph All right, let's invite recursivity in... I thought that was already pretty twisted, but it seems there are no limits. I'm not sure about the s[j][i[j++]], though. Isn't that undefined, per the C specifications? I thought the order of evaluation (j being used twice and with a postincrement) wasn't guaranteed. – dim lost faith in SE – 2017-01-13T12:52:02.730

If that bothers you it only saves 1 char: f(){for(char*c="bcdfghjklmnpqrstvwxz",*v="aeiouy",i[5]={0},*s[]={c,v,c,v,c},j;j>=0;puts("")){for(j=-1;++j<5;)putchar(s[j][i[j]]);for(;j-->0&&!s[j][++i[j]];)i[j]=0;}} 165 nonrecursive. – Christoph – 2017-01-13T13:01:23.367

@Christoph Thanks. There is another thing that bothers me: j isn't actually initialized when declared, and you're testing it right away. Did I miss something? – dim lost faith in SE – 2017-01-13T13:07:48.533

Your making this quite hard: f(){for(char*c="bcdfghjklmnpqrstvwxz",*v="aeiouy",i[5]={0},*s[]={c,v,c,v,c},j=0;j<5;puts("")){for(j=5;j--;putchar(s[j][i[j]]));for(;j++<5&&!s[j][++i[j]];i[j]=0);}} 163 nonrecursive without undefined behavior (as far as I can still tell at this point) – Christoph – 2017-01-13T13:35:08.360

1@Christoph Aha, thanks. Good job. But you seemed to enjoy it, that's why I was pushing the challenge (no, I'm kidding: I did that just because I'm a pain in the ass). Seriously, thanks for the enlightenments. – dim lost faith in SE – 2017-01-13T13:47:26.600

4

Perl, 71 bytes

map{push@{1+/[aeiouy]/},$_}a..z;$"=",";say for glob"{@1}{@2}"x2 ."{@1}"

Try it online!

Explanation

I'll add more explanations later.

map{push@{1+/[aeiouy]/},$_}a..z; creates two arrays: @1 contains the consonants, and @2 contains the vowels.
glob when call with arguments like {a,b}{c,d} returns all permutations of the elements in the braces.

Dada

Posted 2017-01-12T11:52:46.923

Reputation: 8 279

4

Befunge, 95 bytes

::45*%\45*/:6%\6/:45*%\45*/:6%\6/1g,2g,1g,2g,1g,55+,1+:"}0":**-!#@_
bcdfghjklmnpqrstvwxz
aeiouy

Try it online!, although note that the output will be truncated.

This is just a loop over the range 0 to 287999, outputting the index as a mixed based number 20-6-20-6-20, with the "digits" of the number retrieved from the tables on the last two lines.

James Holderness

Posted 2017-01-12T11:52:46.923

Reputation: 8 298

4

Perl 6, 70 bytes

$_=<a e i o u y>;my \c=[grep .none,"a".."z"];.say for [X~] c,$_,c,$_,c

Explanation of the interesting part:

.say for [X~] c, $_, c, $_, c

              c, $_, c, $_, c  # list of five lists
         [X ]                  # lazily generate their Cartesian product
           ~                   # and string-concatenate each result
.say for                       # iterate to print each result

The code before that just generates the list of vowels ($_) and the list of consonants (c), which is regrettably verbose.

smls

Posted 2017-01-12T11:52:46.923

Reputation: 4 352

4

Python 2, 120 117 bytes

Thanks to @WheatWizard for the tabs tip.

x,y='aeiouy','bcdfghjklmnpqrstvwxz'
for a in x:
 for e in x:
	for b in y:
		for c in y:
			for d in y:print b+a+c+e+d

Try it online!

Not sure that this can be golfed much. Try it online truncates at 128KB but shows enough to give an idea. A local run with debug code to count the words gave a total of 288000. Runs in about 45 seconds if anyone wants to test.

zyzyv
zyzyw
zyzyx
zyzyz
Total word count: 288000

Non-compliant and therefore non-competing version (prints out nested arrays instead of the specified format) for 110 bytes:

x,y='aeiouy','bcdfghjklmnpqrstvwxz'
print[[[[c+a+d+b+e for e in y]for d in y]for c in y]for b in x]for a in x]

ElPedro

Posted 2017-01-12T11:52:46.923

Reputation: 5 301

1Was my first implemenation :) – Carra – 2017-01-12T17:14:11.317

Instead of using spaces for all your indentation you can use spaces for the single indent and tabs for double. – Post Rock Garf Hunter – 2017-01-13T01:46:41.113

4

JavaScript (Firefox 30-57), 82 bytes

f=(i=5)=>i?[for(s of f(i-1))for(c of i%2?'bcdfghjklmnpqrstvwxz':'aeiouy')s+c]:['']

Returns an array of strings. Very fast version for 102 101 (1 byte thanks to @ETHproductions) bytes:

_=>[for(i of c='bcdfghjklmnpqrstvwxz')for(j of v='aeiouy')for(k of c)for(l of v)for(m of c)i+j+k+l+m]

Neil

Posted 2017-01-12T11:52:46.923

Reputation: 95 035

Nice. There's an extraneous space in the fast version which can be removed for 101 bytes – ETHproductions – 2017-01-13T17:06:37.260

4

xeger, 49 bytes

([bcdfghj-np-tvwxz][aeiouy]){2}[bcdfghj-np-tvwxz]

Given a regular expression, xeger simply generates all matching strings. In order not to kill the browser, it pauses every 1000 outputs and you need to click to continue, but it'll get there eventually.


Here's a 23-byte version with a bug in ^ fixed:

([:c^y][:v:y]){2}[:c^y]

These are character classes "all lower-case ASCII consonants" [:c] with y excluded ^y, and "all lower-case ASCII vowels" [:v:] with y added.

Michael Homer

Posted 2017-01-12T11:52:46.923

Reputation: 721

What regex flavour is this based on? (Or if you rolled your own, what features does it support? Is there any documentation on this?) – Martin Ender – 2017-01-13T10:10:19.673

@MartinEnder It's a roll-your-own from DFA traversal (grown from a DFA/NFA visualiser I built for students, which has some limited documentation) - no backreferences, nothing non-regular. It's very slow for longer strings. The only interesting feature of the expressions themselves is conjunction with &.

– Michael Homer – 2017-01-13T20:35:01.440

I added documentation of the rest to the page, and some samples. – Michael Homer – 2017-01-13T22:02:11.607

1Looks like you've implemented ranges in character classes. Then you could do [bcdfghj-np-tvwxz]. – Martin Ender – 2017-01-14T09:37:30.233

4

Perl 6, 53 Bytes

/<-[aeiouy]>**3%<[aeiouy]>/&&.say for [...] <a z>Xx 5

Takes a little time to have any output. Very inefficient. Does the job.

Maniacs Thrift Jewels

Posted 2017-01-12T11:52:46.923

Reputation: 41

Welcome to PPCG! – Martin Ender – 2017-01-13T11:05:31.747

3

Perl, 63 59 54 bytes

$a="aeiouy";$b="[^$a][$a]"x2;for("a"x5.."z"x5){say if/$b[^$a]/}
$a="aeiouy";$b="[^$a][$a]"x2;/$b[^$a]/&&say for"a"x5.."z"x5

$a=aeiouy;$b="[^$a][$a]"x2;/$b[^$a]/&&say for a.."z"x5

Trying Perl golf for a change.
EDIT: Looks like I've still got much to learn... :)

smls

Posted 2017-01-12T11:52:46.923

Reputation: 4 352

Nice one (even if Primo's answer is shorter). You can write the end as /$b[^$a]/&&say for"a"x5.."z"x5 to save a few bytes. Edit: and you can drop the $b and do $a="aeiouy";/([^$a][$a]){2}[^$a]/&&say for"a"x5.."z"x5. – Dada – 2017-01-12T13:11:44.067

Also, you don't need the quotes around aeiouy. Also, since your regex checks for 5 characters, you can do a.."z"x5. – Dada – 2017-01-12T19:19:21.640

@Dada: Thanks. As someone who uses Perl for normal programming but until now not for golfing, I didn't even think to exploit non-strict mode. That's why I chose $a and $b as variable names, because those don't need to be declared even in strict mode... :) I also use Perl 6 a lot these days, which doesn't even have a non-strict mode. – smls – 2017-01-13T07:05:38.523

3

CJam, 32 31 29 28 bytes

Saved 2 bytes thanks to Martin Ender and 1 byte thanks to kaine

"aeiouy"_'{,97>^\1$1$1$N]:m*

Try it online! (Note that the output gets cut off on TIO)

Explanation

"aeiouy"_ e# Push the six vowels and duplicate
'{,97>    e# Push the whole alphabet
^         e# Symmetric set difference of the alphabet with the vowels, yields the consonants only
\         e# Swap top two elements
1$1$1$    e# Copy the second-from-the-top string to the top three times
          e# This results in the array being consonants-vowels-consonants-vowels-consonants
N         e# Add a newline character to the end of the list
]         e# End an array. Puts everything done so far in an array
          e# since there was no explicit start of the array.
:m*       e# Reduce the array using Cartesian products

Business Cat

Posted 2017-01-12T11:52:46.923

Reputation: 8 927

'{,97> to get the alphabet. And then "aeiouy"_'{,97>^ to save another byte on 1$. – Martin Ender – 2017-01-12T15:42:35.417

you don't need the very first character. It is assumed if it gets to start of the stack. – kaine – 2017-01-12T18:04:11.307

@kaine Interesting, didn't know that. Thanks. – Business Cat – 2017-01-12T18:30:09.653

$"aeiouy"_'{,97>^]3(;:mN*$ ignore the $ signs. Idk how to put code in comments. – kaine – 2017-01-12T20:55:13.507

@kaine Use backticks, like "`". – Conor O'Brien – 2017-01-15T16:45:04.337

3

Scala, 87 86 bytes

val a="aeiouy"
val b='a'to'z'diff a
for(c<-b;d<-a;e<-b;f<-a;g<-b)println(""+c+d+e+f+g)

jaxad0127

Posted 2017-01-12T11:52:46.923

Reputation: 281

You can replace f"$c$d$e$f$g" with ""+c+d+e+f+g to save a byte. – corvus_192 – 2017-01-13T10:18:23.360

3

Stacked, noncompeting, 51 bytes

(consonants:@c vowels:@v c v c)multicartprod$outmap

Pretty simple. Try it here!

Conor O'Brien

Posted 2017-01-12T11:52:46.923

Reputation: 36 228

3

R, 111 98 bytes

Added y as a vowel, and golfed off 13 bytes, thanks to @Patrick B.

l=letters
v=c(1,5,9,15,21,25)
apply(expand.grid(C<-l[-v],V<-l[v],C,V,C)[,5:1],1,cat,fill=T,sep="")

We use expand.grid to generate all possible combinations of V and C in a matrix, which we define from the preset variable letters (the alphabet). We reverse the combinations (as the default is for the first variable to rotate the fastest) to ensure alphabetical order. Then we iterate through each row of the matrix, printing each letter to stdout. We use the fill argument to cat to ensure that each word begins on a new line.

rturnbull

Posted 2017-01-12T11:52:46.923

Reputation: 3 689

Nice! You can chop this down further to 98 characters (adding 'y' as a vowel, or 95 if not) by using some options in cat and by renaming "letters": l=letters;v=c(1,5,9,15,21,25);apply(expand.grid(C<-l[-v],V<-‌​l[v],C,V,C)[,5:1],1,‌​cat,fill=T,sep="") – Patrick B. – 2017-01-14T02:30:13.810

@PatrickB. Thanks! I've incorporated your suggestions. – rturnbull – 2017-01-16T09:23:15.007

86 bytes – J.Doe – 2018-09-17T11:46:51.917

3

R, 143 132 bytes

q=letters;v=c(1,5,9,15,21,25);x=list(q[-v],q[v],q[-v],q[v],q[-v]);Reduce(paste0,mapply(function(a,b)rep(a,e=b/20),x,cumprod(sapply(x,length))))

q=letters;v=c(1,5,9,15,21,25);x=list(a<-q[-v],b<-q[v],a,b,a);Reduce(paste0,mapply(function(a,b)rep(a,e=b/20),x,cumprod(lengths(x))))

This is my first go at code golf so I'd welcome any suggestions to chop it down further. So far it's all pretty standard R; the only possibly tricky thing here is that paste0 recycles its arguments to the length of the longest one.

Edit: used assignment trick from rturnbull, replaced sapply(x,length) with lengths.

Patrick B.

Posted 2017-01-12T11:52:46.923

Reputation: 131

Welcome to the site! This looks quite good (I have only programmed a bit in R myself) I would just recommend not including old code in your answer. The edit history is always available so anyone that wishes to can always view it. This is more of a personal stylistic thing so feel free to ignore my opinion. – Post Rock Garf Hunter – 2017-01-14T02:56:01.650

You can brute-force it with function assignments for 114 bytes!

– Punintended – 2019-09-04T22:34:29.053

2

C 361 bytes

f(){i,j,k,l,m;v[6]={97,101,105,111,117,121};c[25];s=26;for(i=0;i<26;i++)c[i]=97+i;for(i=0;i<26;i++){for(j=0;j<6;j++)if(c[i]==v[j])c[i]+=1;}for(i=0;i<s;i++)for(j=i+1;j<s;){ if(c[i]==c[j]){for(k=j;k<s-1;++k)c[k]=c[k+1];--s;}else ++j;}for(i=0;i<s;i++)for(j=0;j<6;j++)for(k=0;k<s;k++)for(l=0;l<6;l++)for(m=0;m<s;m++)printf("%c%c%c%c%c\n",c[i],v[j],c[k],v[l],c[m]);}

Ungolfed version:

void f()
{   
int i,j, k,l,m;
int s=26;
int v[6]={97,101,105,111,117,121};
int c[s];

for(i=0;i<s;i++)
 c[i]=97+i;
for(i=0;i<s;i++)
{     
  for(j=0;j<6;j++)
    if(c[i]==v[j])
      c[i]+=1;
     }
for(i=0;i<s;i++)
 for(j=i+1;j<s;)
 { if(c[i]==c[j])
  {
    for(k=j;k<s-1;++k)
      c[k]=c[k+1];
      --s;  
  }else
   ++j;  
  }
for(i=0;i<s;i++)
  for(j=0;j<6;j++)
       for(k=0;k<s;k++)
        for(l=0;l<6;l++)
         for(m=0;m<s;m++)       
      printf("%c%c%c%c%c\n",c[i],v[j],c[k],v[l],c[m]);
}

There must be some way to shorten this definitely.

Explanation

  • Stored the integer values of a,e,i,o,u,y in a numerical array,
  • Stored all alphabets in array, if it was a vowel, replaced it with a consonant, so there were duplicate consonant values in the array,
  • Removed duplicate consonant values,
  • Printed all combinations c-v-c-v-c.

Abel Tom

Posted 2017-01-12T11:52:46.923

Reputation: 1 150

If you could put an ungolfed version that would help immensely. – SIGSTACKFAULT – 2017-01-12T15:35:11.087

2

Clojure, 101 bytes

(print(apply str(for[V["aeiouy"]C["bcdfghjklmnpqrstvwxz"]a C b V c C d V e C](str a b c d e "\n")))))

Not that exciting...

NikoNyrh

Posted 2017-01-12T11:52:46.923

Reputation: 2 361

2

Ruby, 65 61 bytes

Completely different approach:

(b=[*?a..?z]-a="aeiouy".chars).product(a,b,a,b){|x|puts x*""}

New things I learned today: the Array#product function

G B

Posted 2017-01-12T11:52:46.923

Reputation: 11 099

2

Pyth, 25 23 bytes

s.n*F[K-GJ"aeiouy"JKJKb

In pseudocode:

'                       ' G, b = "abcdefghijklmnopqrstuvwxyz", "\n"
'         J"aeiouy"     ' J = "aeiouy"
'      K-GJ             ' K = "bcdfghjklmnpqrstvwxz"
's.n                    ' "".join( flatten(
'   *F                  '   reduce(cartesian_product,
'     [K           JKJKb'     [K,J,K,J,K,b]
'                       ' # b makes it so that every word ends with \n so that
'                       ' # flattening and concatenating automatically deals with
'                       ' # newlines

Try it online!

busukxuan

Posted 2017-01-12T11:52:46.923

Reputation: 2 728

2

C#, 244 242 234 219 bytes

class P{static void Main(){string v="aeiouy",c="bcdfghjklmnpqrstvwxz";int i=0,j,k,l,m;for(;i<20;i++)for(j=0;j<6;j++)for(k=0;k<20;k++)for(l=0;l<6;l++)for(m=0;m<20;)System.Console.Write("\n"+c[i]+v[j]+c[k]+v[l]+c[m++]);}}

Ungolfed:

class P
{
    static void Main()
    {
        string v = "aeiouy", c = "bcdfghjklmnpqrstvwxz";
        int i=0, j, k, l, m;
        for (; i < 20; i++)
            for (j=0; j < 6; j++)
                for (k=0; k < 20; k++)
                    for (l=0; l < 6; l++)
                        for (m=0; m < 20; )
                            System.Console.Write("\n"+c[i]+v[j]+c[k]+v[l]+c[m++]);
    }
}

I doubt I can trim it any further. Done on C# 5, so no {c[i]}

Mr Scapegrace

Posted 2017-01-12T11:52:46.923

Reputation: 221

@dim damn, you are right. Let me rewrite this... – Mr Scapegrace – 2017-01-13T13:03:36.530

Are you sure this can't be shortened with Linq? – VMAtm – 2017-01-15T13:04:08.557

2

Batch, 185 bytes

@set c=b c d f g h j k l m n p q r s t v w x z
@for %%i in (%c%)do @for %%j in (a e i o u y)do @for %%k in (%c%)do @for %%l in (a e i o u y)do @for %%m in (%c%)do @echo %%i%%j%%k%%l%%m

Batch is so verbose that it costs 4 bytes to put the vowels into a variable.

Neil

Posted 2017-01-12T11:52:46.923

Reputation: 95 035

2

T-SQL, 276

This answer assumes a query's result set is valid output.

WITH c AS(SELECT*FROM(VALUES('b'),('c'),('d'),('f'),('g'),('h'),('j'),('k'),('l'),('m'),('n'),('p'),('q'),('r'),('s'),('t'),('v'),('w'),('x'),('z'))c(_)),v AS(SELECT*FROM(VALUES('a'),('e'),('i'),('o'),('u'),('y'))v(_))SELECT c._+v._+b._+a._+d._ FROM c,v,c b,v a,c d ORDER BY 1

It works in SQL Server 2008 R2. I'm not sure currently where you'd be able to run it online given the number of rows returned, though.

One CTE definition holds the consonants from a derived table. The other holds the vowels from another derived table. Take the Cartesian product of three consonant CTEs and two vowel CTEs, and you can get an alphabetized list of the appropriately concatenated values.

Muqo

Posted 2017-01-12T11:52:46.923

Reputation: 499

Nice, just what I was thinking. If you restrict it to SQL 2016 or higher, you can save ~70 bytes by using STRING_SPLIT instead of VALUES.

– BradC – 2019-08-08T13:39:51.060

1

Haskell, 93 bytes

c="bcdfghjklmnpqrstvwxz"
t=[[a,b]|a<-"aeiuoy",b<-c]
main=putStr$unlines[b:y++z|b<-c,y<-t,z<-t]

I have tried to slim the hardcoded lists of consonants and vowels down, but haven't been able to find something that saves bytes. This will output all possible five letter words in the order as stated in the post to stdout, being generated via list comprehensions.

Renzeee

Posted 2017-01-12T11:52:46.923

Reputation: 599

1

Java, 347 bytes -.-

public class N{public static void main(String[]a){String c="bcdfghjklmnpqrstvwxz";String v="aeiouy";int[]i=new int[5],e=new int[5];e[0]=e[2]=e[4]=20;e[1]=e[3]=6;m:while(true){System.out.println(c.charAt(i[0])+v.charAt(i[1])+c.charAt(i[2])+v.charAt(i[3])+c.charAt(i[4]));int p=4;while(true){++i[p];if(i[p]<e[p])break;i[p]=0;if(p==0)break m;--p;}}}}

yeoman

Posted 2017-01-12T11:52:46.923

Reputation: 111

1

Informix-SQL, 254 bytes

an SQL version (IBM Informix dialect)

select x from table(list{'a','e','i','o','u','y'})(x)
into temp v;
select x from table(list{'b','c','d','f','g','h','j','k',
'l','m','n','p','q','r','s','t','v','w','x','z'})(x)
into temp c;
select k.x||j.x||i.x||v.x||c.x
from c,v,c i,v j,c k
order by 1

CompuLingus

Posted 2017-01-12T11:52:46.923

Reputation: 11

1

Brachylog v2, 11 bytes

Ḍ;Ẉj,Ḍ∋ᵐcẉ⊥

Try it online!

Pretty much the same as Fatalize's Brachylog v1 answer.

Unrelated String

Posted 2017-01-12T11:52:46.923

Reputation: 5 300

1

Jelly, 10 bytes

ØỴ,Øỵṁ5ŒpY

Try it online!

Erik the Outgolfer

Posted 2017-01-12T11:52:46.923

Reputation: 38 134

1

Shell, 72 64

Try it online! (Thanks @Grimy)

echo {g..z}{a..f}{g..z}{a..f}{g..z}|tr b-z eiouybcdfghj-np-tvwxz


If it must be delimited by newlines (beware of the spaces) 69 bytes Try it online!:

echo {g..z}{a..f}{g..z}{a..f}{g..z}|tr \ b-z \\neiouybcdfghj-np-tvwxz


Original shell, 72 bytes (bash, ksh, zsh, a simple sh may not expand {..}) Try it online!

echo {a..t}{1..6}{a..t}{1..6}{a..t}|tr a-t1-6 bcdfghjklmnpqrstvwxzaeiouy

Less than half a second. Considering that a C equivalent runs in 0.228sec and a perl equivalent takes 2.1 seconds, this is Not slow (times reported as TiO measured them).

Isaac

Posted 2017-01-12T11:52:46.923

Reputation: 173

64: echo {g..z}{a..f}{g..z}{a..f}{g..z}|tr b-z eiouybcdfghj-np-tvwxz – Grimmy – 2019-09-02T14:22:37.807

Thanks .. @Grimy – Isaac – 2019-09-02T16:14:49.797

1

Zsh, 58 bytes

v=(a e i o u y)
c=(${${:-{b..z}}:|v})
echo $^c$^v$^c$^v$^c

Try it online!

${ :|foo} is set difference, and ${^foo} enables brace expansion over the contents of the array foo.


If newline-delimited is required, 64 bytes:

v=(a e i o u y)
c=(${${:-{b..z}}:|v})
<<<${(F):-$^c$^v$^c$^v$^c}

Try it online!

GammaFunction

Posted 2017-01-12T11:52:46.923

Reputation: 2 838

1I saw the "shell" answer below & thought zsh array diffs & cross-products would work, you beat me to it – roblogic – 2019-09-02T06:26:54.520

0

C (gcc), 123 bytes

char w[6];f(n,m,c,p){for(n=457653;n<1<<24;p&&puts(w))for(m=n++,c=p=1;m;m/=26,c++)p*=c%2==!strchr("aeiouy",w[5-c]=m%26+97);}

Try it online!

gastropner

Posted 2017-01-12T11:52:46.923

Reputation: 3 264

0

J, 52 37 34 33 bytes

echo>,{5$'aeiouy'(-.~;[)u:97+i.26

Try it online!

-1 thanks to Adam's suggestion of u:97+i.26 to replace 26{.97|.a.

  • u:97+i.26 extract letters a..z from ascii alphabet a.
  • 'aeiouy'(-.~;[) subtract the vowels from a..z, and link ; that (the consonants) to the vowels, creating a boxed list consonants ; vowels.
  • 5$ extent that boxed list cyclically to 5 elements, yielding consonants ; vowels ; consonants ; vowels ; consonants.
  • { create the cross product
  • , flatten
  • > open the boxes to create regular strings
  • echo print the results

Jonah

Posted 2017-01-12T11:52:46.923

Reputation: 8 729

0

MathGolf, 25 16 bytes

╩æ╩¼`┼]m▒ε*mÅ─yn

Try it online!

Definitely not optimal, but this challenge got me to actually implement some features of MathGolf that have been in TODO since forever, mainly string subtraction and vowels/consonants. Once it's up on TIO I'll update this answer. MathGolf has been updated, and I'll add this as a disclaimer that some features used in this answer are newer than the challenge itself.

To fetch consonants and vowels from the dictionary, I filtered out words in the dictionary files which were duplicates, and found that I had 3 duplicates within the top 256 words of the dictionary. I decided that that 2 of these slots should be replaced by the string of consonants and the string of vowels. I was unsure of where "y" should be placed, but decided to place it among the vowels.

The one thing that is not in place is cartesian product for strings. Since I have not defined the output format yet, this feature did not make it into the latest version of MathGolf.

Explanation

ʑ                 fetch dictionary word 145 ("bcdfghjklmnpqrstvwxz")
  ʬ               fetch dictionary word 172 ("aeiouy")
    `              duplicate the top two items
     ┼             duplicate second item from top and push to top
      ]            end array / wrap stack in array
                   stack is now ["<cons>", "<vow>", "<cons>", "<vow>", "<cons>"]
       m▒          map each element to a list of chars
         ε*        reduce list by multiplication (cartesian product)
           mÅ      explicit map using next 2 operators
             ─     flatten array
              y    join array without separator to string or number
               n   join array with newlines to a string

maxb

Posted 2017-01-12T11:52:46.923

Reputation: 5 754

0

ink, 224 bytes

LIST V=(a),e,i,o,u,y
LIST C=(b),c,d,f,g,h,j,k,l,m,n,p,q,r,s,t,v,w,x,z
~temp D=C
~temp E=V
~temp F=C
~temp G=V
~temp H=C
-(L){D}{E}{F}{G}{H}
~H++
{H:->L}
~H=C
~G++
{G:->L}
~G=V
~F++
{F:->L}
~F=C
~E++
{E:->L}
~E=V
~D++
{D:->L}

Try it online!

Sara J

Posted 2017-01-12T11:52:46.923

Reputation: 2 576