Random IRC quote :      <coder> de cuello para arriba no son cuernos

El programador en los tiempos del kilobyte

Hoy he empezado a leer el libro Coders at Work, que por cierto recomiendo a los que les guste cotillear en la vida de los programadores famosetes. A unos les va Salsa Rosa y otros leemos estos libros, cosas de ser un friki. El libro es una colección de entrevistas a programadores más o menos conocidos, uno de ellos es Jamie Zawinsky, un tío al que yo no conocía de nada, pero que por lo visto viene del mundo de Lisp, curró en el desarrollo de Netscape, y [salsa rosa=on] tuvo algún que otro rifirrafe con Stallman.[salsa rosa=off]

La cosa es que Zawinsky dice una cosa en la entrevista que me dejó pensando: «eingh… ¿cómo es eso?» No les voy a decir qué fué lo que dijo Zawinsky porque prefiero que lleguéis vosotros mismos a la respuesta. Así que lo dejo en plan concurso. Ahí va…

Imaginemos la típica lista doblemente enlazada, donde cada elemento tiene un puntero al elemento anterior y al siguiente, llamémosles «previous» y «next», y tenemos además los punteros «head» y «tail» que apuntan el primero y al último elemento respectivamente. Suponiendo que siempre recorreremos la lista partiendo de «head» o de «tail», o sea, nunca necesitaremos recorrer la lista empezando por un elemento intermedio. ¿Qué podemos hacer para eliminar uno de los punteros «previous» o «next» de la estructura, pero conservando la posibilidad de recorrer la lista en las dos direcciones?.

En estos tiempos de gigabytes ya no hace falta hacer guarradas para ahorrarnos unos bytes, pero el truco no deja ser curioso.

Al ganador un ejemplar gratuito (en PDF 😛 ) de Coders at Work

8 Comentarios para “El programador en los tiempos del kilobyte”

  1. Comment por Charly | 10/31/09 at 2:20 pm

    Hola, interesate…
    No el acertijo sino la faceta de «marujona coder»… jaja

    No escribo una líea de código desde la facultad, o sea muchos años, pero siendo este un problema de lógica…. vamos a ver….

    Se trata de eiminar, por ejemplo el puntero «previous». Si empezamos por head, no hay problema, siempre encontramos el next a donde dirigirnos…

    El problema viene si empezamos por tail…. llegamos al último de la fila (querida milagros) y… ¿cual es su predecesor?
    Bastará recorrer la lista de sde head buscando que elemento tiene como next al elemento donde nos encontramos, ese es nuestro predecesor.

    No sé si me he explicado bien, pero yo lo veo cuco….

    🙂

    Saludos

  2. Comment por Charly | 10/31/09 at 2:22 pm

    Mis disculpas por el descalabro a la lengua cometido en el anterior post… no sé que le ha pasado a mi teclado o dedos…

  3. Comment por LocoDelAssembly | 10/31/09 at 2:37 pm

    No demasiado bueno en lenguajes con garbage collector tal vez, pero la solución a eso son las XOR linked lists 😀

  4. Comment por slack | 10/31/09 at 2:43 pm

    El clásico truco del XOR 🙂

    Se crea un único campo, llamémoslo «prevnext», en los nodos en el que se guarda el valor (previous ^ next) y cuando recorres en cualquiera de las dos direcciones tienes proximo_a_visitar = anterior_visitado ^ actual->prevnext.

  5. Comment por Ehooo | 10/31/09 at 2:46 pm

    Yo he pensado lo mismo que Charly, pero de ese modo necesitas un puntero más para realizar la comparación y sacrificas velocidad de proceso ya que tienes que realizar muchas iteraciones para hacer el recorrido.

  6. Comment por Miguel | 11/01/09 at 7:04 am

    /*++

    Cualquier operación lógica o matemática que puedas revertir debe servir, puesto que en cada iteración tienes la dirección del elemento anterior y del siguiente. El XOR parece la solución más evidente puesto que en ningún caso provocarás un overflow ni ninguna otra situación «peligrosa», y además tiene la ventaja de ser simétrica. Pero también se podría usar la suma para codificando previos+next y la resta para la descodificación …

    Por cierto, aunque no he comenzado a leerlo, Carlos me ha recomendado ese libro… en que o quien te estás convirtiendo? Es inquietante… xDDDDDDDDDDDDDD

    –*/

  7. Comment por Juan C. | 11/04/09 at 12:57 pm

    Almacenando la distancia del puntero con respecto al head ya nos podria valer, aunque esta claro que meter un elemento en medio nos daria mas problemas, pero es una solucion

  8. Comment por Poney | 05/31/10 at 7:58 am

    Quiza digo una parida, pero si la lista esta doblemente enlazada, en el primero hacemos que anterior apunte a ultimo y empezamos por ahi. Sabremos que hemos dado toda la vuelta cuando el puntero de siguiente sea el de primero.

Se han cerrado los comentarios