text:
Build a small and balanced mobile
You are given a bunch of weights, and your task is to build a small balanced mobile using those weights.
The input is a list of integer weights in the range 1 through 9, inclusive.  There may be duplicates.
The output is an ascii picture of a mobile that, when hung, would balance.  Perhaps best shown by example:
input
3 8 9 7 5

possible output
         |
   +-----+---------+
   |               |
+--+-+        +----+------+
|    |        |           |
8   ++--+     7           5
    |   |
    9   3

You must use the ascii characters as shown.  The horizontal and vertical segments may be of any length.  No part of the mobile may touch (horizontally or vertically) another unconnected part of the mobile.  All weights must be hung from a vertical segment of length at least 1, and there must be a vertical segment from which the whole mobile is hung.
The size of a mobile is the total number of +,-,and | characters required to build it.  Lower sizes are better.
You may put as many connections on a segment as you would like.  For example:
input
2 3 3 5 3 9

possible output
           |
   +---+---+-----------+
   |   |               |
+--+-+ 5               9
|  | |
2  | 3
   |
  +++
  | |
  3 3

The winning program is the one that can generate the lowest average of mobile sizes for a test set of inputs.  The real test is super-secret to prevent hard-coding, but it will be something like this:
8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 7
1 2 3 4 5 6 7 8 9 1 2 3 4 5 6 7 8 9 7 7
3 4 4 4 4 5 5 5 5 6 6 6 6 7 7 7 7

Physics also involved?

@S.Mark: I guess you could say that.  For the physically impaired, the sum of total_weight_hung_from_point * distance_of_point_from_pivot must be the same on both sides of the pivot point.

Perhaps to make examining the diagrams easier, make it so that one bar is equal to about two hyphens? As it stands, your diagrams look out of balance.

Python 2.
I'm cheating a little bit:

I only construct mobiles with one horizontal. I have a feeling (but I haven't proven it) that the optimal mobile under the given conditions actually always does only have one horizontal. Edit: Not always true; with 2 2 9 1 Nabb has found a counter-example in the comments below:
Size 18:                Size 16:
   |                        |
+-++--+-----+            +--++-+
| |   |     |            |   | |
2 9   2     1           -+-  9 1
                        | |
                        2 2

I just do stupid brute-forcing:

The given weights are shuffled randomly.
Two weights at a time are placed on the mobile in the best positions such that it stays balanced.
If the resulting mobile is better than any that we had before, remember it.
Rinse and repeat, until a pre-defined number of seconds is up.

My results for your sample inputs; each was run for 5 seconds (I'm aware that this is ridiculous for the small ones – just going through all possible permutations would be faster). Note that since there's a random element, subsequent runs may find better or worse results.
3 8 9 7 5
Tested 107887 mobiles, smallest size 20:
        |
+-+-----+-+--+
| |     | |  |
5 3     7 9  8

2 3 3 5 3 9
Tested 57915 mobiles, smallest size 23:
      |
+--+-++--+-+---+
|  | |   | |   |
3  5 9   3 3   2

8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 7
Tested 11992 mobiles, smallest size 50:
                |
+-+-+-+--+-+-+-+++-+-+--+-+-+-+-+
| | | |  | | | | | | |  | | | | |
8 8 8 8  8 8 8 8 8 8 8  7 8 8 8 8

1 2 3 4 5 6 7 8 9 1 2 3 4 5 6 7 8 9 7 7
Tested 11119 mobiles, smallest size 62:
                    |
+-+-+-+-+-+--+-+-+-+++-+-+-+--+-+-+-+-+-+
| | | | | |  | | | | | | | |  | | | | | |
2 7 5 6 6 8  3 2 3 7 9 7 8 1  1 7 9 5 4 4

3 4 4 4 4 5 5 5 5 6 6 6 6 7 7 7 7
Tested 16301 mobiles, smallest size 51:
                |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| | | | | | | | | | | | | | | | |
4 6 5 7 7 4 6 5 3 5 6 4 7 6 7 5 4

The code (verbose, as this isn't code golf):
import time, random

def gcd(a, b):
    while b > 0:
        a, b = b, a % b
    return a

class Mobile(object):
    def __init__(self):
        self.contents = [None];
        self.pivot = 0;

    def addWeights(self, w1, w2):
        g = gcd(w1, w2)
        m1 = w2 / g
        m2 = w1 / g
        mul = 0
        p1 = -1
        while True:
            if p1 < 0:
                mul += 1
                p1 = mul * m1
                p2 = -mul * m2
            else:
                p1 *= -1
                p2 *= -1
            if self.free(p1) and self.free(p2):
                self.add(w1, p1)
                self.add(w2, p2)
                return

    def add(self, w, pos):
        listindex = self.pivot - pos
        if listindex < 0:
            self.contents = [w] + (abs(listindex) - 1) * [None] + self.contents
            self.pivot += abs(listindex)
        elif listindex >= len(self.contents):
            self.contents += (listindex - len(self.contents)) * [None] + [w]
        else:
            self.contents[listindex] = w

    def at(self, pos):
        listindex = self.pivot - pos
        if 0 <= listindex < len(self.contents):
            return self.contents[listindex]
        return None

    def free(self, pos):
        return all(self.at(pos + d) is None for d in (-1, 0, 1))

    def score(self):
        return 1 + 2 * len(self.contents) - self.contents.count(None)

    def draw(self):
        print self.pivot * " " + "|"
        print "".join("+" if c is not None or i == self.pivot else "-" for i, c in enumerate(self.contents))
        print "".join("|" if c is not None else " " for c in self.contents)
        print "".join(str(c) if c is not None else " " for c in self.contents)

    def assertBalance(self):
        assert sum((i - self.pivot) * (c or 0) for i, c in enumerate(self.contents)) == 0

weights = map(int, raw_input().split())

best = None
count = 0

# change the 5 to the number of seconds that are acceptable
until = time.time() + 5

while time.time() < until:
    count += 1
    m = Mobile()

    # create a random permutation of the weights
    perm = list(weights)
    random.shuffle(perm)

    if len(perm) % 2:
        # uneven number of weights -- place one in the middle
        m.add(perm.pop(), 0)

    while perm:
        m.addWeights(perm.pop(), perm.pop())

    m.assertBalance() # just to prove the algorithm is correct :)
    s = m.score()
    if best is None or s < bestScore:
        best = m
        bestScore = s

print "Tested %d mobiles, smallest size %d:" % (count, best.score())
best.draw()

@Nabb: Higher weights than 9 aren't possible. As for 1 9 2 8 it generates 1-------8+-9--2; from the top of my head I can't come up with anything better (but I wouldn't rely on that) -- do you have something?

@balpha: Nevermind, wasn't thinking straight when I commented earlier. I thought for some reason that you could stick them as 1-9 and 2-8, but obviously those pairs themselves don't balance!

Okay, here's one that may actually be better with multiple layers: 2 2 9 1, i.e. (2+2)3 = 9+13 for 16 size instead of 2-9+--2----1 which is 18. I'd guess that there's a threshold (maybe 5 or 6) after which a single horizontal row is always optimal.

@Nabb: Yep; that's indeed a good counter-example.

@Nabb, A single bar with 2-2-+9-1 balances, with a score of 13 (4*2+2*2 = 9*1+1*3).  So I don't think that one is a good counterexample.

@KeithRandall: Ah yes, true. My algorithm can't find that one though, because taking away any two would leave it unbalanced.

Here is a solution that brute forces the smallest single row solution.
The code iterates over all permutations and compute the center of mass for each. If the center of mass has integer coordinates, we've found a solution.
After all permutations have been tried, we add a segment to the mix (equivalent to a weight of mass 0) in our current set of weights and retry.
To run the program, do python balance.py 1 2 2 4.
#!/usr/bin/env python3
import itertools, sys

# taken from http://stackoverflow.com/a/30558049/436792
def unique_permutations(elements):
    if len(elements) == 1:
        yield (elements[0],)
    else:
        unique_elements = set(elements)
        for first_element in unique_elements:
            remaining_elements = list(elements)
            remaining_elements.remove(first_element)
            for sub_permutation in unique_permutations(remaining_elements):
                yield (first_element,) + sub_permutation

def print_solution(cm, values):
    print(('  ' * cm) + '|')
    print('-'.join(['-' if v == 0 else '+'  for v in values]))
    print(' '.join([' ' if v == 0 else '|'  for v in values]))
    print(' '.join([' ' if v == 0 else str(v) for v in values]))

input = list(map(int, sys.argv[1:]))
mass = sum(input)
while True:
    n = len(input)
    permutations = filter(lambda p: p[0] != 0 and p[n-1] != 0, unique_permutations(input))
    for p in permutations:
        cm = 0
        for i in range(n):
            cm += p[i] * i;
        if (cm % mass == 0):
            print_solution(cm//mass, p)
            sys.exit(0)
    input.append(0)

which produces these best solutions :
    |
+-+-+-+-+
| | | | |
8 3 9 5 7

    |
+-+-+-+-+-+
| | | | | |
9 2 3 5 3 3

                |
+-+-+-+-+-+-+---+-+-+-+-+-+-+-+-+
| | | | | | |   | | | | | | | | |
8 8 8 8 8 8 8   8 8 8 8 8 8 8 8 7

                        |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| | | | | | | | | | | | | | | | | | | |
1 1 2 2 3 3 4 4 8 8 5 5 6 6 7 7 7 7 9 9

                  |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| | | | | | | | | | | | | | | | |
3 4 4 4 4 5 5 5 5 6 7 6 7 7 7 6 6

Well this is an old question, but I just saw it appear in the top questions tab so here's my (optimal) solution:
#include <stdio.h>
#include <limits.h>
#include <math.h>
#include <stdlib.h>

int main(int argc, const char *const *argv) {
    if(argc < 2) {
        fprintf(stderr,
            "Balances weights on a hanging mobile\n\n"
            "Usage: %s <weight1> [<weight2> [...]]\n",
            argv[0]
        );
        return 1;
    }
    int total = argc - 1;
    int values[total];
    int maxval = 0;
    for(int n = 0; n < total; ++ n) {
        char *check = NULL;
        long v = strtol(argv[n+1], &check, 10);
        if(v <= 0 || v > INT_MAX || *check != '\0') {
            fprintf(stderr,
                "Weight #%d (%s) is not an integer within (0 %d]\n",
                n + 1, argv[n+1], INT_MAX
            );
            return 1;
        }
        values[n] = (int) v;
        if(values[n] > maxval) {
            maxval = values[n];
        }
    }
    int maxwidth = (int) log10(maxval) + 1;
    for(int n = 0; n < total; ++ n) {
        int width = (int) log10(values[n]) + 1;
        fprintf(stdout,
            "%*s\n%*d\n",
            (maxwidth + 1) / 2, "|",
            (maxwidth + width) / 2, values[n]
        );
    }
    return 0;
}

From looking at the rules I'm pretty sure it isn't cheating, although it feels like it is. This will just output all the given numbers in a vertical chain, for a total cost of 2*number_of_inputs (which is the minimum possible because each number must have a bar above it no matter what the layout). Here's an example:
./mobile 3 8 9 7 5

Produces:
|
3
|
8
|
9
|
7
|
5

Which is of course in perfect balance.

I was originally going to try something more in the spirit of this challenge, but it quickly turned out that it just optimised away to this structure anyway

Probably not clear from my description, but you can not connect a | to the bottom of a weight.

@KeithRandall ah ok; with that in mind I might have to have a go at solving this properly.

Python 3
This does no worse than 1 more than optimal on any of the test cases, I believe, and does so in 5 seconds.
Basically, I use a single bar approach. I randomly order the input, then insert the weights onto the bar one at a time. Each element is either put in the position that minimizes the excess weight on either side, or the second best position from that perspective, using the former 75% of the time and the latter 25% of the time. Then, I check whether the mobile is balanced at the end, and is better than the best mobile found so far. I store the best one, then halt and print it out after 5 seconds of searching.
Results, in 5 second runs:
py mobile.py <<< '3 8 7 5 9'
Best mobile found, score 15:
    |
+-+-+-+-+
| | | | |
8 7 3 5 9
py mobile.py <<< '2 2 1 9'
Best mobile found, score 13:
   |
+-++-+-+
| |  | |
1 9  2 2
py mobile.py <<< '2 3 3 5 3 9'
Best mobile found, score 18:
      |
+-+-+-+-+-+
| | | | | |
2 3 3 5 9 3
py mobile.py <<< '8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 7'
Best mobile found, score 49:
                |
+-+--+-+-+-+-+-+++-+-+-+-+-+-+-+
| |  | | | | | | | | | | | | | |
7 8  8 8 8 8 8 8 8 8 8 8 8 8 8 8
\py mobile.py <<< '1 2 3 4 5 6 7 8 9 1 2 3 4 5 6 7 8 9 7 7'
Best mobile found, score 61:
                    |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+--+
| | | | | | | | | | | | | | | | | | |  |
1 7 7 5 4 3 1 9 6 7 8 2 2 9 3 7 6 5 8  4
py mobile.py <<< '3 4 4 4 4 5 5 5 5 6 6 6 6 7 7 7 7'
Best mobile found, score 51:
                |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| | | | | | | | | | | | | | | | |
4 4 6 7 7 4 5 7 6 6 5 4 6 3 5 5 7

Code:
import random
import time

class Mobile:
    def __init__(self):
        self.contents = {}
        self.lean = 0

    def usable(self, loc):
        return not any(loc + k in self.contents for k in (-1,0,1))
    def choose_point(self, w):
        def goodness(loc):
            return abs(self.lean + w * loc)
        gl = sorted(list(filter(self.usable,range(min(self.contents.keys() or [0]) - 5,max(self.contents.keys() or [0]) + 6))), key=goodness)
        return random.choice((gl[0], gl[0], gl[0], gl[1]))

    def add(self, w, loc):
        self.contents[loc] = w
        self.lean += w*loc

    def __repr__(self):
        width = range(min(self.contents.keys()), max(self.contents.keys()) + 1)
        return '\n'.join((''.join(' ' if loc else '|' for loc in width),
                          ''.join('+' if loc in self.contents or loc == 0 else '-' for loc in width),
                          ''.join('|' if loc in self.contents else ' ' for loc in width),
                          ''.join(str(self.contents.get(loc, ' ')) for loc in width)))

    def score(self):
        return max(self.contents.keys()) - min(self.contents.keys()) + len(self.contents) + 2

    def my_score(self):
        return max(self.contents.keys()) - min(self.contents.keys()) + 1

best = 1000000
best_mob = None
in_weights = list(map(int,input().split()))
time.clock()
while time.clock() < 5:
    mob = Mobile()
    for insert in random.sample(in_weights, len(in_weights)):
        mob.add(insert, mob.choose_point(insert))
    if not mob.lean:
        if mob.score() < best:
            best = mob.score()
            best_mob = mob

print("Best mobile found, score %d:" % best_mob.score())
print(best_mob)

The only one of these solutions which I believe is suboptimal is the longest one, which has this solution, which I found after a 10 minute run:
Best mobile found, score 60:
                   |
+-+-+-+-+-+-+-+-+-+++-+-+-+-+-+-+-+-+-+
| | | | | | | | | | | | | | | | | | | |
3 2 9 4 7 8 1 6 9 8 7 1 6 2 4 5 7 3 5 7


text:
Look and say sequence
The look and say sequence is a basic form of run length encoding.
The sequence starts with the number 1 and each additional number encodes the number of digits that are repeated before each digit sequence. For example, "1" becomes "11", because there is one "1". Then "11" becomes "21", and so on.
The first few numbers are 1, 11, 21, 1211, 111221, 312211 and 13112221.
Write a program to output the first 20 numbers.
The catch is you may not use any number in your program, including other bases than base 10. You can only use letters and symbols. Also, the program can't directly contain the numbers (or fetch them from a web server, or from a file); it must actually compute them.
I will accept the answer which works and is the shortest; in case of a tie, vote counts will decide, and in case of a tie there, the winner will be chosen randomly.

By "number" do you mean "character 0-9" or "numeric literal"?

@Peter Taylor: I suppose the former. It would be way too easy otherwise.

As per the FAQ, all questions on this site should have an objective primary winning criterion.

Previously on Stack Overflow as Code Golf: Morris Sequence.

@Thomas: My inclination here is to close this as based on too subjective a criterion. Discussion on meta that may be relevant.

Will edit it soon. Getting a lot of error messages when trying to change the criterion. Here it is for reference: "I will accept the answer which works and is the shortest; in case of a tie, vote counts will decide, and in case of a tie there, the winner will be chosen randomly."

What restrictions are there on the output format? In particular, is superfluous whitespace allowed?

@Peter Taylor, you can output it in any way, provided the numbers appear in some obvious fashion (e.g. on every line, separated with commas... etc.)

This should not be closed as a dupe; the alleged original doesn't have the "no numbers" restriction, making it a very different problem.

Golfscript, 44 43 40 41 38 37 36 chars
Since the criterion now requires golfing, here's the golfed version:
!:^;n).+{[^\{^$^$={;\)}^if\}*].n@}*;

The original, ungolfed, version actually dealt with strings rather than abusing Golfscript's formatting conventions for dumping the stack to stdout at program termination:
# Assumes nothing passed to stdin, so input length is zero
,):$''+
{
    .puts
    # Convert to an array of [count char count char ...]
    [$\{.@.@={;\)\}{\$\}if}*]
    # Convert to an array of [[count char] [count char] ...]
    $)/
    # Form the next string
    ''\{(@\+\+}/
}
# Nineteen times. There are a *lot* of ways of generating the number nineteen
# but I like this one
$).?.)*(*

There's at least 5 characters to be saved -- ! for generating 1, n for generating 19, and another 3 characters in the middle ;)

@Nabb, I haven't got time to figure out the 3 in the middle right now, but thanks for the tips about ! and n.

Perl (60 characters)
perl -e'print,s#(.)\g{$y}*#$&=~y///c.$^N#egfor(++$y.$/)x($^F.$|)'

Look ma, no numbers.  The algorithm is rather similar to the "chinese perl goth's" solution above with a few golf tweaks:

$^F.$| == "20" == 20 in numeric context
$^N == last bracket matched
for loop over (1)x20 is much shorter than trying to use a range
++$y == 1 and use it both as a backreference \g{$y} & to seed the generator
length is more cheaply spelt y///c

I spent a bunch of time trying alternative short ways to write length() before settling on the usual y///c - numbers of the form x = nnnn...n (where there are k digits n) have a lovely property that k = x mod 9 / n.  So you could write it as $& % 9 / $^N.  But now you have to get rid of the 9.
(Fun to golf again - thanks to MtvViewMark for roping me back)

Your title says 60 characters, but I only count 55..

How does this work? Seems like the value of $_ should get get overwritten each time through the loop with another copy of "1\n"?  (You could also use -E, replace the $/ with "" and the print with say to save two characters.)

Mathematica 88  82
t=Flatten;x=b/b;
g@n_:=Grid@NestList[t@Map[Reverse,t[Tally/@Split@#,x],x]&,{x},n-x]

Usage
g[9]

PHP 67 bytes
<?for(;~Î/$s=preg_filter(~Ð×ÑÖ£ÎÕÐš,~£ÏÚÆÐ£ÎßÑß£Î,$s)?:~Îõ;)echo$s;

The above may be copied directly, and saved in an ansi format.
Alternatively, it may generated with the following script, and then piped to a file:
<?="<?for(;~\xce/\$s=preg_filter(~\xd0\xd7\xd1\xd6\xa3\xce\xd5\xd0\x9a,~\xa3\xcf\xda\xc6\xd0\xa3\xce\xdf\xd1\xdf\xa3\xce,\$s)?:~\xce\xf5;)echo\$s;";

The script terminates when the current value of the series, $s, becomes larger than the largest representable floating point number, approximately 1e308. This quite coincidentally occurs just after the 20th value.
Sample usage:
$ php look-and-say.php
1
11
21
1211
111221
312211
13112221
1113213211
31131211131221
13211311123113112211
11131221133112132113212221
3113112221232112111312211312113211
1321132132111213122112311311222113111221131221
11131221131211131231121113112221121321132132211331222113112211
311311222113111231131112132112311321322112111312211312111322212311322113212221
132113213221133112132113311211131221121321131211132221123113112221131112311332111213211322211312113211
11131221131211132221232112111312212321123113112221121113122113111231133221121321132132211331121321231231121113122113322113111221131221
31131122211311123113321112131221123113112211121312211213211321322112311311222113311213212322211211131221131211132221232112111312111213111213211231131122212322211331222113112211
1321132132211331121321231231121113112221121321132122311211131122211211131221131211132221121321132132212321121113121112133221123113112221131112311332111213122112311311123112111331121113122112132113213211121332212311322113212221
11131221131211132221232112111312111213111213211231132132211211131221131211221321123113213221123113112221131112311332211211131221131211132211121312211231131112311211232221121321132132211331121321231231121113112221121321133112132112312321123113112221121113122113121113123112112322111213211322211312113211

Coincidence? I think not! :P

Javascript, 105
z=c=+[];r=x="";s=i=-~c+r;for(e=-~s+r+c;e--;){alert(s);c=z;for(x=r;y=s[c++];++i)y!=s[c]&&(x+=i+y,i=z);s=x}

Output (change alert to console.log)
1
11
21
1211
111221
312211
13112221
1113213211
31131211131221
13211311123113112211
11131221133112132113212221
3113112221232112111312211312113211
1321132132111213122112311311222113111221131221
11131221131211131231121113112221121321132132211331222113112211
311311222113111231131112132112311321322112111312211312111322212311322113212221
132113213221133112132113311211131221121321131211132221123113112221131112311332111213211322211312113211
11131221131211132221232112111312212321123113112221121113122113111231133221121321132132211331121321231231121113122113322113111221131221
31131122211311123113321112131221123113112211121312211213211321322112311311222113311213212322211211131221131211132221232112111312111213111213211231131122212322211331222113112211
1321132132211331121321231231121113112221121321132122311211131122211211131221131211132221121321132132212321121113121112133221123113112221131112311332111213122112311311123112111331121113122112132113213211121332212311322113212221
11131221131211132221232112111312111213111213211231132132211211131221131211221321123113213221123113112221131112311332211211131221131211132211121312211231131112311211232221121321132132211331121321231231121113112221121321133112132112312321123113112221121113122113121113123112112322111213211322211312113211

C: 213 characters
main(){char*a,*b=calloc(' ',' '),*c=calloc(' ',' '),*d,*e,*f;*b='Q'-' ';for(a="                    ";*a;++a){printf("%s\n",b);e=f=b;d=c;while(*e){while(*f==*e){++f;}d+=sprintf(d,"%d%c",f-e,*e);e=f;}e=b;b=c;c=e;}}

Could you replace the space characters with 32?

@ThomasO: You could, and there's other stuff you could reduce it by a bit further. I was just being obscure.

Perl, 94 bytes
$_=$w=cos"a";for$a($w..(ord('<')-ord('('))){print"$_ ";eval"s/(\\d)\\$w*/length(\$&).\$$w/ge"}

Haskell, 116
import List
l=length
f=[l[f]]:map(((\x->[l x,head x])=<<).group)f
main=mapM putStrLn$map(show=<<)$take(l['a'..'t'])f

The trick of using ['a'..'t'] to extract the right number of elements was lifted from MtnViewMark's solution.  Obviously superior to my original choice of "a really long string".

Perl (73)
Named capture buffers rock.
perl -le '$_++;$c=a;$r="(?<f>.)\\$_*";print,s/$r/length($&).$+{f}/eg while$c++ne u'

A bit of explanation:
$_++; incrementing $_ which is undefined at the start, to make it contain 1.
$c=a; - abusing perl's barewords in a horrible way to make $c contain 'a'.
$r="(?<f>.)\\$_*" - constructing a regular expression matching repeated characters.
normally i'd write it as (.)\1* but I can't use digits, so i've declared a capture buffer with the name of f.
this also could be written as (?<f>.)\k<f>* but it'll make the regex one char longer, so I've used \\$_ which evaluates to \1.
print,s/$r/length($&).$+{f}/eg while$c++ne u
Ungolfed:
while($c++ne u) { - taking advantage of the fact that it's possible to increment strings in perl - incrementing a scalar containing 'a' will make it contain 'b', and so on - so the loop will go from 'a' to 'u'
print; - print $_
s/$r/length($&).$+{f}/eg - operating on $_, replace whatever is matched by the previously constructed regular expression (repeated characters) by its length, followed by first char of it.  $& means the whole match, $+{f} means "a named capture buffer with a name f".
}

Some of these tricks are costing you more than they bring. Using \k<f> would let you not save the regex in a variable. Using for$c(a..u) instead of $c=a; plus while$c++ne u is shorter.

Mathematica 62
x=a/a;Grid@NestList[Join@@({Length@#,#〚x〛}&/@Split@#)&,{x},#]&

Ruby 1.9, 119 chars
num = "#{?b.ord-?a.ord}"
one = num.to_i
limit = ?U.ord-?A.ord
loop {
    puts num
    num = num.gsub(/(?<digit>.)\k<digit>*/) { $&.size.to_s + $+ }
    break if (limit -= one) == one - one
}

A golfed version:
k="#{?b.ord-?a.ord}"
j=k.to_i
i=?U.ord-?A.ord
loop{puts k
k=k.gsub(/(?<d>.)\k<d>*/){$&.size.to_s+$+}
(i-=j)==j-j&&exit}

C++
By Chuck Morris
/*  This implements the power of
**    C H U C K  M O R R I S .
*/

#include <iostream>
#include <vector>

/*
**  Deep within the murks
**  Of an assembly programmer's heart
**  Lies an ancient hatred
**  Of recursion
**
**  Yet a true C++ programmer
**  Can appreciate the beauty
**  And elegance
**  Which the following manifests
*/
std::string stringpp(std::string sz, size_t last_digit=(size_t)'\0')
{
    std::string bak = sz;

    if(last_digit < sz.length())
    {
        char nextnum = sz[sz.length() - (size_t)'\x01' - last_digit];
        ++nextnum;

        if(nextnum < ':')
        {
            sz = bak.substr((size_t)'\0', bak.length() - (size_t)'\x01' - last_digit);
            sz += nextnum;
            if(last_digit)
                sz += bak.substr(bak.length() - last_digit, last_digit);
        }
        else
        {
            nextnum = '0';

            sz = bak.substr((size_t)'\0', bak.length() - (size_t)'\x01' - last_digit);
            sz += nextnum;
            if(last_digit)
                sz += bak.substr(bak.length() - last_digit, last_digit);

            sz = stringpp(sz, last_digit + (size_t)'\x01');
        }
    }
    else
    {
        sz = "1";
        sz += bak;
    }

    return(sz);
}

class ChuckMorris
{
private:
    std::string sz;
public:
    ChuckMorris() { sz = "1"; }
    void next();
    std::string get();
};

void ChuckMorris::next()
{
    std::string num;

    std::string bak = sz;
    sz = "";

    for(size_t i = (size_t)'\0'; i < bak.length();)
    {
        num = "0";
        size_t i2 = i;
        for(; (i2 < bak.length()) && (bak.at(i) == bak.at(i2)); ++i2)
            num = stringpp(num);
        sz += num;
        sz += bak.substr(i, 1);
        i = i2;
    }
}

std::string ChuckMorris::get()
{
    return(sz);
}

int main(int argc, char* argv[])
{
    ChuckMorris chucky;

    // std::cout << stringpp("999").c_str() << std::endl;

    for(char chucks = '\0'; chucks < '\x14';)
    {
        std::cout << chucky.get().c_str();
        chucky.next();
        ++chucks;
        if(chucks != '\x14')
            std::cout << ", ";
    }

    std::cout << std::endl;

    return(0);
}

/*  And some elvish for elegance:
**  A Elbereth Gilthoniel
**  silivren penna míriel
**  o menel aglar elenath!
**  Na-chaered palan-díriel
**  o galadhremmin ennorath,
**  Fanuilos, le linnathon
**  nef aear, sí nef aearon!
*/

This is an elegance only Chuck Morris himself can achieve with C++ code. He coded it (for free) in less than zero seconds, while sleeping.
It may not be as "elegant" as Golfscript/others, but it does everything... in a statically typed language!

Having a crappy/clumsy set of builtins for manipulating basic types is nothing to do with statically typed languages. Seems to be a common omission in statically typed languages though for some reason.

@gnibbler I could have converted to number (for stringpp() to be a lot simpler), added, converted to string, but I don't think that's allowed in the challenge. Hmmm... Oh well, it makes my code more (or less) elegant. :)

You used a lot of numbers in this.

@Thomas Language requirements! :D (...And they're chars.)

you're just not trying hard enough!

Python 2.x
from itertools import groupby
s=`len(' ')`
for x in'                    ':
    print s
    s=''.join(i+`len(list(j))` for i,j in groupby(s))

and a version without the hacky strings
from math import *
from itertools import groupby
s=`int(log(e))`
for x in s*int(e**pi-e):
    print s
    s=''.join(i+`len(list(j))` for i,j in groupby(s))

note that e**pi-pi is very close to 20 (19.99909997918947) but slightly smaller, so it's no good to use int with

what are those backticks doing?

@MarkReed In Python2.x the backticks were shorthand for repr() https://portingguide.readthedocs.io/en/latest/syntax.html#backticks

Haskell, 109 characters
import List
q=show.length
l=q" ":map((>>=(\a->q a++[head a])).group)l
main=mapM_(putStrLn.snd)$zip['a'..'t']l

Not a digit in sight, not even as a character in a string! Prints the first 20 numbers, one per line.

Edit (118 -> 109) used suggestion of length to generate the initial 1, then factored out show.length

Might I suggest length[l] in place of fromEnum EQ?

Lua, 138 bytes
p=#' 'm=p c=''..p f=#'    'for k=p,f*f+f do n=''o=#n while o<#c do q=o+p l=c:sub(q,q)i,o=c:find(l.."+",q)n=n..o-i+p..l end c=n print(n)end

JavaScript (102 characters)
Requires support for arrow functions. This will work unmodified in JavaScript Shell or otherwise when print is changed to alert.
for(j=k=l=-~'',j=++j+j,j*=++j;j--;)print(k=(''+k).replace(RegExp('(.)\\'+l+'*','g'),(a,b)=>a.length+b))

You have a 1 in your code...

@mellamokb: Fixed at a cost of 18 characters.

Clojure, 251 chars
(def z`~(count ""))(def t(read-string(str z "xa")))(println(take(+ t t)(iterate(fn[x](#(reduce(fn[a b](+ b(* a t)))%)(mapcat(juxt count first)(partition-by identity(#(loop[u %,d()](if(zero? u)(seq d)(recur(quot u t)(cons(mod u t)d))))x)))))(inc z))))

Heres the ungolfed version. This sure was fun to figure out.
(def z `~(count ""))
(def ten (read-string (str z "xa")))
(defn num->digits [n]
  " Takes a number and returns a sequence containing
    its digits in ascending order
    e.g., 123 -> (1 2 3)"
 (loop [num n, digits ()] (if (zero? num) (seq digits) (recur (quot num ten) (cons (mod num ten) digits)))))
(defn digits->num [seq]
  " Takes a sequence of digits and returns the number
    they represent
    e.g., (1 2 3) -> 123 "
  (reduce (fn [a b](+ b (* a ten))) seq))

(defn look-seq [n]
  " Returns a sequence containing the look-say representation for n"
    (digits->num (mapcat (juxt count first) (partition-by identity (num->digits n)))))

(defn look-n-say
  " Returns a lazy sequence representing
    Conway's look-and-say sequence starting at n"
  ([] (look-n-say (inc z)))
  ([n] (iterate look-seq n)))

(println (take (+ ten ten) (look-n-say)))

Clojure, 172 characters
(let[o(*)t(+ o o)f(+ t t)p partial c comp](dorun(take(+(Math/pow t f)f)(map(c println(p apply str))(iterate(c(p mapcat(juxt count first))(p partition-by identity))[o])))))

This is using the trick that the multiplicative identity is 1; therefore, Clojure has (*) evaluate to 1. I let this be o (one), and then let t (two) be (+ o o), and let f (four) be (+ t t). I also alias partial and comp to one-letter names (hurrah for first class functions!).
I then use math to find the number 20, so I can use it for taking this number of elements from an infinite sequence of look-and-say strings: 2^4 + 4 = 20.
The actual algorithm for finding look-and-say numbers, unobfuscated, looks like this:
(iterate (comp (partial mapcat (juxt count first)) (partial partition-by identity)) [1])

The above produces the infinite sequence of sequences of digits corresponding to look-and-say numbers.

K, 62
{,/,'[;?:'f]@$#:'f:(&~~':x)_x}\["J"$h,$"i"$"\t";,h:*$"i"$"\r"]

Ruby 1.9+, 76 characters
Like @daniero, I shamelessly stole @Lowjacker's regex.
s=$-W.to_s
"\cT".ord.times{puts s;s.gsub!(/(?<d>.)\k<d>*/){$&.size.to_s+$+}}

CJam, 11 bytes
X{NX$se`}J*

Test it here.
This answer does not compete as CJam is much younger than this challenge (and e` is a fairly recent feature). However, I thought the solution is really neat so I wanted to add it for completeness.
Explanation
X     e# Push 1 as the start of the sequence.
{     e# Repeat this block 19 times...
  N   e#   Push a linefeed as a separator.
  X$  e#   Copy the last value (which will be either a number or a nested array of numbers.
  s   e#   Convert it to a string, which will flatten the value if it's an array.
  e`  e#   Run-length encode the string.
}J*

This works because e` happens to use the required order of run-length and value, and because the look-and-say sequence will never contain any "digits" greater than 3, so that we don't lose any information by simply flattening the RLE-result into a single string.

C# - 209
using System.Linq;class P{static void Main(){int i='a',N='b'-i,O=i-i,
x=O;var C=N+"";while(i++<'u'){System.Console.WriteLine(C);var n="";(C+
" ").Aggregate((c,d)=>{x++;if(d!=c){n+=x+""+c;x=O;}return d;});C=n;}}}

Exploits the fact that char is implicitly convertible to int, and since a string is an IEnumerable collection of chars, I used the LINQ Aggregate() method to do the work.
using System.Linq;
class P
{
    static void Main()
    {
        int i = 'a',     // start loop counter at the int value for 'a'
            N = 'b' - i, // N is now literally 1 ('b' - 'a')
            O = i - i,   // O is now literally 0 (1 - 1)
            x = O;       // number counter
        var C = N + "";  // C is the current string. start with "1".

        while (i++ < 'u') // if 'a' is 1, 'u' is 20
        {
            // print the current string
            System.Console.WriteLine(C);

            var n = ""; // this will be our next string

            // aggregate the current string
            (C + " ").Aggregate((c, d) =>
            {
                // increment the number counter
                x++;
                if (d != c)
                {
                    // when a different number is found, update the next string
                    n += x + "" + c;
                    // reset the count
                    x = O;
                }
                // the current number is passed back in as the aggregate (c)
                return d;
            });

            // move next to current
            C = n;
        }
    }
}

Ruby 2.0, 82 characters.
I took Lowjacker's regex and put it into this one-liner.
(?(.ord>>p(n=??.size)).times{puts n=n.to_s.gsub(/(?<d>.)\k<d>*/){$&.size.to_s+$+}}

Haskell, 103/114 characters
this solution prints the numbers inside lists, like so:
[1]
[1,1]
[2,1]
...

code:
import Data.List
l=length
main=mapM print$take(l['a'..'t'])$iterate((>>= \v->[l v,head v]).group)[l[l]]

this version prints them outside lists, but has more characters:
import Data.List
l=length
main=mapM(print.(>>=show))$take(l['a'..'t'])$iterate((>>= \v->[l v,head v]).group)[l[l]]

output:
"1"
"11"
"21"
...

How do you use this? Could not find module ‘List’ It is a member of the hidden package ‘haskell98-2.0.0.3’.

@nyuszika7h sorry, should change it to Data.List

K, 46 bytes
(-/_ic'"TA"){,/+(#:;*:)@'\:_[&o,~=':x]x}\,o:#`

A very old question, but I thought I could improve on the existing K solution.
The phrase -/_ic'"ta" generates the constant 19- the difference between the ASCII characters "t" and "a". I also need the constant 1, so I use the length of the empty symbol. Without these contortions, the program would look like the following:
19{,/+(#:;*:)@'\:_[&1,~=':x]x}\,1

Only 33 bytes, and pretty easy to follow by K standards. For each term of the sequence, find the starting index of each run of identical values (&1,~=':x), slice the sequence into runs (_), and apply count (#:) and first (*:) to each element of the resulting sequence. (@'\:) Take the transpose (+) of that result to reshape it into a list of (count,item) tuples and then finally raze (,/) into a flat list.
In action:
  (-/_ic'"TA"){,/+(#:;*:)@'\:_[&o,~=':x]x}\,o:#`
(,1
 1 1
 2 1
 1 2 1 1
 1 1 1 2 2 1
 3 1 2 2 1 1
 1 3 1 1 2 2 2 1
 1 1 1 3 2 1 3 2 1 1
 3 1 1 3 1 2 1 1 1 3 1 2 2 1
 1 3 2 1 1 3 1 1 1 2 3 1 1 3 1 1 2 2 1 1
 1 1 1 3 1 2 2 1 1 3 3 1 1 2 1 3 2 1 1 3 2 1 2 2 2 1
 ...

Is this k5? I can't get it to run in k4, ic is undefined
There's a k4 solution for 29 bytes that includes numbers 19{,/{(#x),*x}'(&~~':x)_x}\,1

It is k2. It also works correctly in Kona. _ic is a builtin for converting characters into integers. In k5 it would be even easier, since characters will naturally coerce to numbers- you could just do -/"ta".

Also, the k4 solution you included is a slight improvement, but on Kona/K2 it requires tweaks- _x needs to be altered to _ x to avoid confusing "cut x" with a reserved variable called _x, and "cut" needs an initial 0 in its index list. Works just fine in k5! Combining your ideas with mine, you can get a 36 character k5 solution, but k5 is too new to be an official answer.

source: Stack Exchange

license: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/3.0/

all_licenses: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/4.0/

sort: votes


text:
Console Role Playing Game
Below are a basic set of requirements.

The following commands (for an interface to the game):
attack <target>, <move>
goto <place>
buy <item>
enum <
    targets,
    moves,
    places,
    items,
    stats
>

The following player stats:

HP
MP/SP (Mana/Stamina)
XP
Level
Gold
Items

Scoring
(Thanks to @Casey for this idea.)
For each feature implemented, you gain 1 point. The post with the greatest number of points becomes the winner. In the event of a tie, the post with the highest number of votes becomes the winner. (In the event of a tie for that, the master of the dimensions [me] chooses.)

BONUS: Make it fun! Add something special.

Please see http://meta.codegolf.stackexchange.com/questions/305/what-makes-winning-criteria-objective

@Juan It'll be the highest voted game. It's like Wolfenstein 3D vs Halo Reach. Guess which one'll be highest voted?

"It's preferable to post the binaries" No, it's not. I'm willing to consider re-opening if we get something resembling an objective winning condition.

@dmckee Is that a bit better? What would you suggest?

Idea: Assign features points, submissions get points based on # of features they implement. In the event of a tie, the checkmark goes to the highest scoring post (i.e., of those who are tied) with the most upvotes.

@Casey If you could edit for me (I don't get exactly what you mean), that'd be great. Thanks!

@muntoo Well its your question, so I don't want to change it. But here is an explanation of what I mean. Give each feature a point value. For example  the 'attack' command/system could be worth 5 points, while the movement feature could be 1 point. That way people can implement whatever they want (though some features will build on eachother) and they are scored according to how many features they implement.

@muntoo That's a step in the right direction, but I think you should explicitly list features. Not just the features you have, but as many as you can think of. Otherwise what counts as a feature is subjective. For example, if I implement multiple types of NPCs is that a feature per NPC or does that fall under the 'attack' feature?

all_licenses: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/3.0/


text:
Product of Digits
For a given positive integer number N, write a complete program to find the minimal natural M such that the product of digits of M is equal N. N is less than 1,000,000,000. If no M exists, print -1. Your code should not take more than 10 secs for any case.
Sample Inputs
1
3
15
10
123456789
32
432
1296

Sample Outputs
1
3
35
25
-1
48
689
2899

1 giving 1 is an important test case.

You should add more complex cases, like the three I've used below: 32, 432, 1296.  Unless you leave that as an exercise for the coder.

@s-mark 26, eh. Smallest Number.

I believe we should also test the obvious 387420489 (9^9) and 1000000000 for fun.

We should also test for prime numbers in input, e.g. 13.

Because this is an old question and the OP is inactive, this is just a note for future posts: "10 sec" is unclear according to the current standard (on which machine?)

Golfscript, 45 43 40 chars
~9{{1$1$%!{\1$/1$}*}12*(}8*>{];-1}*]$1or

Replaces version which didn't group small primes into powers and saves 8 chars while doing so. Note: 12 = floor(9 log 10 / log 5).
Acknowledgements: two characters saved by nicking a trick from @mellamokb; 3 saved with a hint from @Nabb.

What! You can write Golfscript without testing it? +1, Looks fine, except 123456789, its take more than 1 minute on my machine and I've killed the process. 12345 give me -1, so may be it should work for 123456789 too if I could wait long time enough.

@S.Mark, thanks. Looks like I can't get away with the naive factorisation algorithm.

@Peter: Gives wrong answers for more complex cases. 32 -> 22222, should be 48.  432 -> 2222333, should be 689.  1296 -> 22223333, should be 2899.  etc.

@mellamokb, good point. I think I'll have to rewrite and test.

Wow, 17 characters less.  I need a better algorithm, lol!

PS @Whoever voted this down while it was giving wrong results for some numbers, it's fixed now.

or is generally the best way to handle special cases for 0, [], and ''. It cuts off 3 characters here.

Javascript (84 78 76 74 72 70 68)
n=prompt(m="");for(i=9;i-1;)n%i?i--:(m=i+m,n/=i);alert(n-1?-1:m?m:1)

http://jsfiddle.net/D3WgU/7/
Edit: Borrowed input/output idea from other solution, and shorter output logic.
Edit 2: Saved 2 chars by removing unneeded braces in for loop.
Edit 3: Saved 2 chars by rewriting while loop as if statement with i++.
Edit 4: Saved 2 chars by moving around and reducing operations on i.
Edit 5: Convert if statement into ternary format saving 2 more chars.
Edit 6: Save 2 chars by moving i-- into true part of ternary, remove ++i.

You have counted characters for just the function. Is this a complete program? Can you execute it here http://www.ideone.com/

looks like there is similar input for javascript with spidermonkey at ideone he linked - http://www.ideone.com/samples#sample_lang_112

@fR0DDY: OK, now it's a complete program :)

I finally reduced mine to 69 characters, but you can do that too now with the same sort of idea and the prompt thing.

m?m:1 => m||1

JavaScript, 88 72 78 74 69 68
for(s='',i=2,m=n=prompt();i<m;i++)while(!(n%i)){if(i>9){alert(-1);E()}n/=i;s+=i}alert(s)
4 characters longer, but actually an executable script (as opposed to a function).
Edit: Using ideas from the other JavaScript, I can reduce it to this:
for(s='',i=9,n=prompt();i>1;i--)for(;!(n%i);n/=i)s=i+s;alert(n-1?-1:s?s:1)

Finally! A 69-character solution, only uses 1 for loop ;)
for(s='',i=9,n=prompt();i>1;n%i?i--:[n/=i,s=i+s]);alert(n-1?-1:s?s:1)

Okay, shaved off one comma.
for(i=9,n=prompt(s='');i>1;n%i?i--:[n/=i,s=i+s]);alert(n-1?-1:s?s:1)

Same problem as GolfScript solution.  Fails on inputs 32, 432, and 1296.  There's a reason why I start at 9 and go backwards, and concatenate from the right instead of the left.

Also fails for input 1.  Have to make a special case to handle 1.

I missed the "minimal" part, changed.

@minitech: Still doesn't work for input '1'.  lol, our answers are coming out to be almost exactly identical :-)

Ah, managed to make it 2 characters shorter than yours! :D

Ah, managed to make it 4 characters shorter than yours! :P  And beat Perl to boot.

Ah, managed to make it 1 character shorter than yours!!

@minitech: Yeah, lol, and that didn't even save any characters.  I think I'll switch it back to prompt and alert.

@minitech: You steal my idea, I'll steal yours :)  Now mines 1 character shorter than yours again!! lol!

When did I steal your prompt idea? Edit: Oh, you mean the for thing. I didn't steal that, I always thought you had 2 loops!

Now ours are the same length :)

awk (63 61 59 58 57)
{for(i=9;i>1;$1%i?i--:($1/=i)<o=i o);print 1<$1?-1:o?o:1}

We are calling program for one input only. Multiple inputs are given just to check correctness.

Perl (75) (72)

$d=shift;map{$m=$_.$m,$d/=$_ until$d%$_}reverse 2..9;print$d-1?-1:$m||1

inspired by mellamokb's javascript code; meant to be run with a parameter

Would it not be shorter if you used stdin instead of a parameter?

GolfScript (60 57)

~[{9,{)}%{\.@%!},)\;.@@/.9>2$1>&}do])[.])@@{1>},+\9>[-1]@if$

~{9,{)}%{\.@%!},)\;.@@/.9>2$1>&}do])[.])@@{1>},+$\9>-1@if

Edit
Ok, I think this version gives correct output for every case now :-)
Edit 2
Shaved off 3 chars per @Peter's suggestions.

The reason I commented above that 1 giving 1 is an important test case is that it's a nasty special case - the only number for which the digit 1 appears in the output. And it breaks your code, I'm afraid.

It also breaks for numbers divisible by primes greater than 9.

@Peter: OK, try again.  I think this version works for all test cases now.

Seems to, yes. You can save one character straight away by removing that first [ - if you don't have a [ on the stack when you evaluate a ] it takes everything on the stack. And you can probably save two characters near the end by not wrapping -1 in an array and moving the final $.

@Peter: Thanks, saved 3 more chars!

@Peter: I'm completely new to GolfScript, this is about my third program.  What am I doing wrong that I'm wasting so many characters?  When I look at your solutions, you seem to be fond of the {....}#* pattern.  Is that usually a more efficient approach?

When you can do something as {stuff}num* or {stuff.}do the first is often shorter. And bool{stuff}* is clearly shorter than the equivalent bool{stuff}{}if. I think possibly with practice I'm getting better at avoiding @@ (I wish Golfscript had a rotate-the-other-way operator). I haven't analysed your program in detail, so I'm not sure specifically which parts are costing you characters.

Blocks are fairly expensive. So 9,{)}%{\.@%!},)\;, for example, to find the largest single-digit factor of the number on the stack without destroying it, is an obvious target for improvement. Actually the best I've got for this so far is more C-like: loop down. 9{1$1$%!!-}8*

I also observe that your solution works for any input. Mine doesn't - hence the 12 in my program. 5 13? would break it, and I save quite a bit there by using a fixed number of iterations rather than calculating termination conditions.

Although you can simplify your loop termination condition by a character. x y 1>& will be 0 or 1, but you only really care about 0 or non-0, so if y is certain to be positive x y (* works equally well.

)[.])@@{1>},+$ to take [d0 d1 d2 ... dn] to dn [«dn if >1» d{n-1} ... d1 d0] also raises some red flags. You're sticking dn into a one-element array just to filter it and add it back? Seems like a waste of []{}. In fact you can do better by not removing it in the first place and instead filtering the indices. .).1=@;@$> My version of your implementation is now down to 48 chars.

@Peter: Lol. Do I have to figure it out :)

@mellamokb, you just have to do some search-and-replace ;) ~{9{1$1$%!!-}8*.@@/.9>2$(*}do].).1=@;@$>\9>-1@if but you'll learn more by looking at the changes I proposed individually.

Haskell
f n=head([m|m<-[1..10^9],product(map(read.return)$show m)==n]++[-1])

Shave off one char by changing (show m) to $show m.

shouldn't it be m<-[1..9^9]....otherwise it's an infinite list...so -1 will never occur....correct me if i'm wrong.

I don't think it can work within 10secs....

scala 106 chars:
def p(n:Int,l:Int=9):List[Int]=if(n<=9)List(n)else
if(l<2)List(-1)else
if(n%l==0)l::p(n/l,l)else
p(n,l-1)

Test & Invocation:
scala> val big=9*9*9*8*8*8*7*7*7*5*3
big: Int = 1920360960

scala> p(big)
res1: List[Int] = List(9, 9, 9, 8, 8, 8, 7, 7, 7, 5, 3)

Response time: immediately, < 1s on 2Ghz CPU.

Windows PowerShell, 87
if(($n="$args")-le1){$n;exit}(-1,-join(9..2|%{for(;!($n%$_)){$_;$n/=$_}}|sort))[$n-eq1]

Perl (68)
$x=pop;map{$_-=11;$x/=$_,$@=-$_.$@until$x%$_}1..9;print!$x?-1:$@||1

It seems like the awesome trick that @mellamokb uses in javascript to avoid the nested loop would translate well to perl but it comes out much more verbose because you cannot use the foreach style loop any longer.  It's also a pity that perl does not think map is a loop else redo would come in handy.

Jelly, 18 13 10 bytes
×⁵RDP$€io-

Try it online!
13-byte solution:
×⁵RDP$€iµ’¹¬?

Try it online!
Explanation with input N:
×³R              create a range from 1 to N * 100 (replace ³ with ⁵ for a faster execution time)
   DP$           define a function ($) to get the product of the digits of a number,
      €          apply that function to each element in the list,
       iµ        get the index of the input N in the list (or 0 if it's not there), and yeild it as the input to the next link,
         ’¹¬?    conditional: if the answer is 0, then subtract one to make it -1, otherwise, yeild the answer

18-byte solution:
D×/
×⁵RÇ€i
Ç⁾-1¹¬?

Try it online!
D×/        product of digits function, takes input M
D          split M into digits,
 ×/        reduce by multiplication (return product of digits)

×⁵RÇ€i     range / index function
×⁵R        make a range from 1 to N*10,
   Ç€      run the above function on each of the range elements,
     i     get the index of N in the result, or 0 if it's not there

Ç⁾-1¹¬?    main function:
Ç    ¬?    run the line above and check if the answer is null (0)
 ⁾-1       if it is, return "-1",
    ¹      otherwise, return the answer (identity function).

The last link is only to replace 0 (Jelly's default falsey value, as all lists are one-indexed) with -1. If you consider 0 an OK falsey value, the program is 8 bytes.

Some notes: (1) you use each auxiliary link only once, so there is no reason to make auxiliary link. Just use the $ƊƲµ. (2) As the string -1 and the number -1 is identical when output, using the number saves 2 bytes. (3) P is shorthand for ×/. (4) Fails for input 3125.

@user202729 Thank you so much! I implemented (1), (2), and (3) and they saved 6 bytes! If I changed the ⁵ to a ³, it worked on input 3125 but only after a considerable delay. Do you know if there's a better (and shorter) way, or is my approach (which I know is definitely not the fastest in terms of time-complexity) as good as it will get?

I think _¬$ should work over ’¹¬?

o- is even shorter.

@dylnan Thank you -- I noticed that because of the µ I could just use _¬ without the $ which saved 2 bytes! But then I realized with o- I could just omit the µ entirely and save 3 bytes!

Ruby (100)
n=gets.to_i;(d=1..9).map{|l|[*d].repeated_combination(l){|a|a.reduce(:*)==n&&(puts a*'';exit)}};p -1

Python 2, 89 bytes
f=lambda n,a=0,u=1,i=9:n<2and(a or 1)or-(i<2)or n%i<1and f(n/i,a+i*u,u*10)or f(n,a,u,i-1)

Try it online!
Just because there's no Python answer yet. It's really painful to lack implicit type conversion between string and int.