Lenguajes de programación a través de los años


168

En este desafío, los usuarios se turnarán para completar tres tareas de codificación bastante simples en lenguajes de programación que pueden ser progresivamente más antiguas.

La primera respuesta debe usar un lenguaje de programación que se hizo en el año 2015. Una vez que haya al menos una respuesta de un idioma de 2015, las respuestas pueden usar lenguajes de programación que se hicieron en 2014. Del mismo modo, las respuestas que usan idiomas de 2013 no están permitidas hasta que haya al menos una respuesta de 2014.

En general, el uso de un lenguaje de programación del año Y no está permitido hasta que se haya enviado una respuesta utilizando un lenguaje del año Y + 1. La única excepción es Y = 2015.

Encontrar el año de tu idioma

Para responder a esta pregunta, debe saber el año en que su lenguaje de programación fue "creado". Este es, por supuesto, un término subjetivo; algunos idiomas se desarrollaron en el transcurso de varios años, y muchos idiomas todavía se actualizan cada año. Sea el año en que se "hizo" un idioma el primer año que apareció una implementación para ese idioma en el público en general.

Por ejemplo, Python se hizo en 1991 , aunque su desarrollo había estado en progreso desde 1989, y la versión 1.0 no se lanzó hasta 1994.

Si este año sigue siendo subjetivo, solo use su sentido común para elegir el año más apropiado. No se empantane con ligeros desacuerdos sobre las elecciones de año. Proporcione un enlace a una fuente que indique cuándo se creó su idioma.

Las diferentes versiones o estándares de un lenguaje de programación (por ejemplo, Python 1, 2, 3) se cuentan como el mismo idioma con el mismo año inicial.

Entonces, a menos que el año de su idioma sea 2015, solo puede enviar su respuesta una vez que se haya enviado una respuesta cuyo año de idioma es el año anterior al suyo.

Si ya existe una respuesta válida con el mismo año que la suya, entonces puede responder. No importa si su idioma se desarrolló antes o más tarde en el año.

Tareas

Debe completar las tareas 1 a 3. La tarea 0 es opcional.

Estas tareas fueron más o menos elegidas para corresponder a tres aspectos importantes de la programación: proporcionar salida (Tarea 1), bucle (Tarea 2) y recursividad (Tarea 3).

Tarea 0 - Historial de idiomas (opcional)

Escriba al menos un párrafo que explique la historia de su lenguaje de programación elegido: quién lo desarrolló, por qué, cómo, etc. Esto se recomienda especialmente si usted estuvo presente cuando surgió el lenguaje, y tal vez incluso participó en su desarrollo. Siéntase libre de relatar anécdotas personales sobre el efecto que tuvo el lenguaje en usted o su trabajo, o algo así.

Si eres demasiado joven para saber mucho sobre la historia de tu idioma sin mucha investigación, considera dejar una nota a los usuarios mayores que diga que pueden editar tu publicación y agregar algo de historia de primera mano.

Tarea 1: "¡Hola, mundo!" Variante

Escribe un programa que imprima

[language name] was made in [year made]!

al área de salida estándar de su idioma (stdout para los idiomas más recientes).

Por ejemplo, si el lenguaje fuera Python, el resultado sería:

Python was made in 1991!

Tarea 2 - ASCII Art N

Escriba un programa que permita al usuario ingresar un entero positivo impar (puede suponer que la entrada siempre es válida) e imprime una letra N ASCII con el carácter N.

Si la entrada es 1, la salida es:

N

Si la entrada es 3, la salida es:

N N
NNN
N N

Si la entrada es 5, la salida es:

N   N
NN  N
N N N
N  NN
N   N

Si la entrada es 7, la salida es:

N     N
NN    N
N N   N
N  N  N
N   N N
N    NN
N     N

El patrón continúa así. La salida puede contener espacios finales.

Tarea 3 - MCD

Escriba un programa que permita al usuario ingresar dos enteros positivos (puede suponer que la entrada siempre es válida) e imprime su máximo divisor común . Esto se define como el número entero positivo más grande que divide ambos números sin dejar un resto. Se puede calcular fácilmente utilizando el algoritmo euclidiano .

Ejemplos:

8, 124
12, 84
3, 303
5689, 21
234, 8766

Puede usar una función incorporada, pero intente averiguar si estaba allí en la primera versión de su idioma. Si no, intente no usarlo.

Reglas

  • Puede responder varias veces, pero cada nueva respuesta debe usar un idioma hecho al menos 5 años antes del idioma en su última respuesta. Entonces, si respondió con un idioma de 2015, no podría responder nuevamente hasta que se permitan los idiomas de 2010. Si comienza con una respuesta de 2010, no puede hacer que una respuesta de 2015 sea su segunda respuesta porque 2015 no es antes de 2010.
  • Si es posible, escriba su código para que haya funcionado en la primera versión de su idioma (o una versión tan antigua como sea posible). (Esto no es un requisito porque encontrar compiladores / intérpretes antiguos para algunos idiomas puede ser difícil).
  • Abstenerse de publicar un idioma que ya ha sido publicado a menos que la respuesta publicada tenga errores significativos o tenga una forma muy diferente de completar las tareas.
  • Golfing su código está bien, pero no es obligatorio.
  • Una nueva línea final en la salida de cualquier programa está bien.
  • Para las tareas 2 y 3, todos los valores de entrada por debajo de un máximo razonable como 2 16 deberían funcionar (256 como mínimo).
  • Su idioma debe haber existido antes de que se publicara esta pregunta.
  • Los lenguajes de programación muy antiguos pueden tener diferentes formas de entrada y salida de lo que pensamos hoy. Esto esta bien. Complete las tareas lo mejor que pueda en el contexto de su idioma.

Puntuación

La puntuación de su envío es:

upvotes - downvotes + (2015 - languageYear) / 2 

Por lo tanto, se agrega 0.5 al conteo de votos para cada año antes de 2015, dando la ventaja a los idiomas más antiguos. La presentación con la puntuación más alta gana.

Lista de respuestas

El fragmento de pila a continuación enumera todas las respuestas válidas según su año de idioma.

Debes comenzar tu publicación con esta línea de Markdown para asegurarte de que esté lista correctamente:

#[year] - [language name]

Por ejemplo:

#1991 - Python

El nombre del idioma puede estar en un enlace (será el mismo enlace en la lista de respuestas):

#1991 - [Python](https://www.python.org/)

Las respuestas que no siguen este formato, o tienen un año que aún no está permitido, o provienen de un usuario que ya respondió en los últimos 5 años están marcadas como no válidas.

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script><script>$(function(){function e(e,r){var a="https://api.stackexchange.com/2.2/questions/48476/answers?page="+e.toString()+"&pagesize=100&order=asc&sort=creation&site=codegolf&filter=!YOKGPOBC5Yad160RQxGLP0r4rL";$.get(a,r)}function r(e){if(e.items.forEach(function(e){var r=e.link,a=e.owner.display_name,i=e.body.match(/<h1\b[^>]*>(\d{4}) - (.*?)<\/h1>/);if(i&&i.length>=3)var h=parseInt(i[1]),u=i[2];h&&u&&n>=h&&h>=t&&(!d.hasOwnProperty(e.owner.user_id)||d[e.owner.user_id]-h>=p)?(d[e.owner.user_id]=h,h==t&&--t,o.hasOwnProperty(h)||(o[h]=[]),o[h].push({language:u,user:a,link:r,score:e.score+(n-h)/2})):s.push(' <a href="'+r+'">'+a+"</a>")}),e.has_more)runQuery(++a,r);else{for(var i=n,h=[];o.hasOwnProperty(i);){for(var u=$("<tr>").append($("<td>").text(i.toString())),l=$("<td>"),c=$("<td>"),g=$("<td>"),f=0;f<o[i].length;f++){var v=o[i][f];l.append(v.language),c.append($("<a>").html(v.user).attr("href",v.link)),g.append(v.score),f+1<o[i].length&&(l.append("<br><br>"),c.append("<br><br>"),g.append("<br><br>"))}u.append(l).append(c).append(g),h.push(u),--i}$("#answers").find("tbody").append(h),s.length>0?$("#invalid").append(s):$("#invalid").remove()}}var a=1,n=2015,t=n-1,p=5,o={},s=[],d={};e(1,r)})</script><style>html *{font-family: Helvetica, Arial, sans-serif;}table{border: 4px solid #a4a; border-collapse: collapse;}th{background-color: #a4a; color: white; padding: 8px;}td{border: 1px solid #a4a; padding: 8px;}div{font-size: 75%;}</style><table id='answers'> <tr> <th>Year</th> <th>Language</th> <th>User (answer link)</th> <th>Score</th> </tr></table><div id='invalid'><br>Invalid Answers:</div>


2
Esto debería ayudar.
swish

20
Wikipedia tiene una lista para todo: esta para idiomas no esotéricos por año.
Sanchises

2
¿Debería la Tarea 3 usar realmente la recursividad o es suficiente para que produzca el resultado correcto? Si necesito escribir mi propia función GCD, generalmente solo uso un bucle, pero escribí uno recursivo especialmente para este desafío. Hay muchas respuestas enviadas que solo usan un bucle.
CJ Dennis

55
Tengo ganas de hacer una segunda cuenta solo para superar 1971.
marinus

55
Si podemos volver a 1952, ¡tengo a alguien haciendo girar una máquina histórica que podría hacer soluciones de 1951 (Pegasus) y probarlas!
Brian Tompsett - 汤 莱恩

Respuestas:


173

2013 - Dogescript

Dogescript es un lenguaje creado en 2013 por Zach Bruggeman. No es más que un reemplazo de sintaxis para Javascript para que se lea como los monólogos internos del memético Shiba Inus.

Hola dux

console dose loge with "Dogescript was made in 2013!"

Arte ASCII

such N much N
          much i as 0 next i smaller N next i more 1
              very doge is ("N" + " ".repeat(N-2) + "N").split('')
              s[i] is "N";
              console dose loge with doge.join('')
                              wow
                                      wow

GCD

such gcd_doge much doge, dooge
    rly dooge
              gcd_doge(dooge, doge % dooge)
  but
    rly doge smaller 0
           -doge
    but
          doge
  wow
        wow

113
Wow, tal +1. Muy respuesta Mucha calidad
Alex A.

27
¡Me uní a codegolf solo para votar esta respuesta!
Derek Tomes el

21
Ni siquiera puedo leer el GCD con una cara
seria

16
No puedo leer gcd_doge como good_dog. Ayuda
Yann

Fantástico. Sin embargo, de acuerdo con LANGUAGE.md, las comillas dobles no son compatibles. ¡Me encantaría una explicación de la s[i]parte también!
Docteur

66

2015 - Retina

Retina es un lenguaje de programación basado en expresiones regulares, que escribí para poder competir en desafíos de PPCG con respuestas solo de expresiones regulares, sin tener la sobrecarga innecesaria de llamar a las expresiones regulares en algún lenguaje anfitrión. La retina está completa de Turing. Para demostrarlo, he implementado un solucionador de sistema de 2 etiquetas, así como la Regla 110 . Está escrito en C #, por lo tanto, admite tanto el sabor de .NET (por defecto) como el sabor de ECMAScript (a través de un indicador).

La retina puede funcionar en múltiples modos, pero el más relevante para los cálculos (y el de Turing completo) es el modo Reemplazar. En el modo Reemplazar, le da a Retina un número par de archivos de origen. Estos se emparejan, el primero de cada par es una expresión regular y el segundo un reemplazo. Estos se ejecutan en orden, manipulando la entrada paso a paso. La expresión regular también puede estar precedida por una configuración (delimitada por `). La opción más importante (que hace que Retina Turing sea completa) es +, que hace que Retina aplique el reemplazo en un bucle hasta que el resultado deje de cambiar. En los siguientes ejemplos, también estoy usando ;, que suprime la salida en etapas intermedias.

En cada una de las siguientes presentaciones, cada línea va en un archivo fuente separado. (Alternativamente, puede usar la nueva -sopción y poner todas las líneas en un solo archivo). Los archivos / líneas vacíos se representan como <empty>. Los archivos / líneas que contienen un solo espacio se representan como <space>.

Las explicaciones son bastante largas, así que las he movido al final de la publicación.

Los programas

"¡Hola Mundo!" Variante

<empty>
Retina was made in 2015!

ASCII Art N

Esto supone que STDIN se termina con una nueva línea.

;`^
#
;+`(\d*)#(?:(((((((((9)|8)|7)|6)|5)|4)|3)|2)|1)|0)
$1$1$1$1$1$1$1$1$1$1$2$3$4$5$6$7$8$9$10#
;`#
<empty>
;`\d
N
;`.(?<=(?=(.*\n)).*)|\n
$1
;`N(?=N\n.*\n.*\n`$)
<space>
;+`N(?=.?(.)+\n.* (?<-1>.)+(?(1)!)\n)
<space>
;`(?<=^.*\n.*\nN)N
S
;+`(?<=\n(?(1)!)(?<-1>.)+S.*\n(.)+N?)N
S
S
<space>

GCD

Esto requiere que STDIN no finalice con una nueva línea.

;`\b(?=\d)
#
;+`(\d*)#(?:(((((((((9)|8)|7)|6)|5)|4)|3)|2)|1)|0)
$1$1$1$1$1$1$1$1$1$1$2$3$4$5$6$7$8$9$10#
;`#
<empty>
;`\d
1
;`^(.+)\1* \1+$
$1
;`$
#:0123456789
;+`^(?=1)(1*)\1{9}(#(?=.*(0))|1#(?=.*(?<3>1))|11#(?=.*(?<3>2))|111#(?=.*(?<3>3))|1111#(?=.*(?<3>4))|11111#(?=.*(?<3>5))|111111#(?=.*(?<3>6))|1111111#(?=.*(?<3>7))|11111111#(?=.*(?<3>8))|111111111#(?=.*(?<3>9)))
$1#$3
#|:.*
<empty>

Explicaciones

"¡Hola Mundo!" Variante

Esto es bastante trivial. No necesita entrada (es decir, una cadena vacía), no coincide con nada y la reemplaza por Retina was made in 2015!. También se puede hacer que funcione para entradas arbitrarias, reemplazando el patrón con, [\s\S]*por ejemplo. Eso sorbería STDIN y lo reemplazaría todo con la salida.

ASCII Art N

Esto tiene muchas etapas. La idea es convertir la entrada a unaria, crear un bloque N x N de Nsy luego "tallar" dos triángulos. Veamos las etapas individuales. Recuerde que ;simplemente suprime las salidas intermedias, pero +hace que el reemplazo se aplique en un bucle.

;`^
#

Simple: anteponga a #a la entrada. Esto se usará como marcador en la conversión a unario.

;+`(\d*)#(?:(((((((((9)|8)|7)|6)|5)|4)|3)|2)|1)|0)
$1$1$1$1$1$1$1$1$1$1$2$3$4$5$6$7$8$9$10#

Esto convierte un dígito a unario. Toma los dígitos ya convertidos (\d*)y los repite 10 veces. Y luego toma el siguiente dígito y agrega el número apropiado de dígitos. El valor real de los dígitos es irrelevante en esta etapa. Cuando #llega al final del número, la expresión regular ya no coincide y se realiza la conversión. Como ejemplo, el número 127se procesará como

#127
1#27
111111111122#7
1111111111221111111111221111111111221111111111221111111111221111111111221111111111221111111111221111111111221111111111227777777#

donde la última línea contiene exactamente 127 caracteres de dígitos.

;`#
<empty>
;`\d
N

Dos etapas simples que eliminan eso #y luego convierten todos los dígitos a N. A continuación, usaré input 7como ejemplo. Entonces ahora tenemos

NNNNNNN

La siguiente etapa

;`.(?<=(?=(.*\n)).*)|\n
$1

reemplaza cada una Ncon la cadena completa (recuerde que contiene una nueva línea final) y también elimina la nueva línea final. Por lo tanto, esto convierte la fila individual en una cuadrícula cuadrada:

NNNNNNN
NNNNNNN   
NNNNNNN
NNNNNNN
NNNNNNN
NNNNNNN
NNNNNNN

Ahora el triángulo superior. Primero, comenzamos las cosas convirtiendo la N en la esquina inferior derecha en un espacio:

;`N(?=N\n.*\n.*\n`$)
<space>

La búsqueda anticipada asegura que estamos modificando la correcta N. Esto da

NNNNNNN
NNNNNNN   
NNNNNNN
NNNNNNN
NNNNN N
NNNNNNN
NNNNNNN

Y ahora

;+`N(?=.?(.)+\n.* (?<-1>.)+(?(1)!)\n)
<space>

es una expresión regular que coincide con una Nque está arriba o en la esquina superior izquierda de un carácter de espacio, y la reemplaza con un espacio. Debido a que el reemplazo se repite, esto es esencialmente un relleno de inundación, que convierte el tercer octante del espacio inicial en más espacios:

N     N
NN    N   
NNN   N
NNNN  N
NNNNN N
NNNNNNN
NNNNNNN

Y finalmente, repetimos lo mismo con el triángulo inferior, pero usamos un carácter diferente, por lo que los espacios ya existentes no causan un relleno de inundación incorrecto:

;`(?<=^.*\n.*\nN)N
S

establece la semilla:

N     N
NN    N   
NSN   N
NNNN  N
NNNNN N
NNNNNNN
NNNNNNN

Entonces

;+`(?<=\n(?(1)!)(?<-1>.)+S.*\n(.)+N?)N
S

¿Se llena el diluvio?

N     N
NN    N   
NSN   N
NSSN  N
NSSSN N
NSSSSNN
NSSSSSN

Y finalmente

S
<space>

Los convierte Sen espacios y listo:

N     N
NN    N   
N N   N
N  N  N
N   N N
N    NN
N     N

GCD

GCD en unario es realmente muy trivial con regex. La mayor parte de esto consiste en la conversión de decimal a unario y unario a decimal. Esto podría hacerse de manera más compacta, pero este no es un código de golf, así que ...

;`\b(?=\d)
#
;+`(\d*)#(?:(((((((((9)|8)|7)|6)|5)|4)|3)|2)|1)|0)
$1$1$1$1$1$1$1$1$1$1$2$3$4$5$6$7$8$9$10#
;`#
<empty>
;`\d
1

Estas etapas son esencialmente las mismas que las anteriores, excepto que ambos números de entrada se convierten y el resultado usa 1s en lugar de Ns (no es que importe). Entonces, si la entrada fue 18 24, entonces esto produciría

111111111111111111 111111111111111111111111

Ahora

;`^(.+)\1* \1+$
$1

es todo el cálculo de GCD. Hacemos coincidir un divisor común capturando un número de 1s, y luego usando referencias posteriores para asegurar que ambos números puedan escribirse repitiendo esa cadena (y nada más). Debido a cómo funciona el retroceso en el motor regex (es decir, que .+es codicioso), esto siempre generará el mayor divisor común automáticamente. Como la coincidencia cubre toda la cadena, simplemente escribimos de nuevo el primer grupo de captura para obtener nuestro GCD.

Finalmente, la conversión de unario a decimal ...

;`$
#:0123456789

Agregue un marcador #, un delimitador :y todos los dígitos a la cadena. Esto es necesario, porque no puede producir nuevos caracteres condicionalmente en un reemplazo de expresiones regulares. Si desea un reemplazo condicional, debe extraer los caracteres de la cadena en sí, por lo que los colocamos allí.

;+`^(?=1)(1*)\1{9}(#(?=.*(0))|1#(?=.*(?<3>1))|11#(?=.*(?<3>2))|111#(?=.*(?<3>3))|1111#(?=.*(?<3>4))|11111#(?=.*(?<3>5))|111111#(?=.*(?<3>6))|1111111#(?=.*(?<3>7))|11111111#(?=.*(?<3>8))|111111111#(?=.*(?<3>9)))
$1#$3

Esta es la inversa de la expansión unaria anterior. Encontramos el múltiplo más grande de 10 que se ajusta a la cadena actual. Luego, elegimos el siguiente dígito en función del resto, y dividimos el múltiplo por 10, mientras movemos el marcador a través de los dígitos.

#|:.*
<empty>

Y, por último, solo un paso de limpieza para deshacerse del marcador, delimitador y los dígitos auxiliares.


Creo que debería agregar instrucciones para convertir la entrada numérica en una cadena unaria e instrucciones para volver a convertir la cadena unaria en una entrada numérica. La conversión con regex puro es genial pero demasiado torpe.
n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳

8
+1 Estaba bastante seguro de que la presentación de 2015 sería un lenguaje para el uso de CodeGolf.
Zero Fiber el

@ n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳ Lo estaba considerando antes. Creo que para la mayoría de los campos de golf de código, probablemente solo tomaría la entrada Unary (a menos que el desafío especifique explícitamente "decimal" o algo así ...). Pensé en hacer lo mismo para esto, pero este no es un código de golf, y quería mostrar que también puedo manejar la entrada y salida decimal.
Martin Ender

66
Excelente trabajo. La retina es realmente genial. Y además, ¡también es genial ver el diamante al lado de tu nombre! :)
Alex A.

Es curioso que, aunque los idiomas antiguos se vean favorecidos en esta competencia, el más joven sigue ganando =)
Claudiu

60

2013 - Snap !

Snap ! es un lenguaje basado en Scratch , hecho en la Universidad de Berkeley. Es una actualización a Scratch con datos de primera clase y bloques personalizados (funciones). Al igual que Scratch, no se basa en texto, sino que se realiza mediante "bloques" visuales que se unen.

Snap ! , escrito en JavaScript, es el sucesor de BYOB, que fue escrito en Squeak Smalltalk. Snap ! se lanzó en beta para consumo público en marzo de 2013 .

Snap ! en realidad no es un lenguaje esotérico. Se utiliza como lenguaje de programación para el curso AP CS de Belleza y Alegría de la Computación (BJC) en Berkeley y otros.

Ayudé con las pruebas y esas cosas.

Variante "Hola mundo"

Arte ASCII "N"

ingrese la descripción de la imagen aquí

Esto usa stdlib para algunos de los bloques.

Bucle bastante básico aquí. Toma una entrada. Luego lo agregamos todo junto y lo decimos (resultado para n = 5):

ingrese la descripción de la imagen aquí

Me tomé la libertad de usar solo 2 espacios en lugar de 1, porque ¡Snap! no dice cosas en el monoespacio.

GCD

El algoritmo euclidiano no es muy rápido, pero funciona y es bastante simple. (Lo siento, hice un error tipográfico en el nombre del bloque. Ahora cerré la pestaña sin guardar. Solo tendrá que quedarse).

ingrese la descripción de la imagen aquí

Esta definición de función producirá este bloque:

ingrese la descripción de la imagen aquí


3
Esto se parece MUCHO a la programación en Alice ...
mbomb007

44
Eso es lo que obtienes con los lenguajes basados ​​en bloques. Ahora que lo veo, muchos idiomas se parecen. ;)
Scimonster

1
Incluso Scratch tiene una función mod, por lo que supongo que podría hacer que el GCM / GCD funcione más rápido con un bloque basado en if (b == 0) y luego en otro GCM (b, a% b)
Alchymist

55

2007 - LOLCODE

Historia del lenguaje

LOLCODE fue creado en 2007 por Adam Lindsay, investigador de la Universidad de Lancaster. Su sintaxis se basa en los memes de lolcats popularizados por Cheezburger, Inc.

"¡Hola Mundo!" Variante

HAI
VISIBLE "LOLCODE wuz maed in 2007!"
KTHXBYE

ASCII Art N

HAI

BTW, read n from stdin
GIMMEH n

BTW, convert n from YARN to NUMBR
n R PRODUKT OF n AN 1

BOTH SAEM n AN 1, O RLY?
    YA RLY
        VISIBLE "N"
    NO WAI
        VISIBLE "N"!

        I HAS A butt ITZ 1
        IM IN YR toilet UPPIN YR butt TIL BOTH SAEM butt AN DIFF OF n AN 1
            VISIBLE " "!
        IM OUTTA YR toilet

        VISIBLE "N"

        I HAS A kat ITZ 2
        IM IN YR closet UPPIN YR kat TIL BOTH SAEM kat AN n
            VISIBLE "N"!
            BOTH SAEM kat AN 2, O RLY?
                YA RLY
                    VISIBLE "N"!
                NO WAI
                    I HAS A doge ITZ 1
                    IM IN YR l00p UPPIN YR doge TIL BOTH SAEM doge AN DIFF OF kat AN 1
                        VISIBLE " "!
                    IM OUTTA YR l00p
                    VISIBLE "N"!
            OIC

            I HAS A brd ITZ 1
            IM IN YR haus UPPIN YR brd TIL BOTH SAEM brd AN DIFF OF n AN kat
                VISIBLE " "!
            IM OUTTA YR haus

            VISIBLE "N"
        IM OUTTA YR closet

        VISIBLE "N"!

        I HAS A d00d ITZ 1
        IM IN YR lap UPPIN YR d00d TIL BOTH SAEM d00d AN DIFF OF n AN 1
            VISIBLE " "!
        IM OUTTA YR lap

        VISIBLE "N"
OIC

KTHXBYE

Los valores se leen como cadenas (YARN) de stdin usando GIMMEH. Se pueden convertir a numéricos (NUMBR) multiplicando por 1.

Los valores se imprimen en stdout usando VISIBLE. Por defecto, se agrega una nueva línea, pero se puede suprimir agregando un signo de exclamación.

GCD

HAI

GIMMEH a
a R PRODUKT OF a AN 1

GIMMEH b
b R PRODUKT OF b AN 1

I HAS A d00d ITZ 1
IM IN YR food UPPIN YR d00d TIL BOTH SAEM b AN 0
    I HAS A kitty ITZ a
    I HAS A doge ITZ b
    a R doge
    b R MOD OF kitty AN doge
IM OUTTA YR food

VISIBLE SMOOSH "gcd is " a

KTHXBYE

SMOOSH realiza la concatenación de cadenas.


13
Finalmente, un lenguaje que todos pueden entender.
ASCIIThenANSI

26
IM IN YR toilet UPPIN YR buttBuenos nombres de variables
Cole Johnson el

13
@ColeJohnson: Siempre trate de elegir los nombres de variables que tienen sentido en la situación en lugar de x1, x2, etc.
Alex A.

2
Divertidísimo. No debería leer esto en el trabajo.
Alan Hoover

@AlanHoover: Claramente, lolz son más importantes que el trabajo.
Alex A.

43

1982 - PostScript

PostScript es un lenguaje para crear gráficos vectoriales e imprimir.

Adobe fue fundado en 1982, y su primer producto fue PostScript. El lenguaje se usaba en las impresoras: la impresora interpreta los comandos para crear una imagen ráster, que luego se imprime en la página. Era un componente muy común de las impresoras láser en la década de 1990. Pero obviamente es bastante CPU intensiva en la impresora, y a medida que los procesadores de la computadora se volvieron más potentes, tenía más sentido hacer la rasterización en la computadora que en la impresora. PostScript ha desaparecido en gran medida en las impresoras de consumo, aunque todavía existe en muchas más impresoras de gama alta.

El estándar que reemplazó a PostScript es un formato poco conocido llamado PDF.

PostScript había pasado de moda cuando comencé a programar, pero aprendí un poco mientras estaba en la universidad como otra forma de crear documentos para TeX. Era bastante diferente a otros lenguajes de programación que había usado (notación infijada inversa, apilar, imprimir en una página en lugar de una consola), pero fue agradable desempolvar este viejo lenguaje para divertirme un poco.

Dado que PostScript es un lenguaje de impresión, parece más apropiado usarlo para imprimir algo y luego enviar una salida a la consola.

Tarea 1

/Courier findfont
12 scalefont
setfont
newpath

100 370 moveto
(PostScript was made in 1982!\n) show

Las primeras líneas configuran un lienzo para dibujar. Luego, el movetocomando le dice a PS que dibuje en una posición particular e showimprime la cadena en la página. Tenga en cuenta que los paréntesis marcan una cadena en PostScript, no comillas.

Tarea 2

/asciiartN {% stack: N row col
            % output: draws an "ASCII art" N

  % PostScript doesn't allow you to pass variables directly into a function;
  % instead, you have to pass variables via the global stack. Pop the variables
  % off the stack and define them locally.
  6 dict begin
  /row exch def
  /col exch def
  /N exch def

  % Define how much space will be between each individual "N"
  /spacing 15 def

  % Get the width of the "N". We need this to know where to draw the right-hand
  % vertical
  /endcol col spacing N 1 sub mul add def

  % One row is drawn at a time, with the bottom row drawn first, and working
  % upwards. This stack variable tracks which column the diagonal is in, and so
  % we start on the right and work leftward
  /diagcol endcol def

  % Repeat N times: draw one row at a time
  N {
    % Left-hand vertical of the "N"
    col row moveto
    (N) show

    % Right-hand vertical of the "N"
    endcol row moveto
    (N) show

    % Diagonal bar of the "N"
    diagcol row moveto
    (N) show

    % Advance to the next row. This means moving the row one space up, and the
    % diagonal position one place to the left.
    /row row spacing add def
    /diagcol diagcol spacing sub def

  } repeat

  end
} def

1 100 200 asciiartN
3 150 200 asciiartN
5 230 200 asciiartN

Escribí una función para dibujar el "arte ASCII" N, pero no hay forma de que las funciones PostScript tomen un argumento. En cambio, empuja sus argumentos a la pila, luego los retira. Esa es la /x exch deflinea.

Un ejemplo: supongamos que la pila es 8 9 2. Primero empujamos el nombre /xa la pila, entonces la pila es 8 9 2 /x. El exchoperador intercambia los dos valores de la pila, por lo que ahora la pila es 8 9 /x 2. Luego defmuestra los dos valores superiores de la pila, y define /xtener el valor 2. La pila es ahora 8 9.

Cuando comencé a usar PostScript, encontré esto un poco confuso. Había leído sobre la pila como un concepto teórico, pero esta era la primera vez que la usaba en la práctica.

El resto de la función es un código de dibujo: comience en la esquina inferior derecha, completando una fila a la vez de izquierda a derecha a diagonal.

Tarea 3

/modulo {% stack: x y
         % output: returns (x mod y)
  3 dict begin
  /y exch def
  /x exch def

  % If x = y then (x mod y) == 0
  x y eq {0} {

    % If x < y then (x mod y) == x
    x y lt {x} {

      % If x > y then subtract floor(x/y) * y from x
      /ycount x y div truncate def
      /x x ycount y mul sub def

      /x x cvi def
      x

    } ifelse
  } ifelse
} def

/gcd {% stack: a b
      % returns the gcd of a and b
  2 dict begin
  /b exch def
  /a exch def

  % I'm using the recursive version of the Euclidean algorithm

  % If b = 0 then return a
  b 0 eq {a} {

    % Otherwise return gcd(b, a mod b)
    /a a b modulo def
    b a gcd
  } ifelse

} def

/displaygcd {% stack: a b xcoord ycoord
             % displays gcd(a,b) at position (xcoord, ycoord)
  5 dict begin
  /ycoord exch def
  /xcoord exch def
  /b exch def
  /a exch def
  /result a b gcd def

  xcoord ycoord moveto
  result 20 string cvs show

  % end
} def

8 12 100 80 displaygcd
12 8 150 80 displaygcd
3 30 200 80 displaygcd
5689 2 250 80 displaygcd
234 876 300 80 displaygcd

Nuevamente, utilicé una forma del algoritmo de Euclid, pero olvidé que PostScript tiene un operador de módulo incorporado, así que tuve que escribir el mío. Esto resultó ser un recordatorio útil de las limitaciones de la programación basada en pila. Mi primera implementación de modulose basó en la recursividad:

modulo(x, y)
    if (x = y) return 0
    elif (x < y) return x
    else return module(x - y, y)

lo cual está bien hasta que intente ejecutar esto cuando xes grande y ypequeño (por ejemplo, 5689 y 2). Solo puede tener hasta 250 elementos en la pila, por lo que estaba superando el límite de la pila. Ups Tuve que volver al tablero de dibujo en ese.

El código GCD en sí es bastante simple. Pero así como las funciones no pueden tomar argumentos, tampoco tienen valores de retorno. En su lugar, debe empujar el resultado a la pila donde alguien más puede reventarlo más tarde. Eso es lo que ayb a gcd que hacen las líneas : cuando terminan de evaluar, empujan el valor a la pila.

Si coloca todo el código en un documento e lo imprime, así es como se ve la salida:

ingrese la descripción de la imagen aquí


8
Jaja me encanta la fotografía del trozo de papel impreso. Se siente apropiado para 1982.
Alex A.

1
Además, gracias por su descripción de cómo obtuvo un desbordamiento de pila (literal): ahora entiendo más intuitivamente por qué los idiomas tienen una profundidad de recursión máxima.
DLosc

2
@AlexA .: Sí, pero una impresión de matriz de puntos (con agujeros en los lados del papel) hubiera sido aún más apropiado . ;-)
Amos M. Carpenter

@ AmosM.Carpenter: no realmente, no creo que ninguna impresora de matriz de puntos haya admitido PostScript. Siempre ha estado bastante ligado a las impresoras láser.
ninjalj

41

2009 - > <>

Inspirado por Befunge,> <> (Fish) es un lenguaje 2D esotérico basado en la pila, es decir, el flujo del programa puede ser hacia arriba, hacia abajo, hacia la izquierda o hacia la derecha. La versión inicial de> <> presentaba subprocesos múltiples donde [y ]creaba y terminaba hilos, pero por razones de simplicidad, estas instrucciones se cambiaron para crear y eliminar nuevas pilas respectivamente.

El intérprete oficial actual para> <> se puede encontrar aquí . Desafortunadamente, el enlace al antiguo intérprete en la wiki de Esolang está roto.

"¡Hola Mundo!" Variante

"!9002 ni edam saw ><>"l?!;obb+0.

Observe cómo la cadena se escribe hacia atrás -> <> técnicamente no tiene cadenas, con el único tipo de datos que es una extraña mezcla de char, int y float. "alterna el análisis de cadenas y empuja a cada personaje a la pila hasta que se alcanza un cierre ".

La segunda mitad del código luego empuja la longitud de la pila l, comprueba si es cero ?!y, de ser así, el programa termina ;. De lo contrario, el puntero de instrucción continúa, generando la parte superior de la pila oantes de ejecutarlo bb+0., lo que teletransporta el puntero a la posición (22, 0)justo antes del , creando un bucle.

ASCII Art N

&0 > :&:&:*=?;  :&:&%  :0=?v  :&:&1-=?v  :{:{-&:&,{=?v   " " o   \

                           > ~"N"o                           v    
   +                                  > ~"N"oao              v    
   1                                                 >"N"o   v    

   \                                                         <   /

Con espacio para mayor claridad. Puede probar esto en el nuevo intérprete en línea aquí y ver el puntero de instrucciones dar vueltas y vueltas, solo recuerde ingresar un número en el cuadro de texto "Pila inicial". Si está ejecutando a través del intérprete de Python, use la -vbandera para inicializar la pila, por ej.

py -3 fish.py ascii.fish -v 5

Para este programa, colocamos la entrada nen el registro con &y presionamos un 0, que llamaremos i"iteraciones". El resto del programa es un bucle gigante que dice así:

:&:&:*=?;          If i == n*n, halt. Otherwise ...
:&:&%              Push i%n
:0=?v              If i%n == 0 ...
>~"N"o               Print "N"
:&:&1-=?v          Else if i%n == n-1 ...
>~"N"oao             Print "N" and a newline
:{:{-&:&,{=?v      Else if i%n == i//n, where // is integer division...
>~"N"o               Print "N"
" "o               Otherwise, print a space
1+                 Increment i

Luego repetimos el ciclo desde el principio.

Las flechas ^>v<cambian la dirección del flujo del programa y los espejos /\reflejan la dirección del flujo del programa.

GCD

>:{:}%\
;n{v?:/
v~@/

Aquí hay un ejemplo de cómo se vería un programa de golf> <>. Una vez más, puede probar esto en el intérprete en línea (ingrese dos valores separados por comas en el cuadro "Pila inicial", por ejemplo 111, 87) o utilizando el -vindicador del intérprete de Python, por ejemplo

py -3 fish.py gcd.fish -v 111 87

Este programa utiliza el algoritmo euclidiano. Aquí hay un GIF que preparé antes:

ingrese la descripción de la imagen aquí

Tenga en cuenta que> <> es toroidal, por lo que cuando vse ejecuta la instrucción de la parte inferior izquierda, el puntero de la instrucción va hacia abajo, se envuelve y vuelve a aparecer en la parte superior.


Editar: Al hacer que el código se ejecute completamente de derecha a izquierda , @randomra logró reducir tres bytes con

<~@v!?:%}:{:
;n{/

Supongo que no lo jugué lo suficiente :)


27
Y así fue como descubrí que el nombre ><>es un palíndromo.
Zev Eisenberg

33

2012 - Elemento

Este es un lenguaje que inventé a principios de 2012 para ser un lenguaje simple de golf. Con esto, quiero decir que hay muy poca o ninguna sobrecarga del operador. Los operadores también son más simples y menos numerosos que la mayoría de los idiomas modernos de golf.

Las características más interesantes de este lenguaje son sus estructuras de datos. Hay dos pilas y un hash que se utilizan para almacenar información.

La pila m es la pila principal, donde se realizan operaciones aritméticas y la mayoría de las demás operaciones. Cuando se ingresan o imprimen datos, aquí es donde van o se recuperan.

La pila c es la pila de control. Aquí es donde tiene lugar la aritmética booleana. Los bucles If y While utilizan los valores superiores de la pila c como condición.

El hash es donde se almacenan las variables. los; y~ almacenar y recuperar datos del hash, respectivamente.

Element es un lenguaje muy débilmente escrito. Utiliza la capacidad de Perl para interpretar libremente los números como cadenas y viceversa.

Mientras lo hago, también podría incluir toda la documentación para el idioma. Puede encontrar el intérprete original de 2012, escrito en Perl, aquí mismo . Actualización: he creado una versión más utilizable, que puedes encontrar aquí .

OP    the operator.  Each operator is a single character
STACK tells what stacks are affected and how many are popped or pushed
      "o" stands for "other effect"
HASH  tells if it involves the hash
x & y represent two values that are already on the stack, so the effect of
      the operator can be more easily described

OP     STACK  HASH   DESCRIPTION
text     ->m         --whenever a bare word appears, it pushes that string onto 
                       the main stack
_       o->m         --inputs a word and pushes onto main stack
`       m->o         --output.  pops from main stack and prints
xy;    mm->    yes   --variable assignment.  the top stack element y is assigned 
                       the value x
~       m->m   yes   --variable retrieval.  pops from main stack, pushes contents 
                       of the element with that name
x?      m->c         --test. pops x and pushes 0 onto control stack if x is '0' or 
                       an empty string, else pushes 1
><=     m->c         --comparison. pops two numbers off of stack and performs 
                       test, pushes 1 onto control stack if true and 0 if false
'       m->c         --pops from main stack and pushes onto control stack
"       c->m         --pops from control stack and pushes onto main stack
&|     cc->c         --AND/OR. pops two items from control stack, performs and/or 
                       respectively, and pushes result back onto control stack
!       c->c         --NOT. pops a number off of control stack, pushes 1 if 0 or 
                       empty string, 0 otherwise
[]       c           --FOR statement (view the top number number from control stack 
                       and eval those many times)
{}       c           --WHILE (loop until top number on control stack is 0, also 
                       does not pop)
#       m->          --discard. pops from main stack and destroys
(       m->mm        --pops from main stack, removes first character, pushes the 
                       remaining string onto stack, and pushes the removed character 
                       onto stack
)       m->mm        --pops from main stack, removes last character, pushes the 
                       remaining string onto stack, and pushes the removed character 
                       onto stack
+-*/%^ mm->m         --arithmetic. pops two most recent items, adds/negates
                       /multiplies/divides/modulates/exponentiates them, and places 
                       the result on the stack 
xy@    mm->o         --move. pops x and y and moves xth thing in stack to move to 
                       place y in stack
x$      m->m         --length. pops x and pushs length of x onto the stack
xy:    mm->o         --duplication. pops x and y and pushes x onto the stack y times
xy.    mm->m         --concatination. pops x and y and pushes x concatonated with y
\        o           --escapes out of next character, so it isn't an operator and can
                       be pushed onto the stack
,      m->mm         --character conversion. pops from main stack, coverts it to char
                       and pushes, and converts to num and pushes
Newlines and spaces separate different elements to be pushed 
onto the stack individually, but can pushed onto the stack using \

Tarea 1 - Imprimir texto

Element\ was\ made\ in\ 2012\!`

Una de las partes más incómodas del lenguaje es la falta de delimitadores de cadena, por lo que se necesitan caracteres de escape en esta cadena. El `al final imprime la cadena.

Tarea 2 - ASCII Art N

_+'[y~1+y;0[1+4:"2:'=1=|y~=|\ [#N]`"#]\
`]

Aquí, serás testigo de alguna manipulación de la pila. Para que la explicación sea un poco más fácil de formatear, reemplazaré la nueva línea con una Ly el espacio con una S.

_+'[y~1+y;0[1+4:"2:'=1=|y~=|\S[#N]`"#]\L`]
_+'      input line, convert to #, move to c-stack
[        FOR loop
 y~1+y;  increment the y-pos
 0       set the x-pos (the top # on the stack) to zero
 [       FOR loop
  1+4:   increment x-pos and make 3 additional copies (4 is total #)
  "2:'   make a copy of the N size on the main stack
  =      if x-pos == size
  1=     or if x-pos == 1
  y~=|   of if x-pos == y-pos
  \S     (always) push a space
  [      the IF body (technically a FOR loop)
   #N    if true, remove the space and push an N
  ]      end IF
  `      output the pushed character
  "#     remove the result of the conditional
 ]       end x-pos FOR
 \L`     output a newline
]        end y-pos FOR

Después de hacer un poco de golf extremo de esta respuesta, encontré una solución de 39 bytes, aunque es mucho más complicado.

_'1[y~+y;[#1+3:"2:'%2<y~=|\ [#N]`"]\
`]

Tarea 3 - MCD

__'{"3:~2@%'}`

Este es un método basado en pila.

__                 input the two numbers
  '                use one of the number as a condition so the WHILE loop starts
   {        }      a WHILE loop. Repeats while the c-stack has a true value on top
    "              get the number back from the c-stack to do operations on it
     3:            make it so that there are threes copies on the stack
       ~           takes one of the copies from earlier and converts it to a zero
        2@         take the top item on the stack and move it behind the other two #s
          %        modulo operation
           '       use this number as the condition
             `     since one number is zero (and on the c-stack) print the 
                   other number, which is on m-stack

29

2012 - Julia

Historia del lenguaje

Julia fue desarrollada en 2012 por Jeff Bezanson, Stefan Karpinski y Viral Shah, mientras que Jeff era estudiante en el Instituto de Tecnología de Massachussets (MIT), asesorado por el profesor Alan Edelman. Fueron motivados por el deseo de un lenguaje de programación que fuera de código abierto, rápido y dinámico (entre muchas otras cosas) mientras mantenía la facilidad de uso en una variedad de aplicaciones. El producto fue Julia, un nuevo enfoque para la informática científica de alto rendimiento.

"¡Hola Mundo!" Variante

println("Julia was made in 2012!")

¡Imprimir en STDOUT en Julia es bastante simple!

ASCII Art N

function asciin(n)
    # Create an nxn matrix of spaces
    m = fill(" ", (n, n))

    # Fill the first and last columns with "N"
    m[:,1] = m[:,n] = "N"

    # Fill the diagonal elements with "N"
    setindex!(m, "N", diagind(m))

    # Print each row of the matrix as a joined string
    for i = 1:n
        println(join(m[i,:]))
    end
end

El código tiene sangría para facilitar la lectura, pero Julia no impone restricciones al espacio en blanco.

GCD

function g(a, b)
    b == 0 ? a : g(b, a % b)
end

Lo último enumerado en la función se devuelve implícitamente.


27

1988 - Mathematica

¿O debería llamarlo Wolfram Language? ?

Tarea 0

El creador de Mathematica es Stephen Wolfram, el Fundador y CEO de Wolfram Research. Antes del desarrollo de Mathematica, era físico. Hubo una gran cantidad de cálculo algebraico en física, por lo que se convirtió en un usuario de Macsyma .

Wolfram obtuvo su PHD en 1979, cuando tenía 20 años. Pensó que necesitaba un mejor CAS que Macsyma para hacer física, por lo que comenzó a escribir SMP (el "Programa de Manipulación Simbólica"). La primera versión de SMP se lanzó en 1981. SMP fue el predecesor de Mathematica. Aunque tuvo una profunda influencia en Mathematica, ninguno de sus códigos fue utilizado para Mathematica.

En 1986, Wolfram decidió escribir un "sistema de cómputo definitivo". Comenzó a escribir el código en 1986 y fundó Wolfram Research en 1987. Finalmente, Mathematica 1.0 fue lanzado el 23 de junio de 1988.

Mathematica 1.0

No encontré Mathematica 1.0. De hecho, Mathematica 1.0 no tenía una versión de Windows ni de Linux. Pero encontré Mathematica 2.0 en un sitio web chino. Todavía se puede ejecutar en Windows XP.

Mathematica 2.0

Tarea 1

Print["Mathematica was made in 1988!"]

O simplemente:

"Mathematica was made in 1988!"

Tarea 2

En Mathematica de hoy, podemos escribir:

asciiArtN[n_] := Print @@@ SparseArray[{i_, 1 | i_ | n} -> "N", {n, n}, " "]

Al igual que Julia y R , esta es una solución matricial. En Mathematica, puede definir una matriz dispersa utilizando la coincidencia de patrones.

Sin embargo, SparseArrayse introdujo en Mathematica 5.0, por lo que no podemos usarlo en Mathematica 1.0.

Aquí hay una solución que funciona en Mathematica 1.0:

asciiArtN[n_] := Block[{f},
  f[i_, 1]  = "N";
  f[i_, i_] = "N";
  f[i_, n]  = "N";
  f[__]     = " ";
  Apply[Print, Array[f, {n, n}], 1];
]

No podemos escribir f[i_, 1 | i_ | n] = "N"porque Alternativesse introdujo en Mathematica 2.0.

Tarea 3

Podemos usar la función incorporada:

gcd = GCD

O podemos usar la definición del MCD:

gcd = Max[Intersection @@ Divisors[{##}]] &;

O podemos usar el LCM , aunque más comúnmente el LCM se calcula a partir de GCD:

gcd = Times[##]/LCM[##] &;

O podemos usar el algoritmo euclidiano con coincidencia de patrones:

gcd[a_, 0] := a
gcd[a_, b_] := gcd[b, Mod[a, b]]

O como una función anónima:

gcd = If[#2 == 0, #1, #0[#2, Mod[##]]] &;

Todas las funciones anteriores se introdujeron en Mathematica 1.0.


3
Esta es una respuesta mucho mejor que la mía. Eliminaré el mío.
Martin Ender

25

1999 - XSLT

El Consorcio de la World Wide Web (W3C) creó XSLT para transformar XML en HTML, texto, etc. Los siguientes ejemplos asumen que la entrada está encerrada en <input>..</input>etiquetas.

Tarea 1

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="text" indent="no"/>
  <xsl:template match="/input">XSLT was made in 1999!</xsl:template>
</xsl:stylesheet>

Este es simple. Coincide con uninput etiqueta en el nivel superior y la reemplaza con la salida deseada.

Tarea 2

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="text" indent="no"/>
  <xsl:template match="/input">
    <xsl:call-template name="loop">
      <xsl:with-param name="i">1</xsl:with-param>
      <xsl:with-param name="n">
        <xsl:value-of select="."/>
      </xsl:with-param>
    </xsl:call-template>
  </xsl:template>
  <xsl:template name="loop">
    <xsl:param name="i"/>
    <xsl:param name="n"/>
    <xsl:choose>
      <xsl:when test="$i = 1 or $i = $n">
        <xsl:text>N</xsl:text>
        <xsl:call-template name="spaces">
          <xsl:with-param name="n">
            <xsl:value-of select="$n - 2"/>
          </xsl:with-param>
        </xsl:call-template>
        <xsl:text>N&#13;&#10;</xsl:text>
      </xsl:when>
      <xsl:otherwise>
        <xsl:text>N</xsl:text>
        <xsl:call-template name="spaces">
          <xsl:with-param name="n">
            <xsl:value-of select="$i - 2"/>
          </xsl:with-param>
        </xsl:call-template>
        <xsl:text>N</xsl:text>
        <xsl:call-template name="spaces">
          <xsl:with-param name="n">
            <xsl:value-of select="$n - $i - 1"/>
          </xsl:with-param>
        </xsl:call-template>
        <xsl:text>N&#13;&#10;</xsl:text>
      </xsl:otherwise>
    </xsl:choose>
    <xsl:if test="$i &lt; $n">
      <xsl:call-template name="loop">
        <xsl:with-param name="i">
          <xsl:value-of select="$i + 1"/>
        </xsl:with-param>
        <xsl:with-param name="n">
          <xsl:value-of select="$n"/>
        </xsl:with-param>
      </xsl:call-template>
    </xsl:if>
  </xsl:template>
      <xsl:template name="spaces">
    <xsl:param name="n"/>
    <xsl:if test="$n &gt; 0">
      <xsl:text> </xsl:text>
      <xsl:call-template name="spaces">
        <xsl:with-param name="n">
          <xsl:value-of select="$n - 1"/>
        </xsl:with-param>
      </xsl:call-template>
    </xsl:if>
  </xsl:template>
</xsl:stylesheet>

Este define 2 plantillas recursivas, loopy spaces. loopcon parámetros iy ngenerará la salida deseada para n, comenzando en la posición i. spacescon parámetro ngenerarán espacios.

Tarea 3

La entrada para esto debe estar en las <input><num>..</num><num>..</num></input>etiquetas.

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="text" indent="no"/>
  <xsl:template match="/input">
    <xsl:call-template name="gcd">
      <xsl:with-param name="a"><xsl:value-of select="num[1]"/></xsl:with-param>
      <xsl:with-param name="b"><xsl:value-of select="num[2]"/></xsl:with-param>
    </xsl:call-template>
  </xsl:template>
  <xsl:template name="gcd">
    <xsl:param name="a"/>
    <xsl:param name="b"/>
    <xsl:choose>
      <xsl:when test="$b = 0"><xsl:value-of select="$a"/></xsl:when>
      <xsl:otherwise>
        <xsl:call-template name="gcd">
          <xsl:with-param name="a"><xsl:value-of select="$b"/></xsl:with-param>
          <xsl:with-param name="b"><xsl:value-of select="$a mod $b"/></xsl:with-param>
        </xsl:call-template>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>
</xsl:stylesheet>

Esta es solo una plantilla recursiva gcdque utiliza el algoritmo euclidiano.


¡Y dicen que INTERCAL es raro!
kirbyfan64sos

2
@ kirbyfan64sos Para ser justos, de todos modos no debería usarse para estas cosas ...
LegionMammal978

24

2014 - CJam

CJam fue creado por el usuario aditsu PPCG y fue lanzado alrededor de abril de 2014 .

"¡Hola Mundo!" Variante

"CJam was made in 2014!"

CJam imprime automáticamente el contenido de la pila al final del programa

ASCII Art N

ri:R'#*a_R2-,{_)S*'#+\R((-zS*+}%+\+R<zN*

Explicación del código:

ri:R                                       "Read the input as integer in R";
    '#*a                                   "Get a string of R # and wrap it in an array";
        _R2-,{                }%           "Copy that string and then run this loop R-2";
                                           "times for the diagonal";
              _)S*                         "Get iteration index + 1 spaces";
                  '#+                      "Append the hash";
                     \R((-zS*+             "Append remaining spaces";
                                +\+        "Append and prepend the initial # string";
                                   R<      "Take only R columns/rows. This is for";
                                           "tackling input 1";
                                     zN*   "Transpose and join with new lines";

Toma la altura / anchura de N como entrada a través de STDIN. Pruébalo en línea aquí

GCD

l~{_@\%}h;

Toma los dos números como entrada a través de STDIN. Pruébalo en línea aquí


Me doy cuenta de que esto no es [código-golf], pero puedes acortar el programa ASCII-art N ri_S*0'NtW'Nta1$*\,Sf*'Nf+..e>N*en la CJam moderna.
Esolanging Fruit

24

1990 - Haskell

Haskell es un lenguaje funcional puro (¿o debería decir: el más popular ?). Se destaca de la corriente principal por su modelo de evaluación inusual (por defecto, todo es vago o, técnicamente, no estricto) y por su sistema de tipo basado en Hindley-Milner que, incluso ahora, sigue siendo uno de los más poderosos.

Tarea 1

main = putStrLn "Haskell was made in 1990!"

Tarea 2

-- Infinite list of growing letters 'N'
bigNs :: [[[Char]]]
bigNs = ["N"]
      : ["NN","NN"]
      : [ ins (ins 'N' t) $ map (ins ' ') n | n@(t:_) <- tail bigNs ]

-- Insert a new element after the head (i.e. at the second position).
ins :: a -> [a] -> [a]
ins x (l:ls) = l:x:ls

Demostración, imprima toda la lista infinita (hasta que el usuario aborte o el mundo termine ...)

GHCi> mapM_ (putStrLn . unlines) bigNs
N

NN
NN

N N
NNN
N N

N  N
NN N
N NN
N  N

N   N
NN  N
N N N
N  NN
N   N

N    N
NN   N
N N  N
N  N N
N   NN
N    N

...

Por supuesto, puede acceder fácilmente a uno de estos, accediendo solo a un elemento de la lista infinita:

main :: IO ()
main = do
   i <- readLn
   putStrLn . unlines $ bigNs!!i

Tarea 3

gcd' :: Integer -> Integer -> Integer
gcd' a 0 = a
gcd' a b = gcd' b $ a`mod`b

23

1972 - INTERCAL

Y pensaste que Fortran y Cobol eran raros. ¡Esto es una locura!

Tarea 1

DO ,1 <- #27
DO ,1SUB#1 <- #110
DO ,1SUB#2 <- #32
DO ,1SUB#3 <- #72
PLEASE DO ,1SUB#4 <- #136
DO ,1SUB#5 <- #88
DO ,1SUB#6 <- #136
PLEASE DO ,1SUB#7 <- #64
DO ,1SUB#8 <- #80
DO ,1SUB#9 <- #46
PLEASE DO ,1SUB#10 <- #22
DO ,1SUB#11 <- #104
DO ,1SUB#12 <- #184
PLEASE DO ,1SUB#13 <- #202
DO ,1SUB#14 <- #78
DO ,1SUB#15 <- #48
PLEASE DO ,1SUB#16 <- #96
DO ,1SUB#17 <- #128
DO ,1SUB#18 <- #162
PLEASE DO ,1SUB#19 <- #110
DO ,1SUB#20 <- #32
DO ,1SUB#21 <- #114
PLEASE DO ,1SUB#22 <- #120
DO ,1SUB#23 <- #240
DO ,1SUB#24 <- #128
PLEASE DO ,1SUB#25 <- #208
DO ,1SUB#26 <- #200
DO ,1SUB#27 <- #52
DO READ OUT ,1
DO GIVE UP

No voy a tratar de explicar el sistema de entrada y salida de INTERCAL; Solo lee esto y espero que no mueras.

Tarea 2

DO WRITE IN 7
DO .1 <- .7
DO .2 <- #1
PLEASE DO (1010) NEXT
DO .8 <- .3
DO .5 <- .7
DO .6 <- .8
DO ,9 <- #2

DO (100) NEXT
DO (1) NEXT

(100) DO (99) NEXT
DO ,9SUB#1 <- #142
DO ,9SUB#2 <- #114
PLEASE DO READ OUT ,9
DO ,9SUB#1 <- #176
DO ,9SUB#2 <- #80
PLEASE DO READ OUT ,9
PLEASE GIVE UP

(99) DO .1 <- .7
DO .2 <- #1
PLEASE DO (1010) NEXT
DO .1 <- '.3~.3'~#1
PLEASE DO FORGET .1
DO RESUME #1

(1) PLEASE DO (3) NEXT
PLEASE DO FORGET #1
DO (1) NEXT

(3) DO (4) NEXT
PLEASE GIVE UP

(4) DO (8) NEXT
DO ,9SUB#1 <- #176
DO ,9SUB#2 <- #80
PLEASE DO READ OUT ,9
DO .6 <- .8
DO .1 <- .5
DO .2 <- #1
DO (1010) NEXT
DO .5 <- .3
DO .1 <- '.5~.5'~#1
PLEASE DO FORGET .1
DO RESUME #1

(8) DO (5) NEXT

(5) PLEASE DO (6) NEXT
PLEASE DO FORGET #1
DO (5) NEXT

(6) PLEASE DO (7) NEXT
DO RESUME #2

(7) DO (10) NEXT
DO .1 <- .6
DO .2 <- #1
PLEASE DO (1010) NEXT
DO .6 <- .3
DO .1 <- '.6~.6'~#1
PLEASE DO FORGET .1
DO RESUME #1

(10) DO (11) NEXT
DO (13) NEXT
DO (14) NEXT
DO (15) NEXT

(11) DO (111) NEXT
DO (112) NEXT

(13) DO (113) NEXT
DO (112) NEXT

(14) DO (114) NEXT
DO (112) NEXT

(111) DO .1 <- .6
DO .2 <- .8
DO (1010) NEXT
DO .1 <- '.3~.3'~#1
PLEASE DO FORGET .1
DO RESUME #1

(112) DO ,9SUB#1 <- #142
DO ,9SUB#2 <- #114
PLEASE DO READ OUT ,9
DO RESUME #3

(113) DO .1 <- .6
DO .2 <- #1
DO (1000) NEXT
DO .1 <- .5
DO .2 <- .3
DO (1010) NEXT
DO .1 <- '.3~.3'~#1
PLEASE DO FORGET .1
DO RESUME #1

(114) DO .1 <- '.6~.6'~#1
PLEASE DO FORGET .1
DO RESUME #1

(15) DO ,9SUB#1 <- #252
DO ,9SUB#2 <- #4
PLEASE DO READ OUT ,9
DO RESUME #2

Gracia divina. Esto me llevó un poco entender. Los números de las etiquetas son un desastre y, por lo tanto, reflejan eso. No voy a tratar de explicar esto a menos que alguien pregunte.

Tarea 3

DO WRITE IN .5
DO WRITE IN .6

DO (1) NEXT

(1) PLEASE DO (3) NEXT
DO FORGET #1
DO (1) NEXT

(3) DO (4) NEXT
DO READ OUT .5
PLEASE GIVE UP

(4) DO .1 <- .5
DO .2 <- .6
PLEASE DO (1040) NEXT
DO .1 <- .3
DO .2 <- .6
PLEASE DO (1039) NEXT
DO .2 <- .3
DO .1 <- .5
DO (1010) NEXT
DO .5 <- .6
DO .6 <- .3
DO .1 <- '.6~.6'~#1
PLEASE DO FORGET .1
DO RESUME #1

Este es un poco más simple. Debido a la rareza de INTERCAL, debe ingresar los números de esta manera:

THREE FIVE

Por ejemplo, para obtener el MCD de 42 y 16, ingresaría:

FOUR TWO
ONE SIX

También imprime el número en números romanos ... ¡porque eso es INTERCAL para ti!


2
¿No debería ser 19 7 2? (Puedo entender si está un poco mareado después de escribir esto: P) Su respuesta se considera inválida debido a este error, lo que sería una pena.
marinus

@marinus Gracias! ¡Fijo!
kirbyfan64sos

55
POR FAVOR explique. (Cuando tenga tiempo, por supuesto.)
DLosc

1
¡INTERCAL es mi idioma favorito que nunca he aprendido!
CJ Dennis

1
PLEASE GIVE UP. Ya lo hice .-.
RedClover

23

1967 - APL

En 1957, en la Universidad de Harvard, Ken Iverson comenzó a desarrollar una notación matemática para la manipulación de matrices. Durante la década de 1960, su notación se desarrolló en un lenguaje de programación en IBM. La primera implementación parcial se creó en 1963, e incluso se usó en una escuela secundaria para enseñar a los estudiantes sobre las funciones trascendentales. Una implementación completa y utilizable tuvo que esperar hasta 1965. Durante dos años solo fue utilizada internamente por IBM. En 1967, IBM lanzó al público un intérprete APL que se ejecutó en la computadora IBM 1130, que se había terminado en 1966. Puede comprender que es un poco difícil elegir un año para ello, sin embargo, creo que debería ser 1967, Como este es el primer año, se puso a disposición del público una implementación completa. Si alguien realmente no está de acuerdo, podría cambiarlo.

El código fuente de APL \ 360 está en línea , al igual que un emulador. Esto es lo que he usado para probar estos ejemplos. Data de 1967, y junto con APL \ 1130 (para el mencionado IBM 1130) es más o menos el verdadero original. Como se esperaba, es muy primitivo. Carece de soporte para sutilezas como letras minúsculas, cualquier operador solo funciona con funciones incorporadas, y el conjunto de funciones incorporadas es muy escaso (en particular, es único or y no se duplica gcd). La descripción completa original está disponible aquí , sin embargo, noté que la versión que tenía ni siquiera está completa con respecto a ese documento, faltando entre otros.

He proporcionado los programas tanto en formato Unicode (para que pueda leerlos) como en la codificación original (para que pueda cortarlos y pegarlos en la ventana APL del emulador).

Increíblemente, estos programas se ejecutan correctamente sin ningún cambio (excepto la codificación) en las versiones modernas de Dyalog, NARS2000 y GNU APL. Así que creo que he encontrado la manera de escribir APL portátil: ¡solo finja que es 1967!

Tarea 1:

Unicode:

⎕←'APL WAS MADE IN 1967!'

APL \ 360:

L[Kapl was made in 1967ÝK

Tarea 2:

Unicode:

⎕←' N'[1+((2⍴N)⍴(⍳N)∊1,N)∨(⍳N)∘.=⍳N←⎕]

APL \ 360:

L[K nK;1-::2Rn"R:In"E1,n"(:In"J.%In[L'

Tarea 3:

He resuelto esto de la manera recursiva estándar. En teoría, podría hacer algo inteligente y orientado a la matriz, como la respuesta J; en la práctica, sin embargo, el uso de memoria O (N) y abruma rápidamente el hardware y el software de la era Flower-Power.

Unicode:

∇R←A GCD B
R←A
→(B=0)/0
R←B GCD B|A
∇

⎕←⎕ GCD ⎕

APL \ 360:

Gr[a gcd b
r[a
{:b%0"/0
r[b gcd bMa
G

L[L gcd L

Esto es asombroso
Alex A.

22

1996 - Ocaml

Estaba esperando más de un día para que alguien llenara 1996, para poder llenar Ruby. Bueno, ¿por qué no aprender OCaml entonces, parece similar a haskell ...

Hola Mundo

print_endline "OCaml was made in 1996!";;

ASCII

let ascii n =
  let rec ascii' = function
    | 0 -> ()
    | i ->
        let s = "N" ^ String.make (n-2) ' ' ^ "N" in
        String.fill s (n-i) 1 'N';
        print_endline s;
        ascii' (i-1)
  in ascii' n;;

Cuerdas mutables!

GCD

let rec gcd a b = if b = 0 then a else gcd b (a mod b);;

No ==e infijo mod, eso es lindo


Lo siento, completé Ruby :)
Zero Fiber

44
+1 para aprender un idioma solo para responder a este desafío. :)
Alex A.

¡Acabas de aprender F # también! (es OCaml en el CLR más algunos extras).
Robert Fraser

22

2005 - Preludio

Preludio es un lenguaje muy divertido, cuyo código fuente se compone de varias "voces" que se ejecutan en paralelo y que yo realmente disfruto de la solución de problemas en . Se supone que es la representación ASCII de su fuga de lenguaje hermano , que en realidad toma archivos .midi como código fuente y codifica las instrucciones que se encuentran en Prelude como intervalos en las melodías de las voces.

Prelude es bastante minimalista, pero Turing completo (siempre que esté utilizando al menos 2 voces). Como dije, las voces (líneas de código) se ejecutan simultáneamente, columna por columna. Cada voz opera en su propia pila, que se inicializa en un número infinito de ceros. Prelude admite las siguientes instrucciones:

0-9 ... Push the corresponding digit.
+   ... Add the top two numbers on the stack.
-   ... Subtract the top number from the one beneath.
#   ... Discard the top of the stack.
^   ... Copy the top value from the voice above.
v   ... Copy the top value from the voice below.
?   ... Read a number and push it onto the stack.
!   ... Print the top number (and pop it from the stack).
(   ... If the top of the stack is zero, jump past the matching ')'.
)   ... If the top of the stack is zero, jump to the column after the matching '('.

Algunas notas adicionales:

  • Las voces son cíclicas, entonces ^ en la parte superior se copian las voces de la voz inferior (y viceversa).
  • Múltiples ?y !en la misma columna se ejecutan de arriba a abajo.
  • Según la especificación del idioma , ?y !leer y escribir caracteres con el código de caracteres correspondiente. Sin embargo, el intérprete de Python también tiene un interruptor en su código para imprimir los números en su lugar. Para fines de prueba, en realidad estoy usando una versión modificada que también puede leer números en lugar de caracteres. Pero el consenso aquí es que la entrada / salida numérica en realidad se puede dar como valores de byte, por lo tanto, estas modificaciones no son necesarias para hacer programas válidos que se ocupen de números.
  • Coincidencia (y )no necesita estar en la misma voz. La voz utilizada para la condición es siempre la que (aparece. Por lo tanto, la posición vertical de la )es completamente irrelevante.
  • Debido a la naturaleza de la ejecución simultánea de Prelude, cualquier instrucción en la misma columna que a (se ejecuta solo una vez antes de que comience el ciclo, independientemente de si se ingresó o no. Del mismo modo, cualquier instrucción en la misma columna que a )se ejecuta al final de cada iteración, independientemente de si el bucle se cerrará después de esta iteración.

Primero te mostraré los tres programas sin mucho comentario. Puede encontrar explicaciones extensas a continuación.

Los programas

"¡Hola Mundo!" Variante

9(1-)v98+^++!9v+!  v88++2+!^  ! ^9-3-! v      !    v2-!55+!
8 8+ !     7v+! 1v+!88+^+!^4-!^ v8-^ !!!9v+  !^9+9+!  v5+!
     ^98++4+! ^8-! ^4-   ^ #!^6-!    ^^  #5+! v    ^2-!1+!

Si está utilizando el intérprete de Python, asegúrese de que NUMERIC_OUTPUT = False .

ASCII Art N

      v2-(1-)v         
9(1-)?1-( v!  (1-55+!      0     (0)#  ))55+!
4-4+                  v^-#
     v!      v! v1-v!(1- ^(#^!0)# v! )v!
6 8+           v#

Para facilitar su uso, este programa se beneficia de leer la entrada como números, pero la salida no debe ser numérica. Entonces, si está utilizando el intérprete de Python modificado, establezca

NUMERIC_INPUT = True
NUMERIC_OUTPUT = False

GCD

?(                         v)
? (^-(0 # v   #       ^+0)#^ !
     ^^ (##v^v+)#  0 (0 )   
      1) ^ #  - 1+(#)#

Esto se usa mejor con todas las entradas / salidas numéricas, es decir

NUMERIC_INPUT = True
NUMERIC_OUTPUT = True

Explicaciones

"¡Hola Mundo!" Variante

Esto es bastante sencillo. Estoy usando 3 voces para generar sucesivamente los códigos de caracteres para todos los personajes Prelude was made in 2005!. Comienzo computando 8 + 9*8 = 80, que es el código de caracteres de P:

 9(1-)
 8 8+

Después de eso, solo copie el código de caracteres anterior y sumo o reste la diferencia al siguiente. Aquí está el código, pero con cada uno !reemplazado por el carácter que se está imprimiendo (y _para espacios y %para los dígitos):

9(1-)v98+^++r9v+u  v88++2+w^  _ ^9-3-a v      _    v2-%55+!
8 8+ P     7v+l 1v+e88+^+_^4-s^ v8-^ de_9v+  n^9+9+%  v5+%
     ^98++4+e ^8-d ^4-   ^ #a^6-m    ^^  #5+i v    ^2-%1+!

El final 55+!imprime una nueva línea final, solo porque es más agradable.

Como nota al margen, el número de voces es bastante arbitrario para esta tarea, pero 3 es bastante conveniente porque es el número más grande en el que cada voz puede acceder directamente entre sí.

ASCII Art N

      v2-(1-)v         
9(1-)?1-( v!  (1-55+!      0     (0)#  ))55+!
4-4+                  v^-#
     v!      v! v1-v!(1- ^(#^!0)# v! )v!
6 8+           v#

Con 5 voces, este es definitivamente uno de los programas más complejos que he escrito hasta ahora. Las voces tienen aproximadamente los siguientes propósitos:

  1. Simplemente una voz auxiliar que se almacena N-1para usar en el bucle interno.
  2. Esta es una especie de voz "principal", que lee la entrada, contiene un interruptor importante y también contiene el bucle externo (es decir, el que está sobre las filas).
  3. Esto almacena un 32espacio para imprimir convenientemente.
  4. Contiene el bucle interno (el que está sobre las columnas).
  5. Esto almacena un 78para imprimir convenientemente Ns.

Veamos el código parte por parte. Primero, estoy creando el 32as -4 + 9*4y el 78as 6 + 9*8:

9(1-)
4-4+

6 8+

Ahora estoy imprimiendo un solo N(porque siempre necesitamos uno) mientras leo la entrada Ny el almacenamiento N-1y N-2en las dos primeras voces:

      v2-
     ?1-

     v!

A continuación, hay un "bucle" condicionado N-1. Al final del ciclo, la segunda voz siempre se reduce a 0, y el ciclo sale después de la primera iteración. Entonces, esencialmente, esto solo if(N > 1){...}. Después del bucle, imprimimos una nueva línea final. Para recapitular, ahora tenemos el siguiente marco:

      v2-
9(1-)?1-(                               )55+!
4-4+
     v!
6 8+

Dentro de este condicional, primero N-2espacios y un solo Npara completar la primera fila, y también almacenamos N-1en la primera voz para uso futuro:

         (1-)v         
          v!  

             v!

Ahora la verdadera carne del código. Primero, hay un bucle externo, que imprime N-1filas. Para cada fila, primero imprimimos una nueva línea y una N. Luego, recorremos los N-2tiempos, imprimiendo espacios o Ns (más sobre eso más adelante). Y finalmente imprimimos otro N:

               1-55+!  

                v1-v!(               )v!
               v#

Finalmente, la parte divertida: imprimir cada fila (y obtener la posición de la Nderecha). Realmente no hay un if / else en Prelude, así que tengo que construirlo yo mismo usando dos bucles en diferentes voces. La condición se puede obtener fácilmente restando la variable de bucle interno y externo; obtenemos 0si queremos imprimirN y algo distinto de cero si queremos imprimir un espacio.

La idea básica de un if / else en Prelude es colocar un bucle después del valor relevante, el código "if" (o no cero), y salir inmediatamente presionando a 0. En otra voz, mantienes un valor distinto de cero y otro ciclo después del ciclo "if". Durante el ciclo "if" pones un cero encima de esa otra voz, para evitar que se ejecute el "else". Hay cierta flexibilidad en si empuja los valores cero encima de los valores distintos de cero o simplemente descarta el valor distinto de cero si hay un cero debajo, pero esta es la idea general. Es posible que también deba realizar una limpieza posterior, si desea seguir usando la voz relevante. Así es como se ve el código:

                           0     (0)#
                      v^-#
                      1- ^(#^!0)# v! 

¡Y eso es!

GCD

Esto es "solo" una implementación iterativa del algoritmo euclidiano. Pero el módulo en Prelude es un poco molesto, principalmente porque no se puede verificar fácilmente si un número es positivo o negativo. Este código hace uso de una implementación de signum que escribí hace un tiempo . Es decir, una gran parte del código simplemente convierte un número en -1, 0o 1. Esto puede convertirse fácilmente en una condición para números positivos o negativos sumando o restando 1.

?(                         v)
? (^-(0 # v   #       ^+0)#^ !
     ^^ (##v^v+)#  0 (0 )   
      1) ^ #  - 1+(#)#

Entonces tenemos cuatro voces esta vez. La primera voz simplemente realiza un seguimiento by contiene la condición de terminación principal (es decir, el bucle sale cuando se bconvierte 0). La segunda voz contiene ay con la ayuda de las voces tres y cuatro cálculos a % b, antes de intercambiar el resultado con el anterior b. Finalmente, las !impresiones acuando b == 0.

Veamos primero la parte de signum :

     (0 # v   #
     ^^ (##v^v+)#
      1) ^ #  -

El número de entrada nse encuentra en la primera de esas voces (la segunda voz en el programa completo). El resultado terminará en la voz inferior. Se espera que las otras dos voces estén vacías (es decir, llenas de ceros). Tenga en cuenta que, si n == 0, se saltan ambos bucles y la voz de fondo todavía contiene 0, justo lo que queremos.

Si nno es cero, se ingresa el primer bucle pequeño. Presionamos un cero para salir de inmediato, colocamos dos copias nen la voz media y una 1en la voz inferior. Ahora la idea básica es incrementar una de las copias nmientras se disminuye la otra copia nhasta que una de ellas llegue a cero. Mientras lo hace, la 1voz en la parte inferior cambia su signo todo el tiempo (lo que se hace fácilmente restando de 0debajo de él en la pila). Esto se configura de tal manera que cuando uno de los números llegue a cero, la voz inferior contendrá el signo correcto.

Ahora módulo se implementa restando ba partir ahasta que el resultado es negativo. Cuando eso sucede, agregamos uno bnuevamente. Esa es esta parte:

  (^-  signum         ^+0)#
       signum      0 (0 )   
       signum   1+(#)#

Observe la construcción if / else en la parte inferior, que es similar a la que utilicé para la Tarea 2.


2
Esto realmente debería ser parte de un tutorial de Prelude.
Alex A.

21

2007 - Scratch

Scratch es un lenguaje hecho por el MIT con fines educativos. He estado muy involucrado con esto durante 5 años; Más sobre eso más tarde.

Todo esto se puede ver aquí .

Estoy muy apurado ahora y explicaré los fragmentos más tarde. Sin embargo, espero que se expliquen por sí mismos.

Tarea 1

ingrese la descripción de la imagen aquí

Tarea 2

ingrese la descripción de la imagen aquí

Tarea 3

ingrese la descripción de la imagen aquí


¿Ya es más tarde?
dfeuer

21

1972 - C

Todos sabemos acerca de C, ¿no? C fue creado en Bell Labs, junto con Unix. Unix se escribió en gran parte en C. Todos los derivados modernos de Unix todavía se escriben en gran medida en la sintaxis de C. C ha influido en muchos, muchos lenguajes de programación. Es probablemente el lenguaje de programación más antiguo que todavía se usa ampliamente para nuevos desarrollos.

C en sí es un descendiente de B, que espero que también termine en esta lista. No había lenguaje de programación 'A': B es una variante de BCPL, que a su vez es una CPL reducida. Ninguno de estos idiomas fue muy popular. Sin embargo, BCPL fue el idioma en el que se escribió el primer programa "Hello World". Otro hecho interesante es que B tenía ambos /* */y //comentarios, pero C dejó caer los //comentarios. Posteriormente se reintrodujeron en C con el estándar C99.

Los programas C aquí se probaron con el compilador Unix V5 C, de 1974. Este fue el compilador C más antiguo que pude encontrar y poner en funcionamiento, y estos programas no se compilarán en un compilador C moderno. (Uno de los cambios realizados es que los operadores de mutación como se +=solían escribir =+).

#include <... >aún no existía. Tampoco gran parte de la biblioteca estándar. Tenía que escribir el mío atoi. Revisé parte del código fuente V5 para descubrir qué cosas estaban permitidas y cuáles no. La versión que utilicé fue la primera en incluir structs, pero como no los usé , y la sintaxis no parece haber cambiado mucho hasta V7 (como K&R C), esto podría funcionar también con versiones anteriores.

He hecho todo lo posible para escribir mi código en el mismo estilo que usa el código fuente V5. (Sin embargo, eso no es terriblemente consistente).

Busque aquí enlaces a Unix V5, un emulador, e instrucciones sobre cómo ejecutarlo en una computadora moderna.

Tarea 1

main()
{
   write(1, "C was made in 1972!\n", 20);
}

Tarea 2

atoi(str)
char *str;
{
    register num, digit;
    while (digit = *str++) {
        num =* 10;
        num =+ digit - '0';

    }
    return num;
}

N(n)
{
    register x, y;
    for (y=1; y<=n; y++) {
        for (x=1; x<=n; x++) {
            write(1, " N"+(x==1||x==y||x==n), 1);
        }
        write(1, "\n", 1);
    }
}

main(argc, argv)
char *argv[];
{
    N(atoi(argv[1]));
}

Tarea 3

atoi(str)
char *str;
{
    register num, digit;
    while (digit = *str++) {
        num =* 10;
        num =+ digit - '0';
    }
    return num;
}

gcd(a, b)
{
    return b ? gcd(b, a%b) : a;
}

main(argc, argv)
char *argv[];
{
    printf("%d\n", gcd(atoi(argv[1]), atoi(argv[2])));
}

Wow, nunca me di cuenta de cuánto ha cambiado C ... ¿De dónde sacaste ese compilador?
kirbyfan64sos

1
El compilador es el que se incluye con Unix V5. Hay un enlace en la descripción de una publicación de blog que muestra dónde obtener los archivos y cómo ejecutarlos en una computadora moderna. (Está aquí ) Una vez que lo tenga en ejecución, puede obtener el código usando cat > file.c. (Termina con Ctrl-D, como siempre). También, C ha cambiado menos de lo que parece: si se cambia la =*y =+en las atoifunciones de los equivalentes modernos*= y +=, un moderno GCC los compilará bien y correr, también. Casi ninguna advertencia, incluso.
marinus

1
minnie.tuhs.org/cgi-bin/utree.pl?file=V2/c es el primer compilador de C que pude encontrar (de V2, con fecha '72).
Oberon

20

2009 - Idris

Idris es un lenguaje funcional puro de tipo confiable que enfatiza que, de hecho, es prácticamente utilizable para aplicaciones del mundo real, además de ofrecer las posibilidades de prueba extremadamente rigurosas que se pueden lograr con tipos dependientes.

Tarea 1

module Main

main : IO ()
main = putStrLn "Idris was made in 2009!"

Tarea 2

module InN

import Data.Fin
import Data.Vect

genN : Vect n (Vect n Char)
genN = [[ if inN x y then 'N' else ' ' | x<-range ]| y<-range ]

||| Helper function, determines whether the char at coordinate (x,y)
||| is part of the letter:
inN : Fin n -> Fin n -> Bool
inN {n=S _} x y = x==0 || x==y || x==last

Este no es un programa sino solo una función (más precisamente, valor dependiente ), que produce la letra N deseada como una matriz bidimensional.

$ idris ascii-n.idr 
     ____    __     _                                          
    /  _/___/ /____(_)____                                     
    / // __  / ___/ / ___/     Version 0.9.17.1-
  _/ // /_/ / /  / (__  )      http://www.idris-lang.org/      
 /___/\__,_/_/  /_/____/       Type :? for help               

Idris is free software with ABSOLUTELY NO WARRANTY.            
For details type :warranty.
Type checking ./ascii-n.idr
*ascii-n> genN {n=4}
[['N', ' ', ' ', 'N'],
 ['N', 'N', ' ', 'N'],
 ['N', ' ', 'N', 'N'],
 ['N', ' ', ' ', 'N']] : Vect 4 (Vect 4 Char)

Tarea 3

module gcd

gcd' : Nat -> Nat -> Nat
gcd' a Z = a
gcd' a b = gcd' b $ a`mod`b

Tenga en cuenta que tuve que elegir el nombre gcd'porque ya gcdestá definido en el preludio Idris.

Type checking ./gcd.idr
*gcd> gcd' 8 12
4 : Nat
*gcd> gcd' 12 8
4 : Nat
*gcd> gcd' 234 876
6 : Nat

Eso se ve como tomaron Haskell, intercambian :y ::, y cambiaron _a Z.
wchargin

@WChargin Zes en realidad el constructor de 0 : Nat. El guión bajo se usa en Idris al igual que en Haskell.
dejó de girar en sentido contrario a las agujas del reloj el

oh, bueno, ahí lo tienes! :)
wchargin

19

2014 - Pyth

Como tenemos CJam, también podríamos tener Pyth para completar :)

Pyth es un lenguaje de golf de @isaacg que se compila en Python. Es notable por ser procesal y por usar la notación de prefijo. Pyth apareció por primera vez alrededor de junio de 2014 .

"¡Hola Mundo!" Variante

"Pyth was made in 2014!

Tenga en cuenta la falta de una cita de cierre, que es opcional si un programa Pyth termina en una cadena.

ASCII Art N

VQ+\Nt+P++*Nd\N*t-QNd\N

Pruébalo en línea . El Python equivalente es:

Q = eval(input())
for N in range(Q):
    print("N"+((" "*N+"N"+(Q-N-1)*" ")[:-1]+"N")[1:])

O expandido (la primera y la tercera línea son implícitas):

Q = eval(input())                                        # 
for N in range(Q):                                       #   VQ
    print(                                          )    # 
          "N"+                                           #     +\N
              (                                )[1:]     #        t
                                           +"N"          #         +              \N
               (                     )[:-1]              #          P
                         +(Q-N-1)*" "                    #           +      *t-QNd
                     +"N"                                #            +   \N
                " "*N                                    #             *Nd

GCD

=GvwWQAGQ,Q%GQ)G

Este programa utiliza el algoritmo euclidiano y toma dos números separados por una nueva línea. Pruébalo en línea .

Q = eval(input())     #
G = eval(input())     #    =Gvw
while Q != 0:         #        WQ
  G, Q = Q, G % Q     #          AGQ,Q%GQ)
print(G)              #                   G

i.uQes aún más corto si usamos el incorporado para GCD. Esto es equivalente a print(gcd(*eval(input())))(tomar dos números separados por comas como entrada).


Drat - Iba a hacer Pyth xP
theonlygusti el

@isaacg No puedo evitar preguntarme, y podría preguntarlo aquí: ¿Pyth se inspiró en pyg de alguna forma?
Aprıʇǝɥʇuʎs

@ ɐɔıʇǝɥʇuʎs Había visto PYG antes de hacer Pyth, y podría haber influido en el enfoque de 1 personaje - 1 concepto. Sin embargo, si algo inspiró a Pyth, probablemente fue golfscript.
isaacg

17

1964 - Dartmouth BASIC

BÁSICO es una familia de lenguajes de programación de alto nivel y propósito general cuya filosofía de diseño enfatiza la facilidad de uso. En 1964, John G. Kemeny y Thomas E. Kurtz diseñaron el lenguaje BASIC original en el Dartmouth College de New Hampshire. Querían permitir que los estudiantes en otros campos además de las ciencias y las matemáticas usen computadoras.

Estoy mirando este manual en BASIC de 1964, y este emulador del Sistema de Tiempo Compartido de Darthmouth que funcionaba. El servidor aún está activo, pero lamentablemente, registrar una cuenta parece ser imposible. Por ahora, estos programas deberían funcionar teóricamente:

Tarea 1

10 PRINT "BASIC WAS MADE IN 1964"
20 END

Tarea 2

10 READ N
15 FOR Y = 1 TO N STEP 1
20 FOR X = 1 TO N STEP 1
25 IF X = 1 THEN 50
30 IF X = N THEN 50
35 IF X = Y THEN 50
40 PRINT " ",
45 GO TO 55
50 PRINT "N",
55 NEXT X
60 PRINT
65 NEXT Y
70 DATA 5
75 END

Salida de algo como:

N                       N
N     N                 N
N           N           N
N                 N     N
N                       N

Observe cómo se ingresa la entrada como parte del programa ( 70 DATA 5); la READforma de instrucción en la parte superior obtiene datos desde allí. No hay concatenación de cadenas, pero la sección 3.1 del manual describe cómoPRINT se escriben los resultados en "zonas" tabuladas en la salida.

Tarea 3

La versión lenta del algoritmo de Euclides:

10 READ A, B
20 IF A = B THEN 80
30 IF A < B THEN 60
40 LET A = A - B
50 GO TO 20
60 LET B = B - A
70 GO TO 20
80 PRINT A
85 DATA 144, 250
90 END

Salida:

2

Finalmente, alguien hizo BASIC.
marinus

16

2010 - WTFZOMFG

WTFZOMFG es un lenguaje esotérico basado en Brainfuck. Fue creado por Jay Songdahl en 2010. "WTFZOMFG" es la abreviatura de "¿Cuál es esa función? ¡Zen optimizado archivos maliciosos optimizados!" .

Aquí hay un compilador para sistemas * nix .

Tarea 1

'WTFZOMFG was made in 2010!\n"

Tarea 2

/&(-.N%3 >&>s-{-(-. ).N}>{-(-. ).N}_0 '\n")

Explicación:

Lo siento. No soy bueno escribiendo explicaciones.

/                                           # read the number and store it in cell 0
 &                                          # copy it to cell 1
  (                                         # loop while cell 0 isn't 0
   -                                        # decrease the value of cell 0
    .N                                      # print "N"
      %3                                    # copy cell 0 to cell 3
                                            # a space must be added after the number. I don't know if it's a bug of the compiler or a feature.
         >                                  # move to cell 1
          &                                 # copy cell 1 to cell 2
           >                                # move cell 2
            s                               # let cell 2 = cell 2 - cell 3
             -                              # decrease the value of cell 2
              {                             # if cell 2 isn't 0
               -                            # decrease the value of cell 2
                (-. )                       # while cell 2 isn't 0, decrease it and print " "
                     .N                     # print "N"
                       }                    # end if
                        >                   # move cell 3
                         {                  # if cell 3 isn't 0
                          -                 # decrease the value of cell 3
                           (-. )            # while cell 3 isn't 0, decrease it and print " "
                                .N          # print "N"
                                  }         # end if
                                   _0       # move to cell 0
                                      '\n"  # print a newline
                                          ) # 

Tarea 3

/>>/(<<&>dm<s&>>%0 <&>)<<\

Algoritmo euclidiano. WTFZOMFG no tiene un comando para mod, así que tengo que usar d(dividir), m(multiplicar) y s(restar).


16

2009 - Ir

Go es un lenguaje de programación desarrollado por Google. El desarrollo comenzó en 2007, pero Go se anunció en noviembre de 2009.

Go es un lenguaje de tipo estático influenciado por C que enfatiza la concisión, simplicidad y seguridad.

Tarea 1:

package main
import "fmt"

func main(){
    fmt.Println("Go was made in 2009!")
}

La primera línea declara el paquete del código. Incluso un ejemplo simple como imprimir una línea debe ser parte de un paquete. Y el ejecutable siempre se llamamain .

Tarea 2:

package main

import (
        "fmt"
        "strings"
)

func main(){
    var n int
    fmt.Scan(&n)

    for i := 0; i < n; i++ {
        a := make([]string, n, n)
        for j := 0; j < n; j++ { a[j] = " " }

        a[0] = "N"
        a[i] = "N"
        a[n-1] = "N"

        s := strings.Join(a, "")
        fmt.Println(s)
    }
}

Go tiene una declaración variable bastante concisa ( i := 0es lo mismo quevar i int = 0 ), y el compilador determina el tipo. Esta suele ser una característica más común en lenguajes dinámicos. Usando esta notación corta también es muy fácil asignar funciones a variables ( f := func(x int) int {/* Code */}) y crear Closures.

Tarea 3:

package main

import "fmt"

func gcd(a, b int) int {
    for b != 0 {
        a, b = b, a%b
    }
    return a
}

func main(){
    var a, b int
    fmt.Scan(&a)
    fmt.Scan(&b)

    fmt.Println(gcd(a, b))
}

Aquí puedes ver el a, b = b, a%b sintaxis, que es realmente agradable. No sé el nombre exacto, pero en Python se llama desempaquetado de tuplas. Usando la misma manera, puede devolver múltiples valores de una función (func f() (int, string) { return 42, "Hallo"} ).

Otra cosa que sucede en este código es el bucle. El bucle for es el único bucle en Go. Los bucles while o los bucles do-while no existen. Pero puede crear fácilmente un equivalente para el bucle while for condition {}o un bucle infinito for {}.


16

1991 - Python

Historia del lenguaje

A finales de la década de 1980, Guido van Rossum comenzó a idear Python como un pasatiempo. Su nombre proviene de Flying Circus de Monty Python, un programa de televisión británico del que Rossum es fanático. La primera implementación de Python comenzó en 1989 y se lanzó en 1991. Ha aumentado su popularidad a lo largo de los años, convirtiéndose en el idioma de elección para muchos cursos introductorios de informática.

"¡Hola Mundo!" Variante

print("Python was made in 1991!")

Tenga en cuenta los paréntesis alrededor de la entrada a print. Aunque esta sintaxis funciona en Python 2, normalmente en Python 2 omitiría estos paréntesis. Sin embargo, son necesarios en Python 3. Como lo sugirió Zach Gates, los paréntesis se utilizan para garantizar que el código presentado aquí funcione en todas las versiones.

ASCII Art N

def asciin(n):
    if n == 1:
        print("N")
    else:
        print("N" + " "*(n-2) + "N")

        for i in range(2, n):
            print("N" + " "*(i-2) + "N" + " "*(n-i-1) + "N")

        print("N" + " "*(n-2) + "N")

Las funciones se definen usando def. La concatenación de cadenas se realiza utilizando +y la repetición de cadenas con *.

GCD

def gcd(a, b):
    if b == 0:
        return(a)
    else:
        return(gcd(b, a % b))

Tenga en cuenta que Python requiere espacios en blanco estructurados.


16

1968 - Algol 68

Algol 68 fue definido por el IFIP Working Group 2.1 como sucesor de Algol 60.

Es un lenguaje orientado a la expresión en el que todo tiene un valor. También es ortogonal, en el que puede usar cualquier construcción de cualquier manera. Esto significa que las expresiones pueden estar en el RHS y el LHS de una tarea, por ejemplo.

Todas las estructuras de control tienen una forma abreviada, así como una forma larga con expresiones. También permite las definiciones de operadores.

Los objetivos del lenguaje se citan como:

Los principales objetivos y principios de diseño de ALGOL 68:

  • Integridad y claridad de la descripción.
  • Diseño ortogonal,
  • Seguridad,
  • Eficiencia
  • Comprobación de modo estático
  • Análisis independiente del modo
  • Compilación independiente
  • Optimización de bucle
  • Representaciones: en conjuntos de caracteres mínimos y más grandes

Estos programas han sido probados con el intérprete Algol 68 Genie , que es una implementación completa del lenguaje.

Algunas características que los programadores modernos pueden encontrar diferentes, es que las declaraciones vacías no están permitidas. No puedes simplemente agregar en ;todas partes. Debe usar la SKIPdeclaración si no quiere tener nada explícitamente. También permitió la codificación de programas concurrentes muy fácilmente. Algol 68 también, en particular, utilizó palabras clave hacia atrás como terminadores, como esac , od , fi , etc.

El lenguaje tenía una representación utilizada para escribir el código que usaba muchas fuentes que representaban palabras clave en negrita e identificadores en cursiva , por ejemplo. En ese momento, y probablemente aún, ningún compilador implementó esta característica del diseño. El lenguaje permitió varias representaciones concretas diferentes de programas que utilizan modos de eliminación . Esto permitió que los programas se prepararan utilizando conjuntos de caracteres limitados, como los que se pueden encontrar en las computadoras en la década de 1960. Considere el fragmento de un programa corto, que se representaría como:

si yo < 0, entonces omito fi

Esto podría prepararse para un compilador en modo de eliminación principal como:

'IF' I 'LT' 0 'THEN' 'SKIP' 'FI'

En el modo de eliminación de puntos , esto sería:

.IF I .LT 0 .THEN .SKIP .FI

En caso de modo de eliminación, esto sería:

IF i < 0 THEN SKIP FI

Tengo un gran cariño por este lenguaje, ya que trabajé en una de las implementaciones del compilador, así como en la programación exclusiva durante muchos años.

Tarea 1

print (("¡Algol 68 se hizo en 1968!", nueva línea ))

El punto a tener en cuenta aquí son los paréntesis dobles. Esto es porque imprimir es una función que toma un solo argumento, que es una matriz de longitud variable de la unión de todos los tipos. Los paréntesis internos son el constructor de la matriz. Así es como se maneja el polimorfismo en este lenguaje fuertemente tipado.

En caso de modo de pelado:

print (("Algol 68 was made in 1968!", newline))


C:\>a68g HelloWorld.a68
Algol 68 was made in 1968!

Tarea 2

     int n ;
     leer (( n ));
     para i de 1 a n do
          para j de 1 a n do
               ¢ aquí usamos una cláusula SI abreviada ¢
               print ((( j = 1 OR j = i OR j = n |
                    "N"
               |
                    ""
               )))
          od ;
     print (( nueva línea))
     od

En caso de modo de pelado:

 INT n;
 read ((n));
 FOR i FROM 1 TO n DO
        FOR j FROM 1 TO n DO
            CO here we use an abbreviated IF clause CO
            print (( ( j = 1 OR j = i OR j = n |
                 "N"
            |
                 " "
            ) ))
        OD ;
        print ((newline))
    OD

C:\>a68g ASCIIart.a68
8
N      N
NN     N
N N    N
N  N   N
N   N  N
N    N N
N     NN
N      N

Tarea 3

     ¢ podemos definir nuestros propios operadores en Algol 68 ¢
     op % = ( int a , b ) int :
          (( b = 0 |
               a
          |
               b % ( a mod b )
          ));
     int i , j ;
     leer (( i , j ));
     print (( i % j , nueva línea ))

En caso de modo de pelado:

COMMENT we can define our own operators in Algol 68 COMMENT
OP % = ( INT a, b) INT:
    ((b = 0 |
        a
    |
       b % (a MOD b)
    ));
INT i,j;
read((i,j));
print(( i % j , newline))


C:\>a68g GCD.a68
4 12
         +4

77
Estos fueron probablemente los primeros programas de Algol 68 que escribí y ejecuté en más de 30 años. Lo encontré tan conmovedor que realmente me hizo llorar. Nunca me di cuenta de un "¡Hola Mundo!" ¡El programa podría ser tan emotivo!
Brian Tompsett - 汤 莱恩

1
Tenía muchas ganas de los idiomas de los años 60 y estaba listo con BCPL, Simula, CORAL66, Fortran 66, PL / 1, SNOBOL4, POP-1 y toda una balsa más, solo para descubrir que las reglas son las que tengo esperar 5 años de idiomas ... Al menos hay un surco rico para que alguien más pueda arar.
Brian Tompsett - 汤 莱恩

Es realmente genial ver las diferencias entre Fortran66 (un completo desastre de violencia con tarjetas perforadas), APL (desorden extraño de símbolos de superpotencia) y Algol68, que en realidad es bastante hermoso. Hoy, tendrías que buscar en lenguajes esotéricos para encontrar una variedad de enfoques diferentes ... en ese entonces, esto era bastante corriente, ¿no?
dejó de girar en sentido contrario a las agujas

Por supuesto, el Informe Revisado no se publicó hasta eh, 1976, ¿verdad? Al menos ese es el año de copyright que le da Springer. Y el escaneo que encontré menciona 1978.
Rhialto

[1] A. van Wijngaarden (ed.), Bl Mailloux, 1.EL Peck, CBA Koster, Informe sobre el lenguaje algorítmico ALGOL 68, Numer. Matemáticas. 14 (1969) 79-218; también en Kibenietika 6 (1969) y 7 (1970). [2] A. van Wijngaarden, Bl Mailloux, 1.EL Peck, CBA Koster, M: Sintzoff, CBLindsey, LGLT Meertens y RG Fisker, Informe revisado sobre el lenguaje algorítmico ALGOL 68, Acta Informat. 5 (1975) partes 1-3 (reimpresiones publicadas por Springer, Berlín, y también como Mathematical Center Tract 50 por el Mathematisch Centrum, Amsterdam); también en SIGPLAN Notices 12 (5) (1977)
Brian Tompsett - 汤 莱恩

16

1962 - SNOBOL

El "Lenguaje orientado a cadenas y simbólico". Al principio, al parecer, se llamó al intérprete de expresión simbólica, 'SEXI', que luego tuvo que cambiarse para evitar que los nerds de la década de 1960 se sonrojaran al presentar sus trabajos. Historia verdadera.

Este fue uno de los primeros idiomas que podía lidiar con cadenas y patrones de forma nativa. De hecho, la primera versión de SNOBOL tenía la cadena como su único tipo de datos. Las matemáticas se hicieron luego mediante análisis. La implementación inicial se realizó en el IBM 7090. Parece haber desaparecido hace mucho tiempo, al menos, no pude encontrarlo. Lo que encontré fue el documento original que lo describía, así como un intérprete SNOBOL3 en Java, que puede ejecutarse en una computadora moderna .

El primer SNOBOL tenía casi solo coincidencia de patrones y aritmética básica. SNOBOL 3 luego agregó funciones y cambió la E / S, pero por lo demás parece haberse mantenido compatible con versiones anteriores. SNOBOL 4 cambió la sintaxis y, a partir de ahí, se convirtió en Icon , que mantiene la coincidencia de patrones pero, de lo contrario, casi parece un lenguaje de programación "normal".

Los programas que he escrito utilizan solo la funcionalidad descrita en el documento original, por lo que deberían funcionar con el SNOBOL original con la excepción de las E / S, que hice en el estilo SNOBOL3 para que el intérprete de Java pudiera ejecutarlas. Según el artículo, parece que la diferencia es que SNOBOL1 usa la coincidencia de patrones con una SYSvariable especial , mientras que SNOBOL3 usa variables de entrada y salida:

  • Entrada:
    • 1 SYS .READ *DATA*
    • 3 DATA = SYSPPT
  • Salida:
    • 1 SYS .PRINT 'A STRING' AND VARIABLES
    • 3 SYSPOT = 'A STRING' AND VARIABLES

Hacer estas sustituciones debería hacerte SNOBOL "real" 1. Por supuesto, entonces no puedes ejecutarlo.

Tarea 1

START   SYSPOT = 'SNOBOL WAS MADE IN 1962!'

Tarea 2

Esto muestra matemática, manejo de cadenas y control de flujo. SNOBOL3 tiene funciones útiles, como EQverificar la igualdad; el SNOBOL original no lo hizo, así que no los he usado.

* READ N FROM INPUT
START   SYSPOT = 'SIZE?'
        SZ = SYSPPT

* INITIALIZE
        CS = ''
        ROW = '0'

* OUTPUT PREVIOUS ROW AND START NEXT ONE
ROW     COL = '0'
        SYSPOT = CS
        CS = ''

COL     SUCC = 'N'
        EQ1 = COL
        FAIL = 'CHKE'
        EQ2 = '0'         /(EQUAL)
CHKE    FAIL = 'CHKR'
        EQ2 = SZ - '1'    /(EQUAL)
CHKR    FAIL = 'SPACE'
        EQ2 = ROW         /(EQUAL)

* CONCATENATE THE RIGHT CHARACTER TO THE CURRENT LINE         
SPACE   CS = CS ' '       /(NEXT)
N       CS = CS 'N'       /(NEXT)

* FOR NUMBERS, SUBSTRING MATCH IS ENOUGH IF IT IS KNOWN A<=B
NEXT    COL = COL + '1'
        COL SZ            /F(COL)
        ROW = ROW + '1'
        ROW SZ            /F(ROW)S(FIN)

* THERE SEEMS TO BE NO EQUALITY CHECK, JUST SUBSTRING MATCHING
* OF COURSE, EQ1 == EQ2 IFF EQ1 CONTAINS EQ2 AND VICE VERSA
* THIS ALSO ILLUSTRATES INDIRECTION
EQUAL   EQ1 EQ2           /F($FAIL)
        EQ2 EQ1           /S($SUCC)F($FAIL)

* OUTPUT THE LAST LINE
FIN     SYSPOT = CS     

Tarea 3

Primero, el aburrido. Lo único que se debe tener en cuenta es el cheque más pequeño que, que muestra exactamente cómo estaba realmente SNOBOL orientado a cadenas: (B - A) '-'significa "¿el resultado de BA contiene un signo menos?". SNOBOL3 también puede hacerlo LE(B,A), pero SNOBOL 1 no pudo (al menos el artículo no lo menciona).

* READ A AND B
START   SYSPOT = 'A?'
        A = SYSPPT
        SYSPOT = 'B?'
        B = SYSPPT

* GCD LOOP
STEP    '0' (A - B)          /S(DONE)
        (B - A) '-'          /S(AB)F(BA)
AB      A = A - B            /(STEP)
BA      B = B - A            /(STEP)
DONE    SYSPOT = 'GCD: ' A

Por supuesto, cuando tiene un lenguaje basado completamente en cadenas y coincidencia de patrones, sería una lástima no poder usar la coincidencia y el reemplazo de patrones. Por lo tanto, aquí hay uno de esos GCD basados ​​en unario, incluidas las rutinas para convertir ay desde unario.

* READ A AND B
START   SYSPOT = 'A?'
        A = SYSPPT
        SYSPOT = 'B?'
        B = SYSPPT

* CONVERT TO UNARY
        UNA.IN = A
        UNA.FIN = 'ADONE'          /(UNA)
ADONE   A = UNA.R
        UNA.IN = B
        UNA.FIN = 'BDONE'          /(UNA)
BDONE   B = UNA.R


* USE STRING MATCHING TO FIND GCD
STEP    '' B                       /S(GDONE)
MATCH   A B =                      /S(MATCH)
        C = B
        B = A
        A = C                      /(STEP)

* CONVERT BACK TO DECIMAL
GDONE   DEC.IN = A
        DEC.FIN = 'DONE'           /(DEC)
DONE    SYSPOT = 'GCD: ' DEC.R     /(FIN)

***************************** 
* DECIMAL TO UNARY SUBROUTINE
UNA     UNA.R =
UNA.DGT UNA.IN *.DGT/'1'* =        /F($UNA.FIN)
        .X = UNA.R
        UNA.R =
UNA.MUL .X *.Y/'1'* =              /F(UNA.ADD)
        UNA.R = UNA.R '##########' /(UNA.MUL)
UNA.ADD '1' .DGT                   /S(UNA.1)
        '2' .DGT                   /S(UNA.2)
        '3' .DGT                   /S(UNA.3)
        '4' .DGT                   /S(UNA.4)
        '5' .DGT                   /S(UNA.5)
        '6' .DGT                   /S(UNA.6)
        '7' .DGT                   /S(UNA.7)
        '8' .DGT                   /S(UNA.8)
        '9' .DGT                   /S(UNA.9)
        '0' .DGT                   /S(UNA.DGT)
UNA.1   UNA.R = UNA.R '#'          /(UNA.DGT)
UNA.2   UNA.R = UNA.R '##'         /(UNA.DGT)
UNA.3   UNA.R = UNA.R '###'        /(UNA.DGT)
UNA.4   UNA.R = UNA.R '####'       /(UNA.DGT)
UNA.5   UNA.R = UNA.R '#####'      /(UNA.DGT)
UNA.6   UNA.R = UNA.R '######'     /(UNA.DGT)
UNA.7   UNA.R = UNA.R '#######'    /(UNA.DGT)
UNA.8   UNA.R = UNA.R '########'   /(UNA.DGT)
UNA.9   UNA.R = UNA.R '#########'  /(UNA.DGT)

*****************************
* UNARY TO DECIMAL SUBROUTINE
DEC     DEC.R =
DEC.DGT '' DEC.IN                  /S($DEC.FIN)
        .X = DEC.IN
        DEC.IN =
DEC.DIV .X '##########' =          /F(DEC.ADD)
        DEC.IN = DEC.IN '#'        /(DEC.DIV)
DEC.ADD '' .X                      /S(DEC.0)
        '#' .X                     /S(DEC.1)
        '##' .X                    /S(DEC.2)
        '###' .X                   /S(DEC.3)
        '####' .X                  /S(DEC.4)
        '#####' .X                 /S(DEC.5)
        '######' .X                /S(DEC.6)
        '#######' .X               /S(DEC.7)
        '########' .X              /S(DEC.8)
        '#########' .X             /S(DEC.9)
DEC.0   DEC.R = '0' DEC.R          /(DEC.DGT)
DEC.1   DEC.R = '1' DEC.R          /(DEC.DGT)
DEC.2   DEC.R = '2' DEC.R          /(DEC.DGT)
DEC.3   DEC.R = '3' DEC.R          /(DEC.DGT)
DEC.4   DEC.R = '4' DEC.R          /(DEC.DGT)
DEC.5   DEC.R = '5' DEC.R          /(DEC.DGT)
DEC.6   DEC.R = '6' DEC.R          /(DEC.DGT)
DEC.7   DEC.R = '7' DEC.R          /(DEC.DGT)
DEC.8   DEC.R = '8' DEC.R          /(DEC.DGT)
DEC.9   DEC.R = '9' DEC.R          /(DEC.DGT)

FIN     START

Excelente trabajo de fondo! No es mucho para 1961, parece que COMIT es todo lo que tenemos ...
Brian Tompsett - 汤 莱恩

15

2012 - TypeScript

TypeScript es un lenguaje de programación gratuito y de código abierto desarrollado y mantenido por Microsoft.

El objetivo principal es: cualquier navegador. Cualquier anfitrión Cualquier sistema operativo Fuente abierta. Fue lanzado en octubre de 2012.

Hola TypeScript

Task1(name:string,year:number) {
    return name + " was made in "+ year +"!";
}

Arte ASCII

Task2(n:number,separator:string,space:string) {
    var result:string = "";
    for (var k = 0; k < n; k++)
    {
        for (var j = 0; j < n; j++)
        {
            var i = ((n * k) + j) % n;
            result+=(i == 0 || i == n - 1 || i == k) ? "N" : space;
        }
        result+=separator;
    }
    return result;
}

GCD

Task3(a:number,b:number) {
    while (a != 0 && b != 0)
        {
            if (a > b)
                a %= b;
            else
                b %= a;
        }

        if (a == 0)
            return b;
        else
            return a;
}

Pruébelo en línea y haga una captura de pantalla del mismo.


44
Olvidó mencionar una cosa: TypeScript es un superconjunto de Javascript con pocos cambios de sintaxis y permite (?) Variables y argumentos de tipo fuerte.
Ismael Miguel

1
¡Dios mío, algo de código abierto de MS!
Mega Man

15

2011 - Dart

Dart es un lenguaje de programación de código abierto desarrollado por Google que se desarrolla como un reemplazo para Javascript (aunque se compila a JavaScript). Fue presentado por Google en 2011 durante la conferencia GOTO.

"¡Hola Mundo!" Variante:

main() {
  print('Dart was made in 2011!');
}

ASCII Art N:

Método de fuerza bruta, se ejecuta en 0 (n²), pero realmente no debería importar a menos que use un número gigante.

asciiN(int number){
    if(number == 1){
        print('N');
    }else{
        for(var i = 1; i <= number; i++){
            String currentLine = "";
            for(var j = 1; j <= number; j++){
                if(j==1 || j == number || j == i){
                    currentLine = currentLine + "N";
                }else{
                    currentLine = currentLine + " ";
                }
            }
            print(currentLine);
        }
    }
}

GCD

Método simple de Euclides portado desde Snap! ejemplo anterior

int gcd(int first, int second){
if(second > first){
   return gcd(second, first);
    }else{
        if(first == 0){
            return second;
        }else{
            if(second ==0){
                return first;
            }else{
                return gcd(second, first-second);
            }
        }
    }
}

55
No creo que pueda generar un arte ASCII × n en menos de O (n²).
Paŭlo Ebermann

@ PaŭloEbermann No estoy tan familiarizado con la notación O grande o cómo calcular la complejidad, pero el ejemplo de Julia parece que no es O (n²).
Nzall

@AlexA. La función println () imprime una cadena de n caracteres. Creo que la llamada a la función necesita al menos tiempo O (n) para ejecutarse. En el bucle, entonces O (n²) para todo el programa.
Paŭlo Ebermann

@AlexA. Creo que de lo que habla Ebermann es de que tienes operaciones de concatenación de N cadenas en tu función de impresión. los dos hacemos concatenaciones de cadenas n² en nuestras funciones. Los hago una vez por iteración de bucle interno, los haces para cada println ().
Nzall

1
Si esto no fuera un arte asiatico, sería O (n) mostrar una N. (dibuje 3 líneas en la pantalla, cada línea es O (n), por lo tanto, O (n) complejidad). O, se podría decir, renderizar el N tiene O (N) complejidad ... jeje
rodolphito

15

2010 - óxido

Rust es un lenguaje de programación compilado de múltiples paradigmas y propósito general desarrollado por Mozilla Research. Está diseñado para ser un "lenguaje seguro, concurrente y práctico", que admite estilos puramente funcionales, de actor concurrente, de procedimiento imperativo y orientado a objetos. Wikipedia

Tarea 1

fn main()
{
    println!("Rust was made in 2010!");
}

Tarea 2

fn main()
{
    // get commandline arguments
    // "test 3"
    let args : Vec<_> = std::env::args().collect();

    // convert 2nd argument to integer
    let n = u32::from_str_radix( args[1].as_ref(), 10 ).unwrap();
    print_n( n );
}

fn print_n( n: u32 )
{
    for y in range( 0, n )
    {
        for x in range( 0, n )
        {
            if x == 0 || x == y || x + 1 == n
            {
                print!("N");
            }
            else
            {
                print!(" ");
            }
        }
        println!("");
    }
}

Explicación:

if x == 0 || x == y || x + 1 == n

se encarga de imprimir solo vertical (izquierda y derecha | ) y diagonal ( \)

Tarea 3

implementación simple de Euclidean_algorithm

fn main()
{
    // get commandline arguments
    // "test 453 3"
    let args : Vec<_> = std::env::args().collect();

    // convert 2nd and 3rd argument to integers
    let a = u32::from_str_radix( args[1].as_ref(), 10 ).unwrap();
    let b = u32::from_str_radix( args[2].as_ref(), 10 ).unwrap();
    let g = gcd( a, b );
    println!( "GCD of {} and {} is {}", a, b, g );
}

fn gcd( mut a: u32, mut b: u32 ) -> u32
{
    while b != 0
    {
        let c = a % b;
        a = b;
        b = c;
    }
    return a;
}

¿Podría agregar un fragmento que muestre cómo ingresar dos enteros separados por espacios desde el stdin?
Zero Fiber

3
¿Fue Rust "hecho en" 2010? La línea de tiempo de los lenguajes de programación lo dice, pero el artículo real dice que solo se anunció en 2010 (en realidad 2011 como lo demuestra la referencia ) y que la versión 0.2 se lanzó en 2012.
EMBLEMA

1
@SampritiPanda, eche un vistazo a hastebin.com/raw/lapekowogu
wasikuss

1
Parece un poco moderno. ¿Puede compilarlo la primera versión de trabajo publicada del compilador <s> lanzado </s>?
Vi.

15

2015 - Muffin MC

Muffin MC es un macro-lenguaje Turing completo, divertido (pero serio), funcional y minimalista escrito por Franck Porcher ( http://franckys.com ) a mediados de febrero de 2015 por necesidad como una herramienta (rápida) para potenciar un hoja de cálculo que se utilizará como el único controlador front-end para pilotear e impulsar todas las operaciones relacionadas con el inventario asociadas con un sitio comercial basado en Prestashop para una nueva marca de moda tahitiana: Mutiny Tahiti ( http://mutinytahiti.com - próximamente lanzado).

Muffin MC es un acrónimo de MU tiny F unctional F lexible IN line M acro C ommand language.

Para cumplir con nuestros requisitos, las características centrales de Muffin MC se han diseñado en torno a construcciones semánticas integradas flexibles y eficientes de primera clase, como iteradores , evaluación perezosa , multifunctores , productos de cadena .

Muffin MC tiene sus raíces en la programación funcional (pragmática), FLisp y Perl. Es totalmente compatible con la recursividad (sin ninguna optimización), se escribe de forma dinámica y se define de forma dinámica (enlace superficial). Ofrece a sus usuarios una estructura de datos solamente, aparte de los átomos de tipos de datos básicos (átomos, cadenas, números): ¡listas!

La semántica de la lista MC de Muffin (tipo de) toma prestada la semántica de conjunto de potencia , es decir:

  1. Todas las operaciones de Muffin MC producen una lista, posiblemente vacía.
  2. El acceso a cualquier elemento de lista individual siempre produce una lista de un valor hecha de ese elemento (piense en él como un singleton).
  3. La lista vacía es el elemento neutral en las operaciones de la lista.

Para conciliar con esto, lo siguiente puede ayudar:

  • Uno puede visualizar una lista como el elemento del conjunto de poderes de la lista que tiene la mayor cardinalidad.
  • Visualice el elemento de una lista como el elemento del conjunto de potencia de la lista que es el singleton hecho de ese elemento.
  • Visualice una lista vacía como el conjunto vacío; es decir, el único elemento del conjunto de poder del conjunto vacío.

Como tal, acceder a un elemento de lista vacío produce la lista vacía, ¡y no es un error! De hecho, Muffin MC se esfuerza por arrojar la menor cantidad de errores posible al extender de ese modo la semántica de muchas operaciones tradicionales.

Tarea 1

#(say "MuffinMC was born in 2015 out of necessity !")

#(...)es el comando macro Muffin MC para aplicar una función en una lista de argumentos no evadidos, aquí la función incorporada say, tomada de Perl.

#(say 1 2 3 ...) es funcionalmente idéntico a map {say $_} (1,2,3,...)

Tarea 2

Define la función ascii-art():

=(ascii-art
    '( =(*  x   #(2- $(_1))
        I   I( *($(x) " ") N)
            foo '( #(. #(I $(x))) ))
    #(say ?( #(== $(_1) 1) N "N#(map foo #(.. 1 $(_1)))N" ))
 ))

Ascii-art()La forma de trabajo más corta (88 bytes):

=(f'(=(* x#(2-)I I(*($(x)" ")N)g'(#(.#(I$(x)))))#(say?(#(==$(_1)1)N"N#(map g#(..))N"))))
  • =(var val...)es el comando macro de Muffin MC para definir una variable o reasignarla.

  • $(var)es el comando macro de Muffin MC para acceder al valor de una variable. Naturalmente acepta el formulario $(v1 v2 ...)para acceder a muchas variables a la vez.

  • =(* var1 val1 var2 val2 ...)es la extensión del comando macro Muffin MC=(...) para manejar asignaciones paralelas.

  • Las variables _1, _2, ... tienen un alcance dinámico (mecanismo de encuadernación superficial) y se configuran automáticamente para que se unan a los argumentos de la función. Tomado de Perl5, las variables del sistema #(número de argumentos) y @(lista de argumentos) también se configuran automáticamente.

  • Las funciones son simplemente variables vinculadas a cualquier número de declaraciones de Muffin MC .

Esta solución interesante proviene de combinar dos características integradas naturales de Muffin MC :

  1. El comando macro Muffin MC I(...) , para definir iteradores de ciclos, más tarde utilizado con la forma funcional #(my-iterator want-number-of-values),

  2. El muffin MC cadena de producto constructo, una extensión de la interpolación de variables natural, que, dado cualquier cadena "F1 F2 F3...", donde el F i s son o bien mollete MC literales de cadena o mollete MC comando de macro (formas funcionales aka), producirá tantas cadenas como dado por el producto cardinal (F1) x cardinal (F2) x ....

Por ejemplo, dada la variable xa que contiene 2 valores, dice ayb, y otra variable que contiene 3 valores, dice, 1 2 3, entonces la evaluación de la cadena "x=$(x) y=$(y))"producirá 6 valores diferentes, a saber, en ese orden:

  • "x = ay = 1"
  • "x = ay = 2"
  • "x = ay = 3"
  • "x = por = 1"
  • "x = por = 2"
  • "x = por = 3"

Esta es una de las características altamente deseables del proyecto MUTINY para la que Muffin MC fue diseñada.

Ejecutarlo !

#(ascii-art 1)

N


#(ascii-art 3)

N N  
NNN  
N N 


#(map '( #(ascii-art $(_1))) 5 7 9)

N   N
NN  N
N N N
N  NN
N   N

N     N
NN    N
N N   N
N  N  N
N   N N
N    NN
N     N

N       N
NN      N
N N     N
N  N    N
N   N   N
N    N  N
N     N N
N      NN
N       N

Como funciona

Nuestro algoritmo se basa en lo siguiente:

Dado un llamado a ascii-art (n), {n = 2p + 1 | p entero, p> = 0}, el arte a generar comprende n cadenas de n caracteres, entre los cuales, dos, el más a la izquierda y el más a la derecha, son fijos y siempre iguales: 'N'. Esto permite reducir el problema al producir solo las cadenas intermedias. Por ejemplo, dado n = 5, desmalezaríamos para producir las siguientes 5 cadenas intermedias, cada una compuesta de n-2 caracteres (hemos reemplazado el espacio por una '_' en aras de una mejor visualización):

    The 5 strings :
        _ _ _
        N _ _ 
        _ N _
        _ _ N
        _ _ _

    can be seen as resulting from splitting in groups of 3 characters
    the following infinite sequence of 4 characters :


        /---- < _ _ _ N > ----\
       |                       |
        \---------------------/    


    which, once unfolded, yields the infinite ruban : 

        _ _ _ N _ _ _ N _ _ _ N _ _ _ N _ _ _ N _ _ _ N ...
              ^     ^     ^     ^     
        _ _ _ |     |     |     |
              N _ _ |     |     | 
                    _ N _ |     |
                          _ _ N |
                                _ _ _
  • Dichas cadenas intermedias se pueden producir fácilmente ciclando sobre la secuencia de 4 elementos ('_' '_' '_' 'N')en 5 grupos de 3; dada n, la entrada de la función, dicha secuencia está hecha de n-2 caracteres '_', seguidos del carácter 'N'. Recorrer esta secuencia no requiere nada más que integrar la secuencia dentro de un iterador incorporado Muffin MC I(sequence) (un iterador que realiza un ciclo para siempre sobre su secuencia inicial de valores).

  • Luego, simplemente producimos las cadenas intermedias, de longitud n-2, pidiéndole a nuestro iterador que nos dé sus próximos valores n-2 (n - 2 caracteres), que se concatenan juntos para producir la cadena intermedia esperada.

  • Las n cadenas intermedias se producen repitiendo n veces el proceso anterior, utilizando un mapa para recopilar los n resultados (n cadenas de n-2 caracteres).

  • Utilizamos otro poderoso mollete MC constructo incorporado, es decir, el producto de cadena , para producir las n cadenas finales: "N#(map...)N".

  • Y eso es !

    Commented script  
    
    =(ascii-art                    Define the 'ascii-art' variable to hold
                                   the function's definition.
                                   When called, its argument, the actual
                                   value of n, will be bound to the system
                                   variable _1, accessed as $( _1 ).
    
        '(                         '(...) quote macro-command -- protects 
                                   its arguments, here the function 
                                   definition, from being evaluated.
                                   We want to keep it literally for further evaluation.
    
           =(*                     =(*...) // assignment macro-command.
                                   Similar to the Lisp (let (...)...),
                                   not the let* !
    
               x #(2- $(_1))       Define the variable x to hold the value 
                                   n-2.   
    
               I I(                Define I to be an iterator over the 
                                   the x+1 characters sequence :
                    *( $(x) " ")   . x white-space characters
                    N              . 1 'N' character (here the atom N)
                 )
    
               foo '(              Define the variable foo as a function 
                      #(.          to catenate ( #(. s1...) )
                         #(I $(x)) the iterator's next x elements.
                       )            
               )
           )                       End of =(*...
    
        #(say                      Print each element of:
           ?(                      If
              #(== $(_1) 1)        n equals 1
      N                    the atom N,
      "N#(map foo #(.. 1 $(_1)))N" else the n strings as a string-product 
                                   resulting from foo-computing the  
           )                       n middle-strings.
         )
     ))
    

Tarea 3

Define la función gcd():

=(gcd '( ?( #(== $(_2) 0)
        $(_1)
            #(self $(_2) #(mod $(_1) $(_2)))) ))

gcd()La forma más corta real (37 bytes - 2bytes de ganancia gracias a Rodolvertice)

=(g'(?(#(z$(_2))$(_1)#(g$(_2)#(mod)))))

Ejecutarlo !

#(gcd 225 81)

rinde 9.

Eso es.

Gracias por el buen juego, y posiblemente por tu interés. El idioma está disponible para cualquiera que quiera jugar, usarlo o incluso extenderlo. Solo pídalo y con gusto lo enviaré.

Salud

Franck


PD. La implementación actual de Muffin MC está en Perl5. El código fuente es de aproximadamente 2000 líneas de Perl moderno, incluidos los comentarios, y viene incluido con un conjunto de pruebas de no regresión, que es excelente para aprender construcciones y semánticas de Muffin MC .


¡Muy agradable! La forma más corta del ascii-art tiene un nombre de función acortado, pero el más corto de GCD no. ¿Es esto intencional? Porque si no es así, puede eliminar otros 2 bytes. +1
rodolphito

Claro, y es intencional. Debería ? sí, hagámoslo;) Gracias por el post, y su agradecimiento.
Franck Porcher

1
Como está tratando de deshacerse de los caracteres adicionales (y porque puedo ser una gramática desagradable), podría (debería) eliminar el espacio frente al signo de exclamación para la primera tarea. Ese espacio es correcto en francés afaik, pero no en inglés.
Amos M. Carpenter
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.