Skip to content

Linguaggi di programmazione nel corso degli anni

Dopo aver indagato in diversi repository e pagine Web Internet, abbiamo finalmente trovato la soluzione che condividiamo di seguito.

Soluzione:

2013 - Dogescript

Dogescript è un linguaggio creato nel 2013 da Zach Bruggeman. Non è altro che una sostituzione della sintassi di Javascript per renderlo simile ai monologhi interni di Shiba Inus memetici.

Ciao doge

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

Arte ASCII

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

GCD

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

2015 - Retina

Retina è un linguaggio di programmazione basato su regex, che ho scritto per poter competere nelle sfide PPCG con risposte solo regex, senza avere l'inutile sovraccarico di richiamare le regex in un linguaggio host. Retina è Turing-completo. Per dimostrarlo, ho implementato un risolutore di sistemi a 2 tag e la regola 110. È scritto in C#, quindi supporta sia il linguaggio .NET (per impostazione predefinita) sia il linguaggio ECMAScript (tramite un flag).

Retina può operare in diverse modalità, ma quella più rilevante per i calcoli (e quella Turing-completa) è la modalità Replace. In modalità Replace si fornisce a Retina un numero pari di file sorgente. Questi vengono poi accoppiati, il primo di ogni coppia è una regex e il secondo una sostituzione. Queste vengono eseguite in ordine, manipolando l'input passo dopo passo. La regex può anche essere preceduta da una configurazione (delimitata da `). L'opzione più importante (che rende Retina Turing-completo) è +che fa sì che Retina applichi la sostituzione in un ciclo finché il risultato non smette di cambiare. Negli esempi che seguono, utilizzo anche l'opzione ;che sopprime l'output negli stadi intermedi.

In ciascuno dei seguenti esempi, ogni riga va in un file sorgente separato. (In alternativa, si può usare il nuovo -s e inserire tutte le righe in un unico file). I file/linee vuoti sono rappresentati come . I file/linee contenenti un singolo spazio sono rappresentati come .

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

I programmi

"Ciao, mondo!" Variante


Retina was made in 2015!

Arte ASCII N

Questo presuppone che STDIN sia terminato con una newline.

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

;`d
N
;`.(?<=(?=(.*n)).*)|n
$1
;`N(?=Nn.*n.*n`$)

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

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

GCD

Richiede che STDIN sia non terminato con una newline.

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

;`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
#|:.*

Spiegazioni

"Ciao, mondo!" Variante

È abbastanza banale. Non prende alcun input (cioè una stringa vuota), non corrisponde a nulla e lo sostituisce con Retina was made in 2015!. È possibile farlo funzionare anche per input arbitrari, sostituendo lo schema con [sS]* per esempio. In questo modo, STDIN verrebbe assorbito e sostituito interamente con l'output.

Arte ASCII N

Questo programma ha un gran numero di fasi. L'idea è quella di convertire l'input in unario, creare un blocco N x N di Ne poi "ritagliare" due triangoli. Esaminiamo le singole fasi. Ricordiamo che ; si limita a sopprimere le uscite intermedie, ma + fa sì che la sostituzione venga applicata in un ciclo.

;`^
#

Semplice: anteporre un # all'input. Questo verrà 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#

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

#127
1#27
111111111122#7
1111111111221111111111221111111111221111111111221111111111221111111111221111111111221111111111221111111111221111111111227777777#

dove l'ultima riga contiene esattamente 127 caratteri.

;`#

;`d
N

Due semplici fasi che eliminano questo problema # e poi convertono tutte le cifre in N. Di seguito utilizzerò l'input 7 come esempio. Quindi ora abbiamo

NNNNNNN

Lo stadio successivo

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

sostituisce ogni N con l'intera stringa (ricordando che contiene una linea di separazione) e rimuove anche la linea di separazione stessa. In questo modo, la singola riga viene trasformata in una griglia quadrata:

NNNNNNN
NNNNNNN   
NNNNNNN
NNNNNNN
NNNNNNN
NNNNNNN
NNNNNNN

Ora il triangolo superiore. Per cominciare, trasformiamo la N nell'angolo in basso a destra in uno spazio:

;`N(?=Nn.*n.*n`$)

Il lookahead ci assicura che stiamo modificando il punto corretto N. Si ottiene così

NNNNNNN
NNNNNNN   
NNNNNNN
NNNNNNN
NNNNN N
NNNNNNN
NNNNNNN

E ora

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

è una regex che corrisponde a un N che si trova sopra o nell'angolo superiore sinistro di un carattere di spazio e lo sostituisce con uno spazio. Poiché la sostituzione viene ripetuta, si tratta essenzialmente di un riempimento a tappeto, che trasforma il terzo ottante dello spazio iniziale in altri spazi:

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

Infine, ripetiamo la stessa cosa con il triangolo inferiore, ma utilizziamo un carattere diverso, in modo che gli spazi già esistenti non causino 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

esegue il riempimento.

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

E infine

S

trasforma questi S in spazi e abbiamo finito:

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

GCD

Il GCD in unario è in realtà molto banale con le 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 golf di codice, 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#
;`#

;`d
1

Questi stadi sono essenzialmente identici a quelli precedenti, tranne che per il fatto che entrambi i numeri in ingresso vengono convertiti e il risultato utilizza 1invece di Ns (non che sia importante). Quindi, se l'input era 18 24, allora questo produrrebbe

111111111111111111 111111111111111111111111

Ora

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

è l'intero calcolo del GCD. Si trova un divisore comune catturando un numero di 1e poi usando i backreferences per assicurarsi che entrambi i numeri possano essere scritti ripetendo quella stringa (e nient'altro). A causa del modo in cui il backtracking funziona nel motore regex (cioè che .+ è avido), questo produrrà sempre la stringa più grande comune divisore automaticamente. Poiché la corrispondenza copre l'intera stringa, è sufficiente scrivere il primo gruppo catturante per ottenere il GCD.

Infine, la conversione da unario a decimale...

;`$
#:0123456789

Aggiungere un marcatore #, un delimitatore : e tutte le cifre alla stringa. Questo è necessario, perché non è possibile produrre nuovi caratteri in modo condizionale in una sostituzione regex. Se si desidera una sostituzione condizionale, è necessario estrarre i caratteri dalla stringa stessa, quindi li inseriamo qui.

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

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

#|:.*

Infine, un passo di pulizia per sbarazzarsi del marcatore, del delimitatore e delle cifre di aiuto.

2013 - Scatto !

Scatto ! è un linguaggio basato su Scratch, realizzato all'Università di Berkeley. È un aggiornamento di Scratch con dati di prima classe e blocchi personalizzati (funzioni). Come Scratch, non è basato sul testo, ma piuttosto su "blocchi" visivi che si uniscono tra loro.

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

Snap ! non è un linguaggio esoterico. Viene utilizzato come linguaggio di programmazione per il corso Beauty and Joy of Computing (BJC) AP CS di Berkeley e altri.

Ho dato una mano con i test e altro.

"Variante di "Hello World

Arte ASCII "N"

enter image description here

Utilizza lo stdlib per alcuni blocchi.

Un ciclo piuttosto elementare. Prende un input. Poi lo sommiamo e lo diciamo (risultato per n=5):

enter image description here

Mi sono preso la libertà di usare 2 spazi invece di 1, perché Snap! non dice le cose in monospazio.

GCD

L'algoritmo euclideo non è molto veloce, ma funziona ed è piuttosto semplice. (Scusate, ho fatto un errore di battitura nel nome del blocco. Ora ho chiuso la scheda senza salvare. Dovrà restare così).

enter image description here

Questa definizione di funzione produrrà questo blocco:

enter image description here

Ricorda qualcosa, che hai il privilegio di apprezzare questo post se raggiungi la tua impasse appena in tempo.



Utilizzate il nostro motore di ricerca

Ricerca
Generic filters

Lascia un commento

Il tuo indirizzo email non sarà pubblicato.