Advent of Code 2019 (24 ejercicios de programación por adviento!)

eZpit

#30 Si entiendo bien estás almacenando los puntos finales de cada movimiento y buscando matches. El problema es que las intersecciones pueden ser en "mitad" de esas rectas. Por ejemplo una linea va de (0,0)->(2,0) y otra va de (1,-1)->(1,1) se van a cruzar en (1,0).

1 respuesta
Unrack

#31 Ups, es cierto.

Ranthas

#18 https://github.com/ranthas90/advent-of-code/commit/7aaece7f5068b1e96a01d9523ddb5f6b684bea28

1 respuesta
desu

Detecto gente que no ha sacado le boli y papel :face_with_monocle:

Alguien ha hecho el 3 usando las áreas de los vectores? O algo guapo? Yo me pondré ahora y no sé si haré la matriz de posiciones visitadas o resolver las ecuaciones de intersección de todos los vectores xd

2 respuestas
Unrack

#34

spoiler
eZpit

El 8 está gracioso hay que decodear una imagen y leer el mensaje en ella. Mi advanced rendering engine 😂:

rows
    .map { $0.map { $0 == 0 ? "◼️" : "◽️" }.joined() }
    .joined(separator: "\n")

#34 ¿Aún vas por el 2 dices? No me trollees por aquí anda... Es una buen thread para criticas constructivas, explicando ineficiencias, que se puede mejorar, etc !

1 respuesta
desu

#36 Estoy haciendo el 3 ahora mismo, empecé ayer.

NSFW
CarlosML27

No he empezado aún así que igual no lo he pillado bien, pero para el 3 no sería más fácil

spoiler
Lecherito

#33 He probado a copiar tu solution para mostrarte el bytecode. El problema no es el mapToLong xD, el problema es que estas devolviendo el objeto Long en vez del primitivo long

  // access flags 0x100A
  private static synthetic lambda$main$0(Ljava/lang/String;)J
   L0
    LINENUMBER 20 L0
    ALOAD 0
    INVOKESTATIC java/lang/Long.parseLong (Ljava/lang/String;)J
    INVOKESTATIC org/iota/jota/DayOne.calculateFuelRequirement (J)Ljava/lang/Long;
    INVOKEVIRTUAL java/lang/Long.longValue ()J <-------------
    LRETURN
   L1
    LOCALVARIABLE stringValue Ljava/lang/String; L0 L1 0
    MAXSTACK = 2
    MAXLOCALS = 1

Mira el bytecode de tu funcion. Ese longValue no deberia estar nunca.

Y luego tienes el contrario:

  // access flags 0xA
  private static calculateFuelRequirement(J)Ljava/lang/Long;
   L0
    LINENUMBER 32 L0
    LLOAD 0
    LDC 3
    LDIV
    LDC 2
    LSUB
    INVOKESTATIC java/lang/Long.valueOf (J)Ljava/lang/Long; <-------
    ARETURN
   L1
    LOCALVARIABLE mass J L0 L1 0
    MAXSTACK = 4
    MAXLOCALS = 2

Ese longValue tampoco deberia estar (public static Long valueOf(long l)), esto no seria demasiado problema si los numeros estuvieran comprendidos entre -128 y 127 ya que esos estan cacheados y siempre devuelve el mismo (explicacion con mas detalle) pero como no es asi, estaras creando otro objeto para nada.

Ademas, si te fijas, el bytecode ya te esta diciendo que las funciones (calculate y la lambda) estan devolviendo cosas distintas

private static calculateFuelRequirement(J)Ljava/lang/Long; y
private static synthetic lambda$main$0(Ljava/lang/String;)J

Y por si nunca has visto bytecode, J es el typo long primitivo.

Si simplemente cambias el retorno de Long a long, la magia pasa, ya no existe el Long.valueOf de calculateFuelRequirement

  // access flags 0xA
  private static calculateFuelRequirement(J)J
   L0
    LINENUMBER 31 L0
    LLOAD 0
    LDC 3
    LDIV
    LDC 2
    LSUB
    LRETURN
   L1
    LOCALVARIABLE mass J L0 L1 0
    MAXSTACK = 4
    MAXLOCALS = 2

Y tampoco el longValue del lambda

  // access flags 0x100A
  private static synthetic lambda$main$0(Ljava/lang/String;)J
   L0
    LINENUMBER 20 L0
    ALOAD 0
    INVOKESTATIC java/lang/Long.parseLong (Ljava/lang/String;)J
    INVOKESTATIC org/iota/jota/DayOne.calculateFuelRequirement (J)J
    LRETURN
   L1
    LOCALVARIABLE stringValue Ljava/lang/String; L0 L1 0
    MAXSTACK = 2
    MAXLOCALS = 1

Yo te lo digo para que siempre tengas en cuenta los autoboxing que te pueden comer MUCHO garbage collection (young) y que ya me ha pasado a lo largo de mi carrera profesional, literalmente un aumento te la latencia de la API de un 30% solamente por la cantidad de autoboxings que se hacia y el trabajo que tenia el GC.

6 1 respuesta
Ranthas

#39 Creía que lo decías por el método redundante.

Si bien si sabía como funciona el autoboxing, y que muchas veces te lo tienes que comer sí o sí ya que hay tropecientas interfaces/librerías que no trabajan con primitivos, no sabía que llegaba a impactar de sea manera tan negativa en el rendimiento

1 respuesta
desu

No sé si re pensar el problema o solucinarlo como lo estoy haciendo xd Voy a morir.
Mi idea para resolver el problema:

NSFW

Lecherito

#40 Pero aqui no hay librerias que valgan, ademas si una libreria no acepta el primitivo, no la uses. Menuda basura tiene que ser xddd

1 2 respuestas
Ranthas

#42 Aquí es mala costumbre y ya, como has podido ver xDDDDDD

B

#1 Dentro! Soy #800060. A ver qué tal voy de tiempo para hacerlos.

Fyn4r

Me acabo de dar cuenta de que mi GitHub no está enlazado en la web, a ver si luego lo activo para que #42 me haga caso

1 respuesta
B

#13 Puedes explicar que es lo que haces cuando pones:

[int(i) for i in mass]

No acabo de pillarlo y no sé muy bien como buscarlo en google.

2 respuestas
Unrack

#46 Parseando string a int para todos los elementos de la lista (list comprehension)

1 2 respuestas
B

#47 Estoy aprendiendo un montón mirando tus soluciones, las tuyas en concreto porque lo haces en Python como yo, gracias.

HeXaN

#46 Comprensión de listas. En Python es más rápido que usar bucles o "mapreduce".

1 1 respuesta
B

#47 #49 Muy interesante el uso la funcion sum() con map() para no recorrer la lista con un for o lo que sea. A ver si soy capaz de usarlo para mis ejercicios, pero claro, la mente me lleva a recorrer la lista de la forma "normal" al no comprender cuando es mejor uno u otro.

2 respuestas
Unrack

#50 Eso tiene más que ver con los generadores. Se pueden generar de varias formas, funciones que retornen 'yield', etc. Úsalos cuando no necesites conocer la lista sino algún resultado de ésta (suma en este caso).

De cualquier forma, leete algún artículo o web que hable de soluciones pythonicas. Acabarás acostumbrándote.

CarlosML27

#50 Aun así con numpy se hace incluso más fácil y rápido (especialmente si sabes vectorizar las operaciones), mira la solución que puse en #24

wolfie6949

Joder, pues es un vicio. Igual me planteo retomar Project Euler.

B

To do this, before running the program, replace position 1 with the value 12 and replace position 2 with the value 2. What value is left at position 0 after the program halts?

¿Te dan un input para que cambies tú la posición 1 y 2? ¿Esto es una gilipollez o mi inglés me está jugando una mala pasada?

1 respuesta
desu

Kotlin

1:

NSFW

2:

NSFW
Lecherito

#45 Por que te tengo que hacer caso?

CarlosML27

#54 Es que luego en el segundo tienes que jugar con esos dos cambios y averiguar qué cambios dan un resultado concreto

1 respuesta
B

#57 El 2º no entiendo ni lo que me está pidiendo. Yo creo que me bajo por aquí del reto xD

1 respuesta
GuaNaGe

Voy a apuntarme a un curso de inglés. El nivel BACH da mucha mugre

B
#25eZpit:

¿Como estructuras el proyecto?

Los separo por carpetas, porque tengo un problema con Golang (el lenguaje con el que estoy haciendo el IntcodeComputer), y es que no me permite tener una función main() por cada archivo por separado, y obligatoriamente debo tener un main package en el mismo nivel/carpeta (no puedo separar los packages por day2-day5-day7 para tener diferentes main()). La ventaja es que consigo compilar y correr cada día por separado. La desventaja es que si llega un día X y tengo que usar otra vez el código, hay que copiarlo a otro archivo y modificarlo sólo para ese día.

Ya hice refactor del día 7 y aquí está el programa completo, tratando de tener todo muy ordenado y explicado:

NSFW