15
\$\begingroup\$

The program should print every letter combination (lowercase or uppercase, it doesn't matter) in alphabetic order. It must start with a and the last printed combination should be password.

The output should be:

a b c d e f g h i j k l m n o p q r s t u v w x y z aa ab ac ... passwora passworb passworc password
\$\endgroup\$
2
  • 2
    \$\begingroup\$ Do the separators have to be spaces, or can I use newlines? \$\endgroup\$ Commented Sep 23, 2013 at 21:37
  • \$\begingroup\$ Yes you can, it is just a minor change. \$\endgroup\$
    – ST3
    Commented Sep 24, 2013 at 9:23

16 Answers 16

32
\$\begingroup\$

Perl, 19 chars

say for a..password

Uses newlines as delimiters, per clarification above. Run with perl -M5.010 (or just perl -E 'say for a..password') to enable the Perl 5.10+ say feature. Per meta, this doesn't count as extra chars.

(If you insist on spaces as delimiters, $,=$";say a..password is only two chars longer. However, it's also very slow and wasteful of memory, to the point of being unusable in practice, since it tries to build the entire list in memory before printing it.)

\$\endgroup\$
18
\$\begingroup\$

Ruby, 33 chars (optimal but longer version)

?a.upto('password'){|c|$><<c+' '}

I like the 'a'.upto('password'); it tells you exactly what it's doing. Ruby is great and expressive like that. :D

Of course, print c,' ' would also be much clearer, but using $> is two characters shorter.

Ruby, 29 25 chars (slow version)

$><<[*?a..'password']*' '

This one's shorter, but it prints all of the tokens at once, so it takes a long, long time to run!

\$\endgroup\$
2
  • 1
    \$\begingroup\$ Nice, especially the first. \$\endgroup\$ Commented Sep 23, 2013 at 23:15
  • \$\begingroup\$ In the slow version, (?a..'password').to_a can be shortened to [*?a..'password'] \$\endgroup\$ Commented Sep 30, 2013 at 1:13
6
\$\begingroup\$

Perl, 33 32 24 characters

A solution in 32 characters:

$_=a;print$_++,$"until/passwore/

Not much to say about this one. I could reduce this to 27 characters if I could use newlines instead of spaces to separate the entries.

Ilmari Karonen points out that .. internally calls ++, so a better solution (25 characters) would be:

print$_,$"for a..password

By taking advantage of Perl's command-line options, here's an equivalent 24-character solution:

perl -l40e 'print for a..password'

The rules for counting perl flags is here, for those who aren't familiar with them.

Of course, Ilmari's 21-character solution is shorter still, but it requires a machine that can allocate an array of 129,052,722,140 strings.

\$\endgroup\$
2
  • \$\begingroup\$ Wouldn't .$" instead of ," " save a character? \$\endgroup\$
    – Mr. Llama
    Commented Sep 23, 2013 at 19:54
  • \$\begingroup\$ Yep, total oversight on my part. Thanks. \$\endgroup\$
    – breadbox
    Commented Sep 23, 2013 at 20:02
6
\$\begingroup\$

Perl 6, 20 chars

say "a".../password/

You don't need other things

\$\endgroup\$
5
\$\begingroup\$

Python 2, 91

b=lambda n:n*' 'and b(n/26-(n%26<1))+chr(~-n%26+97)
i=0
exec"i+=1;print b(i);"*129052722140
\$\endgroup\$
4
\$\begingroup\$

PHP 38 37 36 characters

<?for($w=a;$w<passwore;)echo$w++,~ß;

You have to set the encoding to ISO 8859-1 and disable warnings.

\$\endgroup\$
13
  • \$\begingroup\$ I didn't test that, but does it really do that??? \$\endgroup\$
    – ST3
    Commented Sep 25, 2013 at 9:07
  • \$\begingroup\$ @ST3 It's a simple loop. The variable $w is initially set to 'a' and then is incremented until it reaches the first value after 'password' (the last string is not printed). \$\endgroup\$
    – lortabac
    Commented Sep 25, 2013 at 11:17
  • 3
    \$\begingroup\$ @ST3 It is a regular for loop. There is nothing strange in this code, except for the last 2 characters, which are a bitwise-inverted whitespace. Anyway, yes, I tested it up to a shorter word. \$\endgroup\$
    – lortabac
    Commented Sep 25, 2013 at 12:04
  • 1
    \$\begingroup\$ @ST3 Here is a test from passwoqs to password. Because the encoding of codepad is not ISO 8859-1, I had to replace with a whitespace. \$\endgroup\$
    – lortabac
    Commented Sep 27, 2013 at 7:39
  • 1
    \$\begingroup\$ You can save a char with $w<passwore in stead of $w!=passwore. \$\endgroup\$ Commented Dec 15, 2013 at 15:07
2
\$\begingroup\$

Ruby (40 characters)

Interpret a string of a-z letters as a number in base 26, with a = 1, b = 2, ..., z = 26.

So "password" can be thought of as the number N =

16*(26**7) + 
1*(26**6) + 
19*(26**5) + 
19*(26**4) + 
23*(26**3) + 
15*(26**2) + 
18*(26**1) + 
4*(26**0)

If we let s = "a" (that is: 1) and we make (N-1) calls to s.succ!, s will be "password" (N). In other words, N = 1 + (N-1).

For an example that will run more quickly, to prove the calculation of N is correct, consider "pass" as the target, where N is

16*(26**3) + 
1*(26**2) + 
19*(26**1) + 
19*(26**0)

and

s = "a"
(N-1).times { s.succ! }
puts s #== "pass"

Since we want to print "a" too, we need

s = "`"
N.times { print(s.succ! + " ") }

So back to the full "password". N = 129052722140, leaving:

s=?`;0x1e0c2443dc.times{$><<s.succ!+" "}

I hunted for a more compact form of 129052722140 == 0x1e0c2443db but couldn't find one.

(Updated to fix the lack of printing "a", thanks to Cary.)

\$\endgroup\$
7
  • 1
    \$\begingroup\$ Adam, that must have been you in my mind-meld. Don't you want s to start one before 'a'? \$\endgroup\$ Commented Sep 24, 2013 at 17:19
  • \$\begingroup\$ I think what you're getting at is that I've used N instead of N-1 in my iterations! Thanks, I'll edit to fix. (Although 129052722140 is an interesting number to Google :).) \$\endgroup\$
    – ap.
    Commented Sep 24, 2013 at 18:23
  • 1
    \$\begingroup\$ 0x1e0c2443db is just as many chars as 129052722139. \$\endgroup\$
    – steenslag
    Commented Sep 24, 2013 at 19:18
  • \$\begingroup\$ What I meant was that if s=?a, s.succ! starts at 'b'`. \$\endgroup\$ Commented Sep 24, 2013 at 19:29
  • 1
    \$\begingroup\$ With s=?a and N-1 you get 'b c...password'; with s =<backtick> and N you get 'a b...password'. The SO requested the output to begin with 'a'. That's all. \$\endgroup\$ Commented Sep 24, 2013 at 23:24
2
\$\begingroup\$

Javascript, 73

Here is a 73 character version of @Briguys' code, which prints only letter combinations

for(i=s=0;1982613533018>i++;s=i.toString(36))/\d/.test(s)||console.log(s)

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

APL(Dyalog), 46 34

{∇{'PASSWORD '≡⍞←⍵:→⋄⍵}¨⎕A∘.,⍵}' '

Theoretically, it would print until PASSWORD, but I encountered a work space full error after ZZZZ: 5-dimensional array is just too awesome.

EDIT: Must have been too long since I last fiddled with APL. How dare I missed the identity comparision ()!!!

Explanation

{...}: Declares a function which...
⎕A∘.,⍵: Takes the outer product over concatenation (Every combination of an element of the left operand concatenated with an element of the right operand, just like Cartesian Product) between the 26 uppercase alpha (⎕A) and the argument ()

{...}¨: And for each element of the resulting set, plug that into a function which...
⍞←⍵: prints it out
'PASSWORD '≡ and compare it with 'PASSWORD '
: If the comparison returns true (1), then abort the program.
: Else just return the printed string.

: Finally, the outer function recurse itself.

(Then you are taking outer product over concat between the 26 alpha and the 26 alpha, which gives all the 2-letter combinations, and then outer product over concat between the 2-letter combinations and the 26 alpha, etc... Until you reach PASSWORD which triggers the abort)

' ': The spark!! That kick-start the recursive function with the space character.

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

Python 2 - 153 152 151 149 bytes

from itertools import*;R=range
for l in iter(chain(*[product(*((map(chr,R(65,91)),)*n))for n in R(1,9)]).next,tuple("passwore")):print ''.join(l)

Saved one byte by using UPPERCASE and one by using newlines instead of spaces.

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

Golfscript 41

For lack of 'z'+1 == 'aa' logic Golfscript can't win this one.

168036262484,(;{27base{96+}%' '+.96?0<*}%
  • 168036262484, create array from 0 to 168036262483
  • (; drop the 0
  • { .. }% iterate over array
  • 27base convert element to base 27 array
  • {96+}% add 96 to each digit
  • ' '+ convert to string and add a space to the end
  • .96?0<* truncate string to zero if it contains char 96
\$\endgroup\$
0
1
\$\begingroup\$

In Ruby, 39 40.

a=&`
0x1e0c2443dc.times{$><<a.succ!+' '}

..or 129052722140. (Edit: formerly I had 129052722. I had lost some digits cutting and pasting. Previous hex (0x7B13032) was for incorrect number.). Borrowed a=?` from @Doorknob to saves a character.

\$\endgroup\$
7
  • \$\begingroup\$ I tried to fix the a=?` thing, it looks kinda weird and has an extra space at the end but at least it works :P \$\endgroup\$
    – Doorknob
    Commented Sep 24, 2013 at 0:52
  • \$\begingroup\$ So where does the number 129052722 come from? By my calculation, that would seem to give you the range "a" to "kwkokg" ... a bit small. \$\endgroup\$
    – breadbox
    Commented Sep 24, 2013 at 1:04
  • \$\begingroup\$ @Breadbox I calculated that number with the following method (sorry for the formatting, but comments have limitations, eh?): ORD_BASE_ASCII = 'a'.ord-1; def nbr(word); len = word.size; word.split('').inject(0) {|t,c| offset = c.ord - ORD_BASE_ASCII; t + offset*(26**(len -= 1))}; end It's easy to confirm this is correct by just printing out some sequences. \$\endgroup\$ Commented Sep 24, 2013 at 4:55
  • \$\begingroup\$ @breadbox You were right. See edit. Method I gave in comment is OK. \$\endgroup\$ Commented Sep 24, 2013 at 5:11
  • \$\begingroup\$ Fencepost errors. Your script is calculating using a=1..z=26. You need to calculate a=0..z=25 to get the right count. Removing the -1 from the first line, you'll get 120699639557, which (adding one for the zeroth entry) matches my calculation. \$\endgroup\$
    – breadbox
    Commented Sep 24, 2013 at 5:15
1
\$\begingroup\$

Javascript: 57 56 characters (thanks C5H8NNaO4)

Here's a solution that includes numbers as possible characters ("0", "1", "2", .., "passwor9", "passwora", "passworb", "passworc", "password")

for(i=-1;i++<1982613533017;console.log(i.toString(36)));

Here's a fiddle for testing (with only the last 100 iterations so it doesn't lock up your browser).

\$\endgroup\$
8
  • 3
    \$\begingroup\$ This solution is wrong, it doesn't follow the specification. \$\endgroup\$
    – Doorknob
    Commented Sep 24, 2013 at 18:13
  • \$\begingroup\$ @Doorknob - Yes, I mentioned that in my answer. It still prints all cases from the original requirements, but prints all alpha-numeric cases as well. \$\endgroup\$
    – Briguy37
    Commented Sep 24, 2013 at 18:33
  • \$\begingroup\$ Also, after re-reading the question, if I set i to 9 in my code, it would meet ALL the question's requirements except for his example output, which he has already given an exception for (and it would bring the code to 56 characters). \$\endgroup\$
    – Briguy37
    Commented Sep 24, 2013 at 18:58
  • \$\begingroup\$ @Briguy37 The spec says print every **letter** combination Anyway, save a character: {} -> ; \$\endgroup\$
    – C5H8NNaO4
    Commented Sep 25, 2013 at 7:48
  • \$\begingroup\$ @C5H8NNaO4: Which letter combination does my solution not print? Thanks for the tip! \$\endgroup\$
    – Briguy37
    Commented Sep 25, 2013 at 13:14
1
\$\begingroup\$

Haskell, 101

main=putStrLn.concat.takeWhile(/="passwore ").tail.concat.iterate(\k->[x:y|x<-['a'..'z'],y<-k])$[" "]
\$\endgroup\$
0
\$\begingroup\$

Befunge (72)

<_v#:/*2+67\+++88*99%*2+76:
^ >$>:#,_84*+,1+:0\:" Lr$W~"67++**1+***6+`#@_

Prints strings 'a' to 'password' separated by spaces, then exits.

Below is a version that prints only the first 9*9 = 81 words ('a' to 'dd'), for comparison. The 99* is the number of iterations to perform.

<_v#:/*2+67\+++88*99%*2+76:
^ >$>:#,_84*+,1+:0\:99*`#@_
\$\endgroup\$
0
\$\begingroup\$

JavaScript 80 76

for(i=s=0;s!="password";i++){s=i.toString(36).replace(/[0-9]/,'');console.log(s)}

fiddle - stops at "pa".

however this does repeat things.

\$\endgroup\$
3
  • \$\begingroup\$ You can initialize the loop with i=s=0 to save three more characters. \$\endgroup\$
    – Ry-
    Commented Sep 25, 2013 at 21:54
  • \$\begingroup\$ @minitech done. \$\endgroup\$ Commented Sep 25, 2013 at 22:25
  • 1
    \$\begingroup\$ Why keep the var? i was a global before; now s is a global. You can just keep both globals in code golf, usually. \$\endgroup\$
    – Ry-
    Commented Sep 25, 2013 at 22:30

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.