18
\$\begingroup\$

Background

You may be aware that periods in between letters in gmail addresses are ignored. Email sent to [email protected], [email protected], and [email protected] all end up in the same place! This is a great way to have multiple different emails addresses for things like signing up for free trails, or filtering mail from different website. We will refer to gmail address aliases created in this way as dot-aliases.

The Task

Write a program to generate all possible dot-aliases of a given Gmail address.

Input

A Gmail address as a string. You may choose whether or not the "@gmail.com" part is included in the input. The maximum length of a Gmail ID (the part before the '@') is 30 characters (not including dots). The minimum is 6 characters. You may assume the input will not already include any dots.

For more details on gmail ID requirements: https://support.google.com/mail/answer/9211434?hl=en

Output

All of the dot-aliases, in any order, with no duplicates. This can mean printing them to stdout, writing to a file, returning them in a container, returning a iterator, etc. The output must contain the "@gmail.com" suffix. You may choose whether or not to include the original input address in the output.

Scoring

Code Golf here, solution with fewest bytes wins. In the event of a tie, the code who's least common character has the highest number of occurrences wins. In the event of a double tie, earliest timestamp wins.

Example:

Input:          
[email protected]   
or
abcabc
(you pick)


Output:
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]    
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected] (optional)

-8% Byte Bonus: Even though the longest Gmail ID is 30 characters, the maximum length for any valid email address prefix is 64 characters. Make your program work for input up to 64 characters before the '@', but ensure output is also limited to 64 characters before the '@'.

\$\endgroup\$
12
  • 6
    \$\begingroup\$ Gmail is weird. \$\endgroup\$
    – user92069
    May 8, 2020 at 10:01
  • 8
    \$\begingroup\$ Among things to avoid when writing challenges, are bonuses in code golf. \$\endgroup\$
    – Adám
    May 8, 2020 at 10:19
  • 5
    \$\begingroup\$ Please avoid adding unnecessary fluff, like having to append "@gmail.com". \$\endgroup\$
    – Adám
    May 8, 2020 at 10:21
  • 2
    \$\begingroup\$ I think your last (optional) output line is missing abc \$\endgroup\$
    – Adám
    May 8, 2020 at 10:22
  • 2
    \$\begingroup\$ @Adam I tried to the bonus small enough that it would likely not be competitive. I don't consider the requirement of outputting the full email address to be fluff considering. I thought making that part optional for the input would open up more creative ways to solve the problem, but if it wasn't required in the output I feel like nobody would choose to take advantage of it in the input. \$\endgroup\$ May 8, 2020 at 11:27

20 Answers 20

8
\$\begingroup\$

Python 3, 72 69 bytes

-3 bytes thanks to Jitse!

Input includes @gmail.com.

f=lambda s:s[11:]and[s[0]+w+x for x in f(s[1:])for w in('.','')]or[s]

Try it online!

\$\endgroup\$
4
  • \$\begingroup\$ this one fails to add @gmail.com and does not work if it is missing from the input \$\endgroup\$
    – hugovdberg
    May 8, 2020 at 11:37
  • 7
    \$\begingroup\$ @hugovdberg OP clearly said, [email protected] or abcabc **(you pick)** (emphasis mine) \$\endgroup\$
    – user92069
    May 8, 2020 at 11:40
  • \$\begingroup\$ 69 bytes \$\endgroup\$
    – Jitse
    May 15, 2020 at 10:22
  • \$\begingroup\$ @Jitse thanks a lot. \$\endgroup\$
    – ovs
    May 15, 2020 at 14:59
6
\$\begingroup\$

Python 3, 207 145 140 138 bytes

Removed the flexibility to accept both with and without @gmail.com, now requires the domain to be omitted.

g=lambda e:(f"{''.join(p+t for p,t in zip(((['','.'][s>>i&1]for i in range(len(e)-1,-1,-1))),e))}@gmail.com"for s in range(2**(len(e)-1)))

Try it online!

\$\endgroup\$
1
  • 2
    \$\begingroup\$ (len(e)-1) can be ~-len(e) for -2 \$\endgroup\$ May 8, 2020 at 13:46
5
\$\begingroup\$

Haskell, 52 bytes

Input includes @gmail.com.

c s@(a:'@':x)=[s]
c(a:b)=[a:s++x|x<-c b,s<-["","."]]

Try it online!

\$\endgroup\$
4
\$\begingroup\$

05AB1E, 11 bytes

-4 bytes thanks to Kevin Cruijssen.

.œʒθgT›}'.ý

Try it online!

Explanation

.œ          All partitions
  ʒ         Filter:
   θ            The last part
    g           Has a length
     T›}        Larger than 10
        '.ý Join by periods

05AB1E, 16 15 bytes

Saved a lot by porting Adám's APL answer.

g11-oݨbεRÅÏ'.«

Try it online!

Explanation

g                Find the input's length
 11-             Minus 11
    o            2 ** x
     Ý           0-range
      ¨          Pop the last item
       b         Convert to binary
        ε        For every binary item:
         R       Reverse this item
          ÅÏ     Apply to all truthy indices of this binary item:
            '.«  Append a period
\$\endgroup\$
3
  • \$\begingroup\$ "[email protected]"? \$\endgroup\$
    – Adám
    May 8, 2020 at 10:50
  • \$\begingroup\$ @Adám Probably fixed. \$\endgroup\$
    – user92069
    May 8, 2020 at 10:53
  • \$\begingroup\$ 11 bytes \$\endgroup\$ May 8, 2020 at 11:51
4
\$\begingroup\$

APL (Dyalog Extended), 51 45 34 29 bytes

Anonymous tacit prefix function. Requires ⎕IO←0 and trailing @gmail.com. Returns a list of strings.

⊂{∊,∘'.'¨@⍵⊢⍺}∘⍸∘⊤¨∘⍳2*∘≢11∘↓

Try it online!

11∘↓ drop the first eleven characters from the argument

count the number of remaining characters

2*∘ raise two to that power

ɩntegers 0…that

¨∘ on each index:

 convert To binary

⍸∘ɩndices where 1-bits are

⊂{}∘ call the following function with that as right argument () and the entire original argument as left argument ()

  ⊢⍺ on the original text

  @⍵ at the given indices

   ¨ for each of the indexed characters

    ,∘'.' append a period

  ϵnlist (flatten)

\$\endgroup\$
2
  • \$\begingroup\$ In your explanation, you say ",∘' ' append a space", but the code has ,∘'.'. Typo? \$\endgroup\$ Sep 25, 2021 at 17:34
  • \$\begingroup\$ @cairdcoinheringaahing Fixed. \$\endgroup\$
    – Adám
    Sep 25, 2021 at 20:16
3
\$\begingroup\$

Bash + sed, 39

Takes input of just the local part of the email address and not the @gmail.com. Takes input from STDIN.

eval echo `sed 's/\B/{,.}/g'`@gmail.com

Try it online!

\$\endgroup\$
3
  • \$\begingroup\$ Any reason why you didn't use only sed? \$\endgroup\$
    – Wezl
    May 15, 2020 at 17:48
  • \$\begingroup\$ @Wezl Generating all the combinations is super easy with bash expansions. Possible with purely sed too but possibly a good deal more work. \$\endgroup\$ May 15, 2020 at 19:36
  • \$\begingroup\$ Oh, I forgot you had to find all combinations. Just wasn't thinking. \$\endgroup\$
    – Wezl
    May 15, 2020 at 23:26
3
\$\begingroup\$

Perl 6, 48 bytes

*.comb.reduce({@$^a X~$,'.'X~$^b})X~'@gmail.com'

Try it online!

\$\endgroup\$
2
  • \$\begingroup\$ I know nothing about Perl but from the "Try it online!" this seems to have trouble with strings greater than 11 characters. \$\endgroup\$ May 8, 2020 at 17:50
  • 1
    \$\begingroup\$ @ConorHenry The code warnings were a bit too much for TIO to handle. I've added some error suppression in the footer to fix this. \$\endgroup\$
    – Jo King
    May 9, 2020 at 5:49
3
\$\begingroup\$

Ruby -n, 70 56 bytes

Input includes "@gmail.com". Generates all possible ways to distribute valid combinations of dots and empty strings within the id by finding the location of the second character before the @ (this works because the input is guaranteed to have 6 characters), and zips them into the original input.

r=p,?.
r.product(*[r]*~/..@/){|e|puts$_.chars.zip(e)*''}

Try it online!

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

C (gcc), 90 bytes

char s[],*i=s+91;main(j){for(gets(i);*i;j+=i[10]&&fork(s[j]=46))s[j++]=*i++;write(1,s,j);}

Try it online!

According to my test write is atomic, while standard IO aren't

C (gcc), 93-8%=85.56 bytes

char s[],*i=s+91;main(j){for(gets(i);*i;j+=i[10]&&fork(s[j]=46))s[j++]=*i++;write(j<76,s,j);}

Try it online!

First one to do bonus

\$\endgroup\$
5
  • \$\begingroup\$ Does the 97.52 byte version actually work? When I click on the 'Try it online!' link, the output doesn't seem complete... \$\endgroup\$ May 15, 2020 at 10:26
  • \$\begingroup\$ @DominicvanEssen That's the requirement of bonus but ensure output is also limited to 64(I used 7 instead) characters before the '@'. \$\endgroup\$
    – l4m2
    May 15, 2020 at 10:53
  • \$\begingroup\$ Ah! Got it! (it was difficult for me to spot that you'd used a smaller value for the demo) \$\endgroup\$ May 15, 2020 at 10:58
  • \$\begingroup\$ 1) Lots of undefined behavior. It may work.... or kill you. 2) What's with the separator? Apparently you've used a NUL (undefined behavior) at the start as your separator. This may be accidental, as it comes from j being initialized to 1, or more if you give extra parameters. With 64 parameters, there is no output at all. 3) I tried the bonus version with 58 characters before the @. Tries to make 2^58 processes. Drove the machine into the ground, and fork() can fail. \$\endgroup\$
    – David G.
    May 19, 2020 at 15:27
  • \$\begingroup\$ @DavidG. 1)Yeah undefined behavior is common in code golf. 2) Same. 3) I'd treat it as not enough resource \$\endgroup\$
    – l4m2
    May 19, 2020 at 23:46
2
\$\begingroup\$

Perl 5 + -F/(?=.+@)/n 21 bytes

Much less offensive flags thanks to @Abigail!

$"="{,.}";say for<@F>

Try it online!

Explanation

-F splits the input based on the regular expression passed in (with no argument it splits the string into chars) and stores in @F. Setting $" specifies the string used to join list entries when interpolating. <...> is short syntax for a glob string which accepts interpolation. In some (most POSIX-compliant?) shells, the glob a{,.} expands to the list a and a.. for an input [email protected], <@F> is expanded to <a{,.}b{,.}c{,.}d{,.}@gmail.com> thanks to setting $", which finally expands to the list of all permutations which are iterated with for and printed using say.


Perl 5 with -F, 32 bytes

Excludes @gmail.com from the input.

$"="{,.}";say for<@F\@gmail.com>

Try it online!

\$\endgroup\$
5
  • \$\begingroup\$ +1, but I thought it was a custom to add the bytecount of the additional flags to the bytecount of the code itself, wasn't it? \$\endgroup\$
    – Ramillies
    May 9, 2020 at 8:52
  • 1
    \$\begingroup\$ @Ramillies That is classic code golf rules for sure (which is why I added the minimal flags version too) but this link says that flags make it count as a "different language". \$\endgroup\$ May 9, 2020 at 13:09
  • 1
    \$\begingroup\$ Thank you for the link, that's a good solution that I haven't been aware of. \$\endgroup\$
    – Ramillies
    May 9, 2020 at 13:29
  • 1
    \$\begingroup\$ -F/(?=.+@)/n works as well. \$\endgroup\$
    – Abigail
    Jun 19, 2020 at 23:21
  • \$\begingroup\$ @Abigail that's much nicer! I'm sure I looked at that kind of thing but couldn't get something that worked! Thank you! \$\endgroup\$ Jun 20, 2020 at 8:48
1
\$\begingroup\$

Retina 0.8.2, 40 bytes

^.
$&@
+%`@(.)
$1@$'¶$`.$1@
@
@gmail.com

Try it online! Takes input without the domain. Explanation:

^.
$&@

Insert a marker @ after the first character.

+%`@(.)
$1@$'¶$`.$1@

Move the @ right one character each time, duplicating each line, with an extra . in the duplicate.

@
@gmail.com

Add the domain suffix to all lines.

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

C (gcc), 134 \$\cdots\$ 103 102 bytes

Saved 4 8 9 bytes thanks to ceilingcat!!!
Saved 7 9 10 bytes thanks to l4m2!!!

i;j;k;f(char*g){i=strlen(g)-10;for(j=1<<i;j-=2;k=!puts(g+i))for(;k<i;printf(".%c"+!(j>>k++&1),g[k]));}

Try it online!

Takes an email address with the @gmail.com part included and prints out all of its dot-aliases (not with the original).

How

Loops over \$0\dots2^{n-1}\$ where \$n\$ is the length of email address up to @. Uses the binary bits of that loop variable to decide whether or not to insert a dot in between letters.

\$\endgroup\$
7
  • \$\begingroup\$ tio.run/… \$\endgroup\$
    – l4m2
    May 11, 2020 at 20:42
  • \$\begingroup\$ @l4m2 Nice one - thanks! :-) \$\endgroup\$
    – Noodle9
    May 11, 2020 at 21:19
  • \$\begingroup\$ i;j;k;f(char*g){i=index(g,64)-g;for(j=1<<i;j-=2;k=!puts(g+i))for(;k<i;printf(".%c"+!(j>>k++&1),g[k]));} \$\endgroup\$
    – l4m2
    May 12, 2020 at 5:25
  • \$\begingroup\$ @l4m2 Wow! Nice golf - thanks! :D \$\endgroup\$
    – Noodle9
    May 12, 2020 at 11:38
  • \$\begingroup\$ 102 \$\endgroup\$
    – l4m2
    May 15, 2020 at 17:20
1
\$\begingroup\$

Wolfram Language (Mathematica), 52 bytes

Thread@StringInsert[#,".",Subsets@Range[2,StringLength@#-10]]&

Try it online! Pure function. Takes a string as input and returns a list of strings as output. Ignore any StringInsert::psl messages generated.

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

R, 115 104 103 bytes 95 bytes

d=function(s,p=2,`[`=substring)"if"(s[p,p]=="@",s,c(d(s,p+1),d(paste0(s[1,p-1],".",s[p]),p+2)))

Try it online!

Input includes "@gmail.com" (or any other domain, but that's not relevant to the challenge...)

Edit: -8 bytes thanks to Giuseppe

\$\endgroup\$
4
  • 1
    \$\begingroup\$ a couple of tricks: you can put the f=substring into the function arguments to get rid of the {}; also since you're not using [, you can set "["=substring as a 3-argument function like this \$\endgroup\$
    – Giuseppe
    May 18, 2020 at 16:02
  • 1
    \$\begingroup\$ oh, and one more, if is a weird one to golf: 95 bytes \$\endgroup\$
    – Giuseppe
    May 18, 2020 at 16:05
  • \$\begingroup\$ Wow! Thanks! That's just what I was looking for! I was messing around with ifelse without anything working (because of c(... as vector argument), and never realized the trick of using if as a normal, non-inline function. Brilliant! \$\endgroup\$ May 18, 2020 at 17:22
  • 1
    \$\begingroup\$ This has a comparison of different if approaches; all the tips on that page are pretty good too! \$\endgroup\$
    – Giuseppe
    May 18, 2020 at 18:10
1
\$\begingroup\$

Pyth, 14 12 bytes

/#>11QjL\../

Try it online!

Input includes @gmail.com.

./ Partitions of input into disjoint substrings

jL\. Join the chunks of each partition using .

/#>11Q Keep only elements where the last 11 characters of the input string appear in that element (this checks that the "@gmail.com" suffix and preceding character are still intact)

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

Jelly, 12 bytes

ŒṖẈṪ>ɗƇ⁵j€”.

Try it online!

How it works

ŒṖẈṪ>ɗƇ⁵j€”. - Main link. Takes an email E on the left
ŒṖ           - All partitions
     ɗƇ⁵     - Keep those partitions f(P, 10) for which the following is true:
  Ẉ          -   The lengths of each part of P
   Ṫ         -   The last one
    >        -   is greater than 10
        j€”. - Join each of those remaining by ”.
\$\endgroup\$
0
\$\begingroup\$

05AB1E, 29 bytes

g©<'.и.ιæʒ'.мJg®Q}J’@g‚ç.ŒŒ’«

Try it online!

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

T-SQL, 261 bytes

Input is taken from column U of table T (according to the Code Golf rules for SQL).

WITH V(N)AS(SELECT 1UNION ALL SELECT N+1FROM V WHERE N<(SELECT LEN(U)FROM T)),C AS(SELECT U FROM T UNION ALL SELECT CONVERT(VARCHAR(64),STUFF(U,N+1,0,'.'))FROM C,V WHERE N<LEN(U)AND SUBSTRING(U,N,2)NOT LIKE'%.%'AND LEN(U)<64)SELECT DISTINCT U+'@gmail.com'FROM C

DB Fiddle

Duration of execution grows exponentially and it takes minutes on my machine for strings longer than 10 characters, but theoretically (if given unlimited time) it should work for input strings up to 64 characters, limiting the output to 64 characters. Therefore, it should also get the -8% bonus, getting to 240 bytes.

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

JavaScript (Node.js), 86 bytes

(m,e,i)=>{while(m[i])w=m.substr(0,i)+'.'+m.substr(i),console.log(w+e),f(w,e,i+2),i++}

Try it online!

JavaScript (Node.js), 80 bytes

(m,e,i,c)=>{while(m[i])w=m.substr(0,i)+'.'+m.substr(i),c(w+e),f(w,e,i+2,c),i++}

Try it online!

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

PHP, 110 bytes

function f($a,$b,$c){while($a[$c]){$w=substr($a,0,$c).'.'.substr($a,$c);echo $w.$b,"\n";f($w,$b,$c+2);$c++;}};

Try it online!

Human readable version

<?php
function f($address, $suffix, $i)
{
    while ($address[$i]) {
        $str = substr($address, 0, $i) . '.' . substr($address, $i);
        echo $str . $suffix, "\n";
        f($str, $suffix, $i + 2);
        $i++;
    }
};

f('abcabc', '@gmail.com', 1);
\$\endgroup\$
1
  • 1
    \$\begingroup\$ You do not need to count bytes used for testing. Furthermore, I think your input format does not comply with the challenge rules. \$\endgroup\$ Jun 21, 2020 at 4:40

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.