[PYTHON] Trier les colonnes FizzBuzz aléatoires avec un tri rapide

introduction

J'ai appris le tri rapide la dernière fois. La question était de savoir quoi faire, car il existe de nombreuses comparaisons grandes et petites. http://qiita.com/cof/items/7b94aac6794d12ae020f

Solution

  1. Créez une classe qui associe FizzBuzz à une valeur numérique et surchargez l'opérateur de cette classe.
  2. Remplacez les éléments de la colonne aléatoire par une instance de la classe ci-dessus.
  3. Triez rapidement les colonnes aléatoires remplacées.

Il est plus rapide de le numériser complètement une fois, de le trier rapidement et de le remplacer par FizzBuzz plus tard, mais comme pratique de surcharge d'opérateurs, j'ai créé une classe qui associe FizzBuzz à des nombres. référence: http://docs.python.jp/2/reference/datamodel.html#customization

Surcharge de l'opérateur

Un code qui effectue une opération sur la valeur associée à une chaîne de caractères, etc. (clé), et renvoie la chaîne de caractères, etc. correspondant à la clé résultante.

def fizzbuzz(n):
  if (n%15) == 0: return 'FizzBuzz'
  elif (n%5) == 0: return 'Buzz'
  elif (n%3) == 0: return 'Fizz'
  else: return n

class FizzBuzzNumber:
  def __init__(self, value):
    self.key = fizzbuzz(value)
    self.value = value

  def __call__(self):
    return self.key

  def __add__(self, other) :
    return fizzbuzz(self.value + other.value)

  def __sub__(self, other):
    return fizzbuzz(self.value - other.value)

  def __mul__(self, other):
    return fizzbuzz(self.value * other.value)

  def __div__(self, other):
    return fizzbuzz(self.value // other.value)

  def __mod__(self, other):
    return fizzbuzz(self.value % other.value)

  def __pow__(self, other):
    return fizzbuzz(self.value ** other.value)

  def __cmp__(self, other):
    return cmp(self.value, other.value)

  def __lt__(self, other):
    return cmp(self.value, other.value) == -1

  def __le__(self, other):
    return cmp(self.value, other.value) in (-1, 0)

  def __eq__(self, other):
    return cmp(self.value, other.value) == 0

  def __ne__(self, other):
    return cmp(self.value, other.value) != 0

  def __gt__(self, other):
    return cmp(self.value, other.value) == 1

  def __ge__(self, other):
    return cmp(self.value, other.value) in (1, 0)

  def __iadd__(self, other) :
    self.value += other.value
    self.key = fizzbuzz(self.value)
    return self

  def __isub__(self, other) :
    self.value -= other.value
    self.key = fizzbuzz(self.value)
    return self

  def __imul__(self, other) :
    self.value *= other.value
    self.key = fizzbuzz(self.value)
    return self

  def __imod__(self, other) :
    self.value %= other.value
    self.key = fizzbuzz(self.value)
    return self

  def __idiv__(self, other) :
    self.value /= other.value
    self.key = fizzbuzz(self.value)
    return self

  def __ipow__(self, other) :
    self.value **= other.value
    self.key = fizzbuzz(self.value)
    return self

Lorsque vous exécutez le code ci-dessous

fizz = FizzBuzzNumber(3)
buzz = FizzBuzzNumber(5)
print 'fizz + buzz = ', fizz + buzz
print 'fizz - buzz = ', fizz - buzz
print 'fizz * buzz = ',  fizz * buzz
print 'fizz / buzz = ', fizz / buzz
print 'fizz % buzz = ', fizz % buzz
print 'fizz ** buzz = ', fizz ** buzz
print 'fizz > buzz: ', fizz > buzz
print 'fizz < buzz: ', fizz < buzz
print 'fizz == buzz: ', fizz == buzz
print 'fizz != buzz: ', fizz != buzz
print 'fizz <= buzz: ', fizz <= buzz
print 'fizz >= buzz: ', fizz >= buzz
print 'fizz():', fizz()
fizz += buzz
print 'fizz += buzz => fizz() = ' , fizz()
fizz -= buzz
print 'fizz -= buzz => fizz() = ' , fizz()
fizz *= buzz
print 'fizz *= buzz => fizz() = ' , fizz()
fizz /= buzz
print 'fizz /= buzz => fizz() = ' , fizz()
fizz %= buzz
print 'fizz %= buzz => fizz() = ', fizz()
fizz **= buzz
print 'fizz **= buzz => fizz() = ', fizz()

Le résultat suivant est sorti.

fizz + buzz =  8
fizz - buzz =  -2
fizz * buzz =  FizzBuzz
fizz / buzz =  FizzBuzz
fizz % buzz =  Fizz
fizz ** buzz =  Fizz
fizz > buzz =  False
fizz < buzz =  True
fizz == buzz:  False
fizz != buzz:  True
fizz <= buzz:  True
fizz >= buzz:  False
fizz(): Fizz
fizz += buzz => fizz() =  8
fizz -= buzz => fizz() =  Fizz
fizz *= buzz => fizz() =  FizzBuzz
fizz /= buzz => fizz() =  Fizz
fizz %= buzz => fizz() =  Fizz
fizz **= buzz => fizz() =  Fizz

Fonction à quantifier

Après cela, j'ai créé une classe pour quantifier FizzBuzz qui apparaissait dans une colonne aléatoire.

class FizzBuzzCounter:
  def __init__(self, f_start, b_start, fb_start):
    self.f = f_start
    self.b = b_start
    self.fb = fb_start

  def get_value(self, s):
    if s == 'FizzBuzz': 
      return self.fb
    elif s == 'Buzz': 
      return self.b
    elif s == 'Fizz': 
      return self.f
    else: 
      return s

  def next(self, s):
    if s == 'FizzBuzz': 
      self.fb += 15
    elif s == 'Buzz': 
      if (self.b % 15) == 10:
         self.b += 10
      else:
         self.b += 5
    elif s == 'Fizz': 
      if (self.f % 15) == 12:
         self.f += 6
      else:
         self.f += 3
    else: 
      pass

Fonction pour remplacer la colonne FizzBuzz

En utilisant les deux classes ci-dessus, j'ai créé une fonction qui crée une colonne en remplaçant les éléments de la colonne FizzBuzz donnée par une instance de la classe FizzBuzzNumber.

def recreate_fizzbuzz_seq(seq):
  counter = FizzBuzzCounter(3,5,15)
  ret = []
  for e in seq:
   ret.append(FizzBuzzNumber(counter.get_value(e)))
   counter.next(e)
  return ret

Après cela, donnez simplement la nouvelle colonne ci-dessus à la fonction de tri rapide créée la dernière fois.

Fonction de tri rapide créée la dernière fois

def pivot(target, i, j):
  k = i + 1
  while k <= j and target[i] == target[k]: k += 1
  if k > j: return -1
  if target[i] >= target[k]: 
    return i
  else:
    return k

def partition(target, i, j, x):
  l, r = i, j
  while l <= r:
    while l <= j and target[l] < x: l += 1
    while r >= i and target[r] >= x: r -= 1
    if l > r: break
    target[l], target[r] = target[r], target[l]
    l, r = l + 1, r - 1
  return l

def quick_sort(target,i ,j):
  if i == j: return 
  p = pivot(target, i, j)
  if p != -1:
    k = partition(target, i, j, target[p])
    quick_sort(target, i, k-1)
    quick_sort(target, k, j)

Une fonction qui crée une colonne FizzBuzz aléatoire

def make_random_fizzbuzz(start=1,finish=100):
  seq = range(start,finish+1)
  random_fizzbuzz = []
  while seq:
    random_fizzbuzz.append(fizzbuzz(seq.pop(random.randint(0,len(seq)-1))))
  return random_fizzbuzz

Fonction principale

Une fonction qui donne la colonne FizzBuzz donnée à recréer_fizzbuzz_seq () pour créer une nouvelle colonne et donner à la nouvelle colonne un tri rapide

def fizzbuzz_sort(target):
  newtarget = recreate_fizzbuzz_seq(target)
  quick_sort(newtarget,0,len(newtarget)-1)
  return newtarget

Commencez comme suit.

fizzbuzz_sort(make_random_fizzbuzz())

Impressions

Je fais une chose tellement stupide. De plus, je pense qu'il aurait été préférable que la nouvelle instance de FizzBuzzNumber renvoie __add__ () etc.

Recommended Posts

Trier les colonnes FizzBuzz aléatoires avec un tri rapide
Apprenez le tri rapide pour trier les colonnes FizzBuzz aléatoires
Trier les noms avec le module aléatoire de Python
J'ai essayé de trier une colonne FizzBuzz aléatoire avec un tri à bulles.
FizzBuzz en Python3
Tri rapide sans utiliser le tri
Fizzbuzz avec gestion des exceptions
Trier de gros fichiers avec python
Tri à bulles avec animation moelleuse