Problem of the Day
A new programming or logic puzzle every Mon-Fri

Muspi Merol

Muspi Merol or Lorem Ipsum is a tool used to generate dummy text which can be helpful for development purposes. Our goal today is to create a dummy text generation machine. The only input your program should take in is how many paragraphs to output. Outputting random text is fairly easy so to make this more fun our tool needs to produce somewhat authentic looking text. In order to do this our tool must follow these rules:

  • The first two words must be "Muspi Merol"
  • All sentences must begin with a capital letter
  • Words are between 1 and 10 characters
  • Sentences are between 3 and 14 words
  • Paragraphs are between 3 and 6 sentences
  • Bonus: p, o, t, d are the vowels for our generator so they should appear more often than other letters
  • Bonus: Lines should be no longer than 80 characters. Place new line characters before a line gets to 80 characters and make sure to not to cut off a word.

Permalink: http://problemotd.com/problem/muspi-merol/

Comments:

  • z - 10 years, 9 months ago

    reply permalink

  • Anonymous - 10 years, 9 months ago

    Pretty verbose Java solution, not fulfilling the bonus problem number one.

    There is a lot of duplication in this code. Anybody want to suggest a design pattern that would make this code terser?

    import java.util.Random;
    
    /**
     * "Muspi merol" generator.
     */
    public class MuspiMerol {
    
        private static Random random = new Random(System.nanoTime());
    
        private static String formatParagraph(String paragraph, int columns) {
            StringBuilder builder = new StringBuilder();
            int currentColumn = 0;
            for (String word : paragraph.split("\\s+")) {
                if (currentColumn == 0) {
                    builder.append(word);
                    currentColumn += word.length();
                } else {
                    if (currentColumn + word.length() + 1 <= columns) {
                        builder.append(' ');
                        builder.append(word);
                        currentColumn += word.length() + 1;
                    } else {
                        builder.append(System.lineSeparator());
                        builder.append(word);
                        currentColumn = word.length();
                    }
                }
            }
            return builder.toString();
        }
    
        private static String generateWord() {
            int chars = random.nextInt(10) + 1;
            StringBuilder builder = new StringBuilder();
            for (int i = 0; i < chars; i++) {
                builder.append((char)(random.nextInt(26)+97));
            }
            return builder.toString();
        }
    
        private static String generateSentence() {
            int words = random.nextInt(12) + 3;
            StringBuilder builder = new StringBuilder();
            for (int i = 0; i < words-1; i++) {
                builder.append(generateWord());
                builder.append(' ');
            }
            builder.append(generateWord());
            builder.append('.');
            builder.setCharAt(0, Character.toUpperCase(builder.charAt(0)));
            return builder.toString();
        }
    
        private static String generateParagraph() {
            int sentences = random.nextInt(4) + 3;
            StringBuilder builder = new StringBuilder();
            for (int i = 0; i < sentences-1; i++) {
                builder.append(generateSentence());
                builder.append(' ');
            }
            builder.append(generateSentence());
            builder.append(System.lineSeparator());
            return builder.toString();
        }
    
        /**
         * Returns a String with generated "Muspi Merol" text paragraphs.
         *
         * @param paragraphs number of text paragraphs to be generated
         * @return a generated text string
         */
        public static String generateParagraphs(int paragraphs) {
            if (paragraphs < 0) {
                throw new IllegalArgumentException("Negative number of paragraphs");
            }
            if (paragraphs == 0) {
                return "";
            }
    
            StringBuilder builder = new StringBuilder();
            for (int i = 0; i < paragraphs-1; i++) {
                builder.append(formatParagraph(generateParagraph(), 80));
                builder.append(System.lineSeparator());
                builder.append(System.lineSeparator());
            }
            builder.append(formatParagraph(generateParagraph(), 80));
            int secondSpaceIndex = builder.indexOf(" ", builder.indexOf(" ")+1);
            builder.replace(0, secondSpaceIndex, "Muspi merol");
            return builder.toString();
        }
    
        public static void main(String[] args) {
            System.out.println(MuspiMerol.generateParagraphs(4));
        }
    
    }
    

    reply permalink

  • Max Burstein - 10 years, 9 months ago

    Thanks for posting! My Javafu isn't too strong but your code looks pretty much like what I was expecting.

    reply permalink

  • Anonymous - 10 years, 9 months ago

    Perl with bonuses. Could use some cleanup but it's readable. <code><pre> #!/usr/bin/perl

    use strict; use warnings;

    my $flag = 0; my @letter_table = (); my $column_width = 80; my $paragraphs = $ARGV[0]; my $output = "";

    sub create_letter_table { @letter_table = ("a".."z"); push(@letter_table,"p") foreach (1..3); push(@letter_table,"o") foreach (1..5); push(@letter_table,"t") foreach (1..4); push(@letter_table,"d") foreach (1..3); }

    sub create_word { $flag++; my $word_string = ""; my $word_len = int(rand(9))+1; my $letter = ""; for(my $i=0 ; $i<$word_len ; $i++) { $letter = ""; $letter = $letter_table[int(rand(scalar @letter_table))]; $word_string = $word_string . $letter; } if($flag == 1) { return "Muspi"; } if($flag == 2) { return "Merol"; } return $word_string; }

    sub create_sentance { my $sentance = ""; my $word = ucfirst(create_word()); $sentance = $word." "; my $sentance_len = int(rand(12)+2); for( my $i=0 ; $i<$sentance_len ; $i++ ) { $word = create_word(); $sentance = $sentance . $word . " "; } $sentance =~ s/ $/./; return $sentance; }

    sub create_paragraph { my $paragraph = ""; my $num_of_sentances = int(rand(4))+3; for (my $j=0 ; $j < $num_of_sentances ; $j++ ) { my $sentance_string=create_sentance(); $paragraph = $paragraph . $sentance_string . " "; }

    my @paragraph_array = split( /\s+/, $paragraph );
    my $len = 0;
    for( my $i = 0 ; $i < scalar @paragraph_array ; $i++) {
        $len = $len + length($paragraph_array[$i]) + 1;
        if($len > $column_width) {
            $paragraph_array[($i-1)] =~ s/ $/\n/;
            $paragraph_array[$i] = $paragraph_array[$i] ." ";
            $len = length($paragraph_array[$i]) + 1;
        } else {
            $paragraph_array[$i] = $paragraph_array[$i] ." ";
        }
    }
    $paragraph = "";
    $paragraph = join("",@paragraph_array); 
    $paragraph =~ s/ $//;           
    return $paragraph;
    

    } </pre></code>

    reply permalink

  • Anonymous - 10 years, 9 months ago

    Let's try that again ``` #!/usr/bin/perl

    use strict; use warnings;

    my $flag = 0; my @letter_table = (); my $column_width = 80; my $paragraphs = $ARGV[0]; my $output = "";

    sub create_letter_table { @letter_table = ("a".."z"); push(@letter_table,"p") foreach (1..3); push(@letter_table,"o") foreach (1..5); push(@letter_table,"t") foreach (1..4); push(@letter_table,"d") foreach (1..3); }

    sub create_word { $flag++; my $word_string = ""; my $word_len = int(rand(9))+1; my $letter = ""; for(my $i=0 ; $i<$word_len ; $i++) { $letter = ""; $letter = $letter_table[int(rand(scalar @letter_table))]; $word_string = $word_string . $letter; } if($flag == 1) { return "Muspi"; } if($flag == 2) { return "Merol"; } return $word_string; }

    sub create_sentance { my $sentance = ""; my $word = ucfirst(create_word()); $sentance = $word." "; my $sentance_len = int(rand(12)+2); for( my $i=0 ; $i<$sentance_len ; $i++ ) { $word = create_word(); $sentance = $sentance . $word . " "; } $sentance =~ s/ $/./; return $sentance; }

    sub create_paragraph { my $paragraph = ""; my $num_of_sentances = int(rand(4))+3; for (my $j=0 ; $j < $num_of_sentances ; $j++ ) { my $sentance_string=create_sentance(); $paragraph = $paragraph . $sentance_string . " "; }

    my @paragraph_array = split( /\s+/, $paragraph );
    my $len = 0;
    for( my $i = 0 ; $i < scalar @paragraph_array ; $i++) {
        $len = $len + length($paragraph_array[$i]) + 1;
        if($len > $column_width) {
            $paragraph_array[($i-1)] =~ s/ $/\n/;
            $paragraph_array[$i] = $paragraph_array[$i] ." ";
            $len = length($paragraph_array[$i]) + 1;
        } else {
            $paragraph_array[$i] = $paragraph_array[$i] ." ";
        }
    }
    $paragraph = "";
    $paragraph = join("",@paragraph_array); 
    $paragraph =~ s/ $//;           
    return $paragraph;
    

    }

    create_letter_table(); for (my $i=0 ; $i<$paragraphs ; $i++) { $output = $output . create_paragraph() ."\n\n"; } print $output; ```

    reply permalink

  • Max Burstein - 10 years, 9 months ago

    Sorry for your troubles. You need a new line after the first set of backtacks and before the last ones. It looks like you have the backticks on the same lines as your code.

    backticks

    code

    backticks

    reply permalink

  • stefan - 10 years, 9 months ago

    import random, string

    voweldic = list(string.ascii_lowercase)+["p","p","o","o","t","t","d","d"] lc = 0

    def main(): #lc = 0 par_no = int(raw_input("How many paragraphs do you like? ")) #print range(par_no) for i in range(par_no): print "Paragraph",i+1 print genPar()

    #return 0
    

    def genPar(): global lc par_length = random.randint(3,6) par = "Muspi Merol" lc = len(par) for sent in range(par_length): par = par + genSent() par = par + "\n" return par

    def genSent(): global lc sent_length = random.randint(3,14) #generate sentence sent = genWord() sent = sent[0].upper() + sent[1:] for words in range(sent_length-1): sent = sent + " " + genWord()

    sent = sent + ". "
    return sent
    

    def genWord(): global lc word_length = random.randint(1,10) final_word = "" for i in range(word_length): final_word = final_word + random.choice(voweldic)

    if lc + len(final_word) > 80:
        final_word = "\n" + final_word
        lc = len(final_word[2:])
    else:
        lc = lc + len(final_word)
    return final_word      
    

    if name == 'main': main()

    reply permalink

  • Anonymous - 10 years, 9 months ago

    ''' hai '''

    reply permalink

  • Juan José Sisti - 10 years, 9 months ago

    Php, Bonus 1 not implemented.

    ´´´

    <?php /* Muspi Merol

    Muspi Merol or Lorem Ipsum is a tool used to generate dummy text which can be helpful for development purposes. Our goal today is to create a dummy text generation machine. The only input your program should take in is how many paragraphs to output. Outputting random text is fairly easy so to make this more fun our tool needs to produce somewhat authentic looking text. In order to do this our tool must follow these rules:

    The first two words must be "Muspi Merol"
    All sentences must begin with a capital letter
    Words are between 1 and 10 characters
    Sentences are between 3 and 14 words
    Paragraphs are between 3 and 6 sentences
    Bonus: p, o, t, d are the vowels for our generator so they should 
    appear more often than other letters
    Bonus: Lines should be no longer than 80 characters. Place new line 
    characters before a line gets to 80 characters and make sure to not 
    to cut off a word.
    

    */

    // Variables globales $enter = "<br>";

    // La tabla ASCII tiene las minusculas desde el numero // 65 (A) hasta el 90 (Z) // 97 (a) hasta el 122 (z) function LoremIpsumGenWord($wordConf) { $largo = rand($wordConf["min"], $wordConf["max"]); $word = ""; for ($i=0; $i < $largo; $i++) { $word .= chr(rand(97, 122)); } return $word; }

    //$len indica el largo máximo del string, ya no en palabras, sino en letras function LoremIpsumGenString($wordConf, $stringConf, $stringLen, $primer) { $largo = rand($stringConf["min"], $stringConf["max"]); $numLinea = 0; ($primer ? $string[$numLinea] = "Muspi Merol" : $string[$numLinea] = ""); for ($i=0; $i < $largo; $i++) { $word = LoremIpsumGenWord($wordConf); if($i===0 && !$primer) { $word = ucfirst($word); $espacio = ""; } else { $espacio = " "; } if(strlen($string[$numLinea] . $word) >= $stringLen - 1) { $string[$numLinea] = $string[$numLinea] . $GLOBALS["enter"]; $numLinea ++; $string[$numLinea] = $word; } else { $string[$numLinea] = $string[$numLinea] . $espacio . $word; } ($i > 1 ? $primer = false : ""); } $Nstring = ""; foreach ($string as $ln => $str) { $Nstring .= $str; } $Nstring .= "." . $GLOBALS["enter"]; return $Nstring; }

    function LoremIpsumGenParagraph($wordConf, $stringConf, $stringLen, $paraConf) { $largo = rand($paraConf["min"], $paraConf["max"]); $para = ""; // Para el bonus 0 $primer = true; for ($i=0; $i < $largo; $i++) { $string = LoremIpsumGenString($wordConf, $stringConf, $stringLen, $primer); $para .= $string; $primer = false; } $para .= $GLOBALS["enter"] . $GLOBALS["enter"]; return $para; }

    function LoremIpsumGenerator($paraCant) { $wordConf = ["min" => 1, "max" => 10]; $stringConf = ["min" => 3, "max" => 14]; $paraConf = ["min" => 3, "max" => 10]; $stringLen = 80; $loremIpsum = ""; for ($i=0; $i < $paraCant ; $i++) { $para = LoremIpsumGenParagraph($wordConf, $stringConf, $stringLen, $paraConf); $loremIpsum .= $para; } return $loremIpsum; }

    echo(LoremIpsumGenerator(3));

    ´´´

    reply permalink

  • Anonymous - 10 years, 9 months ago

    I've got a basic C++ workup here. Didn't go for the bonuses because it took an embarrassing amount of time to debug it. ''' #include<iostream> #include<cstdlib> #include<fstream> #include<cctype> #include<ctime>

    using namespace std;

    char genletter(int num1, int num2, int num3, int num4);

    int main() { srand(time(NULL)); int slen(0), plen(0), wlen(0), nump(0); string paragraph(""), word(""), filename(""), sentence(""); cout<<"Enter the output file's name: "; cin>>filename; ofstream fout(filename.c_str()); cout<<"Enter the number of paragraphs to generate: "; cin>>nump; fout<<" Muspi Merol"; for(int i = 0; i < nump; i++) { plen = rand() % 3 + 3; paragraph = ""; for(int a = 0; a < plen; a++) { slen = rand() % 11 + 3; sentence = ""; for(int b = 0; b < slen; b++) { wlen = rand() % 10 + 1; word = ""; for(int c = 0; c < wlen; c++) { word.push_back(genletter(b, c, i, a)); } if(plen != 0) { sentence.append(" "); } sentence.append(word); if(b == slen - 1) { sentence.append("."); } } paragraph.append(sentence); } fout<<paragraph<<endl<<" "; } return 0; }

    char genletter(int num1, int num2, int num3, int num4) { char random = 'a' + rand() % 26; if(num1 == 0 && num2 == 0 && num3 != 0) { random = toupper(random); } else if(num1 == 0 && num2 == 0 && num3 == 0 && num4 > 0) { random = toupper(random); }

    return random; } '''

    reply permalink

  • Anonymous - 10 years, 9 months ago

    C# all implemented.

    using System;
    
    namespace MuspiMerol
    {
        class Program
        {
            static void Main(string[] args)
            {
                var maxSize = (byte)(Console.BufferWidth - 1);//max line size on console
    
                var result = GenerateMuspiMerol(3, maxSize);
    
                Console.WriteLine(result);
    
                Console.Write("\n\npress any key to exit..");
                Console.ReadKey();
            }
    
            //constrains (all range values inclusive)
            private const int MaxLineSize = 80;
            private const int MinSentencePerParagraph = 3;
            private const int MaxSentencePerParagraph = 6;
            private const int MinWordsPerSentence = 3;
            private const int MaxWordsPerSentence = 14;
            private const int MinCharsPerWord = 1;
            private const int MaxCharsPerWord = 10;
            private static readonly char[] Vowels = { 'p', 'o', 't', 'd' };
            private static readonly string[] FirstWords = { "Muspi", "Merol" };
    
            private static readonly Random Rnd = new Random();
    
            static string GenerateMuspiMerol(ushort paragraphCount, byte maxLineSize = MaxLineSize)
            {
                var r = string.Empty;
                bool fist = true;
                while (paragraphCount > 0)
                {
                    if (fist)
                    {
                        r = MakeParagraph(maxLineSize, true);
                        fist = false;
                    }
                    else
                        r += "\n\n" + MakeParagraph(maxLineSize, false);
                    paragraphCount--;
                }
                return r;
            }
    
            private static string MakeParagraph(byte maxLineSize, bool isFirst)
            {
                var p = string.Empty;
                var sentenceCount = Rnd.Next(MinSentencePerParagraph, MaxSentencePerParagraph + 1);
                while (sentenceCount > 0)
                {
                    if (isFirst)
                    {
                        p = MakeSentence(FirstWords);
                        isFirst = false;
                    }
                    else
                        p += " " + MakeSentence();
    
                    sentenceCount--;
                }
                return p.Wrap(maxLineSize);
            }
    
            private static string MakeSentence(params string[] startWords)
            {
                var s = string.Join(" ", startWords);
                var wordCount = Rnd.Next(MinWordsPerSentence, (MaxWordsPerSentence - startWords.Length) + 1);
                while (wordCount > 0)
                {
                    s += " " + MakeWord();
                    wordCount--;
                }
                if (startWords.Length == 0)
                    //remove the first space and set first letter to upper.
                    s = char.ToUpper(s[1]) + s.Substring(2);
                return s + ".";
            }
    
            private static string MakeWord()
            {
                var letters = new char[Rnd.Next(MinCharsPerWord, MaxCharsPerWord + 1)];
                for (int i = 0; i < letters.Length; i++)
                    letters[i] = NextLetter();
                return new string(letters);
            }
    
            private static char NextLetter()
            {
                if (Rnd.Next(3) == 1)
                    return Vowels[Rnd.Next(Vowels.Length)];
                return (char)('a' + Rnd.Next(26));
            }
        }
    }
    

    and the Wrap function

    using System;
    using System.Collections.Generic;
    
    namespace MuspiMerol
    {
        /// <summary>
        /// System.String extension that adds line breaks to wrap a block of text without breaking the words.
        /// <remarks>
        /// A word is simply defined as any text between spaces ' '.
        /// There is no extra punctuation check, in the string "Dog Cat Dog.\nCat" the words are "Dog" "Cat" "Dog.\nCat".
        /// </remarks>
        /// </summary>
        public static class StringWrapExtension
        {
            /// <summary>
            /// Wraps the string in lines of words to fit the current Console.BufferWidth. 
            /// </summary>
            public static string Wrap(this string text)
            {
                //-1 because the console adds a break line if its exactly the size of one line.
                return Wrap(text, Console.BufferWidth - 1);
            }
    
            /// <summary>
            /// Wraps the string in lines of words to fit the maxLineLength. 
            /// </summary>
            public static string Wrap(this string text, int maxLineLength)
            {
                var words = text.Split(' ');
                var result = new List<string>();
                var line = string.Empty;
    
                foreach (var word in words)
                {
                    //if the word will not fit even alone..
                    if (word.Length > maxLineLength)
                    {
                        line += word;
                        while (line.Length > maxLineLength)//we split the word
                        {
                            var spl = line.Substring(0, maxLineLength - 1);
                            spl += "-";
                            result.Add(spl);
                            line = line.Substring(maxLineLength - 1);
                        }
                    }
                    //specific case, will add an extra break (on windows console) if not handled
                    else if (string.IsNullOrEmpty(line) && word.Length == maxLineLength)
                    {
                        result.Add(word);
                    }
                    //if the word will fit in the current line..
                    else if (line.Length + word.Length < maxLineLength)
                    {
                        //we add the word plus a space if its not the first word.
                        line += string.IsNullOrEmpty(line) ? word : " " + word;
                    }
                    //if the word will not fit in the current line..
                    else
                    {
                        result.Add(line);//we add the current line
                        line = word;//and the new line is now the word
                    }
                }
                result.Add(line);//we add any last words..
    
                return string.Join("\n", result);//and join all lines with a break
            }
        }
    }
    
    

    reply permalink

  • Max Burstein - 10 years, 9 months ago

    Nicely done. Do you have a github account?

    reply permalink

Content curated by @MaxBurstein