23
\$\begingroup\$

Updates: Time limit removed. You must be able to describe output - see new rule.

A pangram is a sentence that uses every letter in the alphabet at least once, such as:

The quick brown fox jumps over the lazy dog.

A perfect pangram uses every letter exactly once.

Consider writing a program that is a perfect pangram, using the 95 printable ASCII characters (hex codes 20 to 7E) as the alphabet:

 !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~

Such a program must contain exactly 95 characters, with each printable ASCII character occurring exactly once, but in any order. (Thus there are 95! = 1.03×10148 possibilities.)

Your task is to write this program such that the number of printable ASCII characters printed to stdout is as high as possible (i.e. prolific).

Your score is the number of printable ASCII characters your program outputs (the total amount, not the distinct amount: AABC scores 4 whereas ABC scores 3). The highest score wins.

Details

  • The output may contain any characters (including duplicates) but only instances of the 95 printable ASCII characters count towards your score.
    • You can use this JSFiddle to count the number of printable ASCII characters in any string.
  • If your language does not have stdout use the most appropriate alternative.
  • Your program...
    • must have finite runtime (the time limit has been removed)
    • must have finite output
    • may contain comments
    • must compile and run without (uncaught) errors
    • must not prompt for or require input
    • must be time invariant and deterministic
    • must not use external libraries
    • must not require a network connection
    • must not make use of external files
      • (you may use the program file itself as long as changing the file name does not alter the program's behavior)
  • If this task is impossible is some language that's just too bad.
  • You must give your exact output or precisely describe it if it is too large to fit in a post. You do not actually have to run your program. As long as it would run in a finite amount of time on a computer with an unbounded amount of memory it is valid.

Example

This simplistic Python 2 program is a possible solution:

print 9876543210#!"$%&'()*+,-./:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghjklmoqsuvwxyz{|}~

It outputs 9876543210 which contains 10 printable ASCII characters, thus scoring 10.

\$\endgroup\$
14
  • 14
    \$\begingroup\$ As amazingly admirable as alliteration appears, pangrams just pack a powerful punch, as they're quite vexing. \$\endgroup\$
    – Geobits
    Oct 10, 2014 at 1:36
  • 2
    \$\begingroup\$ I just reread the total-not-distinct rule too. I'd skimmed over it earlier, concluding it was obviously a distinct-not-total rule since the alternative would lead to absurd constructions such as printing the letter a six quadrillion times, where it isn't even possible to obtain an accurate upper limit on character count. Anyway, I'm still proud of my 95, even if it is kind of small. Size isn't everything, you know. \$\endgroup\$
    – COTO
    Oct 10, 2014 at 5:50
  • \$\begingroup\$ Why do you think this task is impossible in HQ9+? \$\endgroup\$ Oct 10, 2014 at 8:24
  • \$\begingroup\$ I'm going to try and do this in FORTRAN (so I can make use of the case insensitivity). --- AND scratch that. I need the letter O 4 times: 2 times for the program declaration and 2 times for my loop declaration. \$\endgroup\$
    – Nzall
    Oct 10, 2014 at 9:55
  • 1
    \$\begingroup\$ @Dennis No. 5more \$\endgroup\$ Oct 11, 2014 at 16:03

8 Answers 8

22
\$\begingroup\$

Perl, 70*18446744073709551615*10^987654320

say q{!"#%&'+,-./:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ\]^_`bcdfghijklmnoprtuvwz|}x(1e987654320*~$[)

Output:

!"#%&'+,-./:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ\]^_`bcdfghijklmnoprtuvwz|

repeated 18446744073709551615*10^987654320 times.

$[ is by default 0, so ~$[ is equivalent to 18446744073709551615.

As a side note, I ran out of memory trying to create the number 10^987654320.


Old Answer (7703703696):

say qw(!"#$%&'*+,-./:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`bcdefghijklmnoprtuvz{|}~10)x98765432

Output is:

!"#$%&'*+,-./:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`bcdefghijklmnoprtuvz{|}~10

repeated 98765432 times.

Note: Run all samples with perl -Mbignum -E

\$\endgroup\$
4
  • \$\begingroup\$ nice! but I wonder if one could use recursivity... (not possible to call oneself if you have to use your own name, as it would repeath the characters in the name... but couldn't your function name end up in $_ or another of Perl's variables?).. or use $0 calls cleverly (without filling the heap) \$\endgroup\$ Oct 10, 2014 at 15:48
  • \$\begingroup\$ If you had enough memory, you could do perl -E'say qw{m}x(9876543210*ord$")' \$\endgroup\$
    – hmatt1
    Oct 10, 2014 at 16:34
  • 2
    \$\begingroup\$ If it helps there is no longer a time or memory limit. \$\endgroup\$ Oct 10, 2014 at 20:34
  • 2
    \$\begingroup\$ It's unfortunate that Perl uses ** rather than ^ for exponentiation. \$\endgroup\$
    – Mark
    Oct 12, 2014 at 9:38
12
\$\begingroup\$

GolfScript, over 2↑↑↑(9871↑↑2) chars

2 9871.?,{;0$[45)63]n+*~}/
#!"%&'(-:<=>@ABCDEFGHIJKLMNOPQRSTUVWXYZ\^_`abcdefghijklmopqrstuvwxyz|

Prints an integer. Take advantage of unlimited CPU register size (which determines the maximum string length in Ruby), memory and run time. The linefeed is solely for readability.

The code

2             # Push 2.
9871.?        # Push b := 9871↑↑2 = 9871↑9871 = 9871**9871.
,{            # For each i from 0 to b - 1:
  ;0$         #   Discard i and duplicate the integer on the stack.
  [45)63]n+*  #   Replicate ".?\n" that many times.
  ~           #   Evaluate.
 }/           #

The score

Define b = 9871↑↑2 (see Knuth's up-arrow notation).

  • .? executes f : x ↦ x↑x.

  • The inner block executes g : x ↦ fx(x).

    Since f(x) = x↑x = x↑↑2, f2(x) = (x↑x)↑(x↑x) > x↑x↑x = x↑↑3,
    f3(x) = ((x↑x)↑(x↑x))↑((x↑x)↑(x↑x)) > (x↑x↑x)↑(x↑x↑x) > x↑x↑x↑x = x↑↑4 and so forth, we have
    g(x) > x↑↑(x+1) > x↑↑x.

  • The outer block executes h : x ↦ gb(x).

    Since g(x) = x↑↑x = x↑↑↑2, g2(x) = (x↑↑x)↑↑(x↑↑x) > x↑↑x↑↑x = x↑↑↑3,
    g3(x) = ((x↑↑x)↑↑(x↑↑x))↑↑((x↑↑x)↑↑(x↑↑x)) > (x↑↑x↑↑x)↑(x↑↑x↑↑x) > x↑↑x↑↑x↑↑x = x↑↑↑4 and so forth, we have h(x) > x↑↑↑(b+1).

  • We start with the integer 2 on the stack, so the code calculates h(2) > 2↑↑↑(b+1).

  • The score is the number of decimal digits of h(2), which is log(h(2)) + 1 > log(2↑↑↑(b+1)) > 2↑↑↑b.

Thus, the score is larger than 2↑↑↑(9871↑↑2).

2↑↑↑n grows at a ridiculous pace as n gets larger. 2↑↑↑4 := 2↑↑2↑↑2↑↑2 = 2↑↑2↑↑4 = 2↑↑65536, which is a right-associative power tower of 65536 copies of 2:

                                                                2↑↑↑4                                                                 

Similarly, 2↑↑↑5 := 2↑↑(2↑↑↑4), which is a power tower of 2↑↑↑4 copies of 2.

Now, the score isn't 2↑↑↑4 or 2↑↑↑5, it's larger than 2↑↑↑b, where b > 2 × 1039 428. That's a big number...

\$\endgroup\$
5
  • \$\begingroup\$ @DigitalTrauma - You should check mine ;) \$\endgroup\$
    – Optimizer
    Oct 10, 2014 at 21:46
  • \$\begingroup\$ @Dennis - How much is it roughly ? \$\endgroup\$
    – Optimizer
    Oct 10, 2014 at 21:54
  • \$\begingroup\$ @Optimizer You got me ;-) \$\endgroup\$ Oct 10, 2014 at 22:01
  • \$\begingroup\$ Awesome! It reminds me of Graham's number... That is big! \$\endgroup\$
    – rewritten
    Oct 11, 2014 at 7:24
  • 3
    \$\begingroup\$ Note that, while this theoretically should print a very large number of zeros, in practice it just crashes the interpreter with in `*': bignum too big to convert into `long' (RangeError). \$\endgroup\$ Oct 11, 2014 at 11:56
11
\$\begingroup\$

Bash+coreutils, 151,888,888,888,888,905 (1.5*10^17)

seq 9E15;#\!%*+,-./2346780:=@ABCDFGHIJKLMNOPQRSTUVWXYZ]^_abcdfghijklmnoprtuvwxyz~"'$&()?<>`{}|[

Outputs integers 1 to 9x1015, one per line. Takes a long time.

Why 9E15? It turns out that GNU seq appears to use 64-bit floats (double) internally. The largest whole number we can represent with this type, before increment by one stops working due to lack of precision, is 253 or 9007199254740992. The closest we can get to this with exponential notation is 9E15 or 9000000000000000.

To calculate the score, I am using adding up all the numbers with a given number of digits and adding 9E15, because there is a newline between each number:

8000000000000001*16 + 900000000000000*15 + 90000000000000*14 + 9000000000000*13 + 900000000000*12 + 90000000000*11 + 9000000000*10 + 900000000*9 + 90000000*8 + 9000000*7 + 900000*6 + 90000*5 + 9000*4 + 900*3 + 90*2 + 9 + 9000000000000000

I could pipe this output through od for an extra order of magnitude or so, but that makes the score calculation much harder.


Pre-rule change answer:

Bash+coreutils, 18,926,221,380

seq 1592346780;#\!%*+,-./:=@ABCDEFGHIJKLMNOPQRSTUVWXYZ]^_abcdfghijklmnoprtuvwxyz~"'$&()?<>`{}|[

Outputs 1 to 1592346780. On my mid 2012 macbook (which is not that far off the linked benchmark), this takes about 9m45s.

I couldn't resist optimizing it a bit more, even though its probably meaningless.

Output:

$ time ./pangram.sh | wc
 1592346780 1592346780 18926221380

real    9m46.564s
user    11m7.419s
sys 0m10.974s
$ 
\$\endgroup\$
7
  • \$\begingroup\$ why aren't you doing seq 9876543210;? \$\endgroup\$
    – durron597
    Oct 10, 2014 at 17:14
  • \$\begingroup\$ @durron597 Because that takes too long - probably about an hour. It needs to complete in under 10 minutes. \$\endgroup\$ Oct 10, 2014 at 17:14
  • \$\begingroup\$ but surely the only limiting factor of this program is i/o... any other program in any other language could not really beat this. \$\endgroup\$
    – durron597
    Oct 10, 2014 at 17:17
  • \$\begingroup\$ @durron597 Yes, I think that is right. Though I wouldn't be surprised if someone in this community finds a clever way... \$\endgroup\$ Oct 10, 2014 at 17:21
  • 1
    \$\begingroup\$ @DigitalTrauma I'm actually removing the time limit to ensure this is not the penultimate answer (no offense I just don't want the contest to be over so soon :P), so feel free to use 9876543210. You may want to read the new last rule. \$\endgroup\$ Oct 10, 2014 at 17:39
6
\$\begingroup\$

GolfScript, ≈ 3*10^(2*10^7) i.e. ≈ 3x1020000000

 87 9654321?,`0${;.p}/#!"%&'()*+-9:<=>@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_abcdefghijklmnoqrstuvwxyz|~

How it works

87 9654321?                "Pushes 87^9654321 to stack";
           ,               "Pushes an array [0, 1, 2 ... (87^9654321) - 1] to stack";
            `              "Creates a string representation of the array like "[0 1 2...]";
             0$            "Copies the string";
               {;.p}/      "Print the string wrapped in quotes X times";
                     #...  "This is all comment";

Here X is the character count (length) of the string representation of the array [0, 1, 2..,(87^9654321) - 1] which will be like [0 1 2 3 4 ... (87^9654321) - 1]

I am trying to calculate X here so as to find my score. (87^9654321) - 1 is roughly 10^(10^7.272415829713899) with 18724742 decimal digits.

X is roughly 3*10^(2*10^7) so X*X is also same only. Note that these values are on a very lower side as due to computation limitations of (even) wolframa, I was not able to compute sum (floor(log10(x)) + 1) for x = 1 to (87^9654321 - 1) which is the true value of X

\$\endgroup\$
9
  • \$\begingroup\$ In theory, there would be a few ways of making this even hewuger, but sadly Ruby's BigNum does have limits and 87 9654321? is just Infinity. \$\endgroup\$
    – Dennis
    Oct 10, 2014 at 20:55
  • \$\begingroup\$ Oh! ? Do you know the maximum ? ;) \$\endgroup\$
    – Optimizer
    Oct 10, 2014 at 21:00
  • \$\begingroup\$ Not exactly. Seems to depend on the machine, since the integer has to fit into RAM. With unbounded memory, I don't know where the limit would be. Probably 2**(2**64)-1 for 64-bit Ruby. \$\endgroup\$
    – Dennis
    Oct 10, 2014 at 21:13
  • \$\begingroup\$ We have unbounded amount of RAM \$\endgroup\$
    – Optimizer
    Oct 10, 2014 at 21:16
  • \$\begingroup\$ Yes, that's why I clarified. For CJam, there's a fixed limit and the interpreter just crashes when you exhaust the memory. Ruby seems to be different. \$\endgroup\$
    – Dennis
    Oct 10, 2014 at 21:19
4
\$\begingroup\$

MATLAB, 95

Code

char(37-5:126)% !"#$&'*+,./0489;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`bdefgijklmnopqstuvwxyz{|}~

Output

 !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~

Output contains all specified ASCII characters, each exactly once, and in order.

\$\endgroup\$
1
  • 1
    \$\begingroup\$ Note to viewers: This answer was submitted when the spec asked to maximize unique characters. This is no longer the goal, but it's ok if this answer stays since it is valid. \$\endgroup\$ Oct 10, 2014 at 16:55
2
\$\begingroup\$

Ruby, 89

p %q{!"#$&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnorstuvwxyz|~}

Output:

"!\"\#$&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnorstuvwxyz|~"

Contains all ASCII characters except, p, , %, q, {, and }.

\$\endgroup\$
1
  • 1
    \$\begingroup\$ Note to viewers: This answer was submitted when the spec asked to maximize unique characters. This is no longer the goal, but it's ok if this answer stays since it is valid. \$\endgroup\$ Oct 10, 2014 at 16:56
2
\$\begingroup\$

GolfScript, 93

{ !#$%&()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz|~}

Output:

{ !#$%&()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz|~}
}

Contains all ASCII characters except " and '.

\$\endgroup\$
3
  • 6
    \$\begingroup\$ You're program isn't a perfect pangram though, is it? It doesn't seem to contain " or ' either. \$\endgroup\$ Oct 10, 2014 at 9:01
  • \$\begingroup\$ Note to viewers: This answer was submitted when the spec asked to maximize unique characters. This is no longer the goal, but it's ok if this answer stays if it made valid. \$\endgroup\$ Oct 10, 2014 at 16:57
  • 1
    \$\begingroup\$ It's easy enough to make this valid under the new rules: just remove # from its current position and append #"' to the end. The score will drop by one, though. \$\endgroup\$ Oct 11, 2014 at 11:50
2
\$\begingroup\$

Golfscript - 27*265439870

This my first Golfscript submission! :)

12,`{.+}6543 9870?*#!"$%&'()-/:;<=>@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_abcdefghijklmnopqrstuvwxyz|~

Explanation:

12,                     - Creates an array of ascending numbers from 0 to 11
   `                    - Converts the array to a string
    {.+}                - Duplicates the string on the stack and concatenates the two
        6543 9870?      - Calculates 6543^9870 and pushes it to the stack
                  *     - Repeat the block 6543^9870 times
                   #... - The rest is a comment

The output is a load of lists of numbers. Consider the following code:

12,`{.+}1*

With 12, it produces the following array:

[0 1 2 3 4 5 6 7 8 9 10 11]

The backtick turns that into a string, passing it to the block {.+}. This duplicates the string and then concatenates the two, producing:

[0 1 2 3 4 5 6 7 8 9 10 11][0 1 2 3 4 5 6 7 8 9 10 11]

The 1* tells the interpreter to execute the previous block one time (21 = 2).

So, based upon that:

 12,`{.+}n*

Outputs the output of 12,` 2n times.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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