Random Text from PERL

Can somebody please post me a script, or at least the basics of a script, to produce nonsense text using the regular alphabet.

In order to get the points, you have to satisfy the following condition, however.

The nonsense text must at least *look* like normal text, that is, be sentences, ending with a full stop; each sentence should consist of between one and a hundred words; each word should consist of between one and say, ten letters; the words to be separated with spaces; the words to end with commas every, say one to ten words.

Extra points for good comments...
LVL 2
johnny99Asked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

johnny99Author Commented:
Edited text of question.
0
Kim RyanIT ConsultantCommented:
0
CompTIA Cloud+

The CompTIA Cloud+ Basic training course will teach you about cloud concepts and models, data storage, networking, and network infrastructure.

johnny99Author Commented:
For 250 points you could do better than that -- have you got any idea what it does?

As far as I can see these are modules, not scripts, and from my knowledge of travesty, they take a chunk of text and create more text based on it.

I want to create large volumes of text based on nothing more than the alphabet, but with the conditions above.
0
GnissmanCommented:
This is a very hard thing to do, really. If you want your text to be legible and not just clusters of letters that cannot be pronounced this comes very close to the "new" Turing test. You will need profound knowledge of formal languages to program something like that!

So producing an output like "dks sdlei sjdfw fssfi" is trivial, but "when dogs fly pennybrokers" is... erm... non-trivial :o)

Gniss

0
ozoCommented:
print
  ucfirst
    join ' ',
      map{
        (join ' ',
           map{
             join'',map{ ('a'..'z')[rand(26)] }(0..rand 10)
           }(0..rand 10)
        ).(',','.')[!$_];
      }(reverse 0..rand(10))
;
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
GnissmanCommented:
Try this script and let me know :o)
It does everything you asked for and can be configured.
Gniss
----------------------------------------------------------------

#!/usr/bin/perl

# configure it here
###################################################################
$max_num_of_sentences = 20;  # max no of sentences in output
$max_num_of_words     = 100; # max no of words in a sentence
$max_num_of_letters   = 10;  # max no of letters in a word
$comma_percentage     = 10;  # a comma after x percent of all words
@chars                = ( "a" .. "z" );
###################################################################
$num_of_sentences = int(rand($max_num_of_sentences))+1;

for ($i=0;$i<$num_of_sentences;$i++) {
      $num_of_words = int(rand($max_num_of_words))+1;
      for ($j=0;$j<$num_of_words;$j++) {
            $num_of_letters = int(rand($max_num_of_letters))+1;
            for ($k=0;$k<$num_of_letters;$k++) {
              print $chars[int(rand(26))+1];
        }
        if (($j+1) ne $num_of_words) {
          if (rand(100) <= $comma_percentage) {
                print ", ";
          } else {
            print " ";
          }
        }
  }
  print". ";
}      
0
ozoCommented:
Gnissman's program sometimes produces less than one, or more than ten words between commas.
0
GnissmanCommented:
ozo, I really like your program. I'm quite new to perl and would like to understand it. If you agree I would post a question just for you to explain that code in detail, so that I could award you some points for it. Would you do me that favour?

Gniss
0
ozoCommented:
What would you like explained?
The inner map produces a word, the middle map produces a comma phrase, and the outer map produces a sentence.
It may have been better to write it more like

for( 0..rand 20 ){
  print
    ucfirst(
      join ', ',
        map{
          join ' ',
             map{
               join'',map{ ('a'..'z')[rand 26] }(0..rand 10)
             }(0..rand 10)
        }(0..rand 10)
    ),".\n";
}
0
GnissmanCommented:
I had not yet come across the join-command, and it is explained very poorly in my book.
I also do not understand the last bit (reverse...) and !$_

Seems like your code consists of structures that can be written in a very compressed format in Perl...

Gniss
0
prakashk021799Commented:
> For 250 points you could do better than that -- have you got
> any idea what it does?

Points are cheap. Just because you decided to assign 250 points to the question, doesn't mean one should write an essay for an answer. Both Ozo and Teraplane gave you pointers to the info. Its your responsibility to at least go through them and then ask nicely for more explanation if you have any doubts.

Coming back to your question, as Gnissman has already commented, it is impossible to develop a program which produces random but readable text (if one could write such a beast then all the points in the world are enough to give them).
Without giving some sort of input (a dictionary of words to choose from) to the program, you cannot generate text according to your conditions.
0
time4teaCommented:
#!/usr/local/bin/perl

open(F,"/usr/share/lib/dict/words");

while (<F>) {
  chop;
  push(@words, $_);
}

$para = .025;
$comma = .1;

$stop = .05;

$cap = 1;

srand;

for ($i=0; $i<1000;$i++) {
  $word = $words[rand(@words)];
  if ($cap) {
    print ucfirst($word);
    $cap = 0;
  }
  else {
    print $word;
  }

  if ( rand() <= $para ) {
    print "\n\n";
    $cap = 1;
    next;
  }

  if (rand() <= $comma) {
    print ", ";
    next;
  }

  if (rand() <= $stop) {
    print ".  ";
    $cap = 1;
    next;
  }
 
  print " ";
}


Sample Output:

Red Laurentian objectify
 
Quasiorder Rousseau peasant circumferential chaotic weatherstripping maladjust galvanism injurious, sap geography crankcase relayed demon Arcadia jersey Caesar slam controlled, airfare fungible plenipotentiary restoration well Butterfield hoc incense grandfather breath.  Inseminate.  Gloom amygdaloid.  Soldier inboard Lundberg glum district Pygmalion
 
Kindred Eunice confrere Bryan Cindy thiamin futile.  Corroboree.  Short whimper brimful Hillcrest trout wiretapping cavalier TNT Carnegie warhead quake sizzle belligerent histogram lunge curriculum declivity curvaceous Nigeria workhorse Stewart hilarious Calvert Missy segregant cola formate Barrington hereinafter Nineveh inexpert switchgear inscrutable preferred inimitable prophecy.  Typographer brouhaha athwart impenetrable toluene Carmen inflater 3rd.  Knew lament
 
Abhorrent pica alive berg
 
Excursion.  Singapore insuperable daydream Stewart
0
time4teaCommented:
Oops, but i forgot that a paragraph also needs a full stop.
0
prakashk021799Commented:
johnny99 said:

> I want to create large volumes of text based on nothing more
> than the alphabet ...

Sorry time4tea! You did not meet johnny99's condition.
0
Kim RyanIT ConsultantCommented:
I concur with Prakashk. Modules are there so we don't have to reinvent the wheel, and it is worth studying the documentation to see if they are at least close to what you need. You can always try modifying them yourself.

For what sounds like a fairly trivial problem, I don't see the need to write complex code from scratch.
0
johnny99Author Commented:
I apologise to everyone for not explaining myself properly.

they don't have to be *real* words -- I should have put "words" -- they should just be randomly-arranged letters of similar lengths to normal words.

There is no requirement for them to be actual words in any language, in face quite the opposite. No dictionary is required, no input is necessary.

I will check out the scripts posted when I have more time.

Sorry again.
0
ozoCommented:
> I also do not understand the last bit (reverse...) and !$_
!$_ is true (1) when $_ is false (0)
the reverse makes the 0 the last element instead of the first.
It was intended to treat the last element differently, to end it with "." instead of ","
But since join puts separators between elements, it was actually an unnecessary kludge.
I made the operators return strings instead of just printing in a for loop so that the result could be pased to the ucfirst function

(the problem with
print $chars[int(rand(26))+1];
is that it never prints $chars[0], and $chars[26] is undef)
0
johnny99Author Commented:
Hi, I think ozo has to get the points for sheer efficiency, though I've not marked it Excellent because there aren't any comments.

For everyone else, this is the kind of thing I wanted, and the thing I come to EE for -- Grissman's learning from Ozo, we're all learning from the discussion.

I'd like to give Ozo some points as well, as he posted a perfectly good solution too...
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Perl

From novice to tech pro — start learning today.