Advent of Code 2020

¿Dónde me apunto?

https://adventofcode.com/

Normas

  • Cada día se desbloquea un problema nuevo
  • Programas en el lenguaje que te da la gana
  • Utilizas las técnicas que te da la gana
  • Le dedicas el tiempo que te da la gana
  • Cada problema tiene una caja de texto para meter la solución (suelen ser números o alguna cadena de texto pequeña)

Leaderboard privado para el pique sano

NSFW

Las respuestas se postean en Spoiler + code

Axtrix

#59 que pereza usar fs, yo me lo puse en una variable y a correr

desu

Podriamos explicar la solucion no? Repasando para hacer la parte 2 si que he hecho la solucion optima, filter hace un short circuit.

veo cosas muy raras y es el primer ejercicio xd

(ns aocl.1
  (:gen-class)
  (:require [aocl.core :refer [read-file]]))

(def input (clojure.string/split-lines (read-file "1.txt")))

(defn make-hm [input]
  (zipmap (map #(- 2020 %) input) input))

(defn find-values [input] 
  (let [hm (make-hm input)
        v1 (nth (filter #(contains? hm %) input) 0)
        v2 (get hm v1)]
    (* v1 v2)))

(def part1 (str "part1: " (find-values (map #(Integer/parseInt %) input))))

(defn -main [& args] (run! println [part1]))

part 1

Tienes una lista de elementos e [1 2 3 4 5] y un numero objetivo N

Creas un hasmap poniendo como key N - e y como valor e, para cada e en tu lista de inputs O(N)

Iteras una segunda vez tu lista de inputs y buscas e. O (N)

si la encuentras ya has encontrado N = a + b, tansolo tienes que consultar el hashmap O(1)

coste en tiempo y espacio N.

El one liner en pseudocodigo.

input 
  /> generarHashMap
  => buscarPair
  => devolverMultiplacionDelPair

edit: con la part2, ha sido facil, 1 minuto adaptar el codigo

(ns aocl.1
  (:gen-class)
  (:require [aocl.core :refer [read-file]]))

(def input (clojure.string/split-lines (read-file "1.txt")))

(defn make-hm [input]
  (zipmap (map #(- 2020 %) input) input))

(defn find-values [input] 
  (let [hm (make-hm input)
        v1 (nth (filter #(contains? hm %) input) 0)
        v2 (get hm v1)]
    (* v1 v2)))

(defn make-hm2 [input]
  (zipmap (map #(- 2020 (first %) (second %)) input) input))

(defn find-values2 [input] 
  (let [all-pairs (for [x input y input] (vector x y))
        pairs (filter #(not= (first %) (second %)) all-pairs)
        hm (make-hm2 pairs)
        v1 (nth (filter #(contains? hm %) input) 0)
        v2 (first (get hm v1))
        v3 (second (get hm v1))]
    (* v1 v2 v3)))

(def part1 (str "part1: " (find-values (map #(Integer/parseInt %) input))))
(def part2 (str "part2: " (find-values2 (map #(Integer/parseInt %) input))))

(defn -main [& args] (run! println [part1 part2]))
Leos

Yo hasta la noche no me podré poner, al final creo que lo haré en Rust para no sentir que me rindo con el lenguaje, espero que me salga tan fácil como a todos

NeV3rKilL

Ya hice el primero a lo guarro con 3 fors para no complicarme la vida con accumulates, mientras compute aceptablemente paso de optimizar.

Es muy sencillo y no parece ser de los que se van a encadenar en futuros días.

Me creé ya la típica funcion para leer el input rápido, la metí en un archivo pese a que en el spoiler la meto, por si en otro día se complica la lectura del input no enmerdar.

Python

La parte 1 simplemente es quitar el for del number3.

Axtrix
spoiler
NeV3rKilL

Because of an outage during the day 1 puzzle unlock, day 1 is worth no points.

Puta bida.

Lecherito

#55 En Rust puedes configurar varios ejecutables que puedes ejecutar con cargo run asi que lo puedes tener todo en el mismo proyecto con day1.rs day2.rs

Y si esto no te gusta, puedes tener workspaces, que son basicamente varios proyectos con uno padre que los une: https://doc.rust-lang.org/cargo/reference/workspaces.html#the-workspace-section

Asi te quitas el day1::result() que me da cosa xD

2 respuestas
Unrack

Hoy me apetecía no pensar mucho y he tirado de >itertools.combinations

Bendita librería estándar de python!

1 respuesta
aren-pulid0

Parte 1

spoiler

Explicación

spoiler

Parte 2

spoiler

Explicación

spoiler
bornex

#67 la verdad es que estaba buscando como modularizar el código y al final lo he hecho así, me gusta la idea de tener el código separado por directorios y ponerlos cada dia en un directorio distinto. Voy a mirar lo de los workspaces a ver que tal, acabo de empezar con Rust xD ten paciencia conmigo, aunque ya que estamos te voy a preguntar :P

1 respuesta
Lecherito

#70 Por eso te he dicho lo que se suele hacer, en vez de llamarte retrasado que no sabes lol. Simplemente vi que se puede mejorar

Heysen

Primer ejercicio resuelto con Appian, que es con lo que estoy trabajando ahora

spoiler
ciza

alexilarduya en AoC

A ver cuanto duro, suelo ser mas bien poco constante... Por otra parte, supongo que es como una kata de cualquier web random con la (gran) diferencia de que aqui no tienes máximo de tiempo de ejecución.

1 respuesta
Fyn4r

Actualicé la tabla de #1 , ahora está ordenada por orden alfabético y fui completando los datos que fui viendo por el hilo. Si alguien quiere que le ponga el repo o algo que me cite que igual no me enteré, no me esperaba tal aceptación xD

P.D Yo aún ni lo miré, a ver si esta tarde

#73 tiempo de ejecución no hay, pero recuerdo algún problema del año pasado que como quisieras sacarlo por fuerza bruta ibas a estar ejecutando aún ahora xD

1 respuesta
Jorgvt_ESP

#68 Amén!

desu

#74 si quieres puedes meter mis datos.

a ver cuantos de este hilo llegamos a la mitad, al final no llega nadie xd

sergioRG

Bastante fácil el primero de momento, mi solución en C++ del paleolitico aquí

https://github.com/srgrr/aoc20202/blob/main/1/main.cc

Tiempo O(nlogn), espacio O(n)

Ire actualizando según los vaya sacando

Segundo problema

https://github.com/srgrr/aoc20202/blob/main/1_2/main.cc

O(n2 logn), espacio O(n), se puede hacer en n2 con two pointers si mal no recuerdo, pero que palo xd

Lo mismo pero en n2 (expected) usando hashmaps

https://github.com/srgrr/aoc20202/blob/main/1_2/main_hashing.cc

Mi intención es hacerlos en lo que más me convenga, pero probablemente será java, python, c++, go, bash o algo así.

QuitCat

No tengo muy fresco el tema de las complejidades, pero diría que el acceso mediante diccionario/map es O(1), por lo que se podría tener en O(n) el primer apartado.
En sucio y hecho guarramente en la consola del browser

const f = (a, n) => {
  const m = new Map();
  for(i=0; i<a.length;i++) {
    const v = a[i];
    const r = n-v;
    if(m.has(r)) {
      return v*r;
    }
    m.set(v, true)
  }
  return null;
}

f(array, 2020)

#59 Te habría fallado ese código si hubiera estado el valor 1010 en el array

1 2 respuestas
sergioRG

#78 Yep, realmente lo he hecho así porque empece a hacerlo con un vector y ya me dio palo cambiarlo, pero tienes toda la razón del mundo.

edit: puedes explicar lo del 1010? no se mucho js pero no veo la razón
edit2: porque daría que sí con un mismo número repetido, nvm

1 respuesta
QuitCat

#79 Esta comprobando el mismo nº dos veces

  • [a, b, c]
  • Coge "a" y busca candidatos en [a, b, c], cuando en verdad solo debería buscar en [b, c]

Ejemplo donde obtendría un falso valor:

  • [1010, 3, 5]
    Él obtendría que la suma de 1010 y 1010 cumple los requisitos, pero es incorrecto, puesto que el 1010 solo esta una vez en el array.
1
Traber

No se si es lo más elegante, pero funciona:

Day 1
MartiONE

Done, apuntame fynardo

1 respuesta
Ranthas

Oye cuack, ya tengo esto hecho de la manera más masillera posible, a ver si pongo el GitHub

1 respuesta
Fyn4r

#82 apuntao

#83 no nos cuentes tu vida, cuentanos tus cotas superiores

1 respuesta
Ranthas

#84 A que te rajo

https://github.com/ranthas90/advent-of-code-2020

Apunta eso si te atreves

1
B

#78 ¿Por?

1 respuesta
pineda

venga me uno...

edit no soy capaz de formatearlo bien

package main

import (
	"fmt"
	"io/ioutil"
	"strconv"
	"strings"
)

func main() {
	content, err := ioutil.ReadFile("input.txt")
	checkErr(err)

lines := strings.Split(string(content), "\n")

val := calculateMadafaka(lines, 2020, 1, 0, 0, 1)
fmt.Println(val)
val = calculateMadafaka(lines, 2020, 2, 0, 0, 1)
fmt.Println(val)
}

func calculateMadafaka(lines []string, expectedValue int, stepsLeft int, currentIndex, currentSum int, currentPlus int) int {
	for i:=currentIndex;i<len(lines);i++ {
		firstNum := parseNum(lines[i])
		if stepsLeft > 0 {
			if tmpValue := calculateMadafaka(lines, expectedValue, stepsLeft-1, i, currentSum + firstNum, currentPlus * firstNum); tmpValue != 0 {
				return tmpValue
			}
		} else {
			if currentSum + firstNum == expectedValue {
				return currentPlus * firstNum
			}
		}
	}
	return 0
}

func parseNum(input string) int {
	num, _ := strconv.Atoi(strings.Split(input, "\r")[0])
	return num
}

func checkErr(err error) {
	if err != nil {
		panic(err)
	}
}
mecmec

Estaría guay que algún ducho en matemáticas explicara el tema de las cotas para dividir series de números, porque hacerlo a lo animal con tres bucles creo que está al alcance de cualquiera xD.

1 respuesta
sergioRG

#88 a qué te refieres?

1 respuesta
T

Me uno al reto lo hice con javascript, pero intentare practicar GO.

spoiler

Usuarios habituales

  • Traber
  • sergioRG
  • QuitCat
  • BeheritSp
  • ciza
  • Fyn4r
  • AikonCWD