[Question]
  [
## Haplology
Haplology is a linguistic term:
> 
> the omission of one occurrence of a sound or syllable that is repeated within a word, for example probly for probably.
> 
> 
> 
For this challenge, it means specifically, replacing any sequences of two or more letters that are repeated two or more times with just one copy.
For example:
* haplology -> haplogy
* [boobook](https://en.wikipedia.org/wiki/Australian_boobook) -> book
* couscous -> cous
* [ngorongoro](https://en.wikipedia.org/wiki/Ngorongoro_Conservation_Area) -> ngoro
* hehehe -> he
* [whakakakakaka](https://books.google.com.au/books?id=IIShzeI-l2IC&pg=PA212&lpg=PA212&dq=%22whakakakakaka%22&source=bl&ots=iAvoUxdspI&sig=ACfU3U2NmOv8IKilvNty_Efm8HSd5x_2ww&hl=en&sa=X&ved=2ahUKEwjq_5D9k8X3AhUBH7cAHRTjBRUQ6AF6BAgoEAM#v=onepage&q=%22whakakakakaka%22&f=false) -> whaka
* [lerderderg](https://en.wikipedia.org/wiki/Lerderderg_Gorge) -> lerderg
If there are multiple, non-overlapping repeating sequences, they all get replaced:
* cancangogo -> cango
* yadayadablahblah -> yadablah
Only a single round of replacements is performed, taking the longest possible sequences first, then working from left to right:
* mississippi -> missippi
* mymememymemebooboo -> mymemeboo
* aaaabaaaab -> aaaab
This means the returned result can contain repeating sequences:
* babambambadingding -> babambading
It cans also mean the end result is longer that it would be if replacement happened strictly left to right:
* bababababababadoobababababababadoo -> bababababababadoo (not badoobadoo)
Any spaces or hyphens that occur between elements of a repeating section must be stripped out, and otherwise retained:
* [lang lang](https://en.wikipedia.org/wiki/Lang_Lang) -> lang
* [cha-cha-cha](https://en.wikipedia.org/wiki/Cha-cha-cha_(dance)) -> cha
* hi-di-hi-di-hi-di-ho -> hi-di-ho
* tut-tutting -> tutting
* lady gaga -> lady ga
* banana-cocoa agar agar -> bana-coa agar
* [who put the bop in the bop shoo bop shoo bop who put the dip in the dip da dip da dip](https://www.youtube.com/watch?v=lXmsLe8t_gg) -> who put the bop in the bop shoo bop who put the dip in the dip da dip
* [hare krishna hare krishna krishna krishna hare hare hare rama hare rama rama rama hare hare](https://en.wikipedia.org/wiki/Hare_Krishna_(mantra)) -> hare krishna krishna hare hare rama rama hare
### Challenge
Write a function/program/etc which applies haplology, as defined above, to a single input string.
### Inputs and outputs
Each input will match this regex: `^[a-z]([a-z -]?[a-z])*$`
Your output is a lowercase string containing the haplologised input. No extraneous characters.
Standard rules for taking input and output.
### Scoring
Code golf. Standard rules and exclusions apply.
### Updates
#### Additional test cases and clarification
The algorithm (ignoring punctuation) is:
* find the longest chunk of letters that is repeated at least twice, giving precedence to the left-most chunk
* replace those repeated chunks with one chunk
* repeat, until none left
* never allow any any letter to be processed as part of different chunks
* mamapapatatat -> mapatat (there is no duplicated sequence longer than 2 characters, so work left to right: mama, papa, tata)
* babababa -> baba ([baba] x2)
* ratratatat -> ratat ([rat] x2, [at] x2)
#### Questions
> 
> Why does babambambadingding give babambading instead of bambading (from [baba][mbamba][dingding])?
> 
> 
> 
In order of priority, the chunks are [ding], [bam]. The chunk [mba] is the same length as [bam], but [bam] occurs to its left.
> 
> Why doesn't the "hare krishna" test case greedily take the third consecutive hare?
> 
> 
> 
Because the longer [hare rama] takes precedence over the shorter [hare]
  
[Answer]
# [Jelly](https://github.com/DennisMitchell/jelly), ~~45~~ 38 bytes
```
ḷⱮjⱮƤ““ “-”ẎʋƤṖe@€i1ḣ@ȯ
ŒṖÇƑÐḟẈṢṚƲÞṪÇ€
```
[Try it online!](https://tio.run/##y0rNyan8///hju2PNq7LAuJjSx41zAEiBSDWfdQw9@GuvlPdx5Y83Dkt1eFR05pMw4c7FjucWM91dBJQ6HD7sYmHJzzcMf/hro6HOxc93Dnr2KbD8x7uXHW4Haj2/8PdWw5t1TncngUyT9dOAWTczhbNhztnAwX@/8/NLC4GoYKCTK5EGAAA "Jelly – Try It Online")
~~Should be correct [for real this time](https://tio.run/##y0rNyan8///hju2PNq7LAuJjSx41zAEiBSDWfdQw9@GuvlPdx5akOjxqWpNp@HDHYgeuo5Me7px2uP3YxMMTHu6Y/3BXx8Odix7unHVs0@F5D3euOtwOVPn/4e4th7bqHG7PAhmla6cAMmlni@bDnbOBAv//5ybmJhYAYQkIAgA) thanks to Tanner Swett.~~
Should be correct [*for real this time*](https://tio.run/##y0rNyan8///hju2PNq7LAuJjSx41zAEiBSDWfdQw9@GuvlPdx5Y83Dkt1eFR05pMw4c7FjucWM91dBJQ6HD7sYmHJzzcMf/hro6HOxc93Dnr2KbD8x7uXHW4Haj2/8PdWw5t1TncngUyT9dOAWTczhbNhztnAwX@/8/NLC4GoYKCTK5EGAAA).
It's [even less performant now](https://tio.run/##XYxNSsRAEIX3fYraCvbCC8hcpfJDumNMD0kGmd0gAxEEURcu/AWdlYiiKKbHncEg3qJykVgJkpnY1e@r19WPCv0omjYNFe/182PIqhb17JIvsGQ9u6Ll0c9htSB75o/q/Qe9RcXd6PtJfJ3yqMyrk/KYihtaHpC9JXtevZTXZO/LnLMNfbx@vm2Wedjuk9vQrrPzDbIXPGga5ON0EBHGAbQQrkL5J6G09LQc0IhskklWpjkcoTeFAAMUDsZc0jWuQeBB0kHsKQPjSQaZ8sExY9Bxb1NlzNCshz3dh1vr4VoTChMfdhKdqhhh8Pjfu88VEtzFNbdCHxGYdBVomWL8Cw)! Now designed from the ground up to handle spaces and hyphens, but there's got to be a shorter way to do `““ “-”`...
```
ḷⱮjⱮƤ““ “-”ẎʋƤṖe@€i1ḣ@ȯ    Monadic helper link: de-n-plicate an entire string
            ʋƤ             For each prefix of the argument:
 Ɱ                         create a list of, for each element of the argument
              Ṗ            but one,
ḷ                          a copy of the prefix;
    Ƥ                      for each prefix of that list,
  j                        join the copies on
   Ɱ ““ “-”                each of the empty string, a space, and a hyphen;
           Ẏ               flatten the results.
               e@€         Check if the argument is in each of those,
                  i1       get the first index of 1,
                    ḣ@     and return the argument truncated to that length
                      ȯ    or unchanged if it's 1 long and got clobbered.
ŒṖÇƑÐḟẈṢṚƲÞṪÇ€    Main link
ŒṖ                All ways to partition the input.
         ƲÞ       Sort them by
      Ẉ           the lengths
       ṢṚ         sorted descending of
    Ðḟ            the slices which are not
   Ƒ              unchanged by
  Ç               the helper link,
          Ṫ       take the last,
           Ç€     and map the helper over its slices.
```
[Answer]
# [05AB1E](https://github.com/Adriandmen/05AB1E/wiki/Commands), 45 [bytes](https://github.com/Adriandmen/05AB1E/wiki/Codepage)
```
.œεDü2εËyε„ -SNiÛëÜ}}Ë~y€g≠P*}Zi_1šÏJë¯]˜éIªн
```
Very slow, but should work for all test cases including those in the comments.
[Try it online](https://tio.run/##yy9OTMpM/f9f7@jkc1tdDu8xOrf1cHflua2PGuYp6Ab7ZR6efXj14Tm1tYe76yofNa1Jf9S5IECrNioz3vDowsP9XodXH1ofe3rO4ZWeh1Zd2Pv/f0ambkqmLpTMBwA) or [verify some of the smaller test cases](https://tio.run/##jY8xS8NAFMf3forjRmkKOlakgzrooILgoBS9pOEaGnMhd9HeEBEHQToIOlpER63gFHFQhB6dhOBnyBeJeWd7trh493@P97/HPd6PcWJ7boHXgjAWvI5wY2n40shSXNRG11m6ot4WslT1ZJbmp7fI2t7w1I0aqH6SqN6JzM@eaH5xtzWX7Hr786N7dbmuBsPn5mdfPcjh49d7gWs7Cd6MxfT0Cl5mUeQ6AkUuj33BG7iqXo/kAV7thuWz26oj9bGIiCNi4kON8vOr8rNUvWqxh9suXFxF2GasVAdKh8UcAuo2CX3mMyrB@KQlESWUgAkoi5hOuuVGLS2qJ5CgFGVU90h5bJ3AHXqcg8LQA9sllhbUIhZWGUI3jtuko68eYdkWhPOzRkARpLFBdMagPw5pS2wHNyvAPOY1sAZ0BtNA/vJN4Ka4DJLhGZNMUUwIzPb/Wdys/A0). (Some of the test cases are slightly modified in the test suite.)
**Explanation:**
```
.œ             # Get all partitions of the (implicit) input-string
  ε            # Map over each partition-list:
   D           #  Duplicate the partition-list
    ü2         #  Get the overlapping pairs of the strings
      ε        #  Map over each pair:
       Ë       #   Check if both strings in the pair are the same
       y       #   Push the pair again
        ε      #   Map over it:
         „ -S  #    Push pair ["-"," "]
         Ni    #    If the inner map-index is 1 (thus the right item):
           Û   #     Strip the leading "-"/" "
          ë    #    Else (it's 0, thus the left item):
           Ü   #     Strip the trailing "-"/" "
          }    #    Close the if-else statement
        }Ë     #   After the inner-most map: check if both values are the same
             ~ #   Check if either of the two checks is truthy
       y       #   Push the pair yet again
        €g     #   Get the length of each part
          ≠    #   Check for each length that it's NOT 1
           P   #   Take the product to check whether it's truthy for both
            *  #   Check if both checks are truthy
      }        #  Close the inner map
       Z       #  Push the maximum (without popping the list)
        i      #  Pop, and if this is truthy:
         _     #   Invert all booleans in the list
          1š   #   Prepend an additional leading 1
            Ï  #   Only leave the string-parts at the truthy indices
             J #   And join them together to a string
        ë      #  Else:
         ¯     #   Push an empty list instead
  ]            # Close the if-else statement and outer map
   ˜           # Flatten to remove all empty lists
    é          # Sort the strings by length
     Iª        # Append the input in case it's empty
       н       # Pop and leave the first/shortest one
               # (which is output implicitly as result)
```
[Answer]
# [Python 3.8 (pre-release)](https://docs.python.org/3.8/), 196 bytes
```
import re
def f(s,*r):
 for l in range(-len(s),-2):
  for i in range(len(s)-~l):
   if p:=re.match("(\w[\w -]*\w)(-? ?\\1)+$",x:=s[i:i-l]):s=re.sub(x,"{%s}"%len(r),s);r+=p[1],
 return s.format(*r)
```
[Try it online!](https://tio.run/##bVJtb5swEP6eX3GKVtW0uFK3LxNT1B8S8uEIBlsxtmUbpajq/npmk43kWLkXH89zHHcHborSmh8/nb9c1OCsj@DFphUddCyUT76oNtBZDxqUAY@mF4xrYVgoSv49kzOrbuyV5L/1TILqwFU7L14GjEfJtqw@7@sz8MNTfS4Yf4O3un4tnr9ty/dqF/aqUlwfiirkR8LYsPdy@/EQPrcPua4vylD88s87t389lJvUaRy9gfCSekj1WWr34rwykXXsUaLTVtt@eiyKzYKq1mqMnoJHZQwOdrCGwI21SU801Y4hGwFNb72dHYGlyEKgs8TTIoTRwrez9vR9aJL2tqelJ2wxW6NRZiPkoELI6pyi@DSIJLO/zkZoTFczO7qFBA6ztsr02f6jb9KmsmuAjpmGgezolBL5X6MbVLxVnHhaLo6RJ4vrrjS2E/TY46pXk4Qf7dEiJNLPbvWBLLgxQpQCGuvyf/0vDNJaGtwnt2pJzmGLdwedCb2Ak1dBGgRysz5n8uY8DngX3dySst40fLHqBQaKY7xKAi9/AA "Python 3.8 (pre-release) – Try It Online")
## Credits
* Port of [my Java answer](https://codegolf.stackexchange.com/a/247200/16236).
* -8 bytes, thanks to [Blue](https://codegolf.stackexchange.com/users/42855/blue)
* -5 bytes, thanks to [Ivo Merchiers](https://codegolf.stackexchange.com/users/86502/ivo-merchiers)
* -25 bytes, thanks to [Unrelated String](https://codegolf.stackexchange.com/users/85334/unrelated-string)
* -2 bytes, thanks to [Jakque](https://codegolf.stackexchange.com/users/103772/jakque)
[Answer]
# [Java (JDK)](http://jdk.java.net/), 308 bytes
```
s->{var r=new java.util.Stack();for(int l=s.length(),i;l>1;l--)for(i=0;i<=s.length()-l;){var x=s.substring(i,l+i++);var p=java.util.regex.Pattern.compile("(\\w[\\w -]*\\w)(-? ?\\1)+").matcher(x);s=p.matches()&&r.add(p.group(1))?s.replace(x,"%"+r.size()+"$S"):s;}return"".format(s.toLowerCase(),r.toArray());}
```
[Try it online!](https://tio.run/##jVPBbuM2EL3zKwZCs6DWlrC5UusEiwV62hYFckxyoCVaYkyRXJKKrS78FT30UqA/0S/qF/QP0iEtO7Z3gd2Q8zjDN3xDapwn/syLp2b9IntrXIAnjMshSFWuBl0HaXT5tiJfkXc111q4itSKew@/cKnhCwGww1LJGnzgAZdnIxvokaN3wUnd3j8Cd63PUyrAz1OF93t2vl9uYLV48cXNl2fuwC202JzWDbxe07xaGUelDqAWvlRCt6Gj@VxW6ua6UkWRJ3rxrpLvT/hCVXkS3eKmH5Y@laNyrmZyNsurSNnFay0nWrEtf@MhCKfL2vRWKkEz@vCwuUeD4vEtLjktbuH24eE6n2V52fNQd8LRbV75hZ1CT/M3b1zJm4basnVmsPQ6z289VrCK14Ju59lVNnOll78Lijo/3WU589XOiTA4nWUlvgelqC@D@WQ2wn3kHhPnDuMPzvGR5nm1e6nSVw1uBBrf4mEB8etNvaJ3ow@iL6XODw0A2HT4JkDhjvtfxTbQEw4gqgThAwr5UiP9SWqsW3qrZKAZy/LqLFdqO8TkeOb@3eM5KbZW1EE0B/76gnfCDyqeXpXcWjXSpHZRoTbOoQpmHeRK8XngytP98ZP06blmCKXFRocVza48XHmGdqWz@VHrFrJ///ojAwbZf3//@Q8yqfIcLiR35IA7snvpuFVGmXZkyWtHsjQG55pFILUZfDQWgejWOJOAJSSdiIN1gmw6vj4OliKihGvSbNnebQn2EGdrWsPSSkbe8GhLxbto7BCQXnofp7WS9ZND@rEXOBLuL8qOAeH4t0zAEpIlhn2aDf6LRGPTVvQT/ToalLvcYF/tEIXXhggsAqk7XkzG0Egni0YWZ2jYwSFhCAVaiDeZVhRsRmh5y9nk4b00jqI2teGAhEvAlvvN/RZ@cAPxZxo6AUtjsdlH13fGnDunyY08Jke34ScL@xHV74qRjjsBayd9pzmcBZdrIl/B8Z6feK9wTGHflLtQOB6J3YLULkj9gpbwsB8swv8 "Java (JDK) – Try It Online")
## Explanation
This algorithm takes all substrings that exist, from longest, to smallest and checks if that one is a repetition with spaces or dashes. If it is, it takes the repeated value and stores it in a list (the `Stack` in the code) and replaces that long substring to something with special characters (`%1$S` with 1 being any number, actually) so that it's not matched anymore later on.
After all repetitions are found, the string, taken as lowercase, is actually a formattable that can be properly formatted to wrap up the replacements with `String.format`.
## Credits
* -3 bytes thanks to [Kevin Cruijssen](https://codegolf.stackexchange.com/users/52210/kevin-cruijssen).
* -3 bytes by backporting [Jakque](https://codegolf.stackexchange.com/users/103772/jakque)'s regex suggestion from my Python answer.
[Answer]
# Python3, 283 bytes:
```
R,L=range,len
def f(s):
 m=[]
 for x in R(L(s)):
  for y in R(x+2,L(s)):
   S=s;T=s[x:y];K=0;X=x
   while S[(F:=(X+(X<L(S)and S[X]in[' ','-']))):][:L(T)]==T:K+=1;X=F+L(T)
   if K>1:m+=[[s[:x],T,len(T*K),s[X:]]]
 return s if[]==m else f((M:=max(m,key=lambda x:x[2]))[0])+M[1]+f(M[-1])
```
[Try it online!](https://tio.run/##bZPNjpswEIDveYq5YQpIm@2lInWPe0ly2XCIZPngBANWwEY20cLTp2O2JWta5gfzzWjsGaCfhsbo7z96@3i8pwdqha5l2kq9KWUFFXFxvoGOMr6BylgYQWl4JwfkPjCz6ZONyWu6cDhRtyuoY2M@8d2evuzOdPT8o1GthBMjbzkl54Scfx7IKRa6RHbmSrMIojTKIh5jIc7yAyliTmmR7xO6xSJviSe@kqpg/2ubdwllzLF85Gnhz02Kb/s4deycc46HtnK4Ww0O0xnW6UC2TmJf5JjTToykS29yoq3oLqWAMR/ZK@7MXnicHNmWJxU5smzL40dvlR5IRaJG9K1pTT1FcbxZqCpNKwYbwosxqLeAXc3deQugro01swtwI70E6KMRt0WCSCttOWsd7ic0am3qsPQkSuHt0orGWxDslHNe@16FfOokyuw/ewvCAq/L7MIpIOxmLZWuvf0TfkqJZdcgbBObAe/CLhuR/bFwgiorVRb4sNxwHzK0YX2qVpQT1KIWq7NqlOxqrkYABu3sVi/IQH8fYGgkXEzvf42/S9cYEy6@JpdqSfZL/Bqft7AnYSXcrHKNFhA8rO9z8Oms6MSX1dMtKetJw39GvWAIeYeVepTBC0YevwE)
A no-import solution in Python.
]