# Generate all Possibilities of Words

This is not the same as m-ss-ng-lette-s

Challenge:

Given a string with masked characters, generate all possible words, inclusive of non-meaningfull words.

Rules:

• The sequence of the characters in the string does not change.
• The masked character (*) will be one of an English alphabets [a-z].
• There are no line breaks, space, numbers, special characters or punctuations.
• The output can be a list of non-meaningfull words too.
• Any characters in a string can be masked. Not necessarily alternating characters.
• For memory constraint, lets keep the maximum length of input as 10.

Example 1:

Input:

*o*


Output:

aoa
aob
aoc
...
...
...
boa
bob
boc
...
...
...
zoa
zob
zoc
...
...
...
zoz


Example 2:

Input:

*e*c*m*


Output:

aeacama
aeacamb
...
...
...
welcome
...
...
zezczmz


This is , so shortest answer in bytes wins!

• Welcome to Code Golf and nice first question! For future reference, we recommend using the Sandbox to get feedback on challenge ideas before posting them to main. I've edited out the fastest-code tag as it's a winning criterion tag and this is code golf. Jul 31 at 7:50
• fastest-code and code-golf are both winning criterion tags. fastest-code means that the challenge is scored by the speed of solutions, by some metric; code-golf means that the shortest code wins. You can't have both. Jul 31 at 8:08
• Can delimiters between words be custom? E. g. use   (space) instead of \n
– oeuf
Jul 31 at 8:58
• We can stick to *, as space may create ambiguity when combining with other solutions. Jul 31 at 9:07
• I'd suggest allowing the masking character to be any non-alphabetical character. For most languages, the approach won't change, but the freedom of character is more likely to allow for the odd creative answer that only works for a specific masking character Jul 31 at 17:01

mapM q
q '*'=['a'..'z']
q c=[c]


Try it online!

# Zsh, 25 bytes

eval echo ${1//\*/{a..z}} Attempt This Online! • Why not use echo? Jul 31 at 8:35 • @dingledooper echo won't print each of the word with a newline. – oeuf Jul 31 at 8:59 • 25 bytes if using custom delimiters (in this case a whitespace) is allowed. – oeuf Jul 31 at 9:01 • Nice solution, adding >> Result.log took care of large outputs. Jul 31 at 9:09 • Very nice. Works in bash too with two escapes: eval echo${1//\*/\{a..z\}} ATO Jul 31 at 19:00

# Ruby, 39 bytes

->s{(?a..?z*10).grep /^#{s.tr'*',?.}$/}  Try it online! The range is set to terminate after 10 zs, to fit the constraint. Realistically this takes forever to run unless a smaller number is used. • You need to add ^...$ to the regex, otherwise words longer than the input will be included (See f['aa'] for an example)
– ovs
Jul 31 at 11:32
• @ovs fixed, thanks! Aug 1 at 0:29

# Vyxalj, 5 bytes

×kaVΠ


Try it Online! Input as char lists.

   V  # Replace
×     # Asterisks
ka   # With the lowercase alphabet
Π # Take cartesian product

• Get outgolfed lol Jul 31 at 18:44
• @Steffan no, you get outgolfed lol Aug 1 at 0:05
• So the built-in for the string "*" is……… ×??? Aug 1 at 11:35
• @Fatalize Yep. I don't know why we have it, but it's occasionally useful. Aug 1 at 11:50
• @emanresuA But * is in the code page and is apparently multiplication… why not swap both symbols? Aug 1 at 11:54

# Perl 5 + -n -M5.10.0, 37 bytes

1 byte saved thanks to @Sisyphus!

$"=",";s/\*/{@{[a..z]}}/g;say<"$_\n">

Try it online!

## Explanation

Turns the input into a glob (<"$_\n">) which is then evaluated as a list and printed (say) with newline separators. Note: This does struggle to produce all the output for multiple *s when running on my phone! • save a byte using say<"$_\n"> instead of say for glob Jul 31 at 23:59
• @Sisyphus Nice, I looked as using literal glob syntax, but not with a newline... Thank you! Aug 1 at 11:13
• If you just read from stdin (which you do with -n), $_ will already have a newline, so you can ditch the \n. I guess in your "Try it online", there was no trailing newline in the input. (Add a newline, and you can ditch the \n) Aug 2 at 9:54 • @Abigail I've definitely utilised this in other answers for both requiring and requiring no terminating newline. I've asked a question about what would be preferred. Aug 2 at 11:48 # Python 3, 88 86 bytes def A(x):p=x.find("*");~p and[A(x[:p]+chr(i+97)+x[p+1:])for i in range(26)]or print(x)  Removed 2 bytes thanks to @Adam • Welcome to Code Golf! Jul 31 at 18:40 • You can remove A(input()) - simply defining a function is enough by our rules. Jul 31 at 18:40 • Thanks! Should I add previous length to the title? Jul 31 at 18:52 • You can if you want, but no need :) Jul 31 at 18:59 • You can remove a byte by using ~x instead of x<0 and swapping around the conditions: def A(x):p=x.find("*");[A(x[:p]+chr(i+97)+x[p+1:])for i in range(26)]if~p else print(x). You can remove another by replacing if... else with and... or: def A(x):p=x.find("*");~p and[A(x[:p]+chr(i+97)+x[p+1:])for i in range(26)]or print(x) – Adam Jul 31 at 20:06 # Vyxalj, 14 13 bytes ×Oka↔ƛ?×\%V$%


Try it Online!

Could be 8 bytes by using % instead of *

• When trying for "welcome", getting debug console message as "Code timed out after 10 seconds" Jul 31 at 8:16
• @GokulNathKP that's because the online interpreter is set to time out after 10 seconds. Either use a flag that increases the time out time or use the offline interpreter which doesn't have a time out limit Jul 31 at 8:22
• Get outgolfed lol Jul 31 at 8:52

# R, 65 bytes

f=\(s)if(grepl("[*]",s[1]),f(sapply(letters,sub,pa="[*]",s)),s)

Attempt This Online!

Basically the same recursive idea as in Cong Chen's answer.

# Charcoal, 25 bytes

⊞υＳＦυ¿№ι*Ｆβ⊞υ⭆ι⎇⁻μ⌕ι*λκ⟦ι


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

⊞υＳ


Ｆυ


Check each string.

¿№ι*


If it contains a *, then:

Ｆβ


Loop over the lowercase alphabet.

⊞υ⭆ι⎇⁻μ⌕ι*λκ


Replace the first * in the string with the current letter and push it to the search list.

⟦ι


Otherwise output the string on its own line.

The version of Charcoal on TIO doesn't support joining lists, otherwise the code could probably be 23 bytes, something like this:

⊞υωＦＳ≡ι*≔ΣＥυＥβ⁺κμυ≧⁺ιυυ


Explanation:

⊞υω


ＦＳ


Loop over the characters of the input string.

≡ι*


If the current character is a *, then...

≔ΣＥυＥβ⁺κμυ


... append each lowercase letter to each of the strings so far and join the resulting lists, otherwise...

≧⁺ιυ


... append the current character to each of the strings so far.

υ


Output the final list of strings.

As verbose code:

Push(u, w);
for (InputString()) switch (i) {
case "*": Assign(Sum(Map(u, Map(b, Plus(k, m)))), u);
default: MapAssignRight(Plus, i, u);
}
Print(u);


# Retina, 30 bytes

/\*/{%$25*$(¶$ ,Y0*l\*.*  Try it online! Explanation: /\*/{  Repeat while there are still any *s to process. %$
25*$(¶$


Add 25 copies of each line.

,Y0*l\*.*


Cyclically transliterate the first * on each line to the lowercase alphabet. The , tells Retina to process all matches and the 0 tells Retina to process the first character of each match.

# lin, 49 bytes

"\*".?g.+_.+_"%s"?s.#t ?i len $a.~ /\".t.~ sf"'  Try it here! Returns an iterator of strings. For testing purposes: "*e*c*m*" ; \outln ' _ "\*".?g.+_.+_"%s"?s.#t ?i len$a.~ /\".t.~ sf"'


## Explanation

Prettified code:

"\*".?g.+_.+_ "%s"?s.#t ?i len $a.~ /\ (.t.~ sf ) '  Not very short, but surprisingly straightforward. • "\*".?g regex /\*/g • .+_.+_ "%s"?s.#t replace * with %s and store as t • ?i len get number of *s as n • $a.~ /\ create length-n "digit" sequences from alphabet
• (.t.~ sf ) ' use t to sprintf each sequence

# Vyxalj, 9 bytes

×Ẇ⌈yvkaYΠ


Try it Online!

Based on emanresu A's answer, but shaves off another byte.

# sh + coreutils + hashcat, 31 bytes

sed s/*/?l/g|xargs hashcat -a 3


# 05AB1E, 9 bytes

'*A:.»â€S


Input as a list of characters.

Explanation:

'*A:      '# Replace all "*" in the (implicit) input-list with the lowercase alphabet
.»     # Left-reduce the list of strings by:
â    #  Taking the cartesian product
€S  # Then convert each inner list to a flattened list of characters
# (after which the result is output implicitly)


Minor note: '* could be W in the legacy version of 05AB1E if the input is guaranteed to always contain a "*", but unfortunately the €S should be €˜J in that case, not saving any bytes.

# Julia, 61 bytes

!s=join.(Iterators.product((x>'*' ? x : 'a':'z' for x=s)...))

Attempt This Online!

(This returns a matrix of all possible words, rather than a list/vector.)

• Welcome to Code Golf! Although I do not know much Julia, I suspect that you can remove some whitespace in there. Otherwise, it is a great answer. Aug 4 at 4:18

# R, 91 bytes

\(a,j=Vectorize(\(x,y)sub('*',y,x,,,T),'y'))if(grepl('*',a,,,T),sapply(j(a,letters),f),a)

Recursive solution.

Attempt This Online!

• My solution uses basically the same recursive idea, so feel free to incorporate it into your answer: 65 bytes. Jul 31 at 19:05
• Thanks! I think your solution is much better so recommend posting it. Jul 31 at 19:07
• Thanks, posted. Jul 31 at 19:28

# Factor + spelling, 60 56 bytes

[ 1 group { "*"} ${ ALPHABET } replace [ ] product-map ]  Attempt This Online!  ! "*o*" 1 group ! { "*" "o" "*" } { "*"}${ ALPHABET } replace  ! { "abcdefghijklmnopqrstuvwxyz" "o" "abcdefghijklmnopqrstuvwxyz" }
[ ] product-map               ! { "aoa" "boa" ... "zoz" }


# Brachylog, 13 bytes

ẹ{"*"∧!Ạ∋|}ᵐc


Try it online!

This is a generator predicate that will unify its output with each possible combination. The TIO example uses ᶠ - findall to generate all answers, but in a Prolog REPL you could just press ; repeatedly to get each answer.

### Explanation

ẹ                Split the string into a list of characters
{         }ᵐ    Map for each char:
"*"              If the char is "*"
∧!              Cut (i.e. discard the "else" possibility)
Ạ∋           The output is an element of the alphabet
|        Else don’t modify the char
c   Concatenate back to a string


The cut ! is necessary, otherwise the predicate would also generate answers with the asterisk unchanged.

## JavaScript, 111 bytes

I feel like it's way too long and I'm missing something big.

s=>(r=s=>s[1]?.at?[...'abcdefghijklmnopqrstuvwxyz'].flatMap(c=>r(s.slice(1)).map(p=>s[0]+c+p)):s)(s.split('*'))


# Also Python 3, 86 Bytes:

def f(x):
for i in range(26):y=x.replace('*',chr(i+97),1);f(y)if'*'in y else print(y)


# Julia, 61 bytes

!s=foldl((x,y)->[x.*y...],[x<'a' ? 'a'.+(0:25)' : x for x=s])

Attempt This Online!