Linguaggi di programmazione attraverso gli anni


168

In questa sfida, gli utenti completeranno a turno tre compiti di codifica abbastanza semplici in linguaggi di programmazione che possono essere progressivamente più vecchi.

La prima risposta deve utilizzare un linguaggio di programmazione creato nel 2015. Una volta che esiste almeno una risposta da un linguaggio 2015, le risposte possono utilizzare linguaggi di programmazione creati nel 2014. Allo stesso modo, le risposte che utilizzano i linguaggi dal 2013 non sono consentite fino a quando non vi sarà almeno una risposta per il 2014.

In generale, l'uso di un linguaggio di programmazione dell'anno Y non è consentito fino a quando non viene inviata una risposta utilizzando un linguaggio dell'anno Y + 1. L'unica eccezione è Y = 2015.

Trovare l'anno della tua lingua

Per rispondere a questa domanda, devi sapere l'anno in cui il tuo linguaggio di programmazione è stato "realizzato". Questo è, ovviamente, un termine soggettivo; alcune lingue sono state sviluppate nel corso di diversi anni e molte lingue vengono ancora aggiornate ogni anno. Lascia che l'anno in cui una lingua sia stata "realizzata" sia il primo anno in cui un'implementazione per quella lingua sia apparsa al pubblico.

Ad esempio, Python fu "realizzato nel" 1991 , sebbene il suo sviluppo fosse in corso dal 1989 e la versione 1.0 non fu rilasciata fino al 1994.

Se quest'anno è ancora soggettivo, basta usare il buon senso per scegliere l'anno più appropriato. Non impantanarti in lievi disaccordi sulle scelte dell'anno. Fornisci un link a una fonte che indichi quando è stata creata la tua lingua.

Versioni o standard diversi di un linguaggio di programmazione (ad esempio Python 1, 2, 3) vengono considerati come lo stesso linguaggio con lo stesso anno iniziale.

Pertanto, a meno che l'anno della tua lingua non sia il 2015, puoi inviare la tua risposta solo dopo che è stata inviata una risposta la cui lingua dell'anno è l'anno immediatamente precedente alla tua.

Se esiste già una risposta valida con lo stesso anno del tuo, puoi rispondere. Non importa se la tua lingua è stata sviluppata prima o dopo l'anno.

Compiti

È necessario completare le attività da 1 a 3. L'attività 0 è facoltativa.

Queste attività sono state più o meno scelte per corrispondere a tre aspetti importanti della programmazione: fornire output (Task 1), loop (Task 2) e ricorsione (Task 3).

Attività 0 - Cronologia della lingua (opzionale)

Scrivi almeno un paragrafo che spieghi la storia del tuo linguaggio di programmazione prescelto: chi lo ha sviluppato, perché, come, ecc. Ciò è particolarmente incoraggiato se eri personalmente in giro quando il linguaggio è nato, e forse ha anche avuto un ruolo nel suo sviluppo. Sentiti libero di mettere in relazione aneddoti personali sull'effetto che la lingua ha avuto su di te, sul tuo lavoro o su qualcosa del genere.

Se sei troppo giovane per sapere molto sulla storia della tua lingua senza molte ricerche, considera di lasciare una nota agli utenti più anziani che dice che possono modificare il tuo post e aggiungere un po 'di cronologia di prima mano.

Compito 1 - "Ciao, mondo!" Variante

Scrivi un programma che stampa

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

nell'area di output standard della tua lingua (stdout per le lingue più recenti).

Ad esempio, se la lingua fosse Python, l'output sarebbe:

Python was made in 1991!

Compito 2 - ASCII Art N

Scrivi un programma che consenta all'utente di inserire un numero intero positivo dispari (puoi supporre che l'input sia sempre valido) e stampa una lettera di arte ASCII N creata usando il carattere N.

Se l'ingresso è 1, l'uscita è:

N

Se l'ingresso è 3, l'uscita è:

N N
NNN
N N

Se l'ingresso è 5, l'uscita è:

N   N
NN  N
N N N
N  NN
N   N

Se l'ingresso è 7, l'uscita è:

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

Il modello continua così. L'output può contenere spazi finali.

Compito 3 - GCD

Scrivi un programma che permetta all'utente di inserire due numeri interi positivi (puoi supporre che l'input sia sempre valido) e stampa il loro massimo comune divisore . Questo è definito come il numero intero positivo più grande che divide entrambi i numeri senza lasciare un resto. Può essere facilmente calcolato usando l' algoritmo euclideo .

Esempi:

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

Puoi usare una funzione integrata ma prova a scoprire se era presente nella prima versione della tua lingua. In caso contrario, prova a non usarlo.

Regole

  • Puoi rispondere più volte, ma ogni nuova risposta deve utilizzare una lingua creata almeno 5 anni prima della lingua dell'ultima risposta. Quindi, se hai risposto con una lingua del 2015, non potresti rispondere di nuovo fino a quando le lingue del 2010 non sono consentite. Se inizi con una risposta del 2010, non puoi fare in modo che il 2015 risponda alla tua seconda risposta perché il 2015 non è precedente al 2010.
  • Se possibile, scrivi il tuo codice in modo che funzionasse nella prima versione della tua lingua (o nella versione più vecchia possibile). (Questo non è un requisito perché trovare vecchi compilatori / interpreti per alcune lingue potrebbe essere difficile.)
  • Evita di pubblicare una lingua che è già stata pubblicata a meno che la risposta pubblicata non contenga errori significativi o che tu abbia un modo molto diverso di completare le attività.
  • Giocare a golf il tuo codice va bene ma non è richiesto.
  • Una nuova riga finale nell'output di qualsiasi programma va bene.
  • Per le attività 2 e 3, tutti i valori di input inferiori a un massimo ragionevole come 2 16 dovrebbero funzionare (almeno 256).
  • La tua lingua deve essere esistita prima che questa domanda fosse pubblicata.
  • I linguaggi di programmazione molto vecchi possono avere diverse forme di input e output rispetto a ciò che pensiamo oggi. Questo va bene. Completa le attività al meglio delle tue capacità nel contesto della tua lingua.

punteggio

Il punteggio della tua richiesta è:

upvotes - downvotes + (2015 - languageYear) / 2 

Pertanto, 0,5 viene aggiunto al conteggio dei voti per ogni anno prima del 2015, dando il vantaggio alle lingue più vecchie. Vince l'invio con il punteggio più alto.

Elenco di risposte

Lo snippet di stack di seguito elenca tutte le risposte valide in base all'anno linguistico.

Devi iniziare il tuo post con questa linea Markdown per assicurarti che sia elencato correttamente:

#[year] - [language name]

Per esempio:

#1991 - Python

Il nome della lingua potrebbe essere in un collegamento (sarà lo stesso collegamento nell'elenco delle risposte):

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

Le risposte che non seguono questo formato o che hanno un anno non ancora consentito o che provengono da un utente che ha già risposto negli ultimi 5 anni sono contrassegnate come non valide.

<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
Questo dovrebbe aiutare.
frizzante

20
Wikipedia ha un elenco per tutto: questo per le lingue non esoteriche per anno.
Sanchises,

2
L'attività 3 dovrebbe effettivamente utilizzare la ricorsione o è sufficiente che produca il risultato corretto? Se ho bisogno di scrivere la mia funzione GCD di solito uso solo un loop ma ne ho scritto uno ricorsivo appositamente per questa sfida. Ci sono molte risposte inviate che usano solo un ciclo.
CJ Dennis,

5
Ho voglia di fare un secondo resoconto solo per farci superare il 1971.
marinus

5
Se riusciamo a risalire al 1952, ho qualcuno che fa girare una macchina storica che potrebbe fare soluzioni del 1951 (Pegasus) e testarle!
Brian Tompsett - 莱恩 莱恩

Risposte:


173

2013 - Dogescript

Dogescript è una lingua creata nel 2013 da Zach Bruggeman. Non è altro che un sostituto della sintassi per Javascript per farlo leggere come i monologhi interni del memetico Shiba Inus.

Ciao 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, ad esempio +1. Molto risposta. Molta qualità.
Alex A.

27
Mi sono unito a Codegolf solo per votare questa risposta!
Derek Tomes

21
Non riesco nemmeno a leggere quello GCD con una faccia
seria

16
Non riesco a leggere gcd_doge come good_dog. Aiuto
Yann

Fantastico. Tuttavia, secondo LANGUAGE.md, le virgolette doppie non sono supportate. Mi piacerebbe anche una spiegazione del s[i]po '!
Docteur,

66

2015 - Retina

Retina è un linguaggio di programmazione basato su regex, che ho scritto per essere in grado di competere nelle sfide PPCG con risposte solo regex, senza avere il sovraccarico inutile di chiamare regex in un linguaggio host. Retina è Turing-complete. Per dimostrarlo, ho implementato un solutore di sistema a 2 tag e la Regola 110 . È scritto in C #, quindi supporta sia il sapore .NET (per impostazione predefinita) che il sapore ECMAScript (tramite un flag).

Retina può operare in più modalità, ma la più rilevante per i calcoli (e quella completa di Turing) è la modalità Sostituisci. In modalità Sostituisci dai a Retina un numero pari di file sorgente. Questi vengono quindi accoppiati, il primo di ogni coppia è una regex e il secondo una sostituzione. Questi vengono quindi eseguiti in ordine, manipolando l'input passo dopo passo. Il regex può anche essere preceduto da una configurazione (delimitata da `). L'opzione più importante (che rende Retina Turing completa) è +, che rende Retina applicare la sostituzione in un ciclo fino a quando il risultato non smette di cambiare. Negli esempi seguenti, sto anche usando ;, che sopprime l'output su stadi intermedi.

In ciascuno dei seguenti invii, ogni riga va in un file sorgente separato. (In alternativa, è possibile utilizzare la nuova -sopzione e inserire tutte le righe in un singolo file.) I file / linee vuoti sono rappresentati come <empty>. I file / linee contenenti un singolo spazio sono rappresentati come <space>.

Le spiegazioni sono piuttosto lunghe, quindi le ho spostate alla fine del post.

I programmi

"Ciao mondo!" Variante

<empty>
Retina was made in 2015!

ASCII Art N

Ciò presuppone che STDIN sia terminato con una nuova riga.

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

Ciò richiede che STDIN non venga chiuso con una nuova riga.

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

spiegazioni

"Ciao mondo!" Variante

Questo è abbastanza banale. Non accetta input (ovvero una stringa vuota), non corrisponde a nulla e lo sostituisce con Retina was made in 2015!. Si può anche farlo funzionare per input arbitrari, sostituendo il modello con [\s\S]*per esempio. Ciò consumerebbe STDIN e lo sostituirà con l'output.

ASCII Art N

Questo ha molte fasi. L'idea è di convertire l'input in unario, creare un blocco N x N di Ns e quindi "ritagliare" due triangoli. Passiamo attraverso le singole fasi. Ricorda che ;elimina semplicemente le uscite intermedie, ma +fa sì che la sostituzione venga applicata in un ciclo.

;`^
#

Semplice: anteponi #a all'input. Questo sarà usato come marcatore nella conversione in unario.

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

Questo converte una cifra in unaria. Prende le cifre già convertite (\d*)e le ripete 10 volte. E quindi prende la cifra successiva e aggiunge il numero appropriato di cifre. Il valore effettivo delle cifre è irrilevante in questa fase. Quando #raggiunge la fine del numero, la regex non corrisponde più e la conversione viene eseguita. Ad esempio, il numero 127verrà elaborato come

#127
1#27
111111111122#7
1111111111221111111111221111111111221111111111221111111111221111111111221111111111221111111111221111111111221111111111227777777#

dove l'ultima riga contiene esattamente 127 caratteri.

;`#
<empty>
;`\d
N

Due semplici passaggi che lo eliminano #e quindi convertono tutte le cifre in N. Di seguito userò input 7come esempio. Quindi ora abbiamo

NNNNNNN

Il prossimo stadio

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

sostituisce ciascuna Ncon l'intera stringa (ricorda che contiene una nuova riga finale) e rimuove anche la nuova riga finale. Quindi, questo trasforma la singola riga in una griglia quadrata:

NNNNNNN
NNNNNNN   
NNNNNNN
NNNNNNN
NNNNNNN
NNNNNNN
NNNNNNN

Ora il triangolo superiore. Innanzitutto, iniziamo le cose trasformando la N nell'angolo in basso a destra in uno spazio:

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

Il lookahead assicura che stiamo modificando il corretto N. Questo da

NNNNNNN
NNNNNNN   
NNNNNNN
NNNNNNN
NNNNN N
NNNNNNN
NNNNNNN

E adesso

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

è una regex che corrisponde a una Nsopra o nell'angolo in alto a sinistra di un carattere spazio e la sostituisce con uno spazio. Poiché la sostituzione viene ripetuta, si tratta essenzialmente di un riempimento, che trasforma il terzo ottante dallo spazio iniziale in più spazi:

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

E infine, ripetiamo la stessa cosa con il triangolo inferiore, ma utilizziamo un carattere diverso, quindi gli spazi già esistenti non causano un riempimento errato:

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

imposta il seme:

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

Poi

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

fa il diluvio.

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

E infine

S
<space>

Trasforma quelli Sin spazi e abbiamo finito:

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

GCD

GCD in unario è in realtà molto banale con regex. La maggior parte di questo consiste nella conversione da decimale a unario e da unario a decimale. Questo potrebbe essere fatto in modo più compatto, ma questo non è un codice golf, quindi ...

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

Queste fasi sono essenzialmente le stesse di quelle precedenti, tranne per il fatto che entrambi i numeri di input vengono convertiti e il risultato utilizza 1s anziché Ns (non che contenga). Quindi, se l'input fosse 18 24, ciò produrrebbe

111111111111111111 111111111111111111111111

Adesso

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

è l'intero calcolo GCD. Abbiniamo un divisore comune catturando un numero di 1s e quindi usando i riferimenti indietro per garantire che entrambi i numeri possano essere scritti ripetendo quella stringa (e nient'altro). A causa di come funziona il backtracking nel motore regex (cioè che .+è avido), questo produrrà sempre automaticamente il massimo comun divisore. Poiché la partita copre l'intera stringa, semplicemente riscriviamo il primo gruppo di acquisizione per ottenere il nostro GCD.

Infine, la conversione da unario a decimale ...

;`$
#:0123456789

Aggiungi un marcatore #, un delimitatore :e tutte le cifre alla stringa. Questo è necessario, perché non è possibile produrre nuovi personaggi in modo condizionale in una sostituzione regex. Se si desidera la sostituzione condizionale, è necessario estrarre i caratteri dalla stringa stessa, quindi li inseriamo 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

Questo è l'inverso dell'espansione unaria in precedenza. Troviamo il multiplo più grande di 10 che si adatta alla stringa corrente. Quindi scegliamo la cifra successiva in base al resto e dividiamo il multiplo per 10, spostando l'indicatore tra le cifre.

#|:.*
<empty>

E infine solo un passaggio di pulizia per sbarazzarsi del marker, delimitatore e delle cifre dell'helper.


Penso che dovresti aggiungere le istruzioni per convertire l'input numerico in stringa unaria e le istruzioni per convertire nuovamente la stringa unaria in input numerico. La conversione con regex puro è interessante ma decisamente troppo goffa.
n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳,

8
+1 Ero abbastanza sicuro che l'invio del 2015 sarebbe una lingua per l'uso di CodeGolf.
Zero Fiber

@ n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳ Lo stavo prendendo in considerazione prima. Penso che per la maggior parte dei golf di codice, probabilmente prenderei solo input Unary (a meno che la sfida non specifichi esplicitamente "decimale" o qualcosa del genere ...). Ho pensato di fare lo stesso per questo, ma questo non è un codice golf, e volevo dimostrare che sono in grado di gestire anche input e output decimali.
Martin Ender,

6
Lavoro eccellente. Retina è davvero fantastica. E a parte questo, è anche bello vedere il diamante accanto al tuo nome! :)
Alex A.

Divertente che sebbene le lingue antiche siano favorite in questa competizione, questa è la più giovane che sta ancora vincendo =)
Claudiu

60

2013 - Snap !

Snap ! è una lingua basata su Scratch , realizzata alla Berkeley University. È un aggiornamento a Scratch con dati di prima classe e blocchi personalizzati (funzioni). Come Scratch, non è basato sul testo, ma piuttosto fatto da "blocchi" visivi che si agganciano.

Snap ! , scritto in JavaScript, è il successore di BYOB, che è stato scritto in Squeak Smalltalk. Snap ! è stato rilasciato in versione beta per il consumo pubblico nel marzo 2013 .

Snap ! non è in realtà una lingua esoterica. È usato come linguaggio di programmazione per il corso AP CS Beauty and Joy of Computing (BJC) a Berkeley e altri.

Ho aiutato con test e cose.

Variante "Hello World"

ASCII Art "N"

inserisci qui la descrizione dell'immagine

Questo utilizza lo stdlib per alcuni dei blocchi.

Looping piuttosto semplice qui. Accetta un input. Quindi aggiungiamo tutto insieme e lo diciamo (risultato per n = 5):

inserisci qui la descrizione dell'immagine

Ho preso la libertà qui per usare solo 2 spazi invece di 1, perché Snap! non dice cose in monospazio.

GCD

L'algoritmo euclideo non è molto veloce, ma funziona ed è piuttosto semplice. (Mi dispiace, ho fatto un refuso nel nome del blocco. Ora ho chiuso la scheda senza salvare. Dovrà solo rimanere.)

inserisci qui la descrizione dell'immagine

Questa definizione di funzione produrrà quindi questo blocco:

inserisci qui la descrizione dell'immagine


3
Questo sembra
MOLTO

4
Questo è ciò che ottieni con le lingue basate su blocchi. Vieni a pensarci bene, molte lingue si assomigliano. ;)
Scimonster il

1
Anche Scratch ha una funzione mod, quindi suppongo che potresti rendere più veloce la funzione GCM / GCD con un blocco basato su if (b == 0) e poi su un altro GCM (b, a% b)
Alchymist

55

2007 - LOLCODE

Storia della lingua

LOLCODE è stato creato nel 2007 da Adam Lindsay, ricercatore presso la Lancaster University. La sua sintassi si basa sui meme di lolcats diffusi da Cheezburger, Inc.

"Ciao mondo!" 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

I valori vengono letti come stringhe (YARNs) dallo stdin usando GIMMEH. Possono essere convertiti in numerici (NUMBR) moltiplicando per 1.

I valori vengono stampati su stdout usando VISIBLE. Per impostazione predefinita viene aggiunta una nuova riga, ma può essere eliminata aggiungendo un punto esclamativo.

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 esegue la concatenazione di stringhe.


13
Finalmente una lingua che tutti possono capire.
ASCIIThenANSI

26
IM IN YR toilet UPPIN YR buttSimpatici nomi di variabili
Cole Johnson,

13
@ColeJohnson: cerco sempre di scegliere i nomi delle variabili che hanno senso nella situazione piuttosto che x1, x2ecc
Alex A.

2
Divertente. Non dovrei leggere questo al lavoro.
Alan Hoover,

@AlanHoover: Chiaramente i lolz sono più importanti dei jobz.
Alex A.

43

1982 - PostScript

PostScript è un linguaggio per la creazione di grafica vettoriale e stampa.

Adobe è stata fondata nel 1982 e il loro primo prodotto è stato PostScript. Il linguaggio è stato utilizzato nelle stampanti: i comandi sono interpretati dalla stampante per creare un'immagine raster, che viene quindi stampata sulla pagina. Era un componente molto comune delle stampanti laser fino agli anni '90. Ma ovviamente sulla CPU è piuttosto intensivo e, man mano che i processori per computer diventano più potenti, ha più senso eseguire la rasterizzazione sul computer rispetto alla stampante. PostScript è in gran parte scomparso sulle stampanti consumer, sebbene esista ancora su molte altre stampanti di fascia alta.

Lo standard che ha sostituito PostScript è un formato poco noto chiamato PDF.

Quando ho iniziato a programmare PostScript era passato di moda, ma ho imparato un po 'mentre ero all'università come un altro modo di creare documenti per TeX. Era abbastanza diverso dagli altri linguaggi di programmazione che avevo usato (notazione infografica inversa, pila, stampa su una pagina anziché su una console), ma è stato bello rispolverare questo vecchio linguaggio per un po 'di divertimento.

Poiché PostScript è un linguaggio di stampa, sembra più appropriato utilizzarlo per stampare qualcosa, quindi inviare un output alla console.

Compito 1

/Courier findfont
12 scalefont
setfont
newpath

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

Le prime poche linee creano una tela su cui disegnare. Quindi il movetocomando dice a PS di disegnare in una posizione particolare eshow stampa la stringa sulla pagina. Nota che le parentesi segnano una stringa in PostScript, non le virgolette.

Compito 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

Ho scritto una funzione per disegnare "ASCII art" N, ma non c'è modo per le funzioni PostScript di sostenere un argomento. Invece, spingi i tuoi argomenti in pila, poi li rimuovi. Quello è il/x exch def linea.

Un esempio: supponiamo che lo stack sia 8 9 2. Per prima cosa inseriamo il nome /xnello stack, quindi lo stack è 8 9 2 /x. L' exchoperatore scambia i due valori dello stack, quindi ora lo è 8 9 /x 2. Quindi defapre i primi due valori dello stack e definisce /xdi avere il valore 2. Lo stack è ora 8 9.

Quando ho iniziato a usare PostScript, l'ho trovato un po 'confuso. Avevo letto dello stack come un concetto teorico, ma questa era la prima volta che lo usavo in pratica.

Il resto della funzione è un codice di disegno: inizia nell'angolo in basso a destra, riempiendo una riga alla volta da sinistra a destra a diagonale.

Compito 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

Ancora una volta, ho usato una forma dell'algoritmo di Euclide, ma avevo dimenticato che PostScript ha un operatore modulo integrato, quindi ho dovuto scrivere il mio. Ciò si è rivelato un utile promemoria dei vincoli della programmazione basata su stack. La mia prima implementazione di moduloera basata sulla ricorsione:

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

che va bene fino a quando non si tenta di eseguirlo quando xè grande ed yè piccolo (ad esempio 5689 e 2). Puoi avere fino a 250 elementi in pila, quindi soffiavo ben oltre il limite di pila. Ops. Ho dovuto tornare al tavolo da disegno su quello.

Il codice GCD stesso è abbastanza semplice. Ma proprio come le funzioni non possono accettare argomenti, quindi non hanno valori di ritorno. Invece, devi spingere il risultato nello stack dove qualcun altro può saltar fuori in seguito. Questo è ciò che aeb a gcd linee : quando hanno finito di valutare, spingono il valore nello stack.

Se inserisci tutto il codice in un documento e lo stampi, ecco come appare l'output:

inserisci qui la descrizione dell'immagine


8
Haha Adoro la fotografia del pezzo di carta stampato. Ritenere appropriato per il 1982.
Alex A.

1
Inoltre, grazie per la tua descrizione di come hai ottenuto un overflow dello stack (letterale) - ora capisco più intuitivamente perché le lingue hanno una profondità massima di ricorsione.
DLosc,

2
@AlexA .: Sì, ma una stampa a matrice di punti (con fori sui lati del foglio) sarebbe stata ancora più appropriata . ;-)
Amos M. Carpenter

@ AmosM.Carpenter: non proprio, non credo che nessuna stampante a matrice di punti abbia mai supportato PostScript. È sempre stato piuttosto legato alle stampanti laser.
ninjalj,

41

2009 - > <>

Ispirato da Befunge,> <> (Fish) è un linguaggio esoterico basato su stack 2D, ovvero il flusso del programma può essere su, giù, sinistra o destra. La versione iniziale di> <> presentava il multithreading dove [e] creava e terminava i thread, ma per ragioni di semplicità queste istruzioni sono state cambiate rispettivamente nella creazione e rimozione di nuovi stack.

L'attuale interprete ufficiale per> <> è disponibile qui . Sfortunatamente, il link al vecchio interprete sulla wiki di Esolang è rotto.

"Ciao mondo!" Variante

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

Nota come la stringa è scritta al contrario -> <> non ha tecnicamente stringhe, con l'unico tipo di dati che è un bizzarro mix di char, int e float. "attiva / disattiva l'analisi delle stringhe, spingendo ciascun personaggio in pila fino a quando non "viene raggiunta la chiusura .

La seconda metà del codice quindi spinge la lunghezza dello stack l, controlla se è zero ?!e in tal caso il programma termina ;. Altrimenti il ​​puntatore dell'istruzione continua, emettendo la parte superiore dello stack con oprima dell'esecuzione bb+0., che teletrasporta il puntatore in posizione (22, 0)appena prima dell , creando un loop.

ASCII Art N

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

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

   \                                                         <   /

Con spazio per chiarezza. Puoi provarlo nel nuovo interprete online qui e vedere il puntatore delle istruzioni che gira e gira - ricorda di inserire un numero nella casella di testo "Pila iniziale". Se stai utilizzando l'interprete Python, usa il -vflag per inizializzare lo stack, ad es

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

Per questo programma, inseriamo l'input nnel registro &e inviamo uno 0, che chiameremo i"iterazioni". Il resto del programma è un loop gigante che va così:

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

Quindi ripetiamo il ciclo dall'inizio.

Le frecce ^>v<cambiano la direzione del flusso del programma e gli specchi /\riflettono la direzione del flusso del programma.

GCD

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

Ecco un esempio di come potrebbe apparire un programma golf <>. Ancora una volta, puoi provare questo nell'interprete online (inserisci due valori separati da virgola nella casella "Stack iniziale", ad es. 111, 87) O usando il -vflag dell'interprete Python, ad es.

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

Questo programma utilizza l'algoritmo euclideo. Ecco una GIF che ho preparato prima:

inserisci qui la descrizione dell'immagine

Si noti che> <> è toroidale, quindi quando vviene eseguita l'istruzione in basso a sinistra il puntatore dell'istruzione si sposta verso il basso, si avvolge e ricompare in alto.


Modifica: eseguendo il codice interamente da destra a sinistra , @randomra è riuscito a radere tre byte con

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

Immagino di non averlo giocato abbastanza :)


27
Ed è così che ho scoperto che il nome ><>è palindromo.
Zev Eisenberg,

33

2012 - Elemento

Questa è una lingua che ho inventato all'inizio del 2012 per essere una semplice lingua da golf. Con questo, intendo dire che c'è un sovraccarico dell'operatore minimo o nullo. Gli operatori sono anche più semplici e in numero inferiore rispetto alla maggior parte delle lingue di golf moderne.

Le caratteristiche più interessanti di questo linguaggio sono le sue strutture di dati. Esistono due stack e un hash che vengono utilizzati per archiviare informazioni.

Lo stack m è lo stack principale, dove si svolgono l'aritmetica e la maggior parte delle altre operazioni. Quando i dati vengono immessi o stampati, è qui che vanno o vengono recuperati.

Lo stack c è lo stack di controllo. Qui è dove si svolge l'aritmetica booleana. I valori più alti dello stack c sono usati dai cicli If e While come condizione.

L'hash è dove sono memorizzate le variabili. Il; e ~memorizza e recupera i dati dall'hash, rispettivamente.

Element è un linguaggio tipicamente molto debole. Usa la capacità di Perl di interpretare liberamente i numeri come stringhe e viceversa.

Mentre ci sono, potrei anche includere tutta la documentazione per la lingua. Puoi trovare l' interprete originale del 2012, scritto in Perl, proprio qui . Aggiornamento: ho creato una versione più utilizzabile, che puoi trovare proprio qui .

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 \

Attività 1 - Stampa testo

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

Una delle parti più imbarazzanti del linguaggio è la mancanza di delimitatori di stringa, motivo per cui in questa stringa sono necessari caratteri di escape. Il` fine stampa la stringa.

Compito 2 - ASCII Art N

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

Qui, assisterai ad alcune manipolazioni dello stack. Per semplificare la formattazione della spiegazione, sostituirò la nuova riga con un Le lo spazio con 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

Dopo aver giocato a golf estremo con questa risposta, ho trovato una soluzione da 39 byte, sebbene sia molto più complicata.

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

Compito 3 - GCD

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

Questo è un metodo basato su stack.

__                 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

Storia della lingua

Julia è stata sviluppata nel 2012 da Jeff Bezanson, Stefan Karpinski e Viral Shah mentre Jeff era uno studente del Massachussets Institute of Technology (MIT), consigliato dal professor Alan Edelman. Erano motivati ​​dal desiderio di un linguaggio di programmazione che fosse open source, veloce e dinamico (tra le altre cose) pur mantenendo la facilità d'uso in una varietà di applicazioni. Il prodotto era Julia, un nuovo approccio all'informatica scientifica ad alte prestazioni.

"Ciao mondo!" Variante

println("Julia was made in 2012!")

La stampa su STDOUT in Julia è abbastanza semplice!

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

Il codice è rientrato per leggibilità, ma Julia non impone restrizioni sugli spazi bianchi.

GCD

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

L'ultima cosa elencata nella funzione viene restituita implicitamente.


27

1988 - Mathematica

O dovrei chiamarlo Wolfram Language ?

Compito 0

Il creatore di Mathematica è Stephen Wolfram, fondatore e CEO di Wolfram Research. Prima dello sviluppo di Mathematica, era un fisico. C'era un'enorme quantità di calcoli algebrici in fisica, quindi divenne un utente di Macsyma .

Wolfram ha conseguito il dottorato di ricerca nel 1979, quando aveva 20 anni. Pensava di aver bisogno di un CAS migliore di Macsyma per fare fisica, quindi iniziò a scrivere SMP (il "programma di manipolazione simbolica"). La prima versione di SMP fu rilasciata nel 1981. SMP era il predecessore di Mathematica. Sebbene abbia avuto una profonda influenza su Mathematica, nessuno dei suoi codici è mai stato usato per Mathematica.

Nel 1986, Wolfram decise di scrivere un "sistema di calcolo definitivo". Ha iniziato a scrivere il codice nel 1986 e ha fondato la Wolfram Research nel 1987. Infine, Mathematica 1.0 è stata rilasciata il 23 giugno 1988.

Mathematica 1.0

Non ho trovato Mathematica 1.0. In effetti, Mathematica 1.0 non aveva né una versione Windows né una versione Linux. Ma ho trovato Mathematica 2.0 su un sito Web cinese. Può ancora essere eseguito su Windows XP.

Mathematica 2.0

Compito 1

Print["Mathematica was made in 1988!"]

O semplicemente:

"Mathematica was made in 1988!"

Compito 2

Nel Mathematica di oggi, possiamo scrivere:

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

Proprio come Julia e R , questa è una soluzione a matrice. In Mathematica, puoi definire una matrice sparsa usando la corrispondenza del modello.

Tuttavia, è SparseArraystato introdotto in Mathematica 5.0, quindi non possiamo usarlo in Mathematica 1.0.

Ecco una soluzione che funziona in 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];
]

Non possiamo scrivere f[i_, 1 | i_ | n] = "N"perché è Alternativesstato introdotto in Mathematica 2.0.

Compito 3

Possiamo semplicemente usare la funzione integrata:

gcd = GCD

Oppure possiamo usare la definizione di GCD:

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

Oppure possiamo usare LCM , anche se più comunemente LCM è calcolato da GCD:

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

Oppure possiamo usare l'algoritmo euclideo con pattern matching:

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

O come una funzione anonima:

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

Tutte le funzioni sopra sono state introdotte in Mathematica 1.0.


3
Questa è una risposta molto migliore della mia. Eliminerò il mio.
Martin Ender,

25

1999 - XSLT

Il World Wide Web Consortium (W3C) ha creato XSLT per trasformare XML in HTML, testo, ecc. I seguenti esempi presuppongono che l'input sia racchiuso tra <input>..</input>tag.

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

Questo è semplice. Corrisponde a un inputtag di livello superiore e lo sostituisce con l'output desiderato.

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

Questo definisce 2 modelli ricorsivi loope spaces. loopcon parametri ie ngenererà l'uscita desiderata per n, a partire dalla posizione i. spacescon il parametro ngenereràn spazi.

Compito 3

L'input per questo deve essere nei <input><num>..</num><num>..</num></input>tag.

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

Questo è solo un modello ricorsivo gcdche utilizza l'algoritmo euclideo.


E dicono che INTERCAL è strano!
Kirbyfan64sos,

2
@ kirbyfan64sos Per essere onesti, non dovrebbe essere usato per questa roba comunque ...
LegionMammal978

24

2014 - CJam

CJam è stato creato dall'utente aditsu PPCG ed è stato rilasciato verso aprile 2014 .

"Ciao mondo!" Variante

"CJam was made in 2014!"

CJam stampa automaticamente il contenuto dello stack alla fine del programma

ASCII Art N

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

Spiegazione del codice:

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

Accetta l'altezza / larghezza di N come input tramite STDIN. Provalo online qui

GCD

l~{_@\%}h;

Accetta i due numeri come input tramite STDIN. Provalo online qui


Mi rendo conto che questo non è [code-golf], ma puoi accorciare il programma ASCII-art N ri_S*0'NtW'Nta1$*\,Sf*'Nf+..e>N*in CJam moderno.
Esolanging Fruit,

24

1990 - Haskell

Haskell è un popolare (o dovrei dire: il più popolare linguaggio funzionale puro ?). Si distingue dal mainstream per il suo insolito modello di valutazione (per impostazione predefinita, tutto è pigro o, tecnicamente, non rigido) e per il suo sistema di tipo basato su Hindley-Milner che, anche adesso, è ancora tra i più potenti là fuori.

Compito 1

main = putStrLn "Haskell was made in 1990!"

Compito 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

Demo, stampa l'intero elenco infinito (fino a quando l'utente non si interrompe, o il mondo finisce ...)

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

...

Naturalmente, puoi facilmente arrivare a uno di questi, accedendo a un solo elemento dell'elenco infinito:

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

Compito 3

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

23

1972 - INTERCAL

E pensavi che Fortran e Cobol fossero strani. Questo è folle!

Compito 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

Non proverò a spiegare il sistema di input e output di INTERCAL; appena letto questo e spero di non morire.

Compito 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à gentile.Mi ci è voluto un po 'per capire. I numeri delle etichette sono un disastro e quindi riflettono quello. Non proverò a spiegarlo a meno che qualcuno non lo chieda.

Compito 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

Questo è un po 'più semplice. A causa della stranezza di INTERCAL, devi inserire i numeri in questo modo:

THREE FIVE

Ad esempio, per ottenere il GCD di 42 e 16, inserisco:

FOUR TWO
ONE SIX

Stampa anche il numero in cifre romane ... perché quello è INTERCAL per te!


2
Non dovrebbe essere 19 7 2? (Posso capire se hai un po 'le vertigini dopo aver scritto questo: P) La tua risposta è considerata non valida a causa di questo errore, il che sarebbe un peccato.
marinus,

@marinus Grazie! Fisso!
Kirbyfan64sos,

5
PER FAVORE, Spiegare. (Quando hai tempo, ovviamente.;)
DLosc,

1
INTERCAL è la mia lingua preferita che non ho mai imparato!
CJ Dennis,

1
PLEASE GIVE UP. L'ho già fatto .-.
RedClover il

23

1967 - APL

Nel 1957, all'Università di Harvard, Ken Iverson iniziò a sviluppare una notazione matematica per la manipolazione di array. Durante gli anni '60, la sua notazione fu sviluppata in un linguaggio di programmazione presso IBM. La prima implementazione parziale fu creata nel 1963 e fu persino usata in una scuola superiore per insegnare agli studenti le funzioni trascendentali. Un'implementazione completa e utilizzabile ha dovuto attendere fino al 1965. Per due anni è stata utilizzata solo internamente da IBM. Nel 1967, IBM pubblicò al pubblico un interprete APL in esecuzione sul computer IBM 1130, terminato nel 1966. Puoi capire come sia un po 'difficile scegliere un anno per questo, tuttavia, penso che dovrebbe essere il 1967, poiché questo è il primo anno è stata messa a disposizione del pubblico una piena attuazione. Se qualcuno non fosse davvero d'accordo, potrei cambiarlo.

Il codice sorgente per APL \ 360 è online , così come un emulatore. Questo è quello che ho usato per testare questi esempi. Risale al 1967 e insieme a APL \ 1130 (per il suddetto IBM 1130) è più o meno il vero originale. Come previsto, è molto primitivo. Manca il supporto per cose come lettere minuscole, tutti gli operatori lavorano solo con funzioni integrate e l'insieme di funzioni integrate è molto scarso (in particolare, è solo or e non raddoppia come gcd). La descrizione originale originale è disponibile qui , tuttavia, ho notato che la versione che avevo non è nemmeno completa rispetto a quel documento, mancando tra l'altro.

Ho fornito i programmi sia in formato Unicode (in modo da poterli leggere), sia nella codifica originale (in modo da poterli tagliare e incollare nella finestra APL dell'emulatore).

Incredibilmente, questi programmi funzionano correttamente senza alcuna modifica (ad eccezione della codifica) nelle versioni moderne di Dyalog, NARS2000 e GNU APL. Quindi credo di aver trovato il modo di scrivere APL portatile: fingi solo che sia il 1967!

Compito 1:

Unicode:

⎕←'APL WAS MADE IN 1967!'

APL \ 360:

L[Kapl was made in 1967ÝK

Compito 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'

Compito 3:

Ho risolto questo in modo ricorsivo standard. In teoria, potresti fare qualcosa di intelligente e orientato alla matrice, come la risposta J; in pratica, tuttavia, ha un utilizzo della memoria O (N) e travolge rapidamente hardware e software dell'era Flower-Power.

Unicode:

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

⎕←⎕ GCD ⎕

APL \ 360:

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

L[L gcd L

Questo e spettacolare.
Alex A.

22

1996 - Ocaml

Stavo aspettando da più di un giorno che qualcuno riempisse il 1996, così ho potuto riempire Ruby. Bene, perché non imparare OCaml allora, sembra simile a Haskell ...

Ciao mondo

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

Stringhe mutevoli!

GCD

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

No ==e infix mod, è carino


Mi dispiace, ho compilato Ruby :)
Zero Fiber

4
+1 per l'apprendimento di una lingua solo per rispondere a questa sfida. :)
Alex A.

Hai appena imparato anche F #! (è OCaml sul CLR più alcuni extra).
Robert Fraser,

22

2005 - Preludio

Preludio è un linguaggio molto divertente, il cui codice sorgente è costituito da diverse "voci" che vengono eseguite in parallelo e in cui mi piace molto risolvere i problemi . È pensato per essere la rappresentazione ASCII della sua lingua sorella Fuga gemello , che in realtà prende i file .midi come codice sorgente e codifica le istruzioni trovate in Prelude come intervalli nelle melodie delle voci.

Il preludio è abbastanza minimalista, ma Turing completo (a condizione che tu stia usando almeno 2 voci). Come ho detto, le voci (righe di codice) vengono eseguite simultaneamente, colonna per colonna. Ogni voce opera sul proprio stack, inizializzato su un numero infinito di zero. Prelude supporta le seguenti istruzioni:

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

Alcune note aggiuntive:

  • Le voci sono cicliche, quindi ^ sulla voce superiore si copia dalla voce inferiore (e viceversa).
  • Più ?e !nella stessa colonna vengono eseguiti dall'alto verso il basso.
  • Come da specifica del linguaggio , ?e !leggere e scrivere caratteri con il codice carattere corrispondente. Tuttavia, l'interprete Python ha anche un interruttore nel suo codice per stampare i numeri stessi. A scopo di test sto effettivamente usando una versione modificata che può anche leggere numeri anziché caratteri. Ma il consenso qui è che l'input / output numerico può effettivamente essere dato come valori di byte, quindi queste modifiche non sono necessarie per rendere validi i programmi che trattano i numeri.
  • Corrispondenza (e )non è necessario essere sulla stessa voce. La voce utilizzata per la condizione è sempre quella in cui (appare. Quindi, la posizione verticale di )è completamente irrilevante.
  • A causa della natura dell'esecuzione simultanea di Prelude, qualsiasi istruzione nella stessa colonna di a (viene eseguita una sola volta prima dell'inizio del ciclo e indipendentemente dal fatto che il ciclo sia inserito. Allo stesso modo, qualsiasi istruzione nella stessa colonna di a )viene eseguita alla fine di ogni iterazione, indipendentemente dal fatto che il loop verrà chiuso dopo questa iterazione.

Per prima cosa ti mostrerò i tre programmi senza molti commenti. Di seguito puoi trovare spiegazioni dettagliate.

I programmi

"Ciao mondo!" 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+!

Se stai usando l'interprete Python, assicurati 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#

Per facilità d'uso, questo programma beneficia della lettura di input come numeri, ma l'output non deve essere numerico. Quindi, se si utilizza l'interprete Python modificato, impostare

NUMERIC_INPUT = True
NUMERIC_OUTPUT = False

GCD

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

Questo è meglio usato con tutti gli input / output numerici, ad es

NUMERIC_INPUT = True
NUMERIC_OUTPUT = True

spiegazioni

"Ciao mondo!" Variante

Questo è abbastanza semplice. Sto usando 3 voci per generare successivamente i codici carattere per tutti i personaggi in Prelude was made in 2005!. Comincio dal calcolo 8 + 9*8 = 80, che è il codice carattere di P:

 9(1-)
 8 8+

Dopodiché copio il codice carattere precedente e aggiungo o sottraggo la differenza a quello successivo. Ecco il codice, ma con ciascuno !sostituito con il carattere che viene stampato (e _per gli spazi e %per le cifre):

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

Il finale 55+!stampa una nuova riga finale, solo perché è più bello.

Come nota a margine, il numero di voci è abbastanza arbitrario per questo compito, ma 3 è abbastanza conveniente perché è il numero più grande in cui ogni voce può accedere direttamente all'altra voce.

ASCII Art N

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

Con 5 voci, questo è sicuramente uno dei programmi più complessi che ho scritto finora. Le voci hanno approssimativamente i seguenti scopi:

  1. Solo una voce di aiuto che viene memorizzata N-1per l'uso nel loop interno.
  2. Questa è una specie di voce "principale", che legge l'input, contiene un interruttore importante e contiene anche il loop esterno (cioè quello sopra le righe).
  3. Ciò consente di memorizzare 32comodamente gli spazi.
  4. Questo contiene il ciclo interno (quello sopra le colonne).
  5. Questo memorizza un 78per stampare comodamente Ns.

Esaminiamo il codice parte per parte. In primo luogo, sto creando il 32come -4 + 9*4e il 78come 6 + 9*8:

9(1-)
4-4+

6 8+

Ora sto stampando un singolo N(perché ne abbiamo sempre bisogno) mentre leggo l'input Ne la memorizzazione N-1e N-2nelle prime due voci:

      v2-
     ?1-

     v!

Successivamente, c'è un "loop" condizionato N-1. Alla fine del loop, la seconda voce viene sempre ridotta a 0e il loop esce dopo la prima iterazione. Quindi, essenzialmente, solo questo if(N > 1){...}. Dopo il ciclo stampiamo una nuova riga finale. Per ricapitolare, ora abbiamo il seguente framework:

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

All'interno di questo condizionale, abbiamo prima gli N-2spazi e un singolo Nper completare la prima riga, e memorizziamo anche N-1sulla prima voce per un uso futuro:

         (1-)v         
          v!  

             v!

Ora la vera carne del codice. Innanzitutto, c'è un anello esterno, che stampa le N-1righe. Per ogni riga, stampiamo prima una nuova riga e una N. Quindi ripetiamo i N-2tempi, stampando spazi o Ns (ne parleremo più avanti). E infine ne stampiamo un altro N:

               1-55+!  

                v1-v!(               )v!
               v#

Infine, la parte divertente: stampare ogni riga (e ottenere la posizione di Ndestra). Non c'è davvero un if / else in Prelude, quindi devo costruirlo da solo usando due loop su voci diverse. La condizione può essere facilmente ottenuta sottraendo la variabile del ciclo interno ed esterno - otteniamo 0se vogliamo stampareN e qualcosa di diverso da zero se vogliamo stampare uno spazio.

L'idea di base di un if / else in Prelude è quella di inserire un ciclo dopo il valore pertinente - il codice "if" (o diverso da zero) e uscire immediatamente premendo a 0. Su un'altra voce, si mantiene un valore diverso da zero e un altro loop dopo il loop "if". Durante il ciclo "if" si mette uno zero sopra l'altra voce, in modo da impedire che "else" venga eseguito. C'è una certa flessibilità nel fatto che tu spinga i valori zero sopra i valori diversi da zero o semplicemente scarti il ​​valore diverso da zero se c'è uno zero sotto, ma questa è l'idea generale. Potrebbe anche essere necessario eseguire alcune operazioni di pulizia in seguito, se si desidera continuare a utilizzare la voce pertinente. Ecco come appare il codice:

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

E questo è tutto!

GCD

Questa è "solo" un'implementazione iterativa dell'algoritmo euclideo. Ma modulo in Prelude è un po 'fastidioso, soprattutto perché non puoi facilmente verificare se un numero è positivo o negativo. Questo codice utilizza un'implementazione signum che ho scritto qualche tempo fa . Cioè gran parte del codice trasforma solo un numero in -1,0 o 1. Questo può quindi essere facilmente trasformato in una condizione per numeri positivi o negativi aggiungendo o sottraendo 1.

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

Quindi questa volta abbiamo quattro voci. La prima voce tiene semplicemente traccia be contiene la condizione di terminazione principale (ovvero il loop esce quando bdiventa 0). La seconda voce contiene ae con l'aiuto delle voci tre e quattro calcoli a % b, prima di scambiare il risultato con il precedente b. Infine, le !stampe aquando b == 0.

Diamo un'occhiata prima alla parte signum :

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

Il numero di input nsi trova sulla prima di quelle voci (la seconda voce dell'intero programma). Il risultato finirà sulla voce in basso. Le altre due voci dovrebbero essere vuote (ovvero riempite di zero). Si noti che, se n == 0, entrambi i loop vengono saltati e la voce in basso contiene ancora 0, proprio quello che vogliamo.

Se nè diverso da zero, viene inserito il primo piccolo loop. Spingiamo uno zero per uscire immediatamente, mettiamo due copie di nnella voce centrale e una 1nella voce inferiore. Ora l'idea di base è quella di incrementare una delle copie di nmentre decrementa l'altra copia nfino a quando una di esse raggiunge lo zero. Mentre lo fa, la 1voce in basso capovolge continuamente il suo segno (cosa che si può fare facilmente sottraendola da 0sotto in pila). Questo è impostato in modo tale che quando uno dei numeri raggiunge lo zero, la voce in basso conterrà il segno corretto.

Ora il modulo viene implementato sottraendo bda afino a quando il risultato è negativo. Quando ciò accade, ne aggiungiamo di bnuovo uno . Questo è questo bit:

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

Notare la costruzione if / else in basso, che è simile a quella che ho usato per l'attività 2.


2
Questo dovrebbe davvero far parte di un tutorial di Prelude.
Alex A.

21

2007 - Scratch

Graffiare è una lingua creata dal MIT a fini didattici. Sono stato molto coinvolto con esso per 5 anni; ne parleremo più avanti.

Tutti questi possono essere visualizzati qui .

Sono molto affrettato in questo momento e spiegherò più avanti i frammenti. Spero che siano comunque autoesplicativi.

Compito 1

inserisci qui la descrizione dell'immagine

Compito 2

inserisci qui la descrizione dell'immagine

Compito 3

inserisci qui la descrizione dell'immagine


È più tardi ancora?
lunedì

21

1972 - C

Sappiamo tutti di C, no? C è stata creata presso Bell Labs, insieme a Unix. Unix è stato in gran parte scritto in C. Tutti i derivati ​​Unix moderni sono ancora in gran parte scritti nella sintassi di C. C ha influenzato molti, molti linguaggi di programmazione. È probabilmente il linguaggio di programmazione più antico che è ancora ampiamente utilizzato per i nuovi sviluppi.

C stesso è un discendente di B, che spero finirà anche in questo elenco. Non esisteva un linguaggio di programmazione "A": B è una variante di BCPL, che a sua volta è una CPL ridotta. Nessuna di queste lingue è mai stata molto popolare. Tuttavia, BCPL è stata la lingua in cui è stato scritto il primo programma "Hello World". Un altro fatto interessante è che B aveva entrambi /* */e //commenti, ma C ha lasciato cadere i //commenti. In seguito furono reintrodotti in C con lo standard C99.

I programmi C qui sono stati testati con il compilatore C Unix V5, dal 1974. Questo era il più vecchio compilatore C che riuscissi a trovare e mettermi al lavoro, e questi programmi non verranno compilati su un moderno compilatore C. (Una delle modifiche apportate è che gli operatori di mutazione preferivano +=essere scritti =+.)

#include <... >non esisteva ancora. Né ha fatto gran parte della libreria standard. Ho dovuto scrivere il mio atoi. Ho esaminato alcuni dei codici sorgente V5 per capire quali cose erano permesse e quali no. La versione che ho usato è stata la prima a includere structs, ma poiché non li ho usati e la sintassi non sembra essere cambiata molto fino a V7 (come K&R C), questo potrebbe funzionare anche con le versioni precedenti.

Ho fatto del mio meglio per scrivere il mio codice nello stesso stile utilizzato dal codice sorgente V5. (Non che ciò sia terribilmente coerente, però.)

Cerca qui i collegamenti a Unix V5, un emulatore e le istruzioni per farlo funzionare su un computer moderno.

Compito 1

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

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

Compito 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, non ho mai capito quanto C sia cambiato ... Da dove hai preso quel compilatore?
kirbyfan64sos,

1
Il compilatore è quello incluso con Unix V5. C'è un collegamento nella descrizione di un post sul blog che mostra dove ottenere i file e come eseguirlo su un computer moderno. (È qui ). Una volta eseguito, è possibile ottenere il codice utilizzando cat > file.c. (Termina con Ctrl-D, come sempre). Inoltre, C è cambiato meno di quanto si possa pensare: se si scambiano i tasti =*e=+ nelle atoifunzioni per i moderni equivalenti *=e +=, un GCC moderno li compilerà perfettamente e funzioneranno anche loro. Quasi nessun avvertimento, anche.
Marin

1
minnie.tuhs.org/cgi-bin/utree.pl?file=V2/c è il primo compilatore C che ho potuto trovare (da V2, datato '72).
Oberon,

20

2009 - Idris

Idris è un linguaggio funzionale, tipicamente dipendente, che enfatizza di essere praticamente utilizzabile per applicazioni del mondo reale, oltre a offrire le possibilità di prova estremamente rigorose ottenibili con tipi dipendenti.

Compito 1

module Main

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

Compito 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

Questo non è un programma ma solo una funzione (più precisamente, valore dipendente ), che produce la lettera N desiderata come una matrice bidimensionale.

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

Compito 3

module gcd

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

Nota che ho dovuto scegliere il nome gcd' perché come gcdè già definito nel preludio di Idris.

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

Che sembra come se avessero preso Haskell, scambiati :e ::, e cambiato _a Z.
mercoledì

@WChargin Zè in realtà il costruttore di 0 : Nat. Il carattere di sottolineatura viene utilizzato in Idris proprio come in Haskell.
cessò di girare in senso antiorario il

oh, bene, eccoti! :)
wchargin,

19

2014 - Pyth

Dato che abbiamo CJam, potremmo anche avere Pyth per completezza :)

Pyth è un linguaggio da golf di @isaacg che si compila fino a Python. È notevole per essere procedurale e per usare la notazione con prefisso. Pyth è apparso per la prima volta intorno a giugno 2014 .

"Ciao mondo!" Variante

"Pyth was made in 2014!

Nota la mancanza di un preventivo di chiusura, che è facoltativo se un programma Pyth termina in una stringa.

ASCII Art N

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

Provalo online . Python equivalente è:

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

O espanso (la prima e la terza riga sono implicite):

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

Questo programma utilizza l'algoritmo euclideo e accetta due numeri separati da una nuova riga. Provalo online .

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

i.uQè ancora più breve se usiamo il built-in per GCD. Ciò equivale a print(gcd(*eval(input())))(prendendo come input due numeri separati da virgola).


Drat - Stavo per fare Pyth xP
theonlygusti il

@isaacg Non posso fare a meno di chiedermi, e potrei anche chiederlo qui: pyth è stato ispirato da pyg in qualche modo, forma o forma?
Aprıʇǝɥʇuʎs

@ ɐɔıʇǝɥʇuʎs Avevo visto PYG prima di creare Pyth e avrebbe potuto influenzare l'approccio concettuale 1 carattere - 1. Tuttavia, se qualcosa ha ispirato Pyth, probabilmente era golfscript.
isaacg,

17

1964 - Dartmouth BASIC

BASIC è una famiglia di linguaggi di programmazione generale di alto livello la cui filosofia di progettazione enfatizza la facilità d'uso. Nel 1964, John G. Kemeny e Thomas E. Kurtz progettarono la lingua BASIC originale al Dartmouth College nel New Hampshire. Volevano consentire agli studenti in campi diversi dalla scienza e dalla matematica di utilizzare i computer.

Sto guardando questo manuale su BASIC del 1964 e questo emulatore del sistema di condivisione del tempo di Darthmouth su cui funzionava. Il server è ancora attivo, ma purtroppo la registrazione di un account sembra impossibile. Per ora, questi programmi dovrebbero teoricamente funzionare:

Compito 1

10 PRINT "BASIC WAS MADE IN 1964"
20 END

Compito 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

In uscita qualcosa come:

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

Nota come viene digitato l'input come parte del programma ( 70 DATA 5); il READmodo di istruzione in alto recupera i dati da lì. Non c'è concatenazione di stringhe, ma la sezione 3.1 del manuale descrive comePRINT risultati vengono scritti in "zone" tabulate sull'output.

Compito 3

La versione lenta dell'algoritmo di Euclide:

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

Emissione:

2

Finalmente qualcuno ha fatto BASIC.
Marin

16

2010 - WTFZOMFG

WTFZOMFG è un linguaggio esoterico basato su Brainfuck. È stato realizzato da Jay Songdahl nel 2010. "WTFZOMFG" è l'abbreviazione di "Cos'è quella funzione? Zen Optimized Malicious File Gophers!" .

Ecco un compilatore per i sistemi * nix .

Compito 1

'WTFZOMFG was made in 2010!\n"

Compito 2

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

Spiegazione:

Scusate. Non sono bravo a scrivere spiegazioni.

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

Compito 3

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

Algoritmo euclideo. WTFZOMFG non ha un comando per mod, quindi devo usare d(divide), m(moltiplicare) e s(sottrarre).


16

2009 - Vai

Go è un linguaggio di programmazione sviluppato da Google. Lo sviluppo è iniziato nel 2007, ma Go è stato annunciato nel novembre 2009.

Go è un linguaggio tipicamente statico influenzato da C che enfatizza concisione, semplicità e sicurezza.

Compito 1:

package main
import "fmt"

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

La prima riga dichiara il pacchetto del codice. Anche un semplice esempio di come stampare una riga deve far parte di un pacchetto. E l'eseguibile viene sempre chiamato main.

Compito 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 ha una dichiarazione di variabile abbastanza concisa ( i := 0è la stessa di var i int = 0) e il compilatore determina il tipo. Questa è generalmente una funzionalità più comune nei linguaggi dinamici. Utilizzando questa breve notazione è anche molto facile assegnare funzioni alle variabili ( f := func(x int) int {/* Code */}) e creare chiusure.

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

Qui puoi vedere la a, b = b, a%bsintassi, che è davvero bella. Non conosco il nome esatto, ma in Python si chiama tuple unpacking. Allo stesso modo è possibile restituire più valori da una funzione ( func f() (int, string) { return 42, "Hallo"}).

Un'altra cosa che accade in questo codice è il loop. Il ciclo for è l'unico loop in Go. I cicli while o loop do-while non esistono. Ma puoi facilmente creare un equivalente per il ciclo while for condition {}o un ciclo infinito for {}.


16

1991 - Python

Storia della lingua

Alla fine degli anni '80, Guido van Rossum iniziò a concepire Python come un hobby. Il suo nome deriva da Flying Circus di Monty Python, un programma televisivo britannico di cui Rossum è un fan. La prima implementazione di Python è iniziata nel 1989 ed è stata rilasciata nel 1991. È cresciuta in popolarità nel corso degli anni, diventando la lingua preferita da molti corsi introduttivi di informatica.

"Ciao mondo!" Variante

print("Python was made in 1991!")

Nota le parentesi attorno all'input a print. Sebbene questa sintassi funzioni in Python 2, in genere in Python 2 ometteresti queste parentesi. Tuttavia, sono richiesti in Python 3. Come suggerito da Zach Gates, le parentesi sono utilizzate dappertutto per garantire che il codice presentato qui funzioni tra le versioni.

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

Le funzioni sono definite usando def. La concatenazione di stringhe viene eseguita utilizzando +e ripetizione di stringa con *.

GCD

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

Nota che Python richiede spazi bianchi strutturati.


16

1968 - Algol 68

Algol 68 è stato definito dal gruppo di lavoro IFIP 2.1 come successore di Algol 60.

È un linguaggio orientato all'espressione in cui tutto ha un valore. È anche ortogonale, in cui è possibile utilizzare qualsiasi costrutto in qualsiasi modo. Ciò significa che le espressioni possono essere sull'RHS e sull'LHS di un compito, ad esempio.

Tutte le strutture di controllo hanno una forma abbreviata e una forma lunga usando espressioni. Consente inoltre le definizioni degli operatori.

Gli obiettivi della lingua sono citati come:

I principali obiettivi e principi di progettazione di ALGOL 68:

  • Completezza e chiarezza della descrizione
  • Disegno ortogonale,
  • Sicurezza,
  • Efficienza
  • Controllo della modalità statica
  • Analisi indipendente dalla modalità
  • Compilazione indipendente
  • Ottimizzazione del loop
  • Rappresentazioni - in set di caratteri minimi e più grandi

Questi programmi sono stati testati con l' interprete Algol 68 Genie , che è una completa implementazione della lingua.

Alcune caratteristiche che i programmatori moderni possono trovare diverse, è che non sono consentite dichiarazioni vuote. Non puoi semplicemente aggiungere ;ovunque. Devi usare la SKIPdichiarazione se non vuoi avere esplicitamente nulla. Ha anche permesso la codifica di programmi simultanei molto facilmente. Algol 68 inoltre, in particolare, utilizzava parole chiave all'indietro come terminatori, come esac , od , fi ecc.

La lingua aveva una rappresentazione usata per scrivere il codice che utilizzava molti caratteri che rappresentavano parole chiave in grassetto e identificatori in corsivo , per esempio. All'epoca, e probabilmente ancora, nessun compilatore implementava questa caratteristica del progetto. La lingua consentiva diverse rappresentazioni concrete di programmi che utilizzavano le modalità di tracciamento . Ciò ha permesso di preparare i programmi utilizzando set di caratteri limitati, come quelli che si potevano trovare nei computer negli anni '60. Considera un breve frammento di programma, che sarebbe rappresentato come:

se i < 0 allora salta fi

Questo potrebbe essere preparato per un compilatore in primo modalità raddrizzatura come:

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

In modalità dot stropping questo sarebbe:

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

In caso di modalità accarezzare questo sarebbe:

IF i < 0 THEN SKIP FI

Ho una grande predilezione per questo linguaggio poiché ho lavorato su una delle implementazioni del compilatore, nonché sulla programmazione in esso esclusivamente per molti anni.

Compito 1

print (("Algol 68 è stato realizzato nel 1968!", newline ))

Il punto da notare qui sono le doppie parentesi. Questo perché print è una funzione che accetta un singolo argomento che è un array a lunghezza variabile dell'unione di tutti i tipi. Le parentesi interne sono il costruttore dell'array. Ecco come il polimorfismo viene gestito in questo linguaggio fortemente tipizzato.

In caso di modalità accarezzare:

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


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

Compito 2

     int n ;
     leggi (( n ));
     per i da 1 a n do
          per j da 1 a n do
               ¢ qui utilizziamo una clausola IF abbreviata ¢
               print ((( j = 1 OR j = i OR j = n |
                    "N"
               |
                    ""
               )))
          od ;
     print (( newline))
     od

In caso di modalità accarezzare:

 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

Compito 3

     ¢ possiamo definire i nostri operatori in Algol 68 ¢
     op % = ( int a , b ) int :
          (( b = 0 |
               a
          |
               b % ( a mod b )
          ));
     int i , j ;
     leggi (( i , j ));
     stampa (( i % j , newline ))

In caso di modalità accarezzare:

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
Questi sono stati probabilmente i primi programmi Algol 68 che ho scritto ed eseguito in oltre 30 anni. L'ho trovato così commovente, che in realtà mi ha portato alle lacrime. Non ho mai realizzato un "Hello World!" il programma potrebbe essere così emozionante!
Brian Tompsett -

1
Non vedevo l'ora di conoscere le lingue degli anni '60 ed ero pronto con BCPL, Simula, CORAL66, Fortran 66, PL / 1, SNOBOL4, POP-1 e un'intera zattera in più, solo per scoprire che le regole sono che ho aspettare 5 anni di lingue ... Almeno c'è un ricco solco che qualcun altro solca.
Brian Tompsett - 莱恩 莱恩

È davvero bello vedere le differenze tra Fortran66 (totale pasticcio di violenza da punchcard), APL (strano disordine di simboli di superpotenze) e Algol68, che in realtà è piuttosto bello. Oggi, dovresti cercare in lingue esoteriche per trovare una tale varietà di approcci diversi ... allora, questo era piuttosto mainstream, non è vero?
cessò di girare in senso antiorario

Naturalmente, il Rapporto rivisto non è stato pubblicato fino al 1976, vero? Almeno quello è l'anno del copyright che Springer dà. E la scansione che ho trovato menziona il 1978.
Rhialto

[1] A. van Wijngaarden (a cura di), Bl Mailloux, 1.EL Peck, CBA Koster, Rapporto sul linguaggio algoritmico ALGOL 68, Numer. Matematica. 14 (1969) 79-218; anche in Kibenietika 6 (1969) e 7 (1970). [2] A. van Wijngaarden, Bl Mailloux, 1.EL Peck, CBA Koster, M: Sintzoff, CBLindsey, LGLT Meertens e RG Fisker, relazione rivista sul linguaggio algoritmico ALGOL 68, Acta Informat. 5 (1975) parti 1-3 (ristampe pubblicate da Springer, Berlino, e anche come Mathematical Center Tract 50 del Mathematisch Centrum, Amsterdam); anche in SIGPLAN Avvisi 12 (5) (1977)
Brian Tompsett - 汤 莱恩

16

1962 - SNOBOL

Il "linguaggio orientato e simbolico". Inizialmente apparentemente chiamato interprete delle espressioni simboliche, "SEXI", che poi dovette essere cambiato per evitare che i secchioni dell'era degli anni '60 arrossissero quando presentavano il loro lavoro. Storia vera.

Questa è stata una delle prime lingue in grado di gestire nativamente stringhe e schemi. In effetti, la prima versione di SNOBOL aveva la stringa come unico tipo di dati. La matematica è stata quindi eseguita analizzando. L'implementazione iniziale è stata eseguita sull'IBM 7090. Sembra che non ci sia da tempo, almeno, non sono riuscito a trovarlo. Quello che ho trovato è stato il documento originale che lo descrive, nonché un interprete SNOBOL3 in Java, che può essere eseguito su un computer moderno .

Il primo SNOBOL aveva praticamente solo il pattern matching e l'aritmetica di base. SNOBOL 3 ha quindi aggiunto funzioni e modificato l'I / O, ma per il resto sembra essere rimasto retrocompatibile. SNOBOL 4 ha cambiato la sintassi e da lì si è sviluppato in Icon , che mantiene il pattern matching ma sembra quasi un linguaggio di programmazione "normale" altrimenti.

I programmi che ho scritto usano solo le funzionalità descritte nel documento originale, quindi dovrebbero funzionare con SNOBOL originale ad eccezione dell'I / O, che ho fatto in stile SNOBOL3 in modo che l'interprete Java potesse eseguirli. Dal documento, sembra che la differenza sia che SNOBOL1 utilizza la corrispondenza dei modelli con una SYSvariabile speciale , mentre SNOBOL3 utilizza le variabili di input e output:

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

Effettuare queste sostituzioni dovrebbe renderti SNOBOL "reale" 1. Naturalmente, non puoi eseguirlo.

Compito 1

START   SYSPOT = 'SNOBOL WAS MADE IN 1962!'

Compito 2

Questo mostra matematica, gestione delle stringhe e controllo del flusso. SNOBOL3 ha funzioni utili, come EQcontrollare l'uguaglianza; l'originale SNOBOL non lo ha fatto, quindi non li ho usati.

* 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     

Compito 3

Innanzitutto quello noioso. L'unica cosa degna di nota è il controllo minore di, che mostra esattamente quanto SNOBOL fosse orientato alle stringhe:(B - A) '-' significa "il risultato di BA contiene un segno meno?". Anche SNOBOL3 può farlo LE(B,A), ma SNOBOL 1 non potrebbe (almeno il documento non lo menziona).

* 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

Naturalmente, quando hai un linguaggio interamente basato su stringhe e pattern matching, sarebbe un peccato non usare effettivamente il pattern matching e la sostituzione. Quindi, ecco uno di quei GCD basati su unario, incluse le routine per la conversione da e verso l'unario.

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

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


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

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

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

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

FIN     START

Ottimo lavoro in background! Non molto per il 1961 - sembra che COMIT sia tutto ciò che abbiamo ....
Brian Tompsett - 莱恩 莱恩

15

2012 - TypeScript

TypeScript è un linguaggio di programmazione gratuito e open source sviluppato e gestito da Microsoft.

L'obiettivo principale è: qualsiasi browser. Qualsiasi host. Qualsiasi sistema operativo. Open Source. È stato rilasciato il nell'ottobre 2012

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

provalo online , e screencast di esso.


4
Hai dimenticato di menzionare una cosa: TypeScript è un superset di Javascript con poche modifiche alla sintassi e consente (?) Variabili e argomenti fortemente tipizzati.
Ismael Miguel,

1
O mio dio, qualcosa di open source di MS!
Mega Man,

15

2011 - Dardo

Dart è un linguaggio di programmazione Open Source sviluppato da Google che è stato sviluppato in sostituzione di Javascript (sebbene si compili in javascript). È stato presentato da Google nel 2011 durante la conferenza GOTO.

"Ciao mondo!" Variante:

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

ASCII Art N:

Il metodo Bruteforce funziona a 0 (n²), ma non dovrebbe importare se non si utilizza un numero gigante.

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

GCD

semplice metodo Euclid portato dallo Snap! esempio sopra.

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
Non penso che puoi generare un'arte ASCII × n in meno di O (n²).
Paŭlo Ebermann,

@ PaŭloEbermann Non ho familiarità con la notazione O grande o come calcolare la complessità, ma l'esempio Julia sembra non essere O (n²).
Nzall,

@AlexA. La funzione println () stampa una stringa di n caratteri. Penso che per eseguire la chiamata di funzione sia necessario almeno il tempo O (n). Nel ciclo, quindi O (n²) per l'intero programma.
Paŭlo Ebermann,

@AlexA. Penso che Ebermann stia parlando di avere operazioni di concatenazione di stringhe N nella funzione di stampa. entrambi facciamo concatenazioni di stringhe n² nelle nostre funzioni. Li faccio una volta per iterazione del ciclo interno, li fai per ogni println ().
Nzall,

1
Se questa non fosse ascii art sarebbe O (n) per visualizzare un N. (tracciare 3 linee sullo schermo, ogni linea è O (n) quindi O (n) complessità). Oppure, si potrebbe dire, il rendering della N ha una complessità O (N) ... hehe
rodolphito,

15

2010 - Rust

Rust è un linguaggio di programmazione compilato multi-paradigma, generico, sviluppato da Mozilla Research. È progettato per essere un "linguaggio sicuro, concorrente, pratico", che supporta stili puramente funzionali, contemporanei, imperativi-procedurali e orientati agli oggetti. Wikipedia

Task1

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

Task2

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

Spiegazione:

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

si occupa della stampa solo verticale (sinistra e destra |) e diagonale ( \)

Compito 3

semplice implementazione di Euclidean_algorithm

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

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

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

Potresti aggiungere uno snippet che mostra come inserire due numeri interi separati dallo spazio dallo stdin?
Zero Fiber

3
Rust è stato realizzato nel "2010? La cronologia dei linguaggi di programmazione lo dice, ma l' articolo reale afferma che è stato annunciato solo nel 2010 (in realtà il 2011 come evidenziato dal riferimento ) e che la versione 0.2 è stata rilasciata nel 2012.
EMBLEMA

1
@SampritiPanda, dai un'occhiata a hastebin.com/raw/lapekowogu
wasikuss

1
Sembra un po 'moderno. Può compilare la prima versione funzionante del compilatore <s> rilasciata </s>?
Vi.

15

2015 - Muffin MC

Muffin MC è un macro-linguaggio completo, divertente (ma serio), funzionale e minimalista di Turing scritto da Franck Porcher ( http://franckys.com ) a metà febbraio 2015 per necessità come strumento (rapido) per potenziare un foglio di calcolo da utilizzare come unico controller front-end per pilotare e guidare tutte le operazioni relative all'inventario associate a un sito commerciale basato su Prestashop per un nuovo marchio di moda tahitiano: Mutiny Tahiti ( http://mutinytahiti.com - presto disponibile lanciato).

Muffin MC è l'acronimo di MU piccolo F unzion F lexible IN linea M acro C ommand lingua.

Per soddisfare i nostri requisiti, le caratteristiche principali di Muffin MC sono state progettate attorno a costrutti semantici integrati di prima classe flessibili ed efficienti come iteratori , valutazione pigra , multifunzione , string-product .

Muffin MC affonda le sue radici nella programmazione funzionale (pragmatica), FLisp e Perl. Supporta pienamente la ricorsività (senza alcuna ottimizzazione), è tipizzata in modo dinamico e con ambito dinamico (rilegatura superficiale). Offre ai suoi utenti una sola struttura di dati, a parte i tipi di dati di base atomi (atomi, stringhe, numeri): liste!

La semantica dell'elenco MC di Muffin (tipo di) prende in prestito la semantica del power set , ovvero:

  1. Tutti i muffin MC operazioni di producono un elenco, possibilmente vuoto.
  2. L'accesso a qualsiasi elemento di una singola lista produce sempre una lista di un valore fatta di quell'elemento (pensalo come un singleton).
  3. L'elenco vuoto è l'elemento neutro nelle operazioni dell'elenco.

Per conciliare con questo, potrebbe essere utile quanto segue:

  • Si può visualizzare un elenco come l'elemento del gruppo di potere dell'elenco che ha la più grande cardinalità.
  • Visualizza l'elemento di una lista come l'elemento del power-list della lista che è il singleton fatto di quell'elemento.
  • Visualizza un elenco vuoto come set vuoto; cioè, l'unico elemento del set di potenze del set vuoto.

Come tale, l'accesso a un elemento elenco vuoto produce l'elenco vuoto e non un errore! In effetti, Muffin MC si impegna a gettare il minor numero di errori possibile estendendo in questo modo la semantica di molte operazioni tradizionali.

Compito 1

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

#(...)è il comando macro Muffin MC per l'applicazione di una funzione su un elenco di argomenti non valutati, qui la funzione integrata say, presa in prestito da Perl.

#(say 1 2 3 ...) è funzionalmente identico a map {say $_} (1,2,3,...)

Compito 2

Definire la funzione ascii-art():

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

Ascii-art()La forma di lavoro più breve (88 byte):

=(f'(=(* x#(2-)I I(*($(x)" ")N)g'(#(.#(I$(x)))))#(say?(#(==$(_1)1)N"N#(map g#(..))N"))))
  • =(var val...)è il comando macro Muffin MC per definire una variabile o riassegnarla.

  • $(var)è il comando macro Muffin MC per accedere al valore di una variabile. Accetta naturalmente il modulo $(v1 v2 ...)per accedere a più variabili contemporaneamente.

  • =(* var1 val1 var2 val2 ...)è l'estensione del comando macro Muffin MC=(...) per gestire compiti paralleli.

  • Le variabili _1, _2, ... hanno un ambito dinamico (meccanismo di associazione superficiale) e si impostano automaticamente per legarsi agli argomenti della funzione. Preso in prestito da Perl5, vengono automaticamente impostate anche le variabili di sistema #(numero di argomenti) e @(elenco di argomenti).

  • Le funzioni sono semplicemente variabili associate a un numero qualsiasi di istruzioni Muffin MC .

Questa interessante soluzione nasce dalla combinazione di due funzioni integrate Muffin MC naturali :

  1. Il comando macro Muffin MC I(...) , per definire cicli-iteratori, successivamente utilizzato con il modulo funzionale #(my-iterator want-number-of-values),

  2. Il costrutto stringa-prodotto Muffin MC , un'estensione dell'interpolazione variabile naturale, che, dato qualsiasi stringa"F1 F2 F3..." , dove F i s sono o Muffin MC stringhe o Muffin MC comando macro (alias forme funzionali), produrrà altrettante stringhe come dato dal prodotto Cardinale (F1) x Cardinale (F2) x ....

Ad esempio, data la variabile xa che contiene 2 valori, dice aeb, y un'altra variabile che contiene 3 valori, dice 1 2 3, quindi la valutazione della stringa "x=$(x) y=$(y))"produrrà 6 valori diversi, vale a dire, in questo ordine:

  • "X = y = 1"
  • "X = y = 2"
  • "X = y = 3"
  • "X = da = 1"
  • "X = da = 2"
  • "X = da = 3"

Questa è una delle caratteristiche più ambite del progetto MUTINY per cui Muffin MC è stato progettato.

Eseguirlo !

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

Come funziona

Il nostro algoritmo si basa sui seguenti:

Data una chiamata a ascii-art (n), {n = 2p + 1 | p intero, p> = 0}, l'arte da generare comprende n stringhe di n caratteri, tra cui due, il più a sinistra e il più a destra, sono fissi e sempre gli stessi: 'N'. Ciò consente di ridurre il problema producendo solo le stringhe centrali. Ad esempio, dato n = 5, vorremmo produrre le 5 seguenti stringhe centrali, ciascuna composta da n-2 caratteri (abbiamo sostituito lo spazio con un '_' per una migliore visualizzazione):

    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 |
                                _ _ _
  • Tali stringhe di mezzo possono essere facilmente prodotte facendo scorrere la sequenza di 4 elementi ('_' '_' '_' 'N')in 5 gruppi di 3; dato n, l'input della funzione, tale sequenza è composta da n-2 caratteri '_', seguiti dal carattere 'N'. Scorrere su questa sequenza non richiede nient'altro che incorporare la sequenza all'interno di un iteratore incorporato di Muffin MC I(sequence) (un iteratore che scorre per sempre sulla sequenza iniziale di valori).

  • Quindi produciamo semplicemente le stringhe di mezzo, di lunghezza n-2, chiedendo al nostro iteratore di fornirci i suoi successivi n-2 valori (n - 2 caratteri), che sono concatenati insieme per produrre la stringa di mezzo prevista.

  • Le stringhe n medie vengono prodotte ripetendo n volte il processo sopra descritto, usando una mappa per raccogliere n risultati (n stringhe di n-2 caratteri).

  • Usiamo un altro potente Muffin MC built-in costrutto, vale a dire il prodotto di stringa , per produrre gli n stringhe finali: "N#(map...)N".

  • E questo è tutto!

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

Compito 3

Definire la funzione gcd():

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

gcd()la forma più breve reale (37 byte - 2 byte guadagnano grazie a Rodolvertice)

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

Eseguirlo !

#(gcd 225 81)

rese 9.

Questo è tutto.

Grazie per il bel gioco e forse per l'interesse. La lingua è disponibile per chiunque desideri giocare, usarla o addirittura estenderla. Chiedilo e sarò felice di inviarlo.

Saluti

Franck


PS. L'attuale implementazione di Muffin MC è in Perl5. Il codice sorgente è di circa 2000 righe del moderno Perl, inclusi i commenti, e viene fornito in bundle con una suite di test di non regressione, che è fantastico per imparare i costrutti e la semantica di Muffin MC .


Veramente bello! La forma più breve dell'arte ascii-art ha un nome di funzione abbreviato, ma il più corto GCD no. È intenzionale, perché se non lo è puoi raderti altri 2 byte. +1
rodolphito

Certo, ed è intenzionale. Dovrei ? si, facciamolo;) Grazie per il post e il tuo apprezzamento.
Franck Porcher,

1
Dal momento che stai cercando di sbarazzarti di caratteri extra (e poiché posso essere un incorreggibile grammaticale), potresti (dovresti) rimuovere lo spazio davanti al punto esclamativo per il primo compito. Quello spazio è corretto in francese, ma non in inglese.
Amos M. Carpenter
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.