16
\$\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
    \$\begingroup\$ Do the separators have to be spaces, or can I use newlines? \$\endgroup\$ – Ilmari Karonen Sep 23 '13 at 21:37
  • \$\begingroup\$ Yes you can, it is just a minor change. \$\endgroup\$ – ST3 Sep 24 '13 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\$
  • 1
    \$\begingroup\$ Nice, especially the first. \$\endgroup\$ – Cary Swoveland Sep 23 '13 at 23:15
  • \$\begingroup\$ In the slow version, (?a..'password').to_a can be shortened to [*?a..'password'] \$\endgroup\$ – Paul Prestidge Sep 30 '13 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\$
  • \$\begingroup\$ Wouldn't .$" instead of ," " save a character? \$\endgroup\$ – Mr. Llama Sep 23 '13 at 19:54
  • \$\begingroup\$ Yep, total oversight on my part. Thanks. \$\endgroup\$ – breadbox Sep 23 '13 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\$
  • \$\begingroup\$ I didn't test that, but does it really do that??? \$\endgroup\$ – ST3 Sep 25 '13 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 Sep 25 '13 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 Sep 25 '13 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 Sep 27 '13 at 7:39
  • 1
    \$\begingroup\$ You can save a char with $w<passwore in stead of $w!=passwore. \$\endgroup\$ – Decent Dabbler Dec 15 '13 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\$
  • 1
    \$\begingroup\$ Adam, that must have been you in my mind-meld. Don't you want s to start one before 'a'? \$\endgroup\$ – Cary Swoveland Sep 24 '13 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\$ – Adam Prescott Sep 24 '13 at 18:23
  • 1
    \$\begingroup\$ 0x1e0c2443db is just as many chars as 129052722139. \$\endgroup\$ – steenslag Sep 24 '13 at 19:18
  • \$\begingroup\$ What I meant was that if s=?a, s.succ! starts at 'b'`. \$\endgroup\$ – Cary Swoveland Sep 24 '13 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\$ – Cary Swoveland Sep 24 '13 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\$
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\$
  • \$\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 Sep 24 '13 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 Sep 24 '13 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\$ – Cary Swoveland Sep 24 '13 at 4:55
  • \$\begingroup\$ @breadbox You were right. See edit. Method I gave in comment is OK. \$\endgroup\$ – Cary Swoveland Sep 24 '13 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 Sep 24 '13 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\$
  • 3
    \$\begingroup\$ This solution is wrong, it doesn't follow the specification. \$\endgroup\$ – Doorknob Sep 24 '13 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 Sep 24 '13 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 Sep 24 '13 at 18:58
  • \$\begingroup\$ @Briguy37 The spec says print every **letter** combination Anyway, save a character: {} -> ; \$\endgroup\$ – C5H8NNaO4 Sep 25 '13 at 7:48
  • \$\begingroup\$ @C5H8NNaO4: Which letter combination does my solution not print? Thanks for the tip! \$\endgroup\$ – Briguy37 Sep 25 '13 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\$
  • \$\begingroup\$ You can initialize the loop with i=s=0 to save three more characters. \$\endgroup\$ – Ry- Sep 25 '13 at 21:54
  • \$\begingroup\$ @minitech done. \$\endgroup\$ – Math chiller Sep 25 '13 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- Sep 25 '13 at 22:30

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.