#207 Usar expressiones if let some y maps es mas idiomático que tener unwraps.
Considera que puedes deconstruir de manera similar casi de todo en Rust, tanto parámetros como resultados de expresiones.
Cuando tengas algo verboso, considera la deconstruccion o pattern matching.
Tambien puedes definer la signature de la funcion con un Result<()> y usar la sintaxis de ? para el panic y ahorrarte los expect.
5cts.
A ver si tengo un rato, hoy estoy mas liado xd. Mi idea para sacarlo:
spoilerTengo una lista con las filas/rows [(. . # # . . . . . . .) (# . . . # . . . # . .) (. # . . . . # . . # .) (. . # . # . . . # . #) (. # . . . # # . . # .) (. . # . # # . . . . .) (. # . # . # . . . . #) (. # . .
. . . . . . #) (# . # # . . . # . . .) (# . . . # # . . . . #) (. # . . # . . . # . #)]]
La voy a itrar recursivamente con un take while, empezando por la 0, 1, 2, .. hasta R para en numero de rows. Cuando termino vuelta a empezar... quiero un buffer/circular.
Y me voy a guardar el pointer (x, y) de donde estoy en el tobogan y como estado incremetnare el numero de arboles que me encuentro.
Voy a ir recursivamente saltando de rows y moviendo mi puntero hasta llegar a que mi puntero este en la Y = R. Ultima fila.
Nota: diria que como estoy en un lenguaje funcional + lazy puedo hacer esto en un iterador utilizando un generador. los que haceis python tambien podeis en teoria. seria algo asi.
El generador me devuelve filas incrementalmente, cuando llega a R empieza a devolver por 0 circularmente.
mi pseudo code seria
x, y = 0, 0
result = 0
while r in getRow(y):
newx, newy = x+3, y+1
result += newx in r is tree
x, y = newx, newy
y getRow que sea el generador que te da como yield la fila de debajo, porque siempre haces +1, de esta manera solo tienes que mirar si tu X+3 es un arbol
De esta manera gasto el minimo de memoria posible y diria que es la solucion mas eficiente.
edit: primera y segundo, muy rapido hoy no? luego lo refactorizo quizas.
spoiler(ns aocl.3
(:gen-class)
(:require [aocl.core :refer [read-file]])
(:require [clojure.string :as str]))
(def input (str/split-lines (read-file "3.txt")))
(defn to-seq [string]
(seq (char-array string)))
(defn get-row [pattern max-y slope-y current-y]
(if (>= current-y max-y) nil (get pattern (+ slope-y current-y))))
(defn count-trees [input slope-x slope-y]
(let [
pattern (vec (map to-seq input))
max-x (count (get pattern 0))
max-y (dec (count pattern))]
(loop [current-x slope-x current-y 0 r 0]
(let [row (get-row pattern max-y slope-y current-y)
end? (nil? row)
x (mod current-x max-x)]
(if end?
r
(recur
(+ slope-x current-x)
(+ slope-y current-y)
(+ r (if (= \# (nth row x)) 1 0))))))))
(defn solve2 [input]
(*
(count-trees input 1 1)
(count-trees input 3 1)
(count-trees input 5 1)
(count-trees input 7 1)
(count-trees input 1 2)))
(def part1 (str "part1: " (count-trees input 3 1) ))
(def part2 (str "part2: " (solve2 input)))
(defn -main [& args] (run! println [part1 part2]))