Langages de programmation à travers les années


168

Dans ce défi, les utilisateurs effectueront à tour de rôle trois tâches de codage assez simples dans des langages de programmation dont l’ancienneté est autorisée.

La première réponse doit utiliser un langage de programmation créé en 2015. Une fois qu'il existe au moins une réponse d'un langage de 2015, les réponses peuvent utiliser des langages de programmation créés en 2014. De même, les réponses utilisant des langages à partir de 2013 ne sont pas autorisées. jusqu'à ce qu'il y ait au moins une réponse en 2014.

En général, l'utilisation d'un langage de programmation à partir de l'année Y n'est pas autorisée tant qu'une réponse utilisant un langage à partir de l'année Y + 1 n'a pas été soumise. La seule exception est Y = 2015.

Trouver l'année de votre langue

Pour répondre à cette question, vous devez connaître l'année de fabrication de votre langage de programmation. Ceci est, bien sûr, un terme subjectif; certaines langues ont été développées au cours de plusieurs années et de nombreuses langues font encore l’objet d’une mise à niveau chaque année. Que l’année de fabrication d’une langue soit la première année d’application de cette langue par le grand public.

Par exemple, Python a été "fabriqué en" 1991 , bien que son développement soit en cours depuis 1989 et que la version 1.0 ne soit sortie qu'en 1994.

Si cette année est encore subjective, utilisez votre bon sens pour choisir l’année la plus appropriée. Ne vous perdez pas dans de légers désaccords sur les choix d’année. Veuillez fournir un lien vers une source indiquant à quelle date votre langue a été créée.

Différentes versions ou normes d'un langage de programmation (par exemple, Python 1, 2, 3) sont considérées comme le même langage avec la même année initiale.

Ainsi, à moins que l'année de votre langue soit 2015, vous ne pouvez soumettre votre réponse qu'une fois qu'une réponse a été soumise, l'année de la langue étant l'année précédant la vôtre.

Si une réponse valide avec la même année que la votre existe déjà, vous pouvez répondre. Peu importe que votre langue ait été développée plus tôt ou plus tard dans l'année.

les tâches

Vous devez exécuter les tâches 1 à 3. La tâche 0 est facultative.

Ces tâches ont été plus ou moins choisies pour correspondre à trois aspects importants de la programmation: fournir une sortie (tâche 1), une boucle (tâche 2) et une récursion (tâche 3).

Tâche 0 - Histoire de la langue (facultatif)

Rédigez au moins un paragraphe expliquant l’historique du langage de programmation que vous avez choisi: qui l’a développé, pourquoi, comment, etc. Ceci est particulièrement encourageant si vous étiez personnellement présent au moment de la création du langage et avez peut-être même joué un rôle dans son développement. N'hésitez pas à raconter des anecdotes personnelles sur l'effet de la langue sur vous ou sur votre travail, ou quelque chose du genre.

Si vous êtes trop jeune pour en savoir plus sur l'histoire de votre langue sans faire beaucoup de recherches, pensez à laisser une note aux utilisateurs plus âgés, leur indiquant qu'ils peuvent modifier votre message et ajouter un historique de première main.

Tâche 1 - "Bonjour le monde!" Une variante

Ecrivez un programme qui imprime

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

dans la zone de sortie standard de votre langue (stdout pour les langues les plus récentes).

Par exemple, si le langage était Python, le résultat serait:

Python was made in 1991!

Tâche 2 - Art ASCII N

Ecrivez un programme qui permet à l’utilisateur de saisir un nombre entier positif impair (vous pouvez supposer que la saisie est toujours valide) et d’imprimer une lettre N ASCII créée à l’aide du caractère N.

Si l'entrée est 1, la sortie est:

N

Si l'entrée est 3, la sortie est:

N N
NNN
N N

Si l'entrée est 5, la sortie est:

N   N
NN  N
N N N
N  NN
N   N

Si l'entrée est 7, la sortie est:

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

Le motif continue comme ça. La sortie peut contenir des espaces de fin.

Tâche 3 - GCD

Ecrivez un programme qui permet à l'utilisateur d'entrer deux nombres entiers positifs (vous pouvez en déduire que l'entrée est toujours valide) et affiche son plus grand diviseur commun . Ceci est défini comme le plus grand entier positif qui divise les deux nombres sans laisser de reste. Il peut être facilement calculé en utilisant l' algorithme d'Euclidean .

Exemples:

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

Vous pouvez utiliser une fonction intégrée, mais essayez de savoir si elle était dans la première version de votre langue. Sinon, essayez de ne pas l'utiliser.

Règles

  • Vous pouvez répondre plusieurs fois, mais chaque nouvelle réponse doit utiliser une langue définie au moins 5 ans avant la langue de votre dernière réponse. Donc, si vous avez répondu avec une langue 2015, vous ne pourrez pas répondre jusqu'à ce que 2010 langues soient autorisées. Si vous commencez avec une réponse en 2010, vous ne pouvez pas faire une réponse en 2015 votre deuxième réponse car 2015 n'est pas avant 2010.
  • Si possible, écrivez votre code pour qu'il fonctionne dans la toute première version de votre langue (ou dans une version aussi ancienne que possible). (Ce n'est pas une obligation car il peut être difficile de trouver d'anciens compilateurs / interprètes pour certaines langues.)
  • Abstenez-vous de publier une langue qui a déjà été publiée, sauf si la réponse affichée contient des erreurs importantes ou si vous avez une façon très différente d'accomplir les tâches.
  • Golfer votre code est correct mais pas obligatoire.
  • Un retour à la ligne dans la sortie de tout programme convient.
  • Pour les tâches 2 et 3, toutes les valeurs d'entrée inférieures à un maximum raisonnable comme 2 16 doivent fonctionner (256 au minimum).
  • Votre langue doit avoir existé avant que cette question ne soit posée.
  • Les très vieux langages de programmation peuvent avoir des formes d’entrée et de sortie différentes de celles que nous pensons aujourd’hui. C'est bon. Remplissez les tâches au mieux de vos capacités dans le contexte de votre langue.

Notation

Le score de votre soumission est:

upvotes - downvotes + (2015 - languageYear) / 2 

Ainsi, 0,5 est ajouté au nombre de votes pour chaque année avant 2015, ce qui donne un avantage aux langues plus anciennes. La soumission avec le score le plus élevé gagne.

Liste de réponses

L'extrait de pile ci-dessous répertorie toutes les réponses valides selon leur année linguistique.

Vous devez commencer votre publication avec cette ligne Markdown pour vous assurer qu'elle est correctement répertoriée:

#[year] - [language name]

Par exemple:

#1991 - Python

Le nom de la langue peut être dans un lien (ce sera le même lien dans la liste de réponses):

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

Les réponses qui ne suivent pas ce format, ou qui ont une année qui n’est pas encore autorisée, ou qui proviennent d’un utilisateur qui a déjà répondu au cours des 5 dernières années sont marquées comme non valides.

<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
Cela devrait aider.
swish

20
Wikipedia a une liste pour tout: celle-ci pour les langues non ésotériques par année.
Sanchises

2
La tâche 3 doit-elle réellement utiliser la récursion ou est-ce suffisant pour obtenir le résultat correct? Si j’ai besoin d’écrire ma propre fonction GCD, j’utilise généralement une boucle mais j’en ai écrit une spécialement pour ce défi. De nombreuses réponses soumises utilisent simplement une boucle.
CJ Dennis

5
Je me sens comme faire un deuxième compte juste pour nous faire passer 1971.
marinus

5
Si nous pouvons le récupérer en 1952, il se peut que quelqu'un mette en place une machine historique qui pourrait résoudre les solutions de 1951 (Pegasus) et les tester!
Brian Tompsett -

Réponses:


173

2013 - Dogescript

Dogescript est un langage créé en 2013 par Zach Bruggeman. Ce n'est rien de plus qu'un remplacement de la syntaxe de Javascript pour le rendre lu comme le monologue interne de Shiba Inus.

Bonjour doge

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

ASCII Art

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, tel +1. Très réponse. Beaucoup de qualité.
Alex A.

27
J'ai rejoint codegolf juste pour upvote cette réponse!
Derek Tomes

21
Je ne peux même pas lire celui de GCD avec un visage
impassible

16
Je ne peux pas ne pas lire gcd_doge comme good_dog. Aide
Yann

Fantastique. Cependant, selon LANGUAGE.md, les guillemets doubles ne sont pas pris en charge. J'aimerais une explication du s[i]bit aussi!
Docteur

66

2015 - Retina

Retina est un langage de programmation basé sur les expressions rationnelles, que j’ai écrit pour pouvoir rivaliser dans les défis de PPCG avec des réponses uniquement pour les expressions rationnelles, sans avoir à supporter inutilement une surcharge d’appel dans un langage hôte. La rétine est Turing-complète. Pour le prouver, j'ai implémenté un solveur système à 2 balises ainsi que la règle 110 . Il est écrit en C # et supporte donc à la fois la version .NET (par défaut) et la version ECMAScript (via un indicateur).

Retina peut fonctionner dans plusieurs modes, mais le plus pertinent pour les calculs (et celui de Turing complet) est le mode Remplacer. En mode Remplacer, vous donnez à Retina un nombre pair de fichiers source. Ceux-ci sont ensuite appariés, le premier de chaque paire étant une expression rationnelle et le second un remplacement. Celles-ci sont ensuite exécutées dans l'ordre en manipulant l'entrée pas à pas. L'expression régulière peut également être précédée d'une configuration (délimitée par `). L'option la plus importante (qui rend Retina Turing-complete) est +ce qui permet à Retina d'appliquer le remplacement en boucle jusqu'à ce que le résultat cesse de changer. Dans les exemples suivants, j'utilise aussi ;, qui supprime la sortie sur les étapes intermédiaires.

Dans chacune des soumissions suivantes, chaque ligne est placée dans un fichier source distinct. (Vous pouvez également utiliser la nouvelle -soption et placer toutes les lignes dans un seul fichier.) Les fichiers / lignes vides sont représentés par <empty>. Les fichiers / lignes contenant un seul espace sont représentés par <space>.

Les explications sont assez longues, je les ai donc déplacées à la fin du post.

Les programmes

"Bonjour le monde!" Une variante

<empty>
Retina was made in 2015!

ASCII Art N

Cela suppose que STDIN se termine par une nouvelle ligne.

;`^
#
;+`(\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

Cela nécessite que STDIN ne se termine pas par une nouvelle ligne.

;`\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>

Des explications

"Bonjour le monde!" Une variante

C'est assez trivial. Il ne prend aucune entrée (c.-à-d. Une chaîne vide), ne correspond à rien et le remplace par Retina was made in 2015!. On peut aussi le faire fonctionner pour une entrée arbitraire, en remplaçant le motif par [\s\S]*par exemple. Cela slurp STDIN et remplacerait tout par la sortie.

ASCII Art N

Cela a beaucoup d'étapes. L'idée est de convertir l'entrée en unaire, de créer un N x N bloc de Ns, puis de "sculpter" deux triangles. Passons par les différentes étapes. N'oubliez pas que ;supprime simplement les sorties intermédiaires, mais +provoque l'application du remplacement dans une boucle.

;`^
#

Simple: ajoutez a #à l'entrée. Ceci sera utilisé comme marqueur dans la conversion en unaire.

;+`(\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#

Ceci convertit un chiffre en unaire. Il prend les chiffres déjà convertis (\d*)et les répète 10 fois. Et puis il prend le chiffre suivant et ajoute le nombre approprié de chiffres. La valeur réelle des chiffres est sans importance à ce stade. Lorsque le #atteint la fin du nombre, l'expression régulière ne correspond plus et la conversion est terminée. À titre d’exemple, le numéro 127sera traité comme

#127
1#27
111111111122#7
1111111111221111111111221111111111221111111111221111111111221111111111221111111111221111111111221111111111221111111111227777777#

où la dernière ligne contient exactement 127 caractères numériques.

;`#
<empty>
;`\d
N

Deux étapes simples qui éliminent cela #et convertissent ensuite tous les chiffres en N. Dans ce qui suit, je vais utiliser l'entrée 7comme exemple. Alors maintenant, nous avons

NNNNNNN

L'étape suivante

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

remplace chacun Npar la chaîne complète (rappelez-vous qu'il contient une nouvelle ligne finale) et supprime également la nouvelle ligne finale elle-même. Par conséquent, cela transforme la rangée unique en une grille carrée:

NNNNNNN
NNNNNNN   
NNNNNNN
NNNNNNN
NNNNNNN
NNNNNNN
NNNNNNN

Maintenant le triangle supérieur. Tout d’abord, nous commençons par transformer le N situé dans le coin inférieur droit en un espace:

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

Le lookahead garantit que nous modifions le correct N. Cela donne

NNNNNNN
NNNNNNN   
NNNNNNN
NNNNNNN
NNNNN N
NNNNNNN
NNNNNNN

Et maintenant

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

est une expression rationnelle qui correspond à un élément situé Nau-dessus ou dans le coin supérieur gauche d'un caractère d'espacement et le remplace par un espace. Comme le remplacement est répété, il s’agit essentiellement d’un remplissage intense, qui transforme le 3e octant de l’espace initial en plusieurs espaces:

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

Et enfin, nous répétons la même chose avec le triangle du bas, mais nous utilisons un caractère différent, de sorte que les espaces déjà existants ne génèrent pas un remplissage saturé:

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

définit la graine:

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

ensuite

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

fait le remplissage d'inondation.

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

et enfin

S
<space>

Les transforme Sen espaces et nous avons terminé:

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

GCD

GCD in unary est en réalité très trivial avec regex. La majeure partie de ceci consiste en la conversion décimale à unaire et unaire à décimale. Cela pourrait être fait de manière plus compacte, mais ce n'est pas un code de golf, alors ...

;`\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

Ces étapes sont essentiellement les mêmes que ci-dessus, à l'exception du fait que les deux nombres entrés sont convertis et que le résultat utilise 1s au lieu de Ns (ce n'est pas important). Donc, si l'entrée était 18 24, alors cela produirait

111111111111111111 111111111111111111111111

Maintenant

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

est le calcul complet de GCD. Nous 1comparons un diviseur commun en capturant un nombre de s, puis en utilisant des références arrières pour nous assurer que les deux nombres peuvent être écrits en répétant cette chaîne (et rien d'autre). En raison du fonctionnement du retour en arrière dans le moteur des expressions rationnelles (c’est-à- .+dire glouton), cela donnera toujours le plus grand diviseur commun automatiquement. Comme la correspondance couvre toute la chaîne, nous écrivons simplement le premier groupe de capture à obtenir notre GCD.

Enfin, la conversion unaire à décimale ...

;`$
#:0123456789

Ajoutez un marqueur #, un délimiteur :et tous les chiffres à la chaîne. Cela est nécessaire car vous ne pouvez pas générer de nouveaux caractères de manière conditionnelle dans un remplacement de regex. Si vous souhaitez un remplacement conditionnel, vous devez extraire les caractères de la chaîne elle-même, nous les mettons donc là.

;+`^(?=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

C'est l'inverse de l'expansion unaire plus tôt. Nous trouvons le plus grand multiple de 10 qui correspond à la chaîne actuelle. Ensuite, nous choisissons le chiffre suivant en fonction du reste et divisons le multiple par 10 tout en déplaçant le marqueur à travers les chiffres.

#|:.*
<empty>

Et enfin, juste une étape de nettoyage pour se débarrasser du marqueur, du délimiteur et des chiffres auxiliaires.


Je pense que vous devriez ajouter une instruction pour convertir une entrée numérique en chaîne unaire et une instruction pour convertir une chaîne unaire en entrée numérique. La conversion avec une regex pure est cool mais beaucoup trop maladroite.
n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳

8
+1 J'étais à peu près sûr que la soumission de 2015 serait un langage pour utiliser CodeGolf.
Zero Fibre

@ n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳ Je réfléchissais à cela plus tôt. Je pense que pour la plupart des codes de golf, je prendrais probablement juste une entrée unaire (à moins que le défi spécifie explicitement "décimal" ou quelque chose du genre ...). J'ai pensé faire la même chose pour cela, mais ce n'est pas un code de golf, et je voulais montrer que je peux aussi gérer les entrées et les sorties décimales.
Martin Ender

6
Excellent travail. Retina est vraiment cool. Et à part ça, c'est aussi vraiment cool de voir le diamant à côté de votre nom! :)
Alex A.

C'est drôle, bien que les anciennes langues soient privilégiées dans cette compétition, la plus jeune gagne encore =)
Claudiu

60

2013 - Snap !

Snap ! est un langage basé sur Scratch , créé à l’Université de Berkeley. Il s’agit d’une mise à niveau de Scratch avec des données de première classe et des blocs personnalisés (fonctions). Comme Scratch, il ne s'agit pas d'un texte, mais de "blocs" visuels qui s'emboîtent.

Snap ! , écrit en JavaScript, est le successeur de BYOB, qui a été écrit en Squeak Smalltalk. Snap ! a été publié en version bêta pour la consommation publique en mars 2013 .

Snap ! n'est en réalité pas un langage ésotérique. Il est utilisé comme langage de programmation pour le cours AP CS Beauty and Joy of Computing (BJC) à Berkeley et d’autres.

J'ai aidé avec des tests et des choses.

"Hello World" variante

ASCII Art "N"

entrez la description de l'image ici

Cela utilise stdlib pour certains des blocs.

Jolie base en boucle ici. Prend une entrée. Ensuite, nous additionnons tout simplement et disons (résultat pour n = 5):

entrez la description de l'image ici

J'ai pris la liberté ici de simplement utiliser 2 espaces au lieu de 1, parce que Snap! ne dit pas de choses en monospace.

GCD

L'algorithme euclidien n'est pas très rapide, mais il fonctionne et est assez simple. (Désolé, j'ai fait une faute de frappe dans le nom du bloc. Maintenant, j'ai fermé l'onglet sans sauvegarder. Il ne reste plus qu'à rester.)

entrez la description de l'image ici

Cette définition de fonction produira alors ce bloc:

entrez la description de l'image ici


3
Cela ressemble beaucoup à la programmation dans Alice ...
mbomb007

4
C'est ce que vous obtenez avec les langues basées sur les blocs. Venez, beaucoup de langues se ressemblent. ;)
Scimonster

1
Même Scratch a une fonction mod, je suppose donc que vous pourriez rendre le fonctionnement de GCM / GCD plus rapide avec un bloc basé sur if (b == 0), puis un autre GCM (b, a% b)
Alchymist

55

2007 - LOLCODE

Histoire de la langue

LOLCODE a été créé en 2007 par Adam Lindsay, chercheur à l'Université de Lancaster. Sa syntaxe est basée sur les memes lolcats popularisés par Cheezburger, Inc.

"Bonjour le monde!" Une 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

Les valeurs sont lues sous forme de chaînes (YARN) à partir de stdin using GIMMEH. Ils peuvent être convertis en nombres numériques (NUMBR) en les multipliant par 1.

Les valeurs sont imprimées sur stdout en utilisant VISIBLE. Par défaut, une nouvelle ligne est ajoutée, mais vous pouvez la supprimer en ajoutant un point d'exclamation.

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 effectue une concaténation de chaîne.


13
Enfin, une langue que tout le monde peut comprendre.
ASCIIThenANSI

26
IM IN YR toilet UPPIN YR buttNoms de variables sympas
Cole Johnson

13
@ColeJohnson: J'essaie toujours de choisir des noms de variables qui ont du sens dans la situation plutôt que x1, x2etc.
Alex A.

2
Hilarant. Je ne devrais pas lire ceci au travail.
Alan Hoover

@AlanHoover: Clairement, les lolz sont plus importants que les jobz.
Alex A.

43

1982 - PostScript

PostScript est un langage permettant de créer des graphiques vectoriels et d’imprimer.

Adobe a été fondé en 1982 et son premier produit était PostScript. Le langage a été utilisé dans les imprimantes: les commandes sont interprétées par l’imprimante pour créer une image raster, qui est ensuite imprimée sur la page. C'était un composant très courant des imprimantes laser jusque dans les années 1990. Mais il est évident que l’imprimante nécessite beaucoup de ressources en processeur et, à mesure que les processeurs d’ordinateur devenaient plus puissants, il était plus logique de rasteriser l’ordinateur sur l’ordinateur que sur l’imprimante. PostScript a en grande partie disparu sur les imprimantes grand public, bien qu'il existe encore sur de nombreuses autres imprimantes haut de gamme.

Le standard qui a remplacé PostScript est un format peu connu appelé PDF.

Lorsque je commençais à programmer, PostScript était tombé en désuétude, mais j’ai appris un peu à l’université comme autre moyen de créer des documents pour TeX. C’était assez différent des autres langages de programmation que j’avais utilisés (notation inversée, pile, impression sur une page plutôt que sur une console), mais c’était bien de dépoussiérer cet ancien langage pour s’amuser.

Comme PostScript est un langage d'impression, il semble plus approprié de l'utiliser pour imprimer quelque chose, puis d'envoyer une sortie à la console.

Tache 1

/Courier findfont
12 scalefont
setfont
newpath

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

Les premières lignes constituent un canevas sur lequel s’appuyer. Ensuite, la movetocommande demande à PS de dessiner à une position particulière et d’ showimprimer la chaîne sur la page. Notez que les parenthèses marquent une chaîne dans PostScript, pas des guillemets.

Tâche 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

J'ai écrit une fonction pour dessiner “l'art ASCII” N, mais les fonctions PostScript n'ont aucun moyen de prendre un argument. Au lieu de cela, vous placez vos arguments dans la pile, puis vous les récupérez. C'est la /x exch defligne.

Un exemple: supposons que la pile est 8 9 2. D'abord, nous plaçons le nom /xdans la pile, donc la pile est 8 9 2 /x. L' exchopérateur échange les deux valeurs de la pile 8 9 /x 2. La pile est maintenant . defAffiche ensuite les deux premières valeurs de pile et définit /xla valeur 2. La pile est maintenant 8 9.

Quand j'ai commencé à utiliser PostScript, j'ai trouvé cela un peu déroutant. J'avais lu sur la pile comme un concept théorique, mais c'était la première fois que je l'utilisais dans la pratique.

Le reste de la fonction consiste en un code de dessin: commencez dans le coin inférieur droit, en remplissant une ligne à la fois, de gauche à droite en diagonale.

Tâche 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

Encore une fois, j'ai utilisé une forme de l'algorithme d'Euclid, mais j'avais oublié que PostScript possède un opérateur modulo intégré. J'ai donc dû écrire le mien. Cela s'est avéré être un rappel utile des contraintes de la programmation par pile. Ma première implémentation de moduloétait basée sur la récursivité:

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

ce qui est bien jusqu'à ce que vous essayiez de l'exécuter quand xest grand et ypetit (par exemple 5689 et 2). Vous ne pouvez avoir que 250 éléments maximum sur la pile et je dépassais donc largement la limite de pile. Oops. Je devais revenir à la planche à dessin sur celui-là.

Le code GCD lui-même est assez simple. Mais tout comme les fonctions ne peuvent pas prendre d'arguments, elles n'ont donc pas de valeur de retour. Au lieu de cela, vous devez placer le résultat dans la pile, de sorte que quelqu'un d'autre puisse le récupérer plus tard. C’est ce que les lignes aet b a gcdfont: quand elles ont fini d’évaluer, elles transmettent la valeur à la pile.

Si vous mettez tout le code dans un document et l'imprimez, voici à quoi ressemble le résultat:

entrez la description de l'image ici


8
Haha, j'adore la photo du morceau de papier imprimé. Convient pour 1982.
Alex A.

1
Merci également pour votre description de la manière dont vous avez provoqué un débordement de pile (littéral) - je comprends maintenant plus intuitivement pourquoi les langues ont une profondeur de récursivité maximale.
DLosc

2
@AlexA .: Oui, mais une impression matricielle (avec des trous sur les côtés du papier) aurait été encore plus appropriée . ;-)
Amos M. Carpenter

@ AmosM.Carpenter: pas vraiment, je ne pense pas qu'une imprimante matricielle ait jamais pris en charge PostScript. Cela a toujours été très lié aux imprimantes laser.
Ninjalj

41

2009 - > <>

Inspiré de Befunge,> <> (Fish) est un langage 2D ésotérique basé sur des piles, c’est-à-dire que le déroulement du programme peut être haut, bas, gauche ou droit. La version initiale de> <> en vedette multithreading où [et ]créé et fini les discussions, mais pour des raisons de simplicité ces instructions ont été modifiées pour créer et supprimer des nouvelles piles respectivement.

L'interprète officiel actuel pour> <> peut être trouvé ici . Malheureusement, le lien vers l'ancien interprète sur le wiki Esolang est rompu.

"Bonjour le monde!" Une variante

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

Notez que la chaîne est écrite à l'envers -> <> n'a techniquement pas de chaînes, le seul type de données étant un étrange mélange de char, int et float. "bascule l'analyse des chaînes, en poussant chaque caractère sur la pile jusqu'à ce que la fermeture "soit respectée.

La seconde moitié du code pousse ensuite la longueur de la pile l, vérifie si elle est nulle ?!et si le programme se termine ;. Sinon, le pointeur d'instruction continue en affichant le haut de la pile oavant d'exécuter bb+0., ce qui le téléporte en position (22, 0)juste avant l, créant ainsi une boucle.

ASCII Art N

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

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

   \                                                         <   /

Avec espacement pour plus de clarté. Vous pouvez essayer ceci sur le nouvel interprète en ligne ici et voir le pointeur d’instructions faire le tour - n'oubliez pas de saisir un numéro dans la zone de texte "Pile initiale". Si vous utilisez l’interpréteur Python, utilisez le -vdrapeau pour initialiser la pile, par exemple

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

Pour ce programme, nous mettons l'entrée ndans le registre avec &et poussons un 0, que nous appellerons ides "itérations". Le reste du programme est une boucle géante qui va comme ceci:

:&:&:*=?;          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

Ensuite, nous répétons la boucle depuis le début.

Les flèches ^>v<changent la direction du flux du programme et les miroirs /\reflètent la direction du flux du programme.

GCD

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

Voici un exemple de ce à quoi pourrait ressembler un programme golfé> <>. Encore une fois, vous pouvez essayer ceci dans l' interpréteur en ligne (entrez deux valeurs séparées par des virgules dans le champ "Pile initiale", par exemple 111, 87) ou en utilisant le -vdrapeau de l'interpréteur Python, par exemple

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

Ce programme utilise l'algorithme euclidien. Voici un GIF que j'ai préparé plus tôt:

entrez la description de l'image ici

Notez que> <> est toroïdal. Ainsi, lorsque l' vinstruction en bas à gauche est exécutée, le pointeur d'instruction va vers le bas, tourne autour et réapparaît en haut.


Edit: En faisant tourner le code entièrement de droite à gauche , @randomra a réussi à raser trois octets avec

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

Je suppose que je n'ai pas assez joué au golf :)


27
Et c'est comme ça que j'ai découvert que le nom ><>est un palindrome.
Zev Eisenberg

33

2012 - Element

C’est un langage que j’ai inventé début 2012 pour être un langage simple pour jouer au golf. Par cela, je veux dire qu’il ya très peu, voire aucun opérateur surchargé. Les opérateurs sont également plus simples et moins nombreux que la plupart des langues de golf modernes.

Les caractéristiques les plus intéressantes de ce langage sont ses structures de données. Il y a deux piles et un hachage qui sont utilisés pour stocker des informations.

La pile m est la pile principale, où l'arithmétique et la plupart des autres opérations ont lieu. Lorsque des données sont saisies ou imprimées, c'est à partir de là où elles sont récupérées.

La pile C est la pile de contrôle. C'est là que l'arithmétique booléenne a lieu. Les valeurs les plus élevées de la pile c sont utilisées par les boucles If et While comme condition.

Le hash est l'endroit où les variables sont stockées. Le ;et ~stocker et récupérer des données à partir du hachage, respectivement.

Element est un langage très faiblement typé. Il utilise la capacité de Perl à interpréter librement les nombres comme des chaînes et inversement.

Pendant que j'y suis, je pourrais aussi bien inclure toute la documentation pour la langue. Vous pouvez trouver l' interprète original de 2012, écrit en Perl, ici . Mise à jour: j'ai créé une version plus utilisable, que vous pouvez trouver ici .

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 \

Tâche 1 - Imprimer le texte

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

L’une des parties les plus délicates du langage est l’absence de délimiteurs de chaîne, raison pour laquelle des caractères d’échappement sont nécessaires dans cette chaîne. Le `à la fin imprime la chaîne.

Tâche 2 - Art ASCII N

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

Ici, vous assisterez à des manipulations de pile. Pour rendre l’explication un peu plus facile à mettre en forme, je remplacerai la nouvelle ligne par un Let l’espace par un 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

Après avoir fait quelques remarques extrêmes sur cette réponse, j’ai trouvé une solution de 39 octets, bien que ce soit beaucoup plus compliqué.

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

Tâche 3 - GCD

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

Ceci est une méthode basée sur la pile.

__                 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

Histoire de la langue

Julia a été créée en 2012 par Jeff Bezanson, Stefan Karpinski et Viral Shah, tandis que Jeff était étudiant à l'Institut de technologie du Massachussets (MIT), conseillé par le professeur Alan Edelman. Ils étaient motivés par le désir d'un langage de programmation open source, rapide et dynamique (entre autres choses), tout en maintenant la facilité d'utilisation dans diverses applications. Le produit était Julia, une nouvelle approche du calcul scientifique de haute performance.

"Bonjour le monde!" Une variante

println("Julia was made in 2012!")

Imprimer sur STDOUT chez Julia est assez 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

Le code est mis en retrait pour des raisons de lisibilité, mais Julia n’impose aucune restriction quant aux espaces.

GCD

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

La dernière chose répertoriée dans la fonction est retournée implicitement.


27

1988 - Mathematica

Ou devrais-je l'appeler Wolfram Language ?

Tâche 0

Le créateur de Mathematica est Stephen Wolfram, fondateur et PDG de Wolfram Research. Avant le développement de Mathematica, il était physicien. Il y avait une énorme quantité de calculs algébriques en physique, il est donc devenu un utilisateur de Macsyma .

Wolfram a obtenu son doctorat en 1979, à l'âge de 20 ans. Il pensait qu'il lui fallait un meilleur CAS que Macsyma pour faire de la physique. Il a donc commencé à écrire SMP (le "Programme de manipulation symbolique"). La première version de SMP a été publiée en 1981. SMP était le prédécesseur de Mathematica. Bien qu'il ait eu une influence profonde sur Mathematica, aucun de ses codes n'a jamais été utilisé pour Mathematica.

En 1986, Wolfram décida d'écrire un "système de calcul ultime". Il a commencé à écrire le code en 1986 et a fondé Wolfram Research en 1987. Enfin, Mathematica 1.0 est sorti le 23 juin 1988.

Mathematica 1.0

Je n'ai pas trouvé Mathematica 1.0. En fait, Mathematica 1.0 n’avait ni version Windows ni Linux. Mais j'ai trouvé Mathematica 2.0 sur un site web chinois. Il peut toujours être exécuté sur Windows XP.

Mathematica 2.0

Tache 1

Print["Mathematica was made in 1988!"]

Ou simplement:

"Mathematica was made in 1988!"

Tâche 2

Dans Mathematica d'aujourd'hui, nous pouvons écrire:

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

Tout comme Julia et R , il s'agit d'une solution matricielle. Dans Mathematica, vous pouvez définir une matrice fragmentée à l'aide de la correspondance de motifs.

Cependant, a SparseArrayété introduit dans Mathematica 5.0, nous ne pouvons donc pas l'utiliser dans Mathematica 1.0.

Voici une solution qui fonctionne dans 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];
]

Nous ne pouvons pas écrire f[i_, 1 | i_ | n] = "N"car a Alternativesété introduit dans Mathematica 2.0.

Tâche 3

Nous pouvons simplement utiliser la fonction intégrée:

gcd = GCD

Ou nous pouvons utiliser la définition du GCD:

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

Ou nous pouvons utiliser le LCM , bien que plus communément le LCM soit calculé à partir de GCD:

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

Ou nous pouvons utiliser l'algorithme euclidien avec un filtrage:

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

Ou en tant que fonction anonyme:

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

Toutes les fonctions ci-dessus ont été introduites dans Mathematica 1.0.


3
C'est une bien meilleure réponse que la mienne. Je vais supprimer le mien.
Martin Ender

25

1999 - XSLT

Le World Wide Web Consortium (W3C) a créé XSLT pour transformer XML en HTML, texte, etc. Les exemples suivants supposent que l'entrée est entourée de <input>..</input>balises.

Tache 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>

Celui-ci est simple. Il correspond à une inputbalise au niveau supérieur et la remplace par la sortie souhaitée.

Tâche 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>

Celui-ci définit 2 modèles récursifs, loopet spaces. loopavec des paramètres iet ngénérera la sortie souhaitée pour n, à partir de la position i. spacesavec paramètre ngénérera des nespaces.

Tâche 3

L'entrée pour cela doit être dans les <input><num>..</num><num>..</num></input>balises.

<?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>

Celui-ci est juste un modèle récursif gcdqui utilise l'algorithme euclidien.


Et ils disent qu'INTERCAL est bizarre!
kirbyfan64sos

2
@ kirbyfan64sos Pour être juste, cela ne devrait pas être utilisé pour ce genre de toute façon ...
LegionMammal978

24

2014 - CJam

CJam a été créé par l'utilisateur aditsu du groupe PPCG et a été publié vers avril 2014 .

"Bonjour le monde!" Une variante

"CJam was made in 2014!"

CJam imprime automatiquement le contenu de la pile à la fin du programme

ASCII Art N

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

Explication du code:

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";

Prend la hauteur / largeur de N comme entrée via STDIN. Essayez-le en ligne ici

GCD

l~{_@\%}h;

Prend les deux nombres en entrée via STDIN. Essayez-le en ligne ici


Je sais que ce n'est pas [code-golf], mais vous pouvez raccourcir le programme ASCII-art N ri_S*0'NtW'Nta1$*\,Sf*'Nf+..e>N*en CJam moderne.
Esolanging Fruit

24

1990 - Haskell

Haskell est un langage fonctionnel pur populaire (ou devrais-je dire: le plus populaire ?). Il se démarque du grand public par son modèle d'évaluation inhabituel (par défaut, tout est paresseux ou, techniquement, non strict) et par son système de types basé sur Hindley-Milner qui, même maintenant, est l'un des plus puissants du marché.

Tache 1

main = putStrLn "Haskell was made in 1990!"

Tâche 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

Démo, affiche toute la liste infinie (jusqu'à ce que l'utilisateur abandonne ou que le monde se 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

...

Bien sûr, vous pouvez facilement accéder à un seul d'entre eux en accédant à un seul élément de la liste infinie:

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

Tâche 3

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

23

1972 - INTERCAL

Et vous pensiez que Fortran et Cobol étaient bizarres. C'est insensé!

Tache 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

Je ne vais pas essayer d'expliquer le système d'entrées et de sorties d'INTERCAL; lisez simplement ceci et espérons que vous ne mourrez pas.

Tâche 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

Bonté divine. Cela m'a pris un peu pour comprendre. Les numéros d'étiquette sont en désordre et reflètent donc cela. Je ne vais pas essayer d'expliquer ceci à moins que quelqu'un ne le demande.

Tâche 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

Celui-ci est un peu plus simple. A cause de ... l'étrangeté d'INTERCAL, vous devez entrer les nombres comme ceci:

THREE FIVE

Par exemple, pour obtenir les PGCD de 42 et 16, je voudrais entrer:

FOUR TWO
ONE SIX

Il imprime également le nombre en chiffres romains ... parce que c'est INTERCAL pour vous!


2
Ça ne devrait pas être 19 7 2? (Je peux comprendre si vous êtes un peu étourdi après avoir écrit ceci: P) Votre réponse est considérée comme non valide en raison de cette erreur, ce qui serait dommage.
marinus

@marinus Merci! Fixé!
Kirbyfan64sos

5
S'IL VOUS PLAIT, expliquez. (Quand vous avez le temps, bien sûr.)
DLosc

1
INTERCAL est ma langue préférée que je n'ai jamais apprise!
CJ Dennis

1
PLEASE GIVE UP. Je l'ai déjà fait .-.
RedClover

23

1967 - APL

En 1957, à l'Université Harvard, Ken Iverson commença à développer une notation mathématique pour la manipulation de tableaux. Au cours des années 1960, sa notation a été développée dans un langage de programmation chez IBM. La première implémentation partielle a été créée en 1963 et elle a même été utilisée dans une école secondaire pour enseigner aux étudiants les fonctions transcendantales. Une implémentation complète et utilisable devait attendre 1965. Pendant deux ans, elle n’a été utilisée en interne que par IBM. En 1967, IBM a rendu public un interpréteur APL fonctionnant sur l’ordinateur IBM 1130, achevé en 1966. Vous pouvez comprendre qu’il est un peu difficile de choisir une année, mais je pense que ce devrait être 1967, Comme c’était la première année, une mise en œuvre complète était mise à la disposition du public. Si quelqu'un est vraiment en désaccord, je pourrais le changer.

Le code source de APL \ 360 est en ligne , tout comme un émulateur. C'est ce que j'ai utilisé pour tester ces exemples. Il date de 1967 et, avec APL \ 1130 (pour l’IBM 1130 susmentionné), il s’agit plus ou moins du véritable original. Comme prévu, il est très primitif. Il manque de prise en charge pour des détails tels que les minuscules, tous les opérateurs travaillent uniquement avec des fonctions intégrées, et le jeu de fonctions intégrées est très rare (en particulier, il n’est que double oret ne double pasgcd ). La description originale complète est disponible ici , cependant, j’ai remarqué que la version que j’avais n’était même pas complète en ce qui concerne ce document .

J'ai fourni les programmes à la fois au format Unicode (afin que vous puissiez les lire) et à l'encodage d'origine (pour pouvoir les couper et les coller dans la fenêtre APL de l'émulateur).

Incroyablement, ces programmes fonctionnent correctement sans aucune modification (à l'exception du codage) dans les versions modernes de Dyalog, NARS2000 et GNU APL. Donc, je suppose que j'ai trouvé le moyen d'écrire en APL portable: supposons qu'on est en 1967!

Tache 1:

Unicode:

⎕←'APL WAS MADE IN 1967!'

APL \ 360:

L[Kapl was made in 1967ÝK

Tâche 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'

Tâche 3:

J'ai résolu ceci de la manière récursive standard. En théorie, vous pourriez faire quelque chose d'intelligent et orienté tableau, comme la réponse J; dans la pratique, cependant, elle utilise la mémoire O (N) et écrase rapidement le matériel et les logiciels de l'ère 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

C'est génial.
Alex A.

22

1996 - Ocaml

J'attendais plus que le jour où quelqu'un remplisse l'année 1996 pour pouvoir remplir Ruby. Eh bien, pourquoi ne pas apprendre OCaml alors, semble similaire à haskell ...

Bonjour le monde

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;;

Cordes Mutable!

GCD

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

Non ==et infixe mod, c'est mignon


Je suis désolé, j'ai rempli Ruby :)
Zero Fibre

4
+1 pour apprendre une langue juste pour répondre à ce défi. :)
Alex A.

Vous venez d'apprendre F #, aussi! (c'est OCaml sur le CLR plus quelques extras).
Robert Fraser

22

2005 - Prélude

Prelude est un langage très amusant dont le code source est composé de plusieurs "voix" qui sont exécutées en parallèle et dans lesquelles j'aime beaucoup résoudre des problèmes . Il s’agit de la représentation ASCII de sa langue sœur, Fugue , qui prend en fait des fichiers .midi comme code source et code les instructions trouvées dans Prelude sous forme d’intervalles dans les mélodies des voix.

Prelude est assez minimaliste, mais Turing est complet (à condition que vous utilisiez au moins deux voix). Comme je l'ai dit, les voix (lignes de code) sont exécutées simultanément, colonne par colonne. Chaque voix fonctionne sur sa propre pile, qui est initialisée à un nombre infini de zéros. Prelude prend en charge les instructions suivantes:

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 '('.

Quelques notes supplémentaires:

  • Les voix étant cycliques, ^la voix du haut est copiée à partir de la voix du bas (et inversement).
  • Plusieurs ?et !dans la même colonne sont exécutés de haut en bas.
  • Selon la spécification du langage , ?et !lire et écrire des caractères avec le code de caractères correspondant. Cependant, l'interpréteur Python a également un commutateur dans son code pour imprimer les nombres eux-mêmes. À des fins de test, j'utilise en fait une version modifiée qui peut également lire des chiffres au lieu de caractères. Cependant, on s'entend généralement pour dire que les entrées / sorties numériques peuvent être exprimées en octets. Par conséquent, ces modifications ne sont pas nécessaires pour créer des programmes valides traitant des nombres.
  • Correspondant (et )n'ont pas besoin d'être sur la même voix. La voix utilisée pour la condition est toujours celle où (apparaît. Par conséquent, la position verticale de la )est complètement hors de propos.
  • En raison de la nature de l'exécution simultanée de Prelude, toute instruction de la même colonne en tant que (est exécutée une seule fois avant le début de la boucle, que la boucle soit entrée ou non. De même, toute instruction de la même colonne que a )est exécutée à la fin de chaque itération, que la boucle soit sortie ou non après cette itération.

Je vais d'abord vous montrer les trois programmes sans trop de commentaires. Vous pouvez trouver des explications détaillées ci-dessous.

Les programmes

"Bonjour le monde!" Une 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 vous utilisez l'interpréteur Python, assurez-vous de cela 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#

Pour faciliter l'utilisation, ce programme tire profit de la lecture des entrées sous forme de nombres, mais les sorties ne doivent pas être numériques. Donc, si vous utilisez l'interpréteur Python modifié, définissez

NUMERIC_INPUT = True
NUMERIC_OUTPUT = False

GCD

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

Ceci s’utilise mieux avec toutes les entrées / sorties numériques, c’est-à-dire

NUMERIC_INPUT = True
NUMERIC_OUTPUT = True

Des explications

"Bonjour le monde!" Une variante

C'est assez simple. J'utilise 3 voix pour générer successivement les codes de caractère de tous les caractères Prelude was made in 2005!. Je commence par calculer 8 + 9*8 = 80, qui est le code de caractère de P:

 9(1-)
 8 8+

Après cela, je ne fais que copier le code de caractère précédent et ajouter ou soustraire la différence au prochain. Voici le code, mais chaque code étant !remplacé par le caractère en cours d'impression (ainsi que _pour les espaces et %les chiffres):

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+!

La dernière 55+!affiche une fin de ligne, juste parce que c'est plus joli.

En passant, le nombre de voix est assez arbitraire pour cette tâche, mais 3 est assez pratique car c'est le plus grand nombre de voix où chaque voix peut accéder directement à une autre voix.

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#

Avec 5 voix, c’est certainement l’un des programmes les plus complexes que j’ai écrit jusqu’à présent. Les voix ont à peu près les buts suivants:

  1. Simplement une voix d'assistance qui stocke N-1pour une utilisation dans la boucle interne.
  2. C'est en quelque sorte la voix "principale", qui lit les entrées, contient un commutateur important et contient également la boucle externe (c'est-à-dire celle située au-dessus des lignes).
  3. Ceci stocke un 32pour imprimer facilement des espaces.
  4. Ceci contient la boucle interne (celle sur les colonnes).
  5. Ceci stocke un 78pour imprimer facilement Ns.

Passons en revue le code partie par partie. Tout d'abord, je crée le 32comme -4 + 9*4et le 78comme 6 + 9*8:

9(1-)
4-4+

6 8+

Maintenant, je suis Nen train d’ imprimer un single (car nous en avons toujours besoin) en lisant Net en stockant l’entrée N-1et N-2dans les deux premières voix:

      v2-
     ?1-

     v!

Ensuite, il y a une "boucle" conditionnée N-1. À la fin de la boucle, la deuxième voix est toujours réduite à 0et la boucle se ferme après la première itération. Donc, essentiellement, ceci seulement if(N > 1){...}. Après la boucle, nous imprimons une nouvelle ligne de fin. Pour récapituler, nous avons maintenant le cadre suivant:

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

À l'intérieur de cette condition, nous avons d'abord des N-2espaces et un simple Npour compléter la première ligne, et nous stockons également N-1la première voix pour une utilisation future:

         (1-)v         
          v!  

             v!

Maintenant la vraie viande du code. Premièrement, il y a une boucle externe qui imprime des N-1lignes. Pour chaque ligne, nous imprimons d’ abord une nouvelle ligne et un N. Ensuite, on boucle les N-2temps en imprimant soit des espaces, soit des Ns (nous en parlerons plus tard). Et finalement nous en imprimons un autre N:

               1-55+!  

                v1-v!(               )v!
               v#

Enfin, la partie amusante: imprimer chaque ligne (et obtenir la position de Ndroite). Il n'y a pas vraiment de if / else dans Prelude, je dois donc le construire moi-même en utilisant deux boucles sur des voix différentes. La condition peut facilement être obtenue en soustrayant les variables de boucle interne et externe - nous obtenons 0si nous voulons imprimer Net quelque chose de non-nul si nous voulons imprimer un espace.

L'idée de base d'un if / else dans Prelude est de mettre une boucle après la valeur pertinente - le code "if" (ou différent de zéro), et de la quitter immédiatement en appuyant sur a 0. Sur une autre voix, vous conservez une valeur non nulle et une autre boucle après la boucle "if". Pendant la boucle "if", mettez un zéro au-dessus de cette autre voix afin d'empêcher l'exécution du "else". Il y a une certaine souplesse dans le choix de placer les valeurs zéro au-dessus des valeurs non nulles ou tout simplement d'éliminer les valeurs non nulles s'il y a un zéro inférieur, mais c'est l'idée générale. Si vous souhaitez continuer à utiliser la voix correspondante, vous devrez peut-être également procéder à un nettoyage ultérieur. Voici à quoi ressemble le code:

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

Et c'est tout!

GCD

Ceci est "juste" une implémentation itérative de l'algorithme euclidien. Mais modulo dans Prelude est un peu gênant, principalement parce que vous ne pouvez pas facilement vérifier si un nombre est positif ou négatif. Ce code utilise une implémentation de signum que j'ai écrite il y a longtemps . C'est-à-dire qu'une grande partie du code transforme simplement un nombre en -1, 0ou 1. Cela peut alors être facilement transformé en une condition pour les nombres positifs ou négatifs en ajoutant ou en soustrayant 1.

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

Nous avons donc quatre voix cette fois. La première voix conserve simplement la trace de bla condition de terminaison principale et la contient (c'est-à-dire que la boucle se termine lorsqu'elle bdevient 0). La deuxième voix contient aet à l’aide des voix trois et quatre a % b, avant d’échanger le résultat avec la précédente b. Enfin, les !impressions aquand b == 0.

Regardons d' abord la partie signum :

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

Le numéro saisi nse trouve sur la première de ces voix (la deuxième voix du programme complet). Le résultat se retrouvera sur la voix du bas. Les deux autres voix devraient être vides (c'est-à-dire remplies de zéros). Notez que, si n == 0, les deux boucles sont ignorées et que la voix du bas contient toujours 0ce que nous voulons.

Si nnon-nul, la première petite boucle est entrée. Nous poussons un zéro pour le quitter immédiatement, mettons deux copies de nsur la voix du milieu et un 1sur la voix du bas. Maintenant, l’idée de base est d’incrémenter l’une des copies ntout en décrémentant l’autre copie njusqu’à ce que l’une d’elles atteigne zéro. Ce faisant, la 1voix du bas bascule tout le temps son signe (ce qui est facile à faire en le soustrayant de 0dessous en dessous de la pile). Ceci est configuré de telle sorte que lorsqu'un des numéros frappe zéro, la voix du bas contiendra le bon signe.

Maintenant modulo est mis en œuvre en soustrayant bde ajusqu'à ce que le résultat est négatif. Lorsque cela se produit, nous en ajoutons un à bnouveau. C'est ce bit:

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

Notez la construction if / else en bas, qui est similaire à celle utilisée pour la tâche 2.


2
Cela devrait vraiment faire partie d'un tutoriel Prelude.
Alex A.

21

2007 - Scratch

Scratch est une langue créée par le MIT à des fins éducatives. Je suis très impliqué avec cela depuis 5 ans; plus sur cela plus tard.

Tous ces éléments peuvent être consultés ici .

Je suis très pressé pour le moment et je vous expliquerai les extraits plus tard. Espérons qu'ils soient assez explicites.

Tache 1

entrez la description de l'image ici

Tâche 2

entrez la description de l'image ici

Tâche 3

entrez la description de l'image ici


Est-ce plus tard encore?
Dfeuer

21

1972 - C

Nous savons tous à propos de C, n'est-ce pas? C a été créé chez Bell Labs, avec Unix. Unix était écrit en grande partie en C. Tous les dérivés Unix modernes sont encore en grande partie écrits en C. La syntaxe de C a influencé de nombreux langages de programmation. C'est probablement le plus ancien langage de programmation encore largement utilisé pour les nouveaux développements.

C lui-même est un descendant de B, et j'espère qu'il figurera également dans cette liste. Il n'y avait pas de langage de programmation 'A': B est une variante de BCPL, qui à son tour est un CPL dépouillé. Aucune de ces langues n'a jamais été très populaire. Cependant, BCPL était la langue dans laquelle le premier programme "Hello World" a été écrit. Un autre fait intéressant est que B avait les deux /* */et des //commentaires, mais C a laissé tomber les //commentaires. Ils ont ensuite été réintroduits en C avec la norme C99.

Les programmes C ici ont été testés avec le compilateur Unix V5 C, à partir de 1974. Il s’agit du plus ancien compilateur C que j’ai pu trouver et me mettre au travail. Ces programmes ne seront pas compilés sur un compilateur C moderne. (L’un des changements apportés est que les opérateurs de mutation ont +=été écrits comme auparavant =+.)

#include <... >n'existait pas encore. Ni beaucoup de la bibliothèque standard. Je devais écrire le mien atoi. J'ai parcouru une partie du code source de la V5 pour déterminer les éléments autorisés et ceux qui ne le sont pas. La version que j'ai utilisée était la première à inclure structs, mais comme je ne les utilisais pas et que la syntaxe ne semble pas avoir beaucoup changé jusqu'à la V7 (comme K & R C), cela pourrait également fonctionner avec les versions précédentes.

J'ai fait de mon mieux pour écrire mon code dans le même style que celui utilisé par le code source V5. (Pas que ce soit terriblement cohérent, cependant.)

Recherchez ici des liens vers Unix V5, un émulateur et des instructions pour le faire fonctionner sur un ordinateur moderne.

Tache 1

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

Tâche 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]));
}

Tâche 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, je n'ai jamais réalisé à quel point C avait changé ... D'où vous vient ce compilateur?
Kirbyfan64sos

1
Le compilateur est celui fourni avec Unix V5. Il existe un lien dans la description vers un article de blog qui vous indique où obtenir les fichiers et comment l’exécuter sur un ordinateur moderne. (C'est ici ). Une fois que vous l'avez lancé, vous pouvez obtenir le code avec cat > file.c. (Terminez avec Ctrl-D, comme toujours). En outre, C a moins changé que vous pourriez penser: si vous changez le =*et =+dans les atoifonctions pour les équivalents modernes *=et +=, un CCG moderne va les compiler très bien et ils courent aussi. Presque aucun avertissement, même.
marinus

1
minnie.tuhs.org/cgi-bin/utree.pl?file=V2/c est le premier compilateur C que j'ai pu trouver (de la V2, daté de 1972).
Oberon

20

2009 - Idris

Idris est un langage fonctionnel pur, typé de manière dépendante, qui insiste sur le fait qu'il est pratiquement utilisable pour des applications réelles, en plus d'offrir des possibilités de preuve extrêmement rigoureuses pouvant être atteintes avec des types dépendants.

Tache 1

module Main

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

Tâche 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

Celui-ci n'est pas un programme mais juste une fonction (plus précisément une valeur dépendante ), produisant la lettre N souhaitée sous forme de tableau à deux dimensions.

$ 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)

Tâche 3

module gcd

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

Notez que j'ai dû choisir le nom gcd'car gcdil est déjà défini dans le prélude d'Idris.

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

Cela ressemble ils ont Haskell, permutés :et ::, et changé _à Z.
wchargin

@WChargin Zest en fait le constructeur de 0 : Nat. Le trait de soulignement est utilisé dans Idris, tout comme dans Haskell.
cessé de tourner dans le sens anti-horaire le

ah bon, voilà! :)
wchargin

19

2014 - Pyth

Puisque nous avons CJam, nous pourrions aussi bien avoir Pyth pour la complétude :)

Pyth est un langage de golf créé par @isaacg et compilé en Python. C'est remarquable pour être procédural et pour utiliser la notation préfixe. Pyth est apparu vers juin 2014 .

"Bonjour le monde!" Une variante

"Pyth was made in 2014!

Notez l'absence de guillemet de fermeture, qui est facultatif si un programme Pyth se termine par une chaîne.

ASCII Art N

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

Essayez-le en ligne . L'équivalent Python est:

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

Ou élargi (les première et troisième lignes sont implicites):

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

Ce programme utilise l'algorithme euclidien et prend deux nombres séparés par une nouvelle ligne. Essayez-le en ligne .

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

i.uQest encore plus courte si nous utilisons le mode intégré pour GCD. Cela équivaut à print(gcd(*eval(input())))(prendre deux nombres séparés par des virgules en entrée).


Drat - J'allais faire Pyth xP
theonlygusti

@isaacg Je ne peux m'empêcher de m'émerveiller et de poser la question ici: Pyth a-t-il été inspiré par Pyg de quelque manière que ce soit?
mardi

@ ıʇǝɥʇuʎs J'avais déjà vu PYG avant de créer Pyth et cela aurait pu influencer l'approche concept 1 caractère - 1. Cependant, si quelque chose inspirait Pyth, c’était probablement du golfscript.
isaacg

17

1964 - Dartmouth BASIC

BASIC est une famille de langages de programmation de haut niveau à usage général dont la philosophie de conception met l'accent sur la facilité d'utilisation. En 1964, John G. Kemeny et Thomas E. Kurtz ont conçu le langage BASIC original au Dartmouth College du New Hampshire. Ils voulaient permettre aux étudiants dans des domaines autres que les sciences et les mathématiques d'utiliser des ordinateurs.

Je regarde ce manuel sur BASIC de 1964, et cet émulateur du système de partage du temps de Darthmouth sur lequel il était exécuté. Le serveur est toujours opérationnel, mais malheureusement, l'enregistrement d'un compte semble impossible. Pour l'instant, ces programmes devraient théoriquement fonctionner:

Tache 1

10 PRINT "BASIC WAS MADE IN 1964"
20 END

Tâche 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

Produire quelque chose comme:

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

Notez comment l’entrée est saisie dans le cadre du programme ( 70 DATA 5); la READmanière d'instruction au sommet récupère les données à partir de là. Il n'y a pas de concaténation de chaînes, mais la section 3.1 du manuel explique comment les PRINTrésultats sont écrits dans des "zones" tabulées en sortie.

Tâche 3

La version lente de l'algorithme d'Euclid:

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

Sortie:

2

Enfin, quelqu'un a fait BASIC.
marinus

16

2010 - WTFZOMFG

WTFZOMFG est un langage ésotérique basé sur Brainfuck. Il a été créé par Jay Songdahl en 2010. "WTFZOMFG" est l'abréviation de "Qu'est-ce que c'est que cette fonction? Gophers de fichiers malveillants optimisés par Zen!" .

Voici un compilateur pour les systèmes * nix .

Tache 1

'WTFZOMFG was made in 2010!\n"

Tâche 2

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

Explication:

Pardon. Je ne suis pas bon pour écrire des explications.

/                                           # 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
                                          ) # 

Tâche 3

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

Algorithme euclidien. WTFZOMFG n'a pas de commande pour mod, je dois donc utiliser d(diviser), m(multiplier) et s(soustraire).


16

2009 - Go

Go est un langage de programmation développé par Google. Le développement a commencé en 2007, mais Go a été annoncé en novembre 2009.

Go est un langage à typage statique influencé par C qui met l'accent sur la concision, la simplicité et la sécurité.

Tache 1:

package main
import "fmt"

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

La première ligne déclare le package du code. Même un exemple simple d'impression d'une ligne doit faire partie d'un package. Et l'exécutable s'appelle toujours main.

Tâche 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 a une déclaration de variable assez concise ( i := 0identique à var i int = 0) et le compilateur détermine le type. C'est généralement une fonctionnalité plus courante dans les langages dynamiques. En utilisant cette notation courte, il est également très facile d’attribuer des fonctions à des variables ( f := func(x int) int {/* Code */}) et de créer des fermetures.

Tâche 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))
}

Ici vous pouvez voir la a, b = b, a%bsyntaxe, ce qui est vraiment sympa. Je ne connais pas le nom exact, mais en Python, cela s'appelle le déballage des tuples. De la même manière, vous pouvez renvoyer plusieurs valeurs d’une fonction ( func f() (int, string) { return 42, "Hallo"}).

Une autre chose qui se passe dans ce code est la boucle. La boucle for est la seule boucle de Go. Les boucles while ou do-while-lo n'existent pas. Mais vous pouvez facilement créer un équivalent pour la boucle while for condition {}ou une boucle infinie for {}.


16

1991 - Python

Histoire de la langue

À la fin des années 1980, Guido van Rossum a commencé à concevoir le python comme passe-temps. Son nom vient de Flying Circus de Monty Python, une émission télévisée britannique dont Rossum est fan. La première implémentation de Python a commencé en 1989 et a été publiée en 1991. Sa popularité a pris de l'ampleur au fil des ans et est devenue la langue de choix pour de nombreux cours d'initiation à l'informatique.

"Bonjour le monde!" Une variante

print("Python was made in 1991!")

Notez les parenthèses autour de l'entrée à print. Bien que cette syntaxe fonctionne dans Python 2, vous omettriez généralement ces parenthèses dans Python 2. Cependant, ils sont requis dans Python 3. Comme suggéré par Zach Gates, des parenthèses sont utilisées tout au long du processus pour garantir que le code présenté ici fonctionnera d’une version à l’autre.

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")

Les fonctions sont définies à l'aide de def. La concaténation de chaînes est effectuée à l'aide de +et la répétition de chaînes avec *.

GCD

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

Notez que Python nécessite des espaces blancs structurés.


16

1968 - Algol 68

Algol 68 a été défini par le groupe de travail IFIP 2.1 comme successeur d’Algol 60.

C'est un langage orienté expression dans lequel tout a une valeur. Il est également orthogonal, dans lequel vous pouvez utiliser n’importe quelle construction. Cela signifie que les expressions peuvent être sur le RHS et le LHS d'une assignation, par exemple.

Toutes les structures de contrôle ont une forme abrégée ainsi qu'une forme longue utilisant des expressions. Il permet également de définir les opérateurs.

Les objectifs de la langue sont cités comme suit:

Les principaux objectifs et principes de conception d’ALGOL 68:

  • Complétude et clarté de la description
  • Conception orthogonale,
  • Sécurité,
  • Efficacité
  • Vérification du mode statique
  • Analyse indépendante du mode
  • Compilation indépendante
  • Optimisation de boucle
  • Représentations - dans des jeux de caractères minimaux et plus grands

Ces programmes ont été testés avec l' interprète Algol 68 Genie , qui est une implémentation complète du langage.

Certaines caractéristiques que les programmeurs modernes peuvent trouver différentes sont que les instructions vides ne sont pas autorisées. Vous ne pouvez pas simplement ajouter ;partout. Vous devez utiliser la SKIPdéclaration si vous voulez explicitement ne rien avoir. Cela permettait aussi très facilement de coder des programmes concurrents. Algol 68 a également notamment utilisé des mots-clés inverses comme terminateurs, tels que esac , od , fi, etc.

La langue avait une représentation utilisée pour écrire le code qui utilisait de nombreuses polices représentant des mots-clés en gras et des identifiants en italique , par exemple. À l'époque, et probablement encore, aucun compilateur n'a implémenté cette fonctionnalité de la conception. Le langage permettait plusieurs représentations concrètes de programmes utilisant des modes de sauts . Cela permettait de préparer des programmes en utilisant des jeux de caractères limités, comme ceux que l’on pouvait trouver dans les ordinateurs des années 1960. Considérons le court fragment de programme, qui serait représenté par:

si je < 0 alors saute fi

Cela pourrait être préparé pour un compilateur en mode premier sautant comme:

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

En mode par points , ce serait:

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

En cas de mode stropping, ce serait:

IF i < 0 THEN SKIP FI

J'ai un grand penchant pour ce langage car j'ai travaillé sur l'une des implémentations du compilateur, ainsi que sur une programmation exclusive depuis de nombreuses années.

Tache 1

print (("Algol 68 a été fabriqué en 1968!", nouvelle ligne ))

Le point à noter ici est la double parenthèse. En effet, print est une fonction prenant un seul argument, qui est un tableau de longueur variable représentant l'union de tous les types. Les parenthèses internes sont le constructeur de tableau. C'est comment le polymorphisme est géré dans ce langage fortement typé.

En cas de mode stropping:

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


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

Tâche 2

     int n ;
     lire (( n ));
     pour i de 1 à n do
          pour j de 1 à n do
               ¢ on utilise ici une clause IF abrégée ¢
               print ((( j = 1 OU j = i OU j = n |
                    "N"
               |
                    ""
               )))
          od ;
     print (( newline))
     od

En cas de mode stropping:

 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

Tâche 3

     ¢ nous pouvons définir nos propres opérateurs dans Algol 68 ¢
     op % = ( int a , b ) int :
          (( b = 0 |
               a
          |
               b % ( a mod b )
          ));
     int i , j ;
     lire (( i , j ));
     print (( i % j , nouvelle ligne ))

En cas de mode stropping:

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

7
C’était probablement les premiers programmes Algol 68 que j’ai écrits et exécutés en plus de 30 ans. Je l'ai trouvé si émouvant, que cela m'a fait pleurer. Je n'ai jamais réalisé un "Hello World!" programme pourrait être tellement émotionnel!
Brian Tompsett -

1
J'avais tellement hâte des Langues des années 60 et j'étais prêt avec BCPL, Simula, CORAL66, Fortran 66, PL / 1, SNOBOL4, POP-1 et bien d'autres encore, mais je me suis rendu compte que les règles sont les mêmes que celles que j'ai attendre 5 ans de langues ... Au moins, il y a un sillon riche pour quelqu'un d'autre à labourer.
Brian Tompsett -

C'est vraiment cool de voir les différences entre Fortran66 (désordre total de la violence liée aux cartes perforées), APL (bizarre fouillis de symboles de la superpuissance) et Algol68, qui est en fait assez beau. Aujourd'hui, vous devriez vous pencher sur les langages ésotériques pour trouver une telle variété d'approches différentes… À l'époque, c'était plutôt courant, n'est-ce pas?
cessé de tourner dans

Bien sûr, le rapport révisé n’a été publié qu’en 1976? Au moins, c’est l’année du copyright que donne Springer. Et le scan que j'ai trouvé mentionne 1978.
Rhialto

[1] A. van Wijngaarden (éd.), Bl Mailloux, 1.EL Peck, CBA Koster, Rapport sur le langage algorithmique ALGOL 68, Numer. Math. 14 (1969) 79-218; également dans Kibenietika 6 (1969) et 7 (1970). [2] A. van Wijngaarden, Bl Mailloux, 1.EL Peck, CBA Koster, M: Sintzoff, CBLindsey, LGLT Meertens et RG Fisker, Rapport révisé sur le langage algorithmique ALGOL 68, Acta Informat. 5 (1975), parties 1 à 3 (réimpressions publiées par Springer, Berlin et aussi comme Mathematical Center Tract 50 par le Mathematisch Centrum, Amsterdam); également dans les avis SIGPLAN 12 (5) (1977)
Brian Tompsett - mercredi

16

1962 - SNOBOL

Le "Langage StriNg Oriented et symBOlic". Au début, apparemment appelé l’interprète d’expression symbolique, «SEXI», qu’il a ensuite fallu modifier pour empêcher les nerds des années 1960 de rougir lorsqu’ils présentent leurs offres d’emploi. Histoire vraie.

C'était l'une des premières langues pouvant traiter les chaînes et les modèles de manière native. En effet, la première version de SNOBOL avait la chaîne comme seul type de données. Les maths ont ensuite été analysés. La mise en œuvre initiale a été effectuée sur l’IBM 7090. Cela semble être parti depuis longtemps, du moins, je n’ai pas pu le trouver. Ce que j’ai trouvé, c’est le document original qui le décrit ainsi qu’un interpréteur SNOBOL3 en Java, qui peut s’exécuter sur un ordinateur moderne .

Le premier SNOBOL ne comportait quasiment que l’ appariement de motifs et l’arithmétique de base. SNOBOL 3 a ensuite ajouté des fonctions et modifié les E / S, mais semble être resté compatible avec les versions antérieures. SNOBOL 4 a changé la syntaxe et à partir de là, il est devenu Icon , qui conserve la correspondance du motif mais ressemble presque à un langage de programmation "normal".

Les programmes que j'ai écrits utilisent uniquement la fonctionnalité décrite dans le document d'origine. Ils doivent donc fonctionner avec le SNOBOL d'origine, à l'exception de l'E / S, que j'ai créée dans le style SNOBOL3 afin que l'interpréteur Java puisse les exécuter. D'après le papier, il semble que la différence réside dans le fait que SNOBOL1 utilise une correspondance de modèle avec une SYSvariable spéciale , alors que SNOBOL3 utilise des variables d'entrée et de sortie:

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

Faire ces substitutions devrait vous donner un "vrai" SNOBOL 1. Bien sûr, vous ne pouvez pas le lancer.

Tache 1

START   SYSPOT = 'SNOBOL WAS MADE IN 1962!'

Tâche 2

Cela montre les mathématiques, la gestion des chaînes et le contrôle de flux. SNOBOL3 a des fonctions utiles, comme EQvérifier l’égalité; Le SNOBOL original ne l’a pas été, je ne les ai donc pas utilisés.

* 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     

Tâche 3

D'abord ennuyeux. La seule chose à noter est la vérification plus petite que la précédente, montrant exactement à quoi ressemblait vraiment SNOBOL: (B - A) '-'"le résultat de BA contient-il un moins?". SNOBOL3 peut aussi le faire LE(B,A), mais SNOBOL 1 ne le pourrait pas (du moins le document ne le mentionne pas).

* 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

Bien sûr, lorsque vous utilisez un langage entièrement basé sur les chaînes et la correspondance de modèle, il serait dommage de ne pas utiliser réellement la correspondance et le remplacement de modèle. Ainsi, voici l’un de ces GCD unaires, comprenant des routines de conversion vers et depuis unary.

* 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

Excellent travail de fond! Pas grand chose pour 1961 - on dirait que COMIT est tout ce que nous avons ....
Brian Tompsett - mardi

15

2012 - TypeScript

TypeScript est un langage de programmation libre et open source développé et maintenu par Microsoft.

L'objectif principal est: N'importe quel navigateur. N'importe quel hôte. Tout OS. Open source. Il est sorti en octobre 2012

Bonjour TypeScript

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

ASCII Art

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;
}

essayez-le en ligne et screencast .


4
Vous avez oublié de mentionner une chose: TypeScript est un sur-ensemble de Javascript avec peu de changements de syntaxe et permet (?) Des variables et des arguments fortement typés.
Ismael Miguel

1
O mon dieu, quelque chose d'open source par MS!
Mega Man

15

2011 - Dart

Dart est un langage de programmation Open Source développé par Google qui est développé en remplacement de Javascript (bien qu'il compile au javascript). Il a été dévoilé par Google en 2011 lors de la conférence GOTO.

"Bonjour le monde!" Une variante:

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

ASCII Art N:

La méthode Bruteforce fonctionne à 0 (n²), mais cela ne devrait pas vraiment avoir d'importance sauf si vous utilisez un nombre géant.

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

simple méthode Euclid portée du Snap! exemple ci-dessus.

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);
            }
        }
    }
}

5
Je ne pense pas que vous puissiez produire un dessin en ASCII × n en moins de O (n²).
Paŭlo Ebermann

@ PaŭloEbermann Je ne connais pas très bien la notation O ou le calcul de la complexité, mais l'exemple de Julia semble ne pas être O (n²).
Nzall

@Alexa. La fonction println () imprime une chaîne de n caractères. Je pense que cet appel de fonction nécessite au moins un temps d'exécution O (n). Dans la boucle, donc O (n²) pour tout le programme.
Paŭlo Ebermann

@Alexa. Je pense que ce dont parle Ebermann, c'est que vous avez des opérations de concaténation de chaînes N dans votre fonction print. nous faisons tous les deux des concaténations de n² chaînes dans nos fonctions. Je les fais une fois par itération de la boucle interne, vous les faites pour chaque println ().
Nzall

1
Si ce n’était pas l’art, c’était O (n) d’afficher un N. (tracer 3 lignes à l’écran, chaque ligne est O (n) donc O (n) complexité). Ou, pourrait-on dire, rendre le N a la complexité O (N) ... hehe
rodolphito

15

2010 - rouille

Rust est un langage de programmation compilé à usage général, multi-paradigme développé par Mozilla Research. Il est conçu pour être un "langage sûr, simultané et pratique", prenant en charge les styles fonctionnels purs, à acteur simultané, à procédure impérative et orientés objet. Wikipédia

Tache 1

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

Tâche 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!("");
    }
}

Explication:

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

prend en charge uniquement l’impression verticale (gauche et droite |) et diagonale ( \)

Tâche 3

implémentation simple de l'algorithme euclidien

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;
}

Pourriez-vous ajouter un extrait montrant comment entrer deux entiers séparés par des espaces dans le stdin?
Zero Fibre

3
Rust a-t-il été "fabriqué" en 2010? La chronologie des langages de programmation le dit bien, mais l' article dit qu'il n'a été annoncé qu'en 2010 (en réalité 2011 comme en témoigne la référence ) et que la version 0.2 a été publiée en 2012.
EMBLEM le

1
@SampritiPanda, jetez un coup d'œil sur hastebin.com/raw/lapekowogu
wasikuss

1
Ça a l'air un peu moderne. Peut-il compiler la première version de travail publiée du compilateur <s> publiée </ s>?
Vi.

15

2015 - MC Muffin

Muffin MC est un macro-langage complet, amusant (mais sérieux), fonctionnel et minimaliste écrit par Franck Porcher ( http://franckys.com ) à la mi-février 2015 par nécessité, en tant qu'outil (rapide) de responsabilisation feuille de calcul utilisée comme seul contrôleur frontal permettant de piloter et de piloter toutes les opérations liées aux stocks associées à un site marchand basé sur Prestashop pour une nouvelle marque de mode tahitienne: Mutiny Tahiti ( http://mutinytahiti.com - bientôt disponible) lancé).

Muffin MC est un acronyme pour MU minuscule F onctional F lexible IN line M acro C ommand language.

Pour répondre à nos exigences, les principales fonctionnalités de Muffin MC ont été conçues autour de constructions sémantiques intégrées de première classe, souples et efficaces, telles que des itérateurs , des évaluations paresseuses , des multi-foncteurs et des produits de chaîne .

Muffin MC tire ses racines de la programmation fonctionnelle (pragmatique), FLisp et Perl. Il prend totalement en charge la récursivité (sans aucune optimisation), est typé de manière dynamique et porté de manière dynamique (liaison peu profonde). Il offre à ses utilisateurs une seule structure de données, en dehors des types de données de base atomes (atomes, chaînes, chiffres): des listes!

Muffin MC sémantique de la liste (genre de) emprunte sur Set Power- sémantique, qui est la suivante :

  1. Toutes les opérations Muffin MC donnent une liste, éventuellement vide.
  2. L'accès à un élément de liste individuel donne toujours une liste à valeur unique constituée de cet élément (considérez-le comme un singleton).
  3. La liste vide est l'élément neutre dans les opérations de liste.

Pour réconcilier avec cela, les éléments suivants peuvent aider:

  • On peut visualiser une liste en tant qu'élément du groupe électrogène de la liste qui a la plus grande cardinalité.
  • Visualisez un élément de liste en tant qu'élément de l'ensemble de puissance de la liste qui est le singleton composé de cet élément.
  • Visualiser une liste vide en tant qu'ensemble vide; c'est-à-dire le seul élément de la puissance du groupe vide.

En tant que tel, accéder à un élément de liste vide génère la liste vide, et non une erreur! En effet, Muffin MC s’efforce de réduire le plus possible le nombre d’erreurs en élargissant la sémantique de nombreuses opérations traditionnelles.

Tache 1

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

#(...)est la macro-commande Muffin MC permettant d’appliquer une fonction sur une liste d’arguments non évaluée, ici la fonction intégrée sayempruntée à Perl.

#(say 1 2 3 ...) est fonctionnellement identique à map {say $_} (1,2,3,...)

Tâche 2

Définir la fonction 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()Le formulaire de travail le plus court (88 octets):

=(f'(=(* x#(2-)I I(*($(x)" ")N)g'(#(.#(I$(x)))))#(say?(#(==$(_1)1)N"N#(map g#(..))N"))))
  • =(var val...)est la commande macro Muffin MC pour définir une variable ou la réaffecter.

  • $(var)est la macro-commande Muffin MC pour accéder à la valeur d'une variable. Il accepte naturellement le formulaire $(v1 v2 ...)pour accéder à plusieurs variables à la fois.

  • =(* var1 val1 var2 val2 ...)est l'extension de la macro-commande Muffin MC=(...) pour traiter les assignations parallèles.

  • Les variables _1, _2, ... ont une portée dynamique (mécanisme de liaison peu profond) et sont automatiquement définies pour se lier aux arguments de la fonction. Empruntées à Perl5, les variables système #(nombre d'arguments) et @(liste d'arguments) sont également définies automatiquement.

  • Les fonctions sont simplement des variables liées à un nombre quelconque d' instructions Muffin MC .

Cette solution intéressante provient de la combinaison de deux fonctionnalités intégrées naturelles de Muffin MC :

  1. La macro-commande Muffin MC I(...) , permettant de définir des cycleurs-itérateurs, utilisés ultérieurement avec la forme fonctionnelle #(my-iterator want-number-of-values),

  2. Le Muffin MC chaîne produit construction, une extension de l'interpolation de variables naturelle, qui, étant donné une chaîne "F1 F2 F3...", où les F i s sont soit Muffin MC littéraux de chaîne ou Muffin MC commande macro (aka formes fonctionnelles), produira autant de chaînes que donnée par le produit cardinal (F1) x cardinal (F2) x ....

Par exemple, si xa contient 2 valeurs, a et b, et y une autre variable, 3 1, 1 2 3, l'évaluation de la chaîne "x=$(x) y=$(y))"produira 6 valeurs différentes, à savoir, dans cet ordre:

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

C’est l’une des fonctionnalités hautement souhaitables du projet MUTINY pour laquelle Muffin MC a été conçu.

Exécuter !

#(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

Comment ça marche

Notre algorithme est basé sur les éléments suivants:

Étant donné un appel à ascii-art (n), {n = 2p + 1 | p entier, p> = 0}, l’art de générer comprend n chaînes de n caractères, parmi lesquels deux, la plus à gauche et la plus à droite, sont fixes et sont toujours identiques: 'N'. Cela permet de réduire le problème en produisant uniquement les chaînes moyennes. Par exemple, pour n = 5, nous produirions les 5 chaînes intermédiaires suivantes, chacune composée de n-2 caractères (nous avons remplacé l'espace par un "_" pour une meilleure visualisation):

    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 |
                                _ _ _
  • Ces cordes médianes peuvent facilement être produites en passant sur la séquence de 4 éléments ('_' '_' '_' 'N')en 5 groupes de 3; étant donné n, l'entrée de la fonction, cette séquence est composée de n-2 caractères '_', suivis du caractère 'N'. Parcourir cette séquence ne nécessite rien d’autre que l’incorporer dans un itérateur intégré à Muffin MC I(sequence) (un itérateur qui effectue un cycle permanent sur sa séquence de valeurs initiale).

  • Nous produisons ensuite simplement les chaînes médianes, de longueur n-2, en demandant à notre itérateur de nous fournir ses n-2 valeurs suivantes (n - 2 caractères), qui sont concaténées ensemble pour produire la chaîne médiane attendue.

  • Les n chaînes médianes sont produites en répétant n fois le processus ci-dessus, en utilisant une carte pour collecter les n résultats (n chaînes de n-2 caractères).

  • Nous utilisons un autre puissant Muffin MC construction intégrée, à savoir le produit de chaîne , pour produire les n chaînes finales: "N#(map...)N".

  • Et c'est tout !

    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.
         )
     ))
    

Tâche 3

Définir la fonction gcd():

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

gcd()de » réelle forme la plus courte (37 octets - 2 octets grâce à Rodolvertice gagnent)

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

Exécuter !

#(gcd 225 81)

donne 9.

C'est ça.

Merci pour le beau jeu, et éventuellement pour votre intérêt. Le langage est disponible pour tous ceux qui souhaitent jouer avec, l’utiliser ou même l’étendre. Il suffit de demander et je serai heureux de l'envoyer.

À votre santé

Franck


PS L'implémentation actuelle de Muffin MC est en Perl5. Le code source contient environ 2000 lignes de Perl moderne, commentaires compris, et est fourni avec une suite de tests de non-régression, ce qui est très pratique pour apprendre les constructions et la sémantique pratiques de Muffin MC .


Vraiment sympa! La forme la plus courte de ascii-art a un nom de fonction abrégé, mais pas la plus courte de GCD. Est-ce intentionnel, car sinon, vous pouvez supprimer 2 octets supplémentaires. +1
Rodolphito

Bien sûr, et c'est intentionnel. Devrais-je ? oui, faisons-le;) Merci pour le post et ton appréciation.
Franck Porcher

1
Puisque vous essayez de vous débarrasser des caractères supplémentaires (et parce que je peux être un mauvais grammaire incorrigible), vous pouvez (devriez) supprimer l’espace devant le point d’exclamation pour la première tâche. Cet espace est correct en français autant que je sache, mais pas en anglais.
Amos M. Carpenter,
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.