¿Cuál es el código más hermoso que hayas escrito? Por hermosa quiero decir simple, limpio e implementación de una función / algoritmo potencialmente complejo.

  let undesiredProperties = ['UndesiredProperty1', 'UndesiredProperty2'];

 getEntityFromObject (objeto) {
	 devolver Object.keys (objeto)
		 .reduce ((entidad, clave) =>
      		 undesiredProperties.indexOf (clave) <= -1?
        	 Object.assign (entidad, {[clave]: objeto [clave]}): entidad
     , {});
 }

Recientemente comencé a usar Angular y Typecript, y escribí este método ayer. Es una frase, pero se ve un poco apretada en Quora, así que la he extendido. En pocas palabras, crea una copia de un objeto sin algunas propiedades, como lo especifica la matriz de propiedades no deseadas .

Utiliza un montón de funcionalidades ES5 y ES6:

  Object.keys (objeto)

es un método global que devuelve una matriz de las propiedades enumerables del parámetro.

  dejar arr = [];
 arr.reduce ((acumulador, valor actual) => devolución de llamada, valor inicial);

Reducir es un hermoso método de matriz que itera a través de una matriz, ejecuta alguna función de devolución de llamada y establece el acumulador en el valor devuelto.

  Object.assign (objetivo, fuente)

copia los valores de las propiedades enumerables del objeto de origen al destino.

  {[valor clave}

utiliza una función ES6 que permite claves dinámicas al crear objetos. Se ejecuta de la siguiente manera:

Línea 4: Obtenga las claves del objeto de parámetro como una matriz.

Línea 5: iterar a través de ellos. Inicialice el acumulador en un objeto vacío.

Línea 6: Verifique si la clave está en una matriz de propiedades que se eliminarán.

Línea 7: si no es así, devuelva el objeto acumulador con la propiedad agregada. Si es así, devuelva el objeto acumulador para la próxima iteración.

Línea 8: Devuelve el objeto acumulador.

Lo uso para transformar un objeto local en una entidad aceptable para nuestro backend. Es simple, limpio, pequeño y, aunque no es un algoritmo complejo, lo suficientemente conciso como para estar muy satisfecho con él.

Una de mis piezas de código favoritas que he escrito recientemente fue un reemplazo de los métodos matemáticos de JavaScript: seno y coseno.

Aquí está el código:

  precisión constante = 8
 const tao = 6.283185307179586

 potencia constante = (base, exponente) => {
   let val = base
   dejar i = 0

   mientras que (i  {
   dejar val = n

   mientras que (n> 2) {
     val * = n - 1
     n - = 1
   }

   retorno val
 }

 serie const = (x, offset, precisión) => {
   // Restringe x a PI * 2 para que no necesitemos
   // para agregar más precisión a medida que x aumenta
   x% = tao

   // Cuenta los pasos con `n`
   dejar n = 0

   // Establecer la fuerza de impulso
   dejar val = x

   // Al calcular el coseno, compara el valor
   // a `1` (sin impulso inicial)
   if (desplazamiento === 2) {
     val = 1
   }

   // Hasta que alcancemos nuestra precisión ...
   while (n  {
   const sineOffset = 3
   valor constante = serie (x, sineOffset, precisión)
   valor de retorno

   // Ejemplo:
   // return x -
   // (potencia (x, 3) / factorial (3)) +
   // (potencia (x, 5) / factorial (5)) -
   // (potencia (x, 7) / factorial (7)) +
   // (potencia (x, 9) / factorial (9)) -
   // (potencia (x, 11) / factorial (11)) +
   // (potencia (x, 13) / factorial (13)) -
   // (potencia (x, 15) / factorial (15)) +
   // (potencia (x, 17) / factorial (17)) -
   // (potencia (x, 19) / factorial (19))
 }

 const cos = x => {
   const cosineOffset = 2
   serie de retorno (x, coseno, compensación, precisión)
 }

Me desafié a mí mismo a escribir estas dos funciones usando solo los operadores Plus, Minus, Multiply y Divide. Hice esto para tratar de obtener cierta intuición sobre cómo y por qué funcionan Sine y Cosine.

Puede leer más sobre cómo funcionan los algoritmos en mi artículo de blog: Roll Your Own Math – Sine & Cosine

Aquí hay algunas capturas de pantalla y enlaces a ejemplos de trabajo con los que puede jugar en CodePen:

Roll Your Own Math – Seno y coseno (círculo)

Roll Your Own Math – Sine

Un analizador LL en Prolog. No creo tener el código en ningún lado, pero recuerdo algunos detalles. El árbol de análisis se mantuvo como árboles abiertos (los no terminales eran variables libres en las hojas del árbol). Estos también se mantuvieron en una lista que representaba los no terminales aún por expandir en el resto del texto a analizar. Cada regla de producción coincidía con el texto y expandía los no terminales a terminales y no terminales. Esto hizo que el árbol de análisis creciera en las hojas sin tener que atravesarlo / reconstruirlo. La lista de no terminales también se actualizó cuando se activó cada regla de producción. IIRC, para evitar anexos O (n), esa lista se mantuvo como una lista de diferencias y agregarle nuevos terminales fue una operación O (1). Todo era muy compacto y claro (al menos para mí …)

Escribí una máquina de Turing en una versión de Turtle Art hecha de bloques de programación con el fin de enseñar conceptos de informática a estudiantes de primaria en el programa One Laptop Per Child. Codifiqué los símbolos en la cinta de la máquina de Turing como puntos de colores, que la tortuga podía leer y traducir a enteros utilizados como índices en la tabla del programa.

La tabla también estaba hecha de puntos que la tortuga podía leer para determinar en qué estado entrar, qué símbolo escribir en la cinta y en qué dirección mover la cabeza para la próxima iteración. El estado inicial de la cinta para la suma simple [matemática] 3 + 2 [/ matemática] aparece en el borde superior, y la tabla del programa a continuación.

Al final de la ejecución para este caso simple, cuando la máquina se detiene, obtenemos el estado de la cinta que contiene la respuesta, y también un seguimiento de ejecución, como se muestra a continuación.

Actividades / Turtle Art / Tutoriales / Turtle Art Turing Machine

Aquí hay imágenes del código completo, con anotaciones.

Actividades / Turtle Art / Tutoriales / Turtle Art Code para Turing Machine

También proporcioné una traducción automática al logotipo en una página separada, vinculada a las anteriores.

En comparación con los lenguajes de computadora basados ​​en texto, este tipo de Turtle Art hace imposible la mayoría de los errores de tipeo y sintaxis. El usuario programa directamente en una estructura de árbol, una representación CS mucho más natural de un programa que un texto que tiene que pasar por un análisis léxico y etapas de análisis para llegar a un árbol de análisis.

En una escala mayor, recomiendo una serie de elegantes implementaciones de lenguaje de programación que un estudiante universitario podría leer en su totalidad, incluido el Pure LISP original, el FORTH original, Smalltalk y J, la última versión de APL de Ken Iverson. Algunos de ellos tienen implementaciones escritas completamente en sus propios idiomas, con un núcleo que puede compilarse de forma cruzada con cualquier arquitectura nueva.

Hace muchos años, escribí este pequeño programa para mi Amiga 1000:

ILLEGAL

Sí. Un programa de lenguaje ensamblador de instrucción única, donde esa instrucción única era el código de operación ILEGAL de ensamblaje 68000

Lo que esto hizo, cuando se ejecutó, fue aumentar la excepción de instrucción ilegal. En el Amiga, eso traería el borde rojo “Error de meditación Guru”.


Era, afirmé en ese momento, el programa probablemente más corto que se haya escrito. (O, al menos, estaba atado).

Bueno, no estoy completamente seguro de si este es el código más hermoso que he escrito, pero aquí va.

Tenía una carpeta llamada ‘cosas’ en mi escritorio en la que simplemente tiraba archivos aleatorios cuando terminaba con ellos (código, imágenes, documentos, videos, etc.). Un día estaba buscando algo y aunque “wow, realmente debería organizar esto”. Luego escribí un simple script de Python que podría usar para colocar cada archivo en diferentes carpetas.

También está en mi github (JasonHinds13 / PyFiling)

Editar: ahora me doy cuenta de que probablemente podría haber usado un diccionario para simplificar las cosas.

  desde os import listdir, ruta, makedirs, renombrar

 #Directorio para ordenar
 directorio = raw_input ("Ingresar carpeta:")

 # Para asegurarse de que el directorio termine con un '/'
 si no directorio.endswith ('/'):
     directorio + = '/'

 # Extensiones de tipo de archivo general
 apps = ("Aplicaciones", ['.exe'])
 code = ("Code", ['.py', '. java', '. c', '. cpp', '. rb', '. asm', '. php', '. html',
              '.css', '. js', '. lua', '. jar', '. o', '. obj'])

 music = ("Música", ['.mp3', '. ogg', '. wav'])
 videos = ("Videos", ['.mp4', '. 3gp', '. avi'])
 pictures = ("Imágenes", ['.jpg', '. jpeg', '. png', '. bmp', '. gif'])
 archives = ("Archivos", ['.zip', '. rar', '. 7zip', '. tar', '. iso'])

 documentos = ("Documentos", ['.docx', '. doc', '. pdf', '. txt', '. ppt', '. pptx', '. ppsx', '. pptm',
              '.docm', '. dotx', '. dotm', '. docb', '. xlsx', '. xlsm', '. xltx',
              '.xltm', '. xlsb', '. xla', '. xlam', '. xll', '. xlw',
              '.ACCDB', '. ACCDE', '. ACCDT', '. ACCDR', '. Pub',
              '.potx', '. potm', '. ppam', '. ppsm', '. sldx', '. sldm'])

 allTypes = [aplicaciones, código, música, videos, imágenes, archivos, documentos]

 # Verifique cada archivo en el directorio

 para fil en listdir (directorio):
     para typ en allTypes:
         para x en typ [1]:
             si fil.endswith (x) o fil.endswith (x.upper ()):
                 si no path.exists (directorio + tip [0] + '/'):
                     makedirs (directorio + tip [0] + '/')
                 renombrar (directorio + fil, directorio + tip [0] + '/' + fil)

 impresión ""
 imprima "Cómo encontrar lo que organizamos:"
 print "Carpeta de códigos: contiene código, archivos de objetos y archivos jar".
 imprima "Carpeta de música: contiene archivos de audio".
 imprima "Carpeta de videos: contiene archivos de video".
 imprima "Carpeta de imágenes: contiene archivos de imagen".
 imprima "Carpeta de archivos: contiene archivos rar / zip y otros archivos".
 imprima "Carpeta de documentos: contiene PowerPoint y documentos de MS Office".
 print "Carpeta de aplicaciones: contiene aplicaciones y programas ejecutables".
 print "Otra carpeta: contiene archivos que no se ordenaron en una carpeta".

Recientemente escribí un forro Python one para calcular combinaciones de una cadena de longitud k.

  combinación def (cadena, k):
     filtro de retorno (elemento lambda: len (elemento) == k, reducir (conjunto lambda, elemento: conjunto + mapa (subconjunto lambda: subconjunto + [elemento], conjunto), lista (cadena), [[]]))

Básicamente, este precalcula el conjunto de potencia de la cadena y filtra todos los subconjuntos con longitud k. Considero el one-liner, elegante y hermoso, aunque no muy eficiente.

Escribí este código como respuesta a una pregunta de desbordamiento de pila: ¿cómo se agrega el mismo valor a dos variables en una declaración?

Como puede haber entendido ahora, agrega el mismo valor a dos variables diferentes usando solo una declaración, en JavaScript. Así es como va:

  dejar a = 10;
 dejar b = 20;

 b + = -a + (a + = 5);  // Esta belleza

 console.log (a, b);
 // => 15 25

¿Entonces, cómo funciona?

Básicamente, agrega el inverso del valor inicial de “a” (-10) a lo que se devuelve al hacer “a + = 5” (15), recuperando así solo la diferencia entre la antigua “a” y la nueva “a”.

Es algo simple y no puedo pensar en muchas aplicaciones prácticas. Pero maldita sea, me sentí bien cuando se me ocurrió.

El siguiente código cuando se ejecuta genera el mapa de India:

  #include "stdio.h"
 int main ()
 {
     int a, b, c;
     for (b = c = 10; a = "¡Hola! Bienvenido a GeeksForGeeks. \
       TFy! QJu ROo TNn (ROo) SLq SLq ULo + \
       UHs UJq TNn * RPn / QPbEWS_JSWQAIJO ^ \
       NBELPeHBFHT} TnALVlBLOFAkHFOuFETp \
       HCStHAUFAgcEAelclcn ^ r ^ r \\ tZvYxXy \
       T | S ~ Pn SPm SOn TNn ULo0ULo # ULo-W \
       Hq! WFs XDt! "[B +++ 21];)
  
       para (; a--> 64;)
          putchar (++ c == 'Z'? c = c / 9: 33 ^ b & 1);
     devuelve 0;
 }

El código anterior es un ejemplo típico de código ofuscado, es decir, código que es difícil de entender para los humanos.

Y aquí está la salida del código:

El hermoso mapa de la India.

Aquí está la salida del código en un compilador en línea:

Ideone.com

Jai Hind!

Gracias.

PD : Este no es el código que escribí. Es el código más hermoso que he visto.

Supongo que esto depende del idioma y del sistema operativo involucrado.

Creo que mi mayor triunfo fue un sistema de base de datos que se ejecutó dentro de la versión DOS de Word 5. No había una pantalla fija de entrada de datos, el sistema solicitaba la información necesaria (la mayoría era información dinámica que no se conocía hasta El punto de entrada). En cierto sentido, era un programa RISC porque estaba completamente dentro del conjunto de instrucciones del lenguaje Macro de Word que no era particularmente lujoso. Un intento de traducir el mismo concepto al VB de WinWord no fue tan elegante.

¡Diseñé una bóveda criptográfica para almacenar contraseñas cifradas!

Fondo

Esto estaba relacionado con mi mini proyecto en el segundo año de ingeniería. La idea era pedirle al usuario que ingrese su contraseña, que podría olvidar y una clave. La contraseña ingresada será el texto sin formato y la contraseña almacenada será el texto cifrado.

En caso de que quiera recuperar su contraseña, debe proporcionar la clave y luego recuperará la contraseña descifrada.

Cosas que participé en el proyecto

  1. Construyendo la bóveda
  2. Base de datos
  3. La seguridad de triple capa
  4. API RESTful

El código

Hice un formulario simple usando HTML y CSS donde el usuario tenía que ingresar sus detalles. Después de la presentación, aterrizará en una página donde obtendrá la lista de estándares de cifrado disponibles para él, que van desde Triple DES (Estándar de cifrado de datos) hasta AES256.

El número de rondas de encriptación para AES dependería del tamaño de la clave ingresada por el usuario.

El lenguaje que opté por escribir los algoritmos de cifrado fue PHP. Algunos de ustedes pueden burlarse de mí por eso, pero créanme, considero que PHP es versátil. PHP 7.2 se convirtió en el primer lenguaje en agregar criptografía moderna en su biblioteca estándar.

A continuación se muestra el complemento de una función de cifrado para AES256.

La razon detras

Muchos de ustedes podrían argumentan que hay servicios disponibles que ofrecen almacenar su contraseña. Convenido. Lo que dudo es si cifran la contraseña o no.

En diciembre de 2009, se produjo una violación importante de la contraseña del sitio web Rockyou que condujo al lanzamiento de 32 millones de contraseñas.

Esto podría haberse evitado solo si Rockyou hubiera almacenado la contraseña en forma cifrada y solo si la contraseña de la administración de Rockyou fuera más que un 123456, se podrían haber salvado 32 millones de cuentas.

El problema con el usuario diario es que no quieren mantener una contraseña segura. Con tantas contraseñas para recordar, ¿quién mantendrá una contraseña retorcida y altamente confusa? Y, de nuevo, si alguien lo hace, ¿dónde almacenará esta contraseña para usarla en el futuro?

Esta :

  vector  a, b;
 // ayb obtienen algunos valores, pero tienen la misma longitud
 
 int nMatch = inner_product (a.begin (), a.end (), b.begin (), 0, más  (), equal_to  ());

Cuenta el número de cadenas en a que coinciden con la correspondiente en b

Evalúa (a1 # b1) + (a2 # b2)…. (un # bn) donde # representa una comparación de cadena (equal_to )

Esto hace un mal uso del hecho de que los valores bool que tienen true están representados como el valor 1 (no está garantizado en todos los compiladores, no intente esto en casa).

Entonces obtenemos el número de elementos coincidentes.

A2A.

  1. Nunca estoy 100% feliz con mi código. 🙂
  2. Para ejemplos decentes, mira el libro Beautiful Code.
    Aunque algunos ejemplos no hay lo que personalmente considero hermoso.
  3. El código más hermoso es el que no fue escrito.
    No tiene que ser compatible y nunca tiene errores.
  4. Por cierto, lo mismo ocurre con los correos electrónicos y las conversaciones sin conexión.
  5. Muchas veces, también se aplica a las respuestas de Quora. 🙂

Una máquina universal de Turing en 18 líneas de awk. Había escrito una versión de 1477 líneas en C, pero luego encontré un FSM universal de dos líneas en awk en Programming Pearls de John Bentley. Mi UTM inicial se implementó en 5 líneas de código, pero aumenté el tamaño para manejar el formato de archivo de mi programa C original sin modificaciones.

La definición de UTM que utilicé era del libro de Hopcroft-Ullman que seguí en el invierno de 1991. Escribí el C original poco después. Puede que haya escrito la versión awk una década después. Una máquina de turing que escribí fue encontrar el cuadrado de un número escrito en unario. Encontré ambas versiones el año pasado y estaba feliz de poder ejecutarlas todas de nuevo.

He agregado un convertidor graphviz para el diagrama de estado que crea el diagrama de máquina de estado SVG para el programa.

  COMIENZA {read_delta = 0;  read_input = 0;}
 $ 1 ~ / INICIAL / {init_state = $ 3;}
 $ 1 ~ / FINAL / {for (i = 3; i ") {head ++; if (head> tape_sz) {tape [head] = blank; tape_sz ++}}
        if (delta_move [st, input] == ​​"<") {if ((head == tape_sz) && (tape [head] == blank)) {tape_sz--};  cabeza--;}
        printf "ID:";  for (i = 0; i <= tape_sz; i ++) {if (i == head) printf "[% s]", estado;  printf "% s", cinta [i];  };  impresión;
        if (estado en final_states) {print "ACEPTAR";  salida 0;}
        if (head <0) {print "JAM";  salida 2;}}}

Aquí hay un diagrama g-viz de la cuadratura TM:

El código más sorprendente que he escrito fue una expresión regular que dividía un párrafo de texto en palabras. Duraba más de una página, porque una ‘palabra’ podría significar una palabra simple en inglés con apóstrofes, como no, o un número como 1,234.56, o un nombre de variable de Perl como $ foo, o un nombre de método C ++ como Sib :: Span :: Delete, o todo tipo de otras cosas. Pero Perl le permite dividir una expresión regular larga en lo que efectivamente son funciones, con comentarios, espacios en blanco y diseño ordenado; no solo obtienes dos pantallas de ruido de línea que no se puede mantener. Un colega exclamó que era la expresión regular más elegante que había visto en su vida.

Para usted, puede ser un trillón de líneas de código, pero para mí es un simple script \ aplicación de una página que me permite ejecutar código PHP e inmediatamente ver la salida en el navegador.
Me permite hacer lo siguiente y luego agregarlo en el entorno de producción.

  • Prueba pequeños pero complicados fragmentos de código
  • Esté a salvo de las peculiaridades inesperadas que el lenguaje tipeado libremente como PHP puede hacer
  • Pruebe un fragmento rápidamente sin tener que crear un archivo separado y ejecutarlo en el navegador
  • Demuestre algo a un compañero que discute rápidamente (este es desagradable: D)
  • Ahórrame de aplicaciones web en vivo como PHP Fiddle.
  • Mucho más no puedo enumerar en este momento

Problema. se le da una cadena. También se le da una función, Boolean isSubstring (cadena str1, cadena str2). Necesita regresar si una segunda cadena es una rotación de la primera cadena. para definir una rotación, algunos ejemplos
Hola llohe
Google: oglego
Sin embargo, Ggleoo no es una rotación de Google.

Ahora la captura. Tienes una linea.

La respuesta: return isSubstring (str1, str2 + str2);

el plus se puede reemplazar con la función concatenate si su idioma no tiene autoconcatonation

Mapa de India usando el Programa C.

(Consulte: Generar un mapa de India usando la Programación C – Aprenda Tecnología de la Información)

  / * Aquí está el código * / 
 #include (stdio.h) main () { 	
	 int a, b, c; 
	 int cuenta = 1; 	
	 para (b = c = 10; a = "- FIGURA ?, UMKC, XYZHola, \ 		
		 TFy! QJu ROo TNn (ROo) SLq SLq ULo + \ 		
		 UHs UJq TNn * RPn / QPbEWS_JSWQAIJO ^ \ 
		 NBELPeHBFHT} TnALVlBLOFAkHFOuFETp \ 
		 HCStHAUFAgcEAelclcn ^ r ^ r \\ tZvYxXy \ 		
		 T | S ~ Pn SPm SOn TNn ULo0ULo # ULo-W \ 		
		 Hq! WFs XDt! ”[B +++ 21];  ) 		

	 para (; a—> 64;) 		
	 putchar (++ c == 'Z'? c = c / 9: 33 ^ b & 1);    	
	 devuelve 0;
 }

Explicación: La cadena larga es simplemente una secuencia binaria convertida a ASCII. El primer enunciado for hace que bstart en 10, y el [b+++21] después de que la cadena arroja 31. Tratando la cadena como una matriz, el desplazamiento 31 es el comienzo de los datos “reales” en la cadena (la segunda línea en el código de ejemplo que proporcionó). El resto del código simplemente recorre la secuencia de bits, convirtiendo los 1 y 0 en! Y whitespace e imprimiendo un carácter a la vez.

La extraña parte inteligente está en las declaraciones de putchar . Toma el primer putchar. ASCII ‘Z’ es 90 en decimal, entonces 90/9 = 10 que es un carácter de nueva línea. En el segundo, el decimal 33 es ASCII para ‘!’. Alternar el bit de orden inferior de 33 le da 32, que es ASCII para un espacio. Esto causa ! para imprimir si b es impar, y un espacio en blanco para imprimir si b es par. El resto del código simplemente está ahí para recorrer el “puntero” a través de la cadena.

Salida:

Lea más artículos interesantes en: Aprenda Tecnología de la Información

Regexed json a csv.
[Muy bien, todos los que odian la expresión regular, aquí está la advertencia: esta fue solo una herramienta personal que utilicé para el trabajo de desarrollo, no en una base de código implementada. Eso es en parte lo que lo hace hermoso … ahorrar esfuerzo sin comprometer la calidad]
Estaba trabajando en un proyecto en el que teníamos un mensaje json estructurado proveniente de un servicio web en el que teníamos que seguir buscando varias etiquetas durante el desarrollo para validar los contenidos manualmente. Cada vez que ejecutamos una solicitud, la salida de una IU de descanso necesitaba escanearse a simple vista. El json era esencialmente una secuencia de objetos similares.
Molesto, preparé una macro Notepad ++ que era una secuencia de 5 comandos regex que transformarían el mensaje json en un csv. Luego podría guardar el resultado en un archivo y verlo fácilmente en MS Excel.

Mientras tanto, una compañera de equipo, molesta por la operación manual repetitiva que tenía que realizar en la interfaz gráfica de usuario, escribió un programa de cliente de descanso, pero la salida se almacenó como json, que tuvo que examinar manualmente.

Cuando descubrimos las herramientas de los demás, combinamos las dos piezas y teníamos un convertidor json a csv completamente funcional que guardaba la respuesta json de nuestro servidor a un archivo csv. Todo esto sin tener que escribir ningún manejo de etiquetas json.

¡5 expresiones regulares hicieron el truco!

El código más hermoso que incluso escribí fue en el día anterior a que los chips ARM tuvieran una instrucción de división entera. (¡Hm, buscándolo, parece que algunos todavía no lo hacen!) Escribí un programa de lenguaje ensamblador ARM que logró dividir dos números usando solo dos instrucciones de máquina por bit de resultado, en lugar de las tres o incluso cuatro instrucciones que se usaron en todas las otras implementaciones que he encontrado.

Normalmente, harías una división como esta. Comenzando con un registro numerador ‘num’ y un registro denominador ‘den’, esto calcula el resultado en ‘res’.

  cmp den, num, lsr # 31
 subhs num, den, lsl # 31
 adc res, res, res
 cmp den, num, lsr # 30 
 ...

La primera línea prueba si el denominador se puede restar al numerador después de desplazarlo a la izquierda 31 bits. Si es así, en realidad haces la resta en la línea 2. La tercera línea registra si restamos o no al cambiar el bit de resultado de la derecha a un registro de resultados. Repita esto para cada posición de bit. Así es como todos lo hicieron.

Pero descubrí que podrías combinar el primer y el tercer paso. Por simplicidad, suponga que el numerador es positivo, por lo que el bit 31 es claro, y usted sabe que el denominador es exactamente 20 bits. Luego, primero cambie el denominador a la izquierda 12 bits, y luego repita las siguientes 12 veces:

  rscs num, den, num, lsl # 1
 addcc num, num, den

La primera línea calcula num = (num<<1)-den - 1+c , configurando las banderas. Por lo tanto, el numerador se desplaza a la posición de la izquierda y luego se resta el denominador. Si esto resulta en un flujo inferior, la segunda línea agrega el denominador nuevamente. Como usamos una instrucción rsc, el carry que resultó de la primera resta se desplaza al numerador en la siguiente iteración ... Entonces, después de ejecutar este bit de código, el resultado de la división está en los bits 0..10 del numerador, y El último bit está en el carry.

Creo que esto no es exactamente como lo hice hace 22 años (recuerdo claramente haber calculado el NOT de uno de los operandos por alguna razón), pero es más o menos la misma idea.


También me gusta mi implementación en C de heapsort, que es mucho más conciso de lo que normalmente lo ves, rápido y en realidad no es ilegible si conoces el algoritmo:

 void heapsort(int a[], int n) { int tmp, i, j, l=n/2; // Invariant: subtrees starting at l or higher are in heap order. // (Right from the start, this holds for all the leafs, a[n/2+1..n].) // i and j iterate through a path in the tree, j being i's parent. a--; // I want a[1] to refer to the first element in the list while (n>0) { if (l) { j=l--; tmp=a[j]; } // create heap else { j=1; tmp=a[n]; a[n--]=a[1]; } // sort heap while (1) { i=j+j; if (in || a[i]