Programming Puzzles & Code Golf Stack Exchange is a question and answer site for programming puzzle enthusiasts and code golfers. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

My homework is to write a Martian essay (see below) between 729 and 810 words, inclusive. Your task is to write a program that will generate the essay.

History

Around the turn of the 20th century, spiritualist Catherine-Elise Müller allegedly communicated with Martians. During somnambulatory trances, she would write out Martian scripts. Psychologist Théodore Flourney discovered her Martian writings were very similar to her native French, and in his book "From India to the Planet Mars", he documented Catherine's Martian alphabet.

The following is loosely based on that alphabet with an extended mythos.

Problem Description

The Martian language has 21 letters, shown here next to each Latin equivalent:

enter image description here

Unfortunately, there's no Unicode for Martian (despite Mars being part of the universe), so we're stuck using Latin characters.

Whereas in English our phonemes break out into two major types (consonants/vowels) which we loosely map to letters, Martian has three letter types:

  • The vowels: a e i m n o u
  • The hard consonants: b c d g k p t
  • The soft consonants: f h l r s v z

In addition to this, the Martian language contains a single punctuation mark--the period.

A Martian word is a set of 3 to 9 letters. All Martian words have at least one vowel, one hard consonant, and one soft consonant (in any arrangement). For example, fng, cdaz, vpi, and pascal are Martian words.

A Martian sentence is a set of 3 to 9 Martian words delimited by spaces and followed by a period.

A Martian paragraph is a set of 3 to 9 Martian sentences delimited by spaces and followed by a newline.

A Martian essay is a collection of Martian paragraphs that contains no contiguous word repetitions.

A contiguous word repetition is any construct S S where S is a contiguous set of words. Note that this definition ignores sentence and paragraph boundaries.

Examples

Please note: There's a single trailing newline following each example (since all Martian paragraphs end in a newline)

Not Martian essay

lorem ipsum dolor sit amet. quis nostrud exercitation ullamco laboris.

...for many reasons. This example is to illustrate some miscellaneous rules:

  • lorem is not a Martian word because it has no hard consonants.
  • amet is not a Martian word because it has no soft consonants. (m is a Martian vowel).
  • quis is not a Martian word because it has no hard consonants
  • quis is not a Martian word because q is not a Martian letter
  • exercitation is not a Martian word because it has more than 9 letters
  • exercitation is not a Martian word because x is not a Martian letter

Martian essay

fng cdaz vpi. pascal broke basic. popplers taste great.

...because it is a Martian paragraph. The Martian paragraph contains three Martian sentences.

Not Martian essay

fng cdaz vpi. pascal broke basic. free pascal rules.

...since free pascal rules. is not a Martian sentence, because neither free nor rules are Martian words, because they do not have any hard consonants.

Martian essay

fng cdaz vpi. pascal broke basic. popplers taste great.
cdaz vpi fng. basic breaks pascal. popplers punch hard. fng cdaz vpi.

...which contains two Martian paragraphs. The sentence fng cdaz vpi. appears twice, but that's perfectly fine.

Not Martian essay

popplers taste fng. cdaz vpi pascal. broke fng cdaz vpi.
pascal broke omicron planets. basic scares goats. vpi piv vpi.

...because the construct fng. cdaz vpi pascal. broke fng cdaz vpi. [nl] pascal broke is a contiguous word repetition.

Challenge

Your challenge is to write a function or program that accepts no input, which produces as its output my homework; that is, your program should generate a Martian essay between 729 and 810 words (inclusive). Keep in mind, your program's output must be a valid Martian essay, but you don't have to generate it randomly or different each time. Anything you do to generate a valid Martian essay counts.

I've written a C++ program to check essays that you're allowed to use.

This is code golf. Shortest code in bytes wins. Standard loopholes disallowed.

share|improve this question
2  
Popplers taste great... Is that futurama reference :D – DrMcMoylex yesterday
    
The C++ checker seems to require a trailing new line. – Jonathan Allan yesterday
    
@JonathanAllan That's correct. Without a trailing new line, the last set of sentences cannot be a Martian paragraph (per definition of Martian paragraph). – H Walters 23 hours ago
    
Also, though I answered DrMcMoylex in chat, just for the record here... yes. (FYI, the 729 and 810 word requirement, which is 1000 to 1100 words in base 9, is also an indirect reference) – H Walters 23 hours ago
3  
I think this is the first time I've seen a "Do my homework for me" question on codegolf. Usually those are on stackoverflow proper. :-) – Ray 8 hours ago

Jelly, 28 26 25 24 23 bytes

-1 byte thanks to carusocomputing (replace the word thimble with abcdefg)

9ØaḣŒ!s²ḣµs9K€;€”.K;⁷µ€

TryItOnline!

How?

Makes a list of all 362880 permutations of the first seven nine letters of the English alphabet abcdefghi, which all have the properties of Martian words and are all distinct, and formats them into an essay using the first 729 words.

9ØaḣŒ!s²ḣµs9K€;€”.K;⁷µ€ - Main link: no arguments
9                       - 9 as x
         µ              - monadic chain separation
 Øa                     - yield lowercase alphabet
   ḣ                    - head to x ("abcdefghi")
    Œ!                  - all permutations (362880 distinct Martian words)
       ²                - square x = 81 
      s                 - split into chunks of length 81 (the paragraphs)
        ḣ               - head to x (get the first 9 paragraphs only)
                     µ€ - monadic chain for €ach (for each chunk:)
          s9            -     split into chunks of length 9 (the sentences)
            K€          -     join with spaces for €each (between words in each sentence)
              ;€        -     concatenate €ach with
                ”.      -         '.' (add a full stop* after each sentence)
                  K     -     join with spaces (add a space between the sentences)
                   ;    -     concatenate with
                    ⁷   -         a line feed
                        - implicit print

* period

share|improve this answer
1  
You can save bytes by using the first 7 characters of the alphabet abcdefg. – carusocomputing 15 hours ago
    
Gahhh... That was the byte I could've beat you with too. I'm dumb haha. – carusocomputing 15 hours ago
    
I have a feeling you'll get there anyway! – Jonathan Allan 15 hours ago
3  
Tag, you're it, find another byte ;). – carusocomputing 14 hours ago

Ruby, 86 83 82 79 bytes

(8019..8747).map{|x|$><<x.to_s(3).tr('012','abf')+(x%9>7?".\n":x%3>1?". ":" ")}

The trick: print all numbers between 102000000 and 102222222 in base 3

share|improve this answer
    
Where does 102M come from? – Mukul Kumar 14 hours ago
    
The numbers between 102000000 and 102222222 (base 3) become 9-letter words. 8019 base 10 is 102M base 3. – G B 8 hours ago

Python 3, 121 119 bytes

from itertools import*
i=729
while i:i-=1;print(*list(permutations('thimble'))[i],sep='',end='.'*(i%9<1)+' \n'[i%81<1])

repl.it

How?

Counts down from i=729 and gets a list of the letters of the ith permutation of 'thimble' as the next distinct Martian word (list(permutations('thimble'))[i]).

Avoids ''.join(...) by use of a *expression to unpack the list while changing the default separator for print from a space to the empty string (sep='').

Uses the end argument of print to optionally add spaces, full stops and line feeds as required using modular arithmetic. A full stop goes after every ninth word ('.'*(i%9<1)) and a line feed goes after every eighty-first word, otherwise a space does, achieved by indexing into a two character string (' \n'[i%81<1]).

share|improve this answer

Mathematica, 113 bytes

StringRiffle[(p=Partition)["ark"["bus","car"][[#]]&/@Differences@Array[ThueMorse,730],3]~p~3,n=".\n",". "," "]<>n

Unnamed function that produces a string as output; that string is a Martian essay where each sentence has three words and each paragraph has three sentences. (Its deterministic output is below.)

The core of the algorithm uses the cool mathematical fact that the differences of the Thue–Morse sequence form an infinite sequence of the three symbols –1, 0, and 1 that has no contiguous digit repetitions. Differences@Array[ThueMorse,730] generates that sequence, to length 729.

Then "ark"["bus","car"][[#]]&/@ is applied to this sequence; this converts each 1 to "bus" (the first argument), each –1 to "car" (the last argument), and each 0 to "ark" (the function head). (p=Partition)[...,3]~p~3 divides this sequence of words into nested lists, each consisting of three lists of three words each. Finally, StringRiffle[...,n=".\n",". "," "] concatenates all the words together, with different separators depending on the list levels; and <>n appends the final period and newline.

The output sure doesn't look repetition-free....

ark car bus. car ark bus. ark car ark.
bus car bus. ark car bus. car ark bus.
car bus ark. car ark bus. ark car bus.
car ark bus. ark car ark. bus car bus.
ark car ark. bus ark car. bus car ark.
bus car bus. ark car bus. car ark bus.
ark car ark. bus car bus. ark car bus.
car ark bus. car bus ark. car ark bus.
ark car bus. car ark bus. car bus ark.
car bus car. ark bus ark. car ark bus.
car bus ark. car ark bus. ark car bus.
car ark bus. ark car ark. bus car bus.
ark car bus. car ark bus. car bus ark.
car ark bus. ark car bus. car ark bus.
ark car ark. bus car bus. ark car ark.
bus ark car. bus car ark. bus car bus.
ark car bus. car ark bus. ark car ark.
bus car bus. ark car ark. bus ark car.
bus car ark. bus ark car. ark bus car.
bus ark car. bus car ark. bus car bus.
ark car ark. bus ark car. bus car ark.
bus car bus. ark car bus. car ark bus.
ark car ark. bus car bus. ark car bus.
car ark bus. car bus ark. car ark bus.
ark car bus. car ark bus. ark car ark.
bus car bus. ark car ark. bus ark car.
bus car ark. bus car bus. ark car bus.
car ark bus. ark car ark. bus car bus.
ark car bus. car ark bus. car bus ark.
car ark bus. ark car bus. car ark bus.
car bus ark. car bus car. ark bus ark.
car ark bus. car bus ark. car ark bus.
ark car bus. car ark bus. ark car ark.
bus car bus. ark car bus. car ark bus.
car bus ark. car ark bus. ark car bus.
car ark bus. car bus ark. car bus car.
ark bus ark. car ark bus. car bus ark.
car bus car. ark bus car. bus ark car.
ark bus ark. car bus car. ark bus ark.
car ark bus. car bus ark. car ark bus.
ark car bus. car ark bus. car bus ark.
car bus car. ark bus ark. car ark bus.
car bus ark. car ark bus. ark car bus.
car ark bus. ark car ark. bus car bus.
ark car bus. car ark bus. car bus ark.
car ark bus. ark car bus. car ark bus.
ark car ark. bus car bus. ark car ark.
bus ark car. bus car ark. bus car bus.
ark car bus. car ark bus. ark car ark.
bus car bus. ark car bus. car ark bus.
car bus ark. car ark bus. ark car bus.
car ark bus. car bus ark. car bus car.
ark bus ark. car ark bus. car bus ark.
car ark bus. ark car bus. car ark bus.
ark car ark. bus car bus. ark car bus.
car ark bus. car bus ark. car ark bus.
ark car bus. car ark bus. ark car ark.
bus car bus. ark car ark. bus ark car.
bus car ark. bus car bus. ark car bus.
car ark bus. ark car ark. bus car bus.
ark car ark. bus ark car. bus car ark.
bus ark car. ark bus car. bus ark car.
bus car ark. bus car bus. ark car ark.
bus ark car. bus car ark. bus car bus.
ark car bus. car ark bus. ark car ark.
bus car bus. ark car bus. car ark bus.
car bus ark. car ark bus. ark car bus.
car ark bus. ark car ark. bus car bus.
ark car ark. bus ark car. bus car ark.
bus car bus. ark car bus. car ark bus.
ark car ark. bus car bus. ark car ark.
bus ark car. bus car ark. bus ark car.
ark bus car. bus ark car. bus car ark.
bus car bus. ark car ark. bus ark car.
bus car ark. bus ark car. ark bus car.
bus ark car. ark bus ark. car bus car.
ark bus car. bus ark car. bus car ark.
bus ark car. ark bus car. bus ark car.
bus car ark. bus car bus. ark car ark.
bus ark car. bus car ark. bus car bus.
ark car bus. car ark bus. ark car ark.

Mathematica, 100 bytes

StringRiffle[(p=Partition)[Permutations@Characters@"thimble"~Take~729,9]~p~9,n=".\n",". "," ",""]<>n

A direct port of Jonathan Allen's Jelly algorithm.

share|improve this answer
    
I see car bus car bus in there – Destructible Watermelon 7 hours ago
    
Wait nvm just my display – Destructible Watermelon 7 hours ago
    
It would be shorter to just do Print@"fng cdaz vpi. pascal broke basic. popplers taste great." – Pavel 5 hours ago
    
@Pavel Perfectly valid essay, but you're about 720 words shy of my homework assignment. – H Walters 2 hours ago
    
@HWalters I see, I misread the problem. Oops. – Pavel 1 hour ago

05AB1E, 25 24 22 bytes

A7£œ9ôvyJðý"."«})9ô9£»

Try it online!

A7£                     # Push first 7 letters of the alphabet.
   œ                    # All 5040 permutations of "abcdefg".
    9ô                  # Split into pieces of 9 (Sentences).
       vy       }       # For each piece...
         Jðý"."«        # Join by spaces and finish with a period.
                 )9ô    # Split into pieces of 9 (paragraphs).
                    9£  # Take only the first 9 paragraphs.
                      » # Join by newlines and implicitly print.

Turns out the 810 word version is shorter than the 729 word version.

Output:

abcdefg abcdegf abcdfeg abcdfge abcdgef abcdgfe abcedfg abcedgf abcefdg. abcefgd abcegdf abcegfd abcfdeg abcfdge abcfedg abcfegd abcfgde abcfged. abcgdef abcgdfe abcgedf abcgefd abcgfde abcgfed abdcefg abdcegf abdcfeg. abdcfge abdcgef abdcgfe abdecfg abdecgf abdefcg abdefgc abdegcf abdegfc. abdfceg abdfcge abdfecg abdfegc abdfgce abdfgec abdgcef abdgcfe abdgecf. abdgefc abdgfce abdgfec abecdfg abecdgf abecfdg abecfgd abecgdf abecgfd. abedcfg abedcgf abedfcg abedfgc abedgcf abedgfc abefcdg abefcgd abefdcg. abefdgc abefgcd abefgdc abegcdf abegcfd abegdcf abegdfc abegfcd abegfdc. abfcdeg abfcdge abfcedg abfcegd abfcgde abfcged abfdceg abfdcge abfdecg.
abfdegc abfdgce abfdgec abfecdg abfecgd abfedcg abfedgc abfegcd abfegdc. abfgcde abfgced abfgdce abfgdec abfgecd abfgedc abgcdef abgcdfe abgcedf. abgcefd abgcfde abgcfed abgdcef abgdcfe abgdecf abgdefc abgdfce abgdfec. abgecdf abgecfd abgedcf abgedfc abgefcd abgefdc abgfcde abgfced abgfdce. abgfdec abgfecd abgfedc acbdefg acbdegf acbdfeg acbdfge acbdgef acbdgfe. acbedfg acbedgf acbefdg acbefgd acbegdf acbegfd acbfdeg acbfdge acbfedg. acbfegd acbfgde acbfged acbgdef acbgdfe acbgedf acbgefd acbgfde acbgfed. acdbefg acdbegf acdbfeg acdbfge acdbgef acdbgfe acdebfg acdebgf acdefbg. acdefgb acdegbf acdegfb acdfbeg acdfbge acdfebg acdfegb acdfgbe acdfgeb.
acdgbef acdgbfe acdgebf acdgefb acdgfbe acdgfeb acebdfg acebdgf acebfdg. acebfgd acebgdf acebgfd acedbfg acedbgf acedfbg acedfgb acedgbf acedgfb. acefbdg acefbgd acefdbg acefdgb acefgbd acefgdb acegbdf acegbfd acegdbf. acegdfb acegfbd acegfdb acfbdeg acfbdge acfbedg acfbegd acfbgde acfbged. acfdbeg acfdbge acfdebg acfdegb acfdgbe acfdgeb acfebdg acfebgd acfedbg. acfedgb acfegbd acfegdb acfgbde acfgbed acfgdbe acfgdeb acfgebd acfgedb. acgbdef acgbdfe acgbedf acgbefd acgbfde acgbfed acgdbef acgdbfe acgdebf. acgdefb acgdfbe acgdfeb acgebdf acgebfd acgedbf acgedfb acgefbd acgefdb. acgfbde acgfbed acgfdbe acgfdeb acgfebd acgfedb adbcefg adbcegf adbcfeg.
adbcfge adbcgef adbcgfe adbecfg adbecgf adbefcg adbefgc adbegcf adbegfc. adbfceg adbfcge adbfecg adbfegc adbfgce adbfgec adbgcef adbgcfe adbgecf. adbgefc adbgfce adbgfec adcbefg adcbegf adcbfeg adcbfge adcbgef adcbgfe. adcebfg adcebgf adcefbg adcefgb adcegbf adcegfb adcfbeg adcfbge adcfebg. adcfegb adcfgbe adcfgeb adcgbef adcgbfe adcgebf adcgefb adcgfbe adcgfeb. adebcfg adebcgf adebfcg adebfgc adebgcf adebgfc adecbfg adecbgf adecfbg. adecfgb adecgbf adecgfb adefbcg adefbgc adefcbg adefcgb adefgbc adefgcb. adegbcf adegbfc adegcbf adegcfb adegfbc adegfcb adfbceg adfbcge adfbecg. adfbegc adfbgce adfbgec adfcbeg adfcbge adfcebg adfcegb adfcgbe adfcgeb.
adfebcg adfebgc adfecbg adfecgb adfegbc adfegcb adfgbce adfgbec adfgcbe. adfgceb adfgebc adfgecb adgbcef adgbcfe adgbecf adgbefc adgbfce adgbfec. adgcbef adgcbfe adgcebf adgcefb adgcfbe adgcfeb adgebcf adgebfc adgecbf. adgecfb adgefbc adgefcb adgfbce adgfbec adgfcbe adgfceb adgfebc adgfecb. aebcdfg aebcdgf aebcfdg aebcfgd aebcgdf aebcgfd aebdcfg aebdcgf aebdfcg. aebdfgc aebdgcf aebdgfc aebfcdg aebfcgd aebfdcg aebfdgc aebfgcd aebfgdc. aebgcdf aebgcfd aebgdcf aebgdfc aebgfcd aebgfdc aecbdfg aecbdgf aecbfdg. aecbfgd aecbgdf aecbgfd aecdbfg aecdbgf aecdfbg aecdfgb aecdgbf aecdgfb. aecfbdg aecfbgd aecfdbg aecfdgb aecfgbd aecfgdb aecgbdf aecgbfd aecgdbf.
aecgdfb aecgfbd aecgfdb aedbcfg aedbcgf aedbfcg aedbfgc aedbgcf aedbgfc. aedcbfg aedcbgf aedcfbg aedcfgb aedcgbf aedcgfb aedfbcg aedfbgc aedfcbg. aedfcgb aedfgbc aedfgcb aedgbcf aedgbfc aedgcbf aedgcfb aedgfbc aedgfcb. aefbcdg aefbcgd aefbdcg aefbdgc aefbgcd aefbgdc aefcbdg aefcbgd aefcdbg. aefcdgb aefcgbd aefcgdb aefdbcg aefdbgc aefdcbg aefdcgb aefdgbc aefdgcb. aefgbcd aefgbdc aefgcbd aefgcdb aefgdbc aefgdcb aegbcdf aegbcfd aegbdcf. aegbdfc aegbfcd aegbfdc aegcbdf aegcbfd aegcdbf aegcdfb aegcfbd aegcfdb. aegdbcf aegdbfc aegdcbf aegdcfb aegdfbc aegdfcb aegfbcd aegfbdc aegfcbd. aegfcdb aegfdbc aegfdcb afbcdeg afbcdge afbcedg afbcegd afbcgde afbcged.
afbdceg afbdcge afbdecg afbdegc afbdgce afbdgec afbecdg afbecgd afbedcg. afbedgc afbegcd afbegdc afbgcde afbgced afbgdce afbgdec afbgecd afbgedc. afcbdeg afcbdge afcbedg afcbegd afcbgde afcbged afcdbeg afcdbge afcdebg. afcdegb afcdgbe afcdgeb afcebdg afcebgd afcedbg afcedgb afcegbd afcegdb. afcgbde afcgbed afcgdbe afcgdeb afcgebd afcgedb afdbceg afdbcge afdbecg. afdbegc afdbgce afdbgec afdcbeg afdcbge afdcebg afdcegb afdcgbe afdcgeb. afdebcg afdebgc afdecbg afdecgb afdegbc afdegcb afdgbce afdgbec afdgcbe. afdgceb afdgebc afdgecb afebcdg afebcgd afebdcg afebdgc afebgcd afebgdc. afecbdg afecbgd afecdbg afecdgb afecgbd afecgdb afedbcg afedbgc afedcbg.
afedcgb afedgbc afedgcb afegbcd afegbdc afegcbd afegcdb afegdbc afegdcb. afgbcde afgbced afgbdce afgbdec afgbecd afgbedc afgcbde afgcbed afgcdbe. afgcdeb afgcebd afgcedb afgdbce afgdbec afgdcbe afgdceb afgdebc afgdecb. afgebcd afgebdc afgecbd afgecdb afgedbc afgedcb agbcdef agbcdfe agbcedf. agbcefd agbcfde agbcfed agbdcef agbdcfe agbdecf agbdefc agbdfce agbdfec. agbecdf agbecfd agbedcf agbedfc agbefcd agbefdc agbfcde agbfced agbfdce. agbfdec agbfecd agbfedc agcbdef agcbdfe agcbedf agcbefd agcbfde agcbfed. agcdbef agcdbfe agcdebf agcdefb agcdfbe agcdfeb agcebdf agcebfd agcedbf. agcedfb agcefbd agcefdb agcfbde agcfbed agcfdbe agcfdeb agcfebd agcfedb.
agdbcef agdbcfe agdbecf agdbefc agdbfce agdbfec agdcbef agdcbfe agdcebf. agdcefb agdcfbe agdcfeb agdebcf agdebfc agdecbf agdecfb agdefbc agdefcb. agdfbce agdfbec agdfcbe agdfceb agdfebc agdfecb agebcdf agebcfd agebdcf. agebdfc agebfcd agebfdc agecbdf agecbfd agecdbf agecdfb agecfbd agecfdb. agedbcf agedbfc agedcbf agedcfb agedfbc agedfcb agefbcd agefbdc agefcbd. agefcdb agefdbc agefdcb agfbcde agfbced agfbdce agfbdec agfbecd agfbedc. agfcbde agfcbed agfcdbe agfcdeb agfcebd agfcedb agfdbce agfdbec agfdcbe. agfdceb agfdebc agfdecb agfebcd agfebdc agfecbd agfecdb agfedbc agfedcb. bacdefg bacdegf bacdfeg bacdfge bacdgef bacdgfe bacedfg bacedgf bacefdg.
share|improve this answer
1  
Looks like we both need to find one more save now :) – Jonathan Allan 14 hours ago

JavaScript (ES6), 130 bytes

This essay contains 774 Martian words, from a dictionary of 308 distinct words, made of all Martian letters.

_=>[...Array(2322)].map((_,i)=>['aeimnou','bcdgkpt','fhlrsvz'][i%3][(z=z*71%1e9)%7]+(++i%3?'':i%9?' ':i%27?'. ':`.
`),z=1).join``

Letters are picked in a pseudo-random manner, using the following formula:

(71^n mod 1000000000) mod 7

Where 71 is the smallest value for which no contiguous word repetition appear with this modulo.

let f =

_=>[...Array(2322)].map((_,i)=>['aeimnou','bcdgkpt','fhlrsvz'][i%3][(z=z*71%1e9)%7]+(++i%3?'':i%9?' ':i%27?'. ':`.
`),z=1).join``

console.log(f());

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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