es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Condiciones en Clojure para construir una cadena y actualizar una variable.

Pensé en probar Clojure, haciendo un rompecabezas que imprime una ruta desde el inicio hasta el objetivo. Mi intento no imprime nada.

Entiendo que he escrito esto de manera procedural, pero no estoy seguro de la mejor manera de pensar en escribir esto de manera funcional. Así que me gustaría entender por qué no imprime nada, cómo hacer que una condición ejecute 2 acciones (es decir, agregar la dirección a la cadena y actualizar la posición. Todos los ejemplos que encontré en línea ejecutan solo 1 acción), así como cómo hacer que esto funcione realmente. Idealmente, cómo hacer que funcione mi enfoque y también cuál sería el enfoque ideal en Clojure.

(defn -main [& args]
  (def x 2)
  (def y 3)
  (def t_x 10)
  (def t_y 15)
  (while true
    (let [m ""]
      (cond
        (> y t_y) (let [m (str m "N")]) (- y 1)
        (< y t_y) (let [m (str m "S")]) (+ y 1)
        (> x t_x) (let [m (str m "W")]) (- x 1)
        (< x t_x) (let [m (str m "E")]) (+ x 1))

      ; Una sola línea que proporciona el movimiento que se debe realizar: N NE E SE S SW W o NW
      (println m)))))

Gracias.

Tags:  , ,

Answer

  1. Avatar for davy.ai

    Hay varios problemas con el código proporcionado:

    1. El bucle while se ejecuta indefinidamente y nunca se detiene. En Clojure, podemos usar la recursión en su lugar.
    2. Las asignaciones let dentro de la instrucción cond no actualizan los valores de x, y o m. Necesitamos usar las formas de asignación def o let para actualizar los valores.
    3. La variable m se redefine en cada asignación let, por lo que los cambios no se mantienen. Podemos definir m fuera de la instrucción cond y actualizarlo dentro de cada asignación let.

    Aquí tienes una versión revisada del código que debería funcionar:

    (defn print-path [x y t-x t-y]
      (let [m ""]
        (cond
          (> y t-y) (do (def m (str m "N")) (print-path x (- y 1) t-x t-y))
          (< y t-y) (do (def m (str m "S")) (print-path x (+ y 1) t-x t-y))
          (> x t-x) (do (def m (str m "W")) (print-path (- x 1) y t-x t-y))
          (< x t-x) (do (def m (str m "E")) (print-path (+ x 1) y t-x t-y))
          :else (println m))))
    
    (print-path 2 3 10 15)
    

    En esta versión, definimos una nueva función print-path que toma cuatro argumentos x, y, t-x y t-y. Dentro de la función, usamos la forma de asignación let para definir la variable m como una cadena vacía. Luego, dentro de la instrucción cond, usamos la forma do para actualizar el valor de m y llamar recursivamente a print-path con valores actualizados de x y y.

    Podemos simplificar aún más la función usando las funciones if y str de Clojure:

    (defn print-path [x y t-x t-y]
      (let [dir (cond
                  (> y t-y) "N"
                  (< y t-y) "S"
                  (> x t-x) "W"
                  (< x t-x) "E"
                  :else "")]
        (if (empty? dir)
          (println "")
          (do (print dir)
              (recur (if (= dir "E") (+ x 1) (if (= dir "W") (- x 1) x))
                     (if (= dir "S") (+ y 1) (if (= dir "N") (- y 1) y))
                     t-x t-y))))))
    
    (print-path 2 3 10 15)
    

    En esta versión, definimos una variable dir utilizando una instrucción cond y actualizamos los valores de x e y en función de la dirección. También comprobamos si dir está vacío para terminar la recursión cuando alcanzamos el objetivo. Usamos la forma recur para llamar a la función con valores actualizados de x e y. La función print se utiliza para imprimir la dirección en la consola.

Comments are closed.