43
\$\begingroup\$

The Challenge:

Print every 2 letter word acceptable in Scrabble using as few bytes as possible. I have created a text file list here. See also below. There are 101 words. No word starts with C or V. Creative, even if nonoptimal, solutions are encouraged.

AA
AB
AD
...
ZA

Rules:

  • The outputted words must be separated somehow.
  • Case does not matter, but should be consistent.
  • Trailing spaces and newlines are allowed. No other characters should be outputted.
  • The program should not take any input. External resources (dictionaries) cannot be used.
  • No standard loopholes.

Wordlist:

AA AB AD AE AG AH AI AL AM AN AR AS AT AW AX AY 
BA BE BI BO BY 
DE DO 
ED EF EH EL EM EN ER ES ET EX 
FA FE 
GO 
HA HE HI HM HO 
ID IF IN IS IT 
JO 
KA KI 
LA LI LO 
MA ME MI MM MO MU MY 
NA NE NO NU 
OD OE OF OH OI OM ON OP OR OS OW OX OY 
PA PE PI 
QI 
RE 
SH SI SO 
TA TI TO 
UH UM UN UP US UT 
WE WO 
XI XU 
YA YE YO 
ZA
\$\endgroup\$
13
  • 9
    \$\begingroup\$ Do the words have to be outputted in the same order? \$\endgroup\$
    – Sp3000
    Commented Aug 13, 2015 at 3:26
  • 2
    \$\begingroup\$ @Sp3000 I'll say no, if something interesting can be thought up \$\endgroup\$
    – qwr
    Commented Aug 13, 2015 at 3:29
  • 2
    \$\begingroup\$ Please clarify what exactly counts as separated somehow. Does it have to be whitespace? If so, would non-breaking spaces be allowed? \$\endgroup\$
    – Dennis
    Commented Aug 13, 2015 at 14:14
  • 5
    \$\begingroup\$ Ok, found a translation \$\endgroup\$ Commented Aug 13, 2015 at 15:16
  • 3
    \$\begingroup\$ Vi isn't a word? News to me... \$\endgroup\$
    – jmoreno
    Commented Aug 15, 2015 at 15:23

49 Answers 49

1
2
1
\$\begingroup\$

Perl, 248 bytes

@v=split(//,"AEIOU");@s=split(' ',"ADEGIRSWX LSTX DFN EFIPRX HPST BHLMNTY DFHMNR ST DHMNSWY MN ZFKP WYPB KQXLHPMB LGJTB X");for(0..14){foreach $c(split(//,@s[$_])){$_<10?print @v[$_%5].$c." ":a;$_>4?print $c.@v[$_%5]." ":a;}}print "MM MY BY HM SH";

First time using perl (and first time golfing), so there's definitely room for improvement. Factored out the vowels and grouped the remaining letters based on how the resulting word was created - adding the vowel first, last, or both vowel first and last create a word on the list.

\$\endgroup\$
2
  • \$\begingroup\$ I don't know Perl, but I assume you are separating the output by spaces. It seems "MM "."MY "."BY "."HM "."SH " could be shortened to "MM MY BY HM SH". \$\endgroup\$ Commented Aug 14, 2015 at 19:05
  • \$\begingroup\$ @steveverrill Thanks! I got so caught up in the rest of the code that I overlooked how redundant that was. \$\endgroup\$ Commented Aug 14, 2015 at 19:18
1
\$\begingroup\$

Javascript (ES6), 214

Perhaps not the shortest way to do it, but definitely interesting.

_=>(i=0,[...'ABDEFGHILMNOPRSTUWXY'].map(z=>[...`ABFHKLMNPTYZ
A
AEIO
ABDFHMNOPRWY
EIO
A
AEOSU
ABHKLMOPQSTX
AE
AEHMOU
AEIOU
BDGHJLMNSTWY
OU
AEO
AEIOU
AEIU
MNX
AO
AEO
ABMO`.split`
`[i++]].map(g=>g+z).join` `).join`
`)

Loops through each letter in the first string, adding it onto each letter in the corresponding line of the second. This returns the words in order of their last letter, like so:

AA BA FA HA KA LA MA NA PA TA YA ZA
AB
AD ED ID OD
AE BE DE FE HE ME NE OE PE RE WE YE
EF IF OF
AG
AH EH OH SH UH
AI BI HI KI LI MI OI PI QI SI TI XI
AL EL
AM EM HM MM OM UM
AN EN IN ON UN
BO DO GO HO JO LO MO NO SO TO WO YO
OP UP
AR ER OR
AS ES IS OS US
AT ET IT UT
MU NU XU
AW OW
AX EX OX
AY BY MY OY

Suggestions welcome!

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

Java, 255 254 bytes

Found a way to squeeze one more byte out of it.

class C{public static void main(String[]a){char c='A';for(char l:"ABDEGHILMNRSTWXY AEIOY  EO DFHLMNRSTX AE O AEIMO DFNST O AI AIO AEIMOUY AEOU DEFHIMNPRSWXY AEI I E HIO AIO HMNPST  EO IU AEO A".toCharArray())if(l<'A')c++;else System.out.print(" "+c+l);}}

Or (though not much clearer):

class C {
    public static void main(String[] a) {
        char c = 'A';
        for (char l : "ABDEGHILMNRSTWXY AEIOY  EO DFHLMNRSTX AE O AEIMO DFNST O AI AIO AEIMOUY AEOU DEFHIMNPRSWXY AEI I E HIO AIO HMNPST  EO IU AEO A"
                .toCharArray())
            if (l < 'A')
                c++;
            else
                System.out.print(" " + c + l);
    }
}
\$\endgroup\$
1
  • \$\begingroup\$ You can save two bytes by changing both occurrences of 'A' into 65. \$\endgroup\$
    – ProgramFOX
    Commented Aug 15, 2015 at 12:31
1
\$\begingroup\$

Haskell, 333 308 298 bytes

Just for fun!

Evaluating s will print all of the words in a weird order - I used the fact that most combinations are vowel-consonant or vice versa, could probably optimize even more with custom character "classes", shortening the encoded matrix (here, w and k).

Does anybody know a shorter way to print strings without quotes and brackets than my monadic one? Type classes are even longer as far as I can tell.

Also, there might also be a shorter way of doing p's job...

v="AEIOU"
c="BCDFGHJKLMNPQRSTVWXYZ"
w=[976693,321324,50188,945708,52768]
k=[15,0,10,3,8,15,8,5,13,31,27,7,4,2,12,13,0,10,20,11,1]
z a b x=[[c:[e]|(e,f)<-b#p d,f]|(c,d)<-a#x]
(#)=zip
p 0=[]
p n=((n`mod`2)>0):p(n`div`2)
s=mapM_ putStrLn$concat$z v c w++z c v k++[words"AA AE AI BY HM MM MY OE OI SH"]
\$\endgroup\$
4
  • \$\begingroup\$ Isn't sequence_ the same as void$sequence? Then you can omit also the import. \$\endgroup\$
    – nimi
    Commented Aug 13, 2015 at 22:40
  • \$\begingroup\$ That's oddly packaged, but yes. Thanks! \$\endgroup\$ Commented Aug 13, 2015 at 22:48
  • \$\begingroup\$ Isn't, void had to be imported. Anyways, gonna/gotta remember this. \$\endgroup\$ Commented Aug 13, 2015 at 22:52
  • 1
    \$\begingroup\$ Ah, and sequence_$map putStrLn is mapM_ putStrLn. Replace the (, ) around concat$... with another $. \$\endgroup\$
    – nimi
    Commented Aug 13, 2015 at 23:07
1
\$\begingroup\$

PHP, 170 bytes

shortest approach I could find so far ...

for(;$c=ABFHKLMNPTYZ1A2AEIO1ABDFHMNOPRWY1EIO1A1AEOSU1ABHKJMOPQSTX3AE1AEHMOU1AEIOU1BDGHJLMNSTWY1OU11AEO1AEIOU1AEIU1MNX2AO1AEO1ABMO[$i++];)$c<1?print$c.chr($k+65)._:$k+=$c;

breakdown

for(;$c=CHARACTERS[$i++];)  // loop $c through map
    $c<1                            // if $c is a letter (integer value < 1)
        ?print$c.chr($k+65)._           // print first letter, second letter, delimiter
        :$k+=$c                         // else increase second letter
    ;

Note The shortest bit-mapping version with printable ascii costs 190 bytes (113 bytes data+77 bytes decoding) using 6 bits=base 64, 174 bytes (97 data, 77 decoding) using 7 bits (base 128); possibly some more for escaping.

for(;$p<676;)                   // loop through combinations
    ord("MAPPING"[$p/6])-32>>$p%6&1     // test bit
        ?                                       // if set, do nothing
        :print chr($p/26+65).chr($p++%26+65)._; // if not, print combination+delimiter

Base 224 (using ascii 32..255) takes 87 bytes data (+ escaping); but I guess the decoding will cost more than 10 bytes extra.
Excluding C and V from the map would save 16/14/13 bytes on the data but cost a lot in decoding.

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

Python 2, 202 200 bytes

for s in'AABALIFEN KITOELOPE LAYAINUNEREMI AMANAHI MOHMYEX UPI UTAGOFAWOWETI BY OR BI ZAXI PAS BE AD AEDEHAT QI UMMUS JOIDONOSHOYOD BOMESISOXUHEF KAR'.split():
 for i in range(len(s)-1):print s[i:i+2]

Try it online!

Try to join up overlapping pairs; i.e. ZAXI encodes ZA, AX, XI. Looks like 140 bytes of encoded text is about the best possible with this approach.

\$\endgroup\$
1
  • 1
    \$\begingroup\$ 140 bytes is the theoretical limit for this approach. \$\endgroup\$
    – Joel
    Commented Aug 30, 2019 at 2:43
1
\$\begingroup\$

05AB1E, 143 bytes

•ZÐFý8ù6„=4ÅœÿWì±7Ë5Œ¾`ó/îAnµ%Ñ¥Ëø±/ÀéNzքѧIJ¶D—ÙVEStvÖò…¸¾6F³#EXŠm¯Cĵ±ÓoÊ°}^€Ftå߀ðŒ=«j;F-Â1;xX3i&QZÒ'Ü”>lwìlOs>íÙVÇI)~î‰Hç²?Öd0È^ÝQ°•36B2ô»

Try it online!

\$\endgroup\$
2
  • \$\begingroup\$ 95 bytes by porting @Sp3000's Python 3 answer. \$\endgroup\$ Commented Aug 30, 2019 at 7:16
  • 1
    \$\begingroup\$ @KevinCruijssen 91 (and I'm sure this method can get lower, but I hand-picked the dictionary words for humor). \$\endgroup\$
    – Grimmy
    Commented Aug 30, 2019 at 13:33
1
\$\begingroup\$

Python 3, 182 bytes

[print(f+l)for*F,l in'ABFHKLMNPTYZA AB AEIOD ABDFHMNOPRWYE EIOF AG AEOSUH ABHKLMOPQSTXI AEL AEHMOUM AEIOUN BDGHJLMNSTWYO OUP AEOR AEIOUS AEIUT MNXU AOW AEOX ABMOY'.split()for f in F]

Try it online!

This was briefly the shortest Python 3 solution :)

Each section of the magic string, e.g. AEIOD, encodes e.g. AD ED ID OD. (The last letter of the section should be combined with each other letter.)

Equivalent to:

for *FIRSTS, last in (
    'ABFHKLMNPTYZA AB AEIOD ABDFHMNOPRWYE EIOF AG AEOSUH ABHKLMOPQSTXI AEL AEHMOUM AEIOUN BDGHJLMNSTWYO OUP AEOR AEIOUS AEIUT MNXU AOW AEOX ABMOY'
    .split()
):
    for first in FIRSTS:
        print(first+last)
\$\endgroup\$
0
\$\begingroup\$

F#, 205 bytes

Seq.iteri(fun i s->Seq.iter(printf"%c%c "((char)i+'A'))s;printfn"")("ABDEGHILMNRSTWXY AEIOY  EO DFHLMNRSTX AE O AEIMO DFNST O AI AIO AEIMOUY AEOU DEFHIMNPRSWXY AEI I E HIO AIO HMNPST  EO IU AEO A".Split())

Live version.

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

scala, 223 bytes

print(("AABDEGHILMNRSTWXY BAEIOY DEO EDFHLMNRSTX FAE GO HAEIMO IDFNST JO KAI LAIO MAEIMOUY NAEOU ODEFHIMNPRSWXY PAEI QI RE SHIO TAIO UHMNPST WEO XIU YAEO ZA".split(" ").flatMap(a=>a.tail.map(a(0).toString+_))).mkString(" "))

Not especially compact, but vaguely idiomatic .. eval with

scala -e '...'
\$\endgroup\$
0
\$\begingroup\$

Java, 288

class E{public static void main(String[]a){a="ABDEGHILMNRSTWXY,AEIOY,,EO,DFHLMNRSTX,AE,O,AEIMO,DFNST,O,AI,AIO,AEIMOUY,AEOU,DEFHIMNPRSWXY,AEI,I,E,HIO,AIO,HMNPST,,EO,IU,AEO,A".split(",");for(int i=26,j;i-->0;)for(j=0;j<a[i].length();)System.out.println((char)('A'+i)+""+a[i].charAt(j++));}}

By just stringing together the second letters of each word (plus a delimiter), you just loop through while keeping track of the first. Not as fancy as the base-encoded versions, but much simpler and a good score for Java. Prints in order by descending-first-letter (ZA YA YE YO XI XU), one word per line.

With line breaks:

class E{
    public static void main(String[]a){
        a="ABDEGHILMNRSTWXY,AEIOY,,EO,DFHLMNRSTX,AE,O,AEIMO,DFNST,O,AI,AIO,AEIMOUY,AEOU,DEFHIMNPRSWXY,AEI,I,E,HIO,AIO,HMNPST,,EO,IU,AEO,A".split(",");
        for(int i=26,j;i-->0;)
            for(j=0;j<a[i].length();)
                System.out.println((char)('A'+i)+""+a[i].charAt(j++));
    }
}
\$\endgroup\$
0
\$\begingroup\$

Python 239 bytes

import re;f=lambdax:''.join(re.findall('..',x));a,b='ABAHALAMANATAYDEDOEFEHEMENERHOISITMOMUNONUOSOWOY','AAADAEAGAIARASAWAXBEBIBOBYELESETEXFAGOHIHMIDIFINJOKAKILILOMIMMMYOEOFOIOPOROXPAPEPIQISHTOUHUPUSUTWEXIXUYEZA';print f(a),f(a[::-1]),f(b)

This is a bit long, but I've given it a try. I've counted all the patterns that also have the reversed counterparts. Ex) 'AB'/'BA' and so on.

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

Python 3, 248 bytes

e=enumerate
[print(*(chr(x+65)+chr(j+65)+" "for j,i in e(bin(k)[2:])if int(i)))for x,k in e([30292443,16793873,0,16400,9320616,17,16384,20753,794664,16384,257,16641,17846545,1064977,29798840,273,256,16,16768,16641, 831616,0,16400,1048832,16401,1])]

The numbers were generated by an additional script
I'm sure that it can be optimized further

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

C# (Visual C# Interactive Compiler), 208 bytes

()=>"ABDEGHILMNRSTWXY,AEIOY,EO,DFHLMNRSTX,AE,O,AEIMO,DFNST,O,AI,AIO,AEIMOUY,AEOU,DEFHIMNPRSWXY,AEI,I,E,HIO,AIO,HMNPST,EO,IU,AEO,A".Split(',').SelectMany((x,y)=>x.Select(z=>""+"ABDEFGHIJKLMNOPQRSTUWXYZ"[y]+z))

Try it online!

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

PHP, 187 bytes

for($n=A,$l=ABDEGHILMNRSTWXYAEIOY1EODFHLMNRSTXAEGOAEIMODFNS2TOAIAIOAEIMOUYAEOUDEFFHIMNPRSWXYAEI3IE4HIOAIOHMNPST5EOIUAEOA;$q=$l[$x++];){if($q<A)$n++;else{if($q<$p)$n++;$p=$q;echo"$n$q
";}}

Try it online!

Basically, the list is mostly just the second letters in the word list - I noticed in almost all cases, when incrementing the first letter, the second letter is before the one before it. For example going from AY to BA, A is before Y in the alphabet, and going from QI to RE, E is before I in the alphabet. In the very few cases where the second letter was the same or after the previous one, or to skip C and V, I put a number in the string so it knows to increment the first letter.

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

Retina, 167 bytes


¶AABDEGHIcWXY¶BbOY¶DEaEDFHcX¶FAE¶GaHbMaIDFNST¶JaKAI¶LAIaMbMOUY¶NAEOU¶ODEFHIMNPRSWXY¶Pb¶QI¶RE¶SHIaTAIaUHMNPST¶WEaXIU¶YAEaZA
c
LMNRST
b
AEI
a
O¶
+`(¶(.)\S+)(\S)
$1 $2$3

Try it online!

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

C#, 161 bytes

w=>"aBFHKLMNPTYZeBDFHMNOPRWYiBHKLMOPQSTXmEHMOUhEOSUnEIOUsEIOUdEIOtEIUyBMOrEOxEOlEwObgoBDGHJLMNSTWYfEIOuMNXpOU".Select((x,i)=>x>90&&w!=(w=""+x)?i>80?"":"a"+w:x+w)

The string is every possible second letter (lowercase) followed by each of its valid first letters (uppercase).

Every time a lowercase letter is reached, var w is updated to store that letter, and return "". Each time an uppercase letter is reached, return that letter + w.

Additionally, "a" + w is automatically added every time a new lowercase letter is reached, unless that letter is one of f, o, p or u (this is achieved by putting these 4 at the end of the string and conditionally adding "a"+w based on index).

Try it online!

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

JavaScript (V8), 182 bytes

"A ABFHKLMNPTYZB AD AEIOE ABDFHMNOPRWYG AH AEOSUI ABHKLMOPQSTXL AEM AEHMOUN AEIOUR AEOS AEIOUT AEIUW AOX AEOY ABMOO BDGHJLMNSTWYF EIOU MNXP OU".replace(/. ?/g,c=>c[1]?a=c:print(c+a))

Try it online!

Not that bad

\$\endgroup\$
1
  • \$\begingroup\$ gzip compress this best (comparing to other compress) to 172:( \$\endgroup\$
    – l4m2
    Commented Dec 23, 2022 at 10:05
0
\$\begingroup\$

Python 2, 23+176 = 199 bytes

print('...'.decode('zip'))

Try it online!

Hexdump of the string in place of ...:

['0x78', '0x9c', '0x0d', '0xc7', '0xd1', '0x8d', '0xc3', '0x30', '0x0c', '0x44',
 '0xc1', '0x56', '0x5e', '0x2b', '0x6b', '0x88', '0x8e', '0x78', '0x31', '0x45',
 '0x9f', '0x25', '0xc1', '0x56', '0xfa', '0x2f', '0x24', '0xf9', '0x19', '0x60',
 '0x24', '0xb4', '0xa1', '0x82', '0x0c', '0xbd', '0x50', '0x45', '0x8e', '0x0e',
 '0x14', '0xa8', '0xa1', '0x0b', '0x75', '0x34', '0xd0', '0x8d', '0x1e', '0xb4',
 '0xd8', '0xc4', '0x66', '0x6c', '0xce', '0x96', '0x6c', '0x8b', '0x62', '0x94',
 '0xc4', '0x0a', '0xb6', '0x63', '0x15', '0x3b', '0xb0', '0xc0', '0x1a', '0x76',
 '0x61', '0x1d', '0x1b', '0xd8', '0xc3', '0x2e', '0x76', '0xe3', '0x95', '0x54',
 '0x51', '0x8d', '0xea', '0xd4', '0xa0', '0x26', '0x5e', '0xf0', '0x1d', '0x6f',
 '0x78', '0xc7', '0x07', '0x7f', '0xc9', '0x5b', '0xbc', '0x9d', '0x43', '0x1c',
 '0x3f', '0x93', '0x10', '0x61', '0x84', '0x13', '0x41', '0xfc', '0x3a', '0x89',
 '0x45', '0x13', '0xcd', '0x68', '0x49', '0x9b', '0x64', '0x21', '0x8d', '0xdc',
 '0xc9', '0x4a', '0x3a', '0x19', '0x64', '0x23', '0x4f', '0xf2', '0x22', '0x3b',
 '0x79', '0x93', '0x0f', '0xb9', '0x38', '0xc5', '0x69', '0x9c', '0xce', '0xbf',
 '0x73', '0x19', '0xbd', '0xd2', '0x9d', '0x9e', '0x0c', '0x31', '0x9c', '0x91',
 '0xcc', '0xca', '0x0c', '0x66', '0x63', '0x9e', '0xcc', '0xce', '0x1c', '0xdc',
 '0xc6', '0x9d', '0x3c', '0xce', '0x33', '0x59', '0x62', '0x19', '0x2b', '0xf9',
 '0xe8', '0x0b', '0x93', '0x2f', '0x47', '0xe5']
\$\endgroup\$
1
2

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.