Python implementation of the generated self description script share of very interesting programs

  • 2020-04-02 13:53:25
  • OfStack

A self-describing statement is a statement whose content is a description of itself. (nonsense...) Take the following sentence:


This is a self-describing statement that contains all except punctuation 125 , in which 33 Each "each", 29 A" 2 ", 5 A" 3 ", 3 A "fu", 3 A" 5 ", 2 A one, 2 "It", 2 A "bag", 2 "Of", 2 "Mark", 2 That's it. 2 "I", 2 "Outside", 2 A "contain", 2 "In", 2 A "yes", 2 A" 1 ", 2 "Segment", 2 "Dot", 2 A description, 2 A" 9 ", 2 A word, 2 "This", 2 A sentence, 2 Divide by, 2 A "self", 2 "Language", 2 A "communist party", 2 A statement, 2 A number, 2 "It".

This sentence is generated by a Python script, and the principle is as follows:

1. Give a template to let the content of the sentence know where to appear;
2. Generate sentences according to the current information;
3. Take the current sentence as input and repeat the operation of step 2.
Until the information in each part of the sentence is correct.

In short, it is a process of continuous iteration and correction.

Among them, it should be noted that only one change should be made in each iteration, so as to avoid the dead loop caused by two simultaneous changes affecting each other. In addition, if there are several places in the sentence that need to be fixed, try to choose one at random to correct, rather than in a certain order, again to reduce the risk of falling into a dead loop.

Even so, it's possible to get stuck in a loop in certain situations, such as if one step leads to the following sentence:


This sentence is very 2 It contains 3 A" 2 ".

This is obviously wrong, because there are only two "2's". So, if we change that "3" to "2", is that right? It is easy to see that if we make such a change, the sentence will become:


This sentence is very 2 It contains 2 A" 2 ".

At this point, the sentence contains three more twos. It seems impossible to simply change a sentence like this to a correct self-description, because changing it anyway can lead to an endless loop.

Finally, the Python script I used to generate the top self-describing statement is as follows:


# -*- coding: utf-8 -*-

import random

class SelfDesc(object):

  ignore_chars = u" . "" "

  def __init__(self, template):

    self.template = template
    self.length = 0
    self.detail = ""
    self.content = ""
    self.chars = ""
    self.char_count = {}
    self.makeContent()
    self.char_count = self.getCharCount()
    self.getCharCount()
    self.makeContent()


  def __str__(self):

    return self.content


  def makeContent(self):

    self.makeDetail()
    self.content = self.template.replace(u"{length}", u"%d" % self.length)
      .replace(u"{detail}", self.detail)
    self.getChars()


  def getChars(self):

    chars = self.content
    for c in self.ignore_chars:
      chars = chars.replace(c, "")

    self.chars = chars
    return chars


  def getLength(self):

    self.length = len(self.chars)


  def getCharCount(self):

    d = {}
    for c in self.chars:
      if c in self.ignore_chars:
        continue
      d.setdefault(c, 0)
      d[c] += 1

    return d


  def makeDetail(self):

    d = self.char_count
    items = d.items()
    items.sort(key=lambda x: -x[1])

    s = []
    for c, n in items:
      s.append(u"%d A" %s " " % (n, c))

    self.detail = u" . ".join(s)


  def correct(self):

    print "-" * 50

    char_count = self.getCharCount()
    items = char_count.items()
    random.shuffle(items)
    for c, n in items:
      if n <= 1 and c in self.char_count:
        del self.char_count[c]
        continue

      if self.char_count.get(c) == n:
        continue
      else:
        self.char_count[c] = n
        return True

    else:
      len = self.length
      self.getLength()

      if len != self.length:
        return True

    return False


  def generate(self):

    icount = 0
    while self.correct():
      icount += 1
      self.makeContent()
      print u"#%d %s" % (icount, self)


def main():

  template = u" This is a self-describing statement that contains all except punctuation {length} , in which {detail} . "
  sd = SelfDesc(template)
  sd.generate()
  print u"%s" % sd


if __name__ == "__main__":
  main()


Related articles: