Encuentre dos números en una matriz ordenada cuya suma esté más cerca de un número dado -- algorithm campo con haskell camp codereview Relacionados El problema

Find two numbers in a sorted array whose sum is closest to a given number


4
vote

problema

Español

Dada una matriz ordenada y un número X, encuentre un par en matriz cuya suma esté más cerca de x.

Aquí está mi solución:

  def has_voted(cookie, question_id):     """Checks for question_id in cookie"""     return cookie and          re.match(cookie_pattern, cookie) and          question_id in list(map(int, cookie.split('-')))   class DetailView(generic.DetailView):     model = Question     template_name = 'polls/detail.html'      # ...     def get_context_data(self, **kwargs):         context = super().get_context_data(**kwargs)         # Check duplicate vote cookie         cookie = self.request.COOKIES.get(cookie_name)         if has_voted(cookie, self.object.id):             context['voted'] = True         return context   def vote(request, question_id):     question = get_object_or_404(Question, pk=question_id)     cookie = request.COOKIES.get(cookie_name)     if has_voted(cookie, question.id):         return render(request, 'polls/detail.html', {             'question': question,             'voted': True,         }) 2  

Estoy en su mayoría autodidacta, así que me encantaría saber de qué manera no es mi código de acuerdo con la práctica común. Más específicamente:

  • ¿Cómo puedo alinear más claramente mi def has_voted(cookie, question_id): """Checks for question_id in cookie""" return cookie and re.match(cookie_pattern, cookie) and question_id in list(map(int, cookie.split('-'))) class DetailView(generic.DetailView): model = Question template_name = 'polls/detail.html' # ... def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) # Check duplicate vote cookie cookie = self.request.COOKIES.get(cookie_name) if has_voted(cookie, self.object.id): context['voted'] = True return context def vote(request, question_id): question = get_object_or_404(Question, pk=question_id) cookie = request.COOKIES.get(cookie_name) if has_voted(cookie, question.id): return render(request, 'polls/detail.html', { 'question': question, 'voted': True, }) 3 - def has_voted(cookie, question_id): """Checks for question_id in cookie""" return cookie and re.match(cookie_pattern, cookie) and question_id in list(map(int, cookie.split('-'))) class DetailView(generic.DetailView): model = Question template_name = 'polls/detail.html' # ... def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) # Check duplicate vote cookie cookie = self.request.COOKIES.get(cookie_name) if has_voted(cookie, self.object.id): context['voted'] = True return context def vote(request, question_id): question = get_object_or_404(Question, pk=question_id) cookie = request.COOKIES.get(cookie_name) if has_voted(cookie, question.id): return render(request, 'polls/detail.html', { 'question': question, 'voted': True, }) 4 def has_voted(cookie, question_id): """Checks for question_id in cookie""" return cookie and re.match(cookie_pattern, cookie) and question_id in list(map(int, cookie.split('-'))) class DetailView(generic.DetailView): model = Question template_name = 'polls/detail.html' # ... def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) # Check duplicate vote cookie cookie = self.request.COOKIES.get(cookie_name) if has_voted(cookie, self.object.id): context['voted'] = True return context def vote(request, question_id): question = get_object_or_404(Question, pk=question_id) cookie = request.COOKIES.get(cookie_name) if has_voted(cookie, question.id): return render(request, 'polls/detail.html', { 'question': question, 'voted': True, }) 5 - 99887776655443316 - def has_voted(cookie, question_id): """Checks for question_id in cookie""" return cookie and re.match(cookie_pattern, cookie) and question_id in list(map(int, cookie.split('-'))) class DetailView(generic.DetailView): model = Question template_name = 'polls/detail.html' # ... def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) # Check duplicate vote cookie cookie = self.request.COOKIES.get(cookie_name) if has_voted(cookie, self.object.id): context['voted'] = True return context def vote(request, question_id): question = get_object_or_404(Question, pk=question_id) cookie = request.COOKIES.get(cookie_name) if has_voted(cookie, question.id): return render(request, 'polls/detail.html', { 'question': question, 'voted': True, }) 7 Expresiones?
  • Yo uso una lista intermedia de def has_voted(cookie, question_id): """Checks for question_id in cookie""" return cookie and re.match(cookie_pattern, cookie) and question_id in list(map(int, cookie.split('-'))) class DetailView(generic.DetailView): model = Question template_name = 'polls/detail.html' # ... def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) # Check duplicate vote cookie cookie = self.request.COOKIES.get(cookie_name) if has_voted(cookie, self.object.id): context['voted'] = True return context def vote(request, question_id): question = get_object_or_404(Question, pk=question_id) cookie = request.COOKIES.get(cookie_name) if has_voted(cookie, question.id): return render(request, 'polls/detail.html', { 'question': question, 'voted': True, }) 8 tuples, que no estoy encantado. ¿Hay una forma más elegante de hacer esto, sin sacrificar el rendimiento?
  • Estoy en la cerca sobre def has_voted(cookie, question_id): """Checks for question_id in cookie""" return cookie and re.match(cookie_pattern, cookie) and question_id in list(map(int, cookie.split('-'))) class DetailView(generic.DetailView): model = Question template_name = 'polls/detail.html' # ... def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) # Check duplicate vote cookie cookie = self.request.COOKIES.get(cookie_name) if has_voted(cookie, self.object.id): context['voted'] = True return context def vote(request, question_id): question = get_object_or_404(Question, pk=question_id) cookie = request.COOKIES.get(cookie_name) if has_voted(cookie, question.id): return render(request, 'polls/detail.html', { 'question': question, 'voted': True, }) 9 vs listItem0 . ¿Se considera que esto se considera nitpicking, o las personas tienen una fuerte opinión sobre esto?
  • ¿tendría más sentido cambiar los parámetros de esta función? Tengo la sensación de que listItem1 precede por lo general listItem2 con el estilo de PointFree en mente, pero no estoy seguro de esto.
  • Cualquier otra cosa que no haya pensado :)
Original en ingles

Given a sorted array and a number x, find a pair in array whose sum is closest to x.

Here's my solution:

import Data.List (minimumBy) import Data.Ord (comparing)  closestPairSum :: (Num a, Ord a) => [a] -> a -> (a, a) closestPairSum xs n = snd $ minimumBy (comparing fst) pairs   where      pairs = sums xs (reverse xs)     sums xxs@(x:xs) yys@(y:ys) = let sum = x + y in       if n < sum       then (sum - n, (x, y)) : sums xxs ys       else (n - sum, (x, y)) : sums xs yys     sums _ _ = [] 

I'm mostly self-taught, so I would love to know in which ways my code is not according to common practice. More specifically:

  • How can I more clearly align my let-in and if-then-else expressions?
  • I use an intermediate list of (a, (a, a)) tuples, which I'm not thrilled about. Is there a more elegant way to do this, without sacrificing performance?
  • I'm on the fence about sum xs (reverse xs) vs sum xs $ reverse xs. Is this just considered nitpicking, or do people have a strong opinion about this?
  • Would it make more sense to swap the parameters of this function? I have the feeling that a would usually precede [a] with pointfree style in mind, but I'm not sure about this one.
  • Anything else that I might not have thought of :)
     

Lista de respuestas

2
 
vote
vote
La mejor respuesta
 
  • ¿Cómo puedo alinear más claramente mi let - in1 if - 9988777665544333 - 9988776655544334 Expresiones?

Bueno, eso depende de usted, para ser honesto. Podría poner let ... in en una nueva línea, por ejemplo:

  sums xxs@(x:xs) yys@(y:ys) =    let sum = x + y    in if n < sum      then (sum - n, (x, y)) : sums xxs ys      else (n - sum, (x, y)) : sums xs yys sums _ _ = []   

Por lo general, prefiero guardias:

  sums xxs@(x:xs) yys@(y:ys) =    | n < sum   = (sum - n, (x, y)) : sums xxs ys   | otherwise = (n - sum, (x, y)) : sums xs yys   where sum = x + y  sums _ _ = []   

Dije "generalmente", porque no me gusta el 9988776655544338 al final.

  • Utilizo una lista intermedia de (a, (a, a)) Tuples, con las que no estoy emocionada. ¿Hay una forma más elegante de hacer esto, sin sacrificar el rendimiento?

está bien. in0 A partir de in1 Utiliza básicamente el mismo enfoque:

  in2  

Si algo es lo suficientemente bueno para la biblioteca estándar, debería estar lo suficientemente bien para usted. Tenga en cuenta que el in3 podría ser necesario producir más rendimiento.

  • Estoy en la cerca sobre in4 vs in5 . ¿Se considera que esto se considera nitpicking, o las personas tienen una fuerte opinión sobre esto?

Eso es nitpicking. Algunas personas prefieren in6 , ya que no puede olvidar accidentalmente un 99887766555443317 , otros prefieren paréntesis, ya que son más fáciles de entender para los principiantes. El programa generado se comportará lo mismo.

  • ¿tendría más sentido cambiar los parámetros de esta función? Tengo la sensación de que in8 generalmente precede a in9 con el estilo de PointFree en mente, pero no estoy seguro de esto.

Si esta función será parte de una colección, entonces es más importante que todas sus funciones sigan el mismo estilo. Aparte de eso, se prefiere que use el argumento que cambie rara vez primero, o si está usando un contenedor, el contenedor el último. Entonces, sí, su función sería un candidato perfecto para cambiar.

  • Cualquier otra cosa que no haya pensado :)

si. No utilice los nombres reservados, si es posible. if0 se define en if1 , lo ha usado para enlazar if2 . Tampoco use los mismos nombres dos veces. Has usado if3 Tanto en su if4 , así como en if5 . Esto puede llevar a errores cuando refactores su función.

Aparte de eso: bien hecho. Para comparación, aquí es cómo escribiría su función:

  if6  
 
  • How can I more clearly align my let-in and if-then-else expressions?

Well, that's up to you, to be honest. You could put let ... in into a new line, for example:

sums xxs@(x:xs) yys@(y:ys) =    let sum = x + y    in if n < sum      then (sum - n, (x, y)) : sums xxs ys      else (n - sum, (x, y)) : sums xs yys sums _ _ = [] 

I usually prefer guards:

sums xxs@(x:xs) yys@(y:ys) =    | n < sum   = (sum - n, (x, y)) : sums xxs ys   | otherwise = (n - sum, (x, y)) : sums xs yys   where sum = x + y  sums _ _ = [] 

I said "usually", because I don't like the dangling sums at the end.

  • I use an intermediate list of (a, (a, a)) tuples, which I'm not thrilled about. Is there a more elegant way to do this, without sacrificing performance?

It's fine. sortOn from Data.List basically uses the same approach:

sortOn f = map snd . sortBy (comparing fst) . map (\x -> let y = f x in y `seq` (y, x)) 

If something is fine enough for the standard library, it should be fine enough for you. Note that the seq might be necessary to yield more performance.

  • I'm on the fence about sum xs (reverse xs) vs sum xs $ reverse xs. Is this just considered nitpicking, or do people have a strong opinion about this?

That's nitpicking. Some people prefer ($), since you cannot accidentally forget a ), others prefer parentheses, since they are easier to understand for beginners. The generated program will behave the same.

  • Would it make more sense to swap the parameters of this function? I have the feeling that a would usually precede [a] with pointfree style in mind, but I'm not sure about this one.

If this function will be part of a collection, then it's more important that all your functions follow the same style. Other than that, it's preferred that you use the argument which will change seldom first, or, if it's using a container, the container last. So yes, your function would be a perfect candidate for switching.

  • Anything else that I might not have thought of :)

Yes. Don't use reserved names, if possible. sum is defined in the Prelude, you've used it to bind x + y. Also don't use the same names twice. You've used xs both in your closestPairSum as well as in sums. This can lead to errors when you refactor your function.

Other than that: Well done. For comparison, here is how I would write your function:

import Data.List (minimumBy) import Data.Ord (comparing)  closestPairSum :: (Num a, Ord a) => a -> [a] -> (a, a) closestPairSum n = snd . minimumBy (comparing fst) . pairs   where      pairs xs = sums xs (reverse xs)      sums [] _ = []     sums _ [] = []     sums xxs@(x:xs) yys@(y:ys)       | n < s     = (s - n, (x, y)) : sums xxs ys -- sum greater than n, use lesser y       | otherwise = (n - s, (x, y)) : sums xs yys -- sum lesser than n, use greater x       where         s = x + y 
 
 
     
     
2
 
vote

La "matriz intermedia" no requiere espacio adicional debido a una evaluación perezosa. if7 es if8 . Sí, intercambiando los parámetros tiene sentido. En línea if9 y then0 Una vez más. No me preocuparía tanto por los factores constantes: ¿lo ha compilado con -O2 y probado (por ejemplo, con criterio)?

Importar datos. Lista (Minidad)

  then1  
 

The "intermediate array" takes no extra space due to lazy evaluation. minimumBy . comparing is minimumOn. Yes, swapping the parameters makes sense. Inline then and else once more. I wouldn't worry so much about constant factors - have you compiled it with -O2 and tested (eg with criterion)?

import Data.List (minimumOn)

closestPairSum :: (Num a, Ord a) => a -> [a] -> (a, a) closestPairSum n xs = minimumOn (abs . (n-) . uncurry (+)) pairs where   pairs = sums xs (reverse xs)   sums xxs@(x:xs) yys@(y:ys) = (x, y) : if n < x + y     then sums xxs ys     else sums xs yys   sums _ _ = [] 
 
 
   
   

Relacionados problema

3  Implementación de la división de flujos (donde es una corriente de coeficientes polinomiales)  ( Implementing division of streams where its a stream of polynomial coefficients ) 
por esta tarea , yo ' m Tratando de implementar un Fractional (Stream Integer) donde la corriente representa los coeficientes de polinomios: donde q se ...

2  Palidrome Checker en Haskell  ( Palidrome checker in haskell ) 
Decidí evitar el 9988776655544339 intentado escribir un método con la coincidencia de patrones y la recursión. #include <stdio.h> #include <fcntl.h> #inc...

5  Seguridad, Compartir y Laziness  ( Safety sharing and laziness ) 
¿Hay una manera más sucinta de escribir un código como este que tenga mucho compartir entre las sucursales de la declaración de la caja? (Esta es la parte p...

4  Agregar una entrada duplicada al azar a una lista en Haskell usando Mónad aleatorio  ( Adding a duplicate entry randomly into a list in haskell using random monad ) 
Hay una nueva versión de esto como V2 - Agregar una entrada duplicada al azar a una lista en Haskell usando Monad Random Escribí esto tratando de configur...

4  Decidir si una lista de tipos de sumas es homogénea  ( Deciding whether a list of sum types is homogeneous ) 
Me encontré con un problema recientemente, donde tuve que decidir si un conjunto de tipos de sumas fue homogéneo (todo lo mismo). En sí mismo, este es un prob...

6  Nuevo paquete Haskell: OpenCl  ( New haskell package opencl ) 
Estoy desarrollando una encuadernación de OpenCl de alto nivel en Haskell, y necesito revisión de pares y pruebas. Actualmente solo recibe la plataforma y la ...

4  Simple Haskell Key Value File Store  ( Simple haskell key value file store ) 
Como ejercicio en el aprendizaje de Haskell, implementé una tienda de valores clave simple, donde puede poner y obtener valores (como ByteString s). (Para r...

3  BEFUNMENT-93 intérprete en Haskell  ( Befunge 93 interpreter in haskell ) 
Este es un intérprete que toma en un bEFUNCH-93 más alterado (sin entrada del usuario, sin límites en el tamaño y la división por los valores predeterminados ...

6  Programa Haskell para cambiar el nombre de las imágenes basadas en datos exif  ( Haskell program to rename images based on exif data ) 
movido originalmente de StackOverFlow , sin saber la existencia de este sitio hermano ... Debe decir que encuentro la programación en Haskell para requer...

3  Generador de horario aleatorio  ( Random schedule generator ) 
En un intento de probar algo nuevo, y posiblemente ayudar en el trabajo, intenté crear un generador de programación aleatorio que genera horarios basados ​​en...




© 2022 respuesta.top Reservados todos los derechos. Centro de preguntas y respuestas reservados todos los derechos