Linguagens de programação ao longo dos anos


168

Nesse desafio, os usuários se revezam na conclusão de três tarefas de codificação bastante simples em linguagens de programação que podem ser progressivamente mais antigas.

A primeira resposta deve usar uma linguagem de programação que foi feita no ano de 2015. Quando houver pelo menos uma resposta de uma linguagem de 2015, as respostas poderão usar linguagens de programação que foram feitas em 2014. Da mesma forma, respostas que usam linguagens de 2013 não são permitidas até que haja pelo menos uma resposta de 2014.

Em geral, o uso de uma linguagem de programação do ano Y não é permitido até que uma resposta usando uma linguagem do ano Y + 1 seja enviada. A única exceção é Y = 2015.

Encontrando o ano do seu idioma

Para responder a essa pergunta, você deve saber o ano em que sua linguagem de programação foi "criada". É claro que este é um termo subjetivo; alguns idiomas foram desenvolvidos ao longo de vários anos e muitos idiomas ainda estão sendo atualizados a cada ano. Que o ano em que um idioma foi "criado" seja o primeiro ano em que uma implementação desse idioma apareceu no público em geral.

Por exemplo, o Python foi "fabricado" em 1991 , embora seu desenvolvimento estivesse em andamento desde 1989, e a versão 1.0 não foi lançada até 1994.

Se este ano ainda for subjetivo, use seu bom senso para escolher o ano mais apropriado. Não fique atolado em pequenas divergências sobre as escolhas de ano. Forneça um link para uma fonte que diz quando seu idioma foi criado.

Versões ou padrões diferentes de uma linguagem de programação (por exemplo, Python 1, 2, 3) são contados como a mesma linguagem no mesmo ano inicial.

Portanto, a menos que o ano do seu idioma seja 2015, você só poderá enviar sua resposta depois que uma resposta for enviada, cujo ano do idioma é o ano imediatamente anterior ao seu.

Se uma resposta válida com o mesmo ano que a sua já existir, você poderá responder. Não importa se o seu idioma foi desenvolvido no início ou no final do ano.

Tarefas

Você deve concluir as tarefas de 1 a 3. A tarefa 0 é opcional.

Essas tarefas foram mais ou menos escolhidas para corresponder a três aspectos importantes da programação: fornecer saída (tarefa 1), loop (tarefa 2) e recursão (tarefa 3).

Tarefa 0 - Histórico do idioma (opcional)

Escreva pelo menos um parágrafo explicando o histórico da sua linguagem de programação escolhida: quem a desenvolveu, por que, como, etc. Isso é especialmente encorajado se você estiver por perto quando a linguagem surgiu, e talvez até tenha participado de seu desenvolvimento. Sinta-se à vontade para contar histórias pessoais sobre o efeito que o idioma teve sobre você ou seu trabalho ou algo assim.

Se você é jovem demais para saber muito sobre o histórico do seu idioma sem muita pesquisa, considere deixar um recado para os usuários mais velhos, informando que eles podem editar sua postagem e adicionar um histórico em primeira mão.

Tarefa 1 - "Olá, mundo!" Variante

Escreva um programa que imprima

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

para a área de saída padrão do seu idioma (stdout para os idiomas mais recentes).

Por exemplo, se a linguagem fosse Python, a saída seria:

Python was made in 1991!

Tarefa 2 - ASCII Art N

Escreva um programa que permita ao usuário digitar um número inteiro positivo ímpar (você pode assumir que a entrada é sempre válida) e imprima uma letra de arte ASCII N feita com o caractere N .

Se a entrada for 1, a saída é:

N

Se a entrada for 3, a saída é:

N N
NNN
N N

Se a entrada for 5, a saída é:

N   N
NN  N
N N N
N  NN
N   N

Se a entrada for 7, a saída é:

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

O padrão continua assim. A saída pode conter espaços à direita.

Tarefa 3 - GCD

Escreva um programa que permita ao usuário digitar dois números inteiros positivos (você pode assumir que a entrada é sempre válida) e imprima seu maior divisor comum . Isso é definido como o maior número inteiro positivo que divide os dois números sem deixar resto. Pode ser facilmente calculado usando o algoritmo euclidiano .

Exemplos:

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

Você pode usar uma função interna, mas tente descobrir se ela estava lá na primeira versão do seu idioma. Caso contrário, tente não usá-lo.

Regras

  • Você pode responder várias vezes, mas cada nova resposta deve usar um idioma criado pelo menos 5 anos antes do idioma em sua última resposta. Portanto, se você respondeu com um idioma de 2015, não poderá responder novamente até que 2010 sejam permitidos. Se você começar com uma resposta de 2010, não poderá fazer da resposta de 2015 sua segunda resposta, porque 2015 não é anterior a 2010.
  • Se possível, escreva seu código para que ele funcione na primeira versão do seu idioma (ou na versão mais antiga possível). (Isso não é um requisito, pois pode ser difícil encontrar compiladores / intérpretes antigos para alguns idiomas.)
  • Evite postar um idioma que já tenha sido publicado, a menos que a resposta publicada tenha erros significativos ou você tenha uma maneira muito diferente de concluir as tarefas.
  • Jogar golfe com seu código é bom, mas não obrigatório.
  • Uma nova linha à direita na saída de qualquer programa é boa.
  • Para as tarefas 2 e 3, todos os valores de entrada abaixo de um máximo razoável, como 2 16, devem funcionar (256 no mínimo).
  • Seu idioma deve ter existido antes que esta pergunta fosse publicada.
  • Linguagens de programação muito antigas podem ter diferentes formas de entrada e saída do que pensamos hoje. Isto é bom. Complete as tarefas da melhor maneira possível no contexto do seu idioma.

Pontuação

A pontuação do seu envio é:

upvotes - downvotes + (2015 - languageYear) / 2 

Assim, 0,5 é adicionado à contagem de votos para cada ano antes de 2015, dando a vantagem para os idiomas mais antigos. A finalização com a pontuação mais alta vence.

Lista de respostas

O snippet de pilha abaixo lista todas as respostas válidas de acordo com o ano do idioma.

Você deve iniciar sua postagem com esta linha de Markdown para garantir que ela esteja listada corretamente:

#[year] - [language name]

Por exemplo:

#1991 - Python

O nome do idioma pode estar em um link (será o mesmo link na lista de respostas):

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

As respostas que não seguem esse formato, ou têm um ano que ainda não é permitido, ou são de um usuário que já respondeu nos últimos 5 anos são marcadas como inválidas.

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


2
Isso deve ajudar.
abanada

20
A Wikipedia tem uma lista de tudo: esta para idiomas não esotéricos por ano.
Sanchises 06/04/2015

2
A Tarefa 3 deve realmente usar recursão ou é suficiente para produzir o resultado correto? Se eu precisar escrever minha própria função GCD, normalmente apenas uso um loop, mas escrevi um recursivo especialmente para esse desafio. Existem muitas respostas enviadas que usam apenas um loop.
CJ Dennis

5
Sinto-me como fazer uma segunda conta apenas para obter-nos passado 1971.
marinus

5
Se conseguirmos voltar a 1952, tenho alguém que está montando uma máquina histórica que poderia fazer soluções de 1951 (Pegasus) e testá-las!
Brian Tompsett - #

Respostas:


173

2013 - Dogescript

Dogescript é uma linguagem criada em 2013 por Zach Bruggeman. Nada mais é do que uma substituição de sintaxe para o Javascript fazê-lo ler como os monólogos internos do memético Shiba Inus.

Hello 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

113
Uau, como +1. Muito resposta. Muita qualidade.
Alex A.

27
Entrei no codegolf apenas para votar nesta resposta!
Derek Tomes

21
Eu não posso sequer ler o GCD com uma cara séria
Cole Johnson

16
Não consigo ler gcd_doge como good_dog. Ajuda
Yann

Fantástico. No entanto, de acordo com LANGUAGE.md, aspas duplas não são suportadas. Adoraria uma explicação do s[i]pouco também!
Docteur

66

2015 - Retina

O Retina é uma linguagem de programação baseada em regex, que escrevi para poder competir nos desafios do PPCG com respostas somente regex, sem a sobrecarga desnecessária de chamar o regex em alguma linguagem host. Retina é Turing-completa. Para provar isso, implementei um solucionador de sistema de 2 marcas e a Regra 110 . É escrito em C #, portanto, suporta o sabor .NET (por padrão) e o sabor ECMAScript (por meio de um sinalizador).

O Retina pode operar em vários modos, mas o mais relevante para cálculos (e o Turing-complete) é o modo Substituir. No modo Substituir, você fornece à Retina um número par de arquivos de origem. Estes são então emparelhados, o primeiro de cada par sendo uma expressão regular e o segundo uma substituição. Estes são então executados em ordem, manipulando a entrada passo a passo. O regex também pode ser precedido por uma configuração (delimitada por `). A opção mais importante (que torna o Retina Turing completo) é o +que faz com que o Retina aplique a substituição em um loop até que o resultado pare de mudar. Nos exemplos a seguir, também estou usando ;, que suprime a saída nos estágios intermediários.

Em cada um dos seguintes envios, cada linha entra em um arquivo de origem separado. (Como alternativa, você pode usar a nova -sopção e colocar todas as linhas em um único arquivo.) Arquivos / linhas vazios são representados como <empty>. Arquivos / linhas contendo um único espaço são representados como<space> .

As explicações são bastante longas, então as mudei para o final do post.

Os programas

"Olá Mundo!" Variante

<empty>
Retina was made in 2015!

ASCII Art N

Isso pressupõe que STDIN seja finalizado com uma nova linha.

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

Isso requer que o STDIN não seja finalizado com uma nova linha.

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

Explicações

"Olá Mundo!" Variante

Isso é bastante trivial. Não recebe entrada (isto é, uma string vazia), não corresponde a nada e a substitui por Retina was made in 2015!. Pode-se também fazê-lo funcionar para entradas arbitrárias, substituindo o padrão por[\s\S]* por exemplo. Isso consumiria STDIN e substituiria tudo pela saída.

ASCII Art N

Isso tem várias etapas. A idéia é converter a entrada em unária, criar um bloco N x N de Nse "entalhar" dois triângulos. Vamos passar pelos estágios individuais. Lembre-se de que ;apenas suprime as saídas intermediárias, mas +faz com que a substituição seja aplicada em um loop.

;`^
#

Simples: acrescente #a à entrada. Isso será usado como um marcador na conversão para unário.

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

Isso converte um dígito em unário. Ele pega os dígitos já convertidos (\d*)e os repete 10 vezes. E então pega o próximo dígito e acrescenta o número apropriado de dígitos. O valor real dos dígitos é irrelevante neste estágio. Quando #chega ao final do número, a regex não corresponde mais e a conversão é feita. Como exemplo, o número 127será processado como

#127
1#27
111111111122#7
1111111111221111111111221111111111221111111111221111111111221111111111221111111111221111111111221111111111221111111111227777777#

onde a última linha contém exatamente 127 caracteres.

;`#
<empty>
;`\d
N

Dois estágios simples que se livram disso #e convertem todos os dígitos para N. A seguir, usarei a entrada 7como exemplo. Então agora nós temos

NNNNNNN

O próximo estágio

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

substitui cada Numa pela sequência inteira (lembre-se de que ela contém uma nova linha à direita) e também remove a própria linha à direita. Portanto, isso transforma a única linha em uma grade quadrada:

NNNNNNN
NNNNNNN   
NNNNNNN
NNNNNNN
NNNNNNN
NNNNNNN
NNNNNNN

Agora o triângulo superior. Primeiro, começamos transformando o N no canto inferior direito em um espaço:

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

O lookahead garante que estamos modificando o correto N. Isto dá

NNNNNNN
NNNNNNN   
NNNNNNN
NNNNNNN
NNNNN N
NNNNNNN
NNNNNNN

E agora

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

é uma regex que corresponde a uma Nque está acima ou no canto superior esquerdo de um caractere de espaço e a substitui por um espaço. Como a substituição é repetida, trata-se essencialmente de um preenchimento de inundação, que transforma o terceiro octante do espaço inicial em mais espaços:

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

E, finalmente, repetimos a mesma coisa com o triângulo inferior, mas usamos um caractere diferente, para que os espaços já existentes não causem um preenchimento incorreto:

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

define a semente:

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

Então

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

faz a inundação.

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

E finalmente

S
<space>

Transforma isso Sem espaços e pronto:

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

GCD

GCD em unário é realmente muito trivial com regex. A maior parte disso consiste na conversão de decimal em unário e de unário em decimal. Isso pode ser feito de forma mais compacta, mas este não é um código de golfe, então ...

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

Esses estágios são essencialmente os mesmos que acima, exceto que os dois números de entrada são convertidos e o resultado usa 1s em vez de Ns (não que isso importe). Então, se a entrada foi 18 24, isso produziria

111111111111111111 111111111111111111111111

Agora

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

é todo o cálculo do GCD. Combinamos um divisor comum capturando um número de 1s e, em seguida, usando referências anteriores para garantir que ambos os números possam ser gravados repetindo essa sequência (e nada mais). Devido a como o backtracking funciona no mecanismo regex (ou seja, que .+é ganancioso), isso sempre gera o maior divisor comum automaticamente. Como a partida abrange toda a sequência, simplesmente escrevemos de volta o primeiro grupo de captura para obter nosso GCD.

Finalmente, a conversão de unário para decimal ...

;`$
#:0123456789

Anexe um marcador #, um delimitador :e todos os dígitos à sequência. Isso é necessário, porque você não pode produzir novos caracteres condicionalmente em uma substituição de regex. Se você deseja uma substituição condicional, é necessário extrair os caracteres da própria string, então os colocamos 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

Este é o inverso da expansão unária anteriormente. Encontramos o maior múltiplo de 10 que se encaixa na cadeia atual. Em seguida, escolhemos o próximo dígito com base no restante e dividimos o múltiplo por 10, enquanto movemos o marcador pelos dígitos.

#|:.*
<empty>

E, finalmente, apenas uma etapa de limpeza para se livrar do marcador, do delimitador e dos dígitos auxiliares.


Eu acho que você deve adicionar instruções para converter entrada numérica em string unária e instruções para converter string unária de volta em entrada numérica. A conversão com regex puro é legal, mas muito desajeitada.
N

8
+1 Eu tinha certeza de que o envio de 2015 seria um idioma para o uso do CodeGolf.
Fibra Zero

@ n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳ Eu estava considerando isso antes. Eu acho que para a maioria dos jogadores de código, eu provavelmente pegaria a entrada Unary (a menos que o desafio especifique explicitamente "decimal" ou algo assim ...). Pensei em fazer o mesmo para isso, mas este não é um código de golfe, e queria mostrar que também posso lidar com entradas e saídas decimais.
Martin Ender

6
Excelente trabalho. Retina é muito legal. E como um aparte, também é muito legal ver o diamante ao lado do seu nome! :)
Alex A.

Engraçado que, embora línguas antigas são favorecidos nesta competição, este mais mais jovem ainda está ganhando =)
Claudiu

60

2013 - Snap !

Snap ! é uma linguagem baseada no Scratch , criada na Universidade de Berkeley. É uma atualização para o Scratch, com dados de primeira classe e blocos personalizados (funções). Como o Scratch, não é baseado em texto, mas sim por "blocos" visuais que se encaixam.

Snap ! , escrito em JavaScript, é o sucessor do BYOB, que foi escrito no Squeak Smalltalk. Snap ! foi lançado para consumo público em março de 2013 .

Snap ! na verdade não é uma linguagem esotérica. É usada como linguagem de programação para a Beauty and Joy of Computing (BJC) curso AP CS em Berkeley e outros.

Eu ajudei com testes e outras coisas.

Variante "Hello World"

ASCII Art "N"

insira a descrição da imagem aqui

Isso usa o stdlib para alguns dos blocos.

Um loop bastante básico aqui. Recebe uma entrada. Depois, adicionamos tudo e dizemos (resultado para n = 5):

insira a descrição da imagem aqui

Tomei a liberdade aqui para usar apenas 2 espaços em vez de 1, porque Snap! não diz coisas no espaço aeroespacial.

GCD

O algoritmo euclidiano não é muito rápido, mas funciona e é bastante simples. (Desculpe, cometi um erro de digitação no nome do bloco. Agora fechei a guia sem salvá-lo. Só terá que ficar.)

insira a descrição da imagem aqui

Essa definição de função produzirá este bloco:

insira a descrição da imagem aqui


3
Isso se parece muito com programação em Alice ...
mbomb007

4
É o que você obtém com idiomas baseados em blocos. Resumindo: muitas línguas são parecidas. ;)
Scimonster 06/04

1
Mesmo zero tem uma função mod assim que eu supor que você poderia fazer a GCM / GCD funcionar mais rápido com um bloco baseado em if (b == 0), em seguida, uma outra GCM (b, a% b)
Alchymist

55

2007 - LOLCODE

História do idioma

LOLCODE foi criado em 2007 por Adam Lindsay, pesquisador da Universidade de Lancaster. Sua sintaxe é baseada nos memes lolcats popularizados pela Cheezburger, Inc.

"Olá Mundo!" Variante

HAI
VISIBLE "LOLCODE wuz maed in 2007!"
KTHXBYE

ASCII Art N

HAI

BTW, read n from stdin
GIMMEH n

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

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

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

        VISIBLE "N"

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

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

            VISIBLE "N"
        IM OUTTA YR closet

        VISIBLE "N"!

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

        VISIBLE "N"
OIC

KTHXBYE

Os valores são lidos como cadeias (YARNs) de stdin usando GIMMEH. Eles podem ser convertidos em numéricos (NUMBRs) multiplicando por 1.

Os valores são impressos em stdout usando VISIBLE. Por padrão, uma nova linha é anexada, mas pode ser suprimida adicionando um ponto de exclamação.

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 executa concatenação de string.


13
Finalmente, uma linguagem que todos possam entender.
ASCIIThenANSI

26
IM IN YR toilet UPPIN YR buttNomes de variáveis ​​agradáveis
Cole Johnson

13
@ColeJohnson: Eu sempre tentar escolher os nomes das variáveis que fazem sentido na situação em vez de x1, x2, etc.
Alex A.

2
Hilário. Eu não deveria ler isso no trabalho.
Alan Hoover

@ Alananover: Claramente os lolz são mais importantes que os jobz.
11555 Alex A.

43

1982 - PostScript

PostScript é uma linguagem para criar gráficos vetoriais e impressão.

A Adobe foi fundada em 1982 e seu primeiro produto foi o PostScript. A linguagem foi usada nas impressoras: os comandos são interpretados pela impressora para criar uma imagem rasterizada, que é impressa na página. Foi um componente muito comum das impressoras a laser nos anos 90. Mas obviamente é bastante intensivo de CPU na impressora e, à medida que os processadores do computador se tornaram mais poderosos, fazia mais sentido fazer a rasterização no computador do que na impressora. O PostScript desapareceu amplamente em impressoras de consumo, embora ainda exista em muito mais impressoras de ponta.

O padrão que substituiu o PostScript é um formato pouco conhecido chamado PDF.

O PostScript ficou fora de moda quando comecei a programar, mas aprendi um pouco enquanto estava na universidade como outra maneira de criar documentos para o TeX. Era bem diferente de outras linguagens de programação que eu tinha usado (notação de infixo reverso, empilhamento, impressão em uma página em vez de em um console), mas foi bom tirar o pó dessa linguagem antiga por um pouco de diversão.

Como o PostScript é uma linguagem de impressão, parece mais apropriado usá-lo para imprimir algo e enviar uma saída para o console.

Tarefa 1

/Courier findfont
12 scalefont
setfont
newpath

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

As primeiras linhas configuram uma tela para desenhar. Em seguida, o movetocomando diz ao PS para desenhar em uma posição específica eshow imprime a string na página. Observe que os parênteses marcam uma sequência em PostScript, não as aspas.

Tarefa 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

Eu escrevi uma função para desenhar a “arte ASCII” N, mas não há como as funções PostScript argumentarem. Em vez disso, você envia seus argumentos para a pilha e os recupera. Essa é a/x exch def linha.

Um exemplo: suponha que a pilha seja 8 9 2. Primeiro, colocamos o nome /xna pilha, para que a pilha seja 8 9 2 /x. O exchoperador troca os dois valores da pilha, agora a pilha é 8 9 /x 2. Em seguida, defaparece os dois principais valores da pilha e define /xcomo tendo o valor 2. A pilha está agora 8 9.

Quando comecei a usar o PostScript, achei isso um pouco confuso. Eu li sobre a pilha como um conceito teórico, mas essa foi a primeira vez que a usei na prática.

O restante da função é um código de desenho: comece no canto inferior direito, preenchendo uma linha por vez da esquerda para a direita para a diagonal.

Tarefa 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

Novamente, usei uma forma do algoritmo de Euclides, mas esqueci que o PostScript possui um operador de módulo embutido, então tive que escrever o meu. Isso acabou sendo um lembrete útil das restrições da programação baseada em pilha. Minha primeira implementação de modulofoi baseada em recursão:

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

o que é bom até você tentar executar isso quando xé grande e yé pequeno (por exemplo, 5689 e 2). Você só pode ter até 250 elementos na pilha, e eu estava ultrapassando o limite da pilha. Opa Eu tive que voltar para a prancheta nessa.

O próprio código GCD é bastante simples. Mas, assim como as funções não podem receber argumentos, elas não têm valores de retorno. Em vez disso, você deve enviar o resultado para a pilha, onde outra pessoa pode retirá-lo mais tarde. Isso é o que aeb a gcd linhas : quando terminam de avaliar, colocam o valor na pilha.

Se você colocar todo o código em um documento e imprimi-lo, é assim que a saída será:

insira a descrição da imagem aqui


8
Haha Eu amo a fotografia do pedaço de papel impresso. Parece apropriado para 1982.
Alex A.

1
Além disso, obrigado por sua descrição de como você obteve um estouro de pilha (literal) - agora entendo mais intuitivamente por que os idiomas têm uma profundidade máxima de recursão.
DLosc

2
@AlexA .: Sim, mas uma impressão em matriz de pontos (com orifícios nas laterais do papel) teria sido ainda mais apropriada . ;-)
Amos M. Carpenter

@ AmosM.Carpenter: na verdade, não acho que nenhuma impressora matricial tenha suporte para PostScript. Sempre esteve muito ligado às impressoras a laser.
Ninjalj

41

2009 - > <>

Inspirado no Befunge,> <> (Fish) é uma linguagem 2D esotérica baseada em pilha, ou seja, o fluxo do programa pode ser alto, baixo, esquerda ou direita. A versão inicial de> <> apresentava multithreading onde [e] criou e terminou, mas por motivos de simplicidade, essas instruções foram alteradas para criar e remover novas pilhas, respectivamente.

O intérprete oficial atual de> <> pode ser encontrado aqui . Infelizmente, o link para o antigo intérprete no wiki da Esolang está quebrado.

"Olá Mundo!" Variante

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

Observe como a string é escrita de trás para frente -> <> tecnicamente não tem strings, com o único tipo de dados sendo uma mistura estranha de char, int e float. "alterna a análise de sequência, empurrando cada caractere para a pilha até que um fechamento "seja alcançado.

A segunda metade do código empurra o comprimento da pilha l, verifica se é zero ?!e se o programa termina ;. Caso contrário, o ponteiro de instruções continuará, exibindo a parte superior da pilha oantes de executar bb+0., que teleporta o ponteiro para a posição (22, 0)imediatamente antes dol , criando um loop.

ASCII Art N

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

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

   \                                                         <   /

Com espaçamento para maior clareza. Você pode tentar isso no novo intérprete on-line aqui e ver o ponteiro de instruções girar e girar - lembre-se de inserir um número na caixa de texto "Pilha inicial". Se você estiver executando através do interpretador Python, use o -vsinalizador para inicializar a pilha, por exemplo

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

Para este programa, colocamos a entrada nno registro com &e pressionamos um 0, que chamaremos ide "iterações". O resto do programa é um loop gigante que é assim:

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

Então repetimos o loop desde o início.

As setas ^>v<mudam a direção do fluxo do programa e os espelhos /\refletem a direção do fluxo do programa.

GCD

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

Aqui está um exemplo de como pode ser um programa de golfe <>>. Mais uma vez, você pode tentar isso no intérprete online (digite dois valores separados por vírgula na caixa "Pilha inicial", por exemplo 111, 87) ou usando o -vsinalizador do intérprete Python, por exemplo

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

Este programa usa o algoritmo euclidiano. Aqui está um GIF que eu preparei anteriormente:

insira a descrição da imagem aqui

Observe que> <> é toroidal; portanto, quando a vinstrução inferior esquerda é executada, o ponteiro da instrução desce, gira e volta a aparecer na parte superior.


Edit: Ao fazer o código rodar inteiramente da direita para a esquerda , o @randomra conseguiu raspar três bytes com

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

Acho que não joguei o suficiente :)


27
E foi assim que descobri que o nome ><>é um palíndromo.
Zev Eisenberg

33

2012 - Elemento

Essa é uma linguagem que eu inventei no início de 2012 para ser uma linguagem simples de golfe. Com isso, quero dizer que há muito pouca ou nenhuma sobrecarga de operador. Os operadores também são mais simples e têm menor número do que a maioria das linguagens de golfe modernas.

As características mais interessantes dessa linguagem são suas estruturas de dados. Existem duas pilhas e um hash que são usados ​​para armazenar informações.

A pilha m é a pilha principal, onde ocorrem operações aritméticas e a maioria das outras operações. Quando os dados são inseridos ou impressos, é para onde eles vão ou são recuperados.

A pilha c é a pilha de controle. É aqui que a aritmética booleana ocorre. Os valores superiores da pilha c são usados ​​pelos loops If e While como a condição.

O hash é onde as variáveis ​​são armazenadas. O ;e~ armazena e recupera dados do hash, respectivamente.

Elemento é uma linguagem de tipo muito fraco. Ele usa a capacidade do Perl de interpretar livremente números como strings e vice-versa.

Enquanto estou nisso, posso incluir toda a documentação do idioma. Você pode encontrar o intérprete original de 2012, escrito em Perl, aqui . Atualização: eu criei uma versão mais utilizável, que você pode encontrar aqui .

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 \

Tarefa 1 - Imprimir texto

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

Uma das partes mais estranhas da linguagem é a falta de delimitadores de strings, e é por isso que caracteres de escape são necessários nessa string. O `no final imprime a string.

Tarefa 2 - ASCII Art N

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

Aqui, você testemunhará alguma manipulação de pilha. Para facilitar a formatação da explicação, substituirei a nova linha por um Le o espaço por um 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

Depois de fazer algumas jogadas extremas nessa resposta, encontrei uma solução de 39 bytes, embora seja muito mais complicada.

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

Tarefa 3 - GCD

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

Este é um método baseado em pilha.

__                 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

História do idioma

Julia foi desenvolvida em 2012 por Jeff Bezanson, Stefan Karpinski e Viral Shah, enquanto Jeff estudava no Instituto de Tecnologia Massachussets (MIT), orientado pelo professor Alan Edelman. Eles foram motivados pelo desejo de uma linguagem de programação de código aberto, rápida e dinâmica (entre muitas outras coisas), mantendo a facilidade de uso em uma variedade de aplicativos. O produto foi Julia, uma nova abordagem para a computação científica de alto desempenho.

"Olá Mundo!" Variante

println("Julia was made in 2012!")

Imprimir em STDOUT em Julia é bastante simples!

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

O código é recuado para facilitar a leitura, mas Julia não impõe restrições ao espaço em branco.

GCD

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

A última coisa listada na função é retornada implicitamente.


27

1988 - Mathematica

Ou devo chamá-lo Wolfram Language ?

Tarefa 0

O criador do Mathematica é Stephen Wolfram, o Fundador e CEO da Wolfram Research. Antes do desenvolvimento do Mathematica, ele era físico. Havia uma enorme quantidade de cálculo algébrico em física, então ele se tornou um usuário de Macsyma .

Wolfram obteve seu doutorado em 1979, quando tinha 20 anos. Ele achava que precisava de um CAS melhor que Macsyma para fazer física, então começou a escrever SMP (o "Programa de Manipulação Simbólica"). A primeira versão do SMP foi lançada em 1981. O SMP foi o antecessor do Mathematica. Embora tenha tido uma influência profunda no Mathematica, nenhum de seu código foi usado para o Mathematica.

Em 1986, Wolfram decidiu escrever um "sistema de computação final". Ele começou a escrever o código em 1986 e fundou a Wolfram Research em 1987. Finalmente, o Mathematica 1.0 foi lançado em 23 de junho de 1988.

Mathematica 1.0

Não encontrei o Mathematica 1.0. De fato, o Mathematica 1.0 não tinha uma versão para Windows nem para Linux. Mas eu encontrei o Mathematica 2.0 em um site chinês. Ainda pode ser executado no Windows XP.

Mathematica 2.0

Tarefa 1

Print["Mathematica was made in 1988!"]

Ou simplesmente:

"Mathematica was made in 1988!"

Tarefa 2

No Mathematica de hoje, podemos escrever:

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

Assim como Julia e R , esta é uma solução matricial. No Mathematica, você pode definir uma matriz esparsa usando a correspondência de padrões.

No entanto, SparseArrayfoi introduzido no Mathematica 5.0, portanto, não podemos usá-lo no Mathematica 1.0.

Aqui está uma solução que funciona no 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];
]

Não podemos escrever f[i_, 1 | i_ | n] = "N"porque Alternativesfoi introduzido no Mathematica 2.0.

Tarefa 3

Podemos apenas usar a função interna:

gcd = GCD

Ou podemos usar a definição do GCD:

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

Ou podemos usar o LCM , embora o LCM seja mais comumente calculado a partir do GCD:

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

Ou podemos usar o algoritmo euclidiano com correspondência de padrões:

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

Ou como uma função anônima:

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

Todas as funções acima foram introduzidas no Mathematica 1.0.


3
Esta é uma resposta muito melhor que a minha. Eu vou apagar o meu.
Martin Ender

25

1999 - XSLT

O World Wide Web Consortium (W3C) criou o XSLT para transformar XML em HTML, texto etc. Os exemplos a seguir pressupõem que a entrada esteja entre <input>..</input>tags.

Tarefa 1

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

Este é simples. Ele corresponde a uma inputtag no nível superior e a substitui pela saída desejada.

Tarefa 2

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

Este define 2 modelos recursivos, loope spaces. loopcom parâmetros ie nirá gerar a saída desejada para n, começando na posição i. spacescom parâmetro nirá gerarn espaços.

Tarefa 3

A entrada para isso deve estar em <input><num>..</num><num>..</num></input>tags.

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

Este é apenas um modelo recursivo gcdque usa o algoritmo euclidiano.


E eles dizem que INTERCAL é estranho!
precisa saber é o seguinte

2
@ kirbyfan64sos Para ser justo, ele não deve ser usado para essas coisas de qualquer maneira ...
LegionMammal978

24

2014 - CJam

O CJam foi criado pelo usuário do PPCG aditsu e foi lançado em abril de 2014 .

"Olá Mundo!" Variante

"CJam was made in 2014!"

CJam imprime automaticamente o conteúdo da pilha no final do programa

ASCII Art N

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

Explicação do código:

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

Toma a altura / largura de N como entrada via STDIN. Experimente online aqui

GCD

l~{_@\%}h;

Toma os dois números como entrada via STDIN. Experimente online aqui


Sei que isso não é [code-golf], mas você pode reduzir o programa N da arte ASCII para ri_S*0'NtW'Nta1$*\,Sf*'Nf+..e>N*o CJam moderno.
Esolanging Fruit

24

1990 - Haskell

Haskell é uma linguagem funcional pura popular (ou devo dizer: a mais popular ?). Destaca-se do mainstream por seu modelo de avaliação incomum (por padrão, tudo é preguiçoso ou, tecnicamente, não-estrito) e por seu sistema de tipo baseado em Hindley-Milner que, ainda hoje, ainda está entre os mais poderosos por aí.

Tarefa 1

main = putStrLn "Haskell was made in 1990!"

Tarefa 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, imprima a lista infinita inteira (até o usuário ser abortado ou o mundo acabar ...)

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

...

Obviamente, você pode acessar facilmente um deles acessando apenas um elemento da lista infinita:

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

Tarefa 3

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

23

1972 - INTERCAL

E você pensou que Fortran e Cobol eram estranhos. Isso é uma loucura!

Tarefa 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

Não vou tentar explicar o sistema de entrada e saída da INTERCAL; apenas leia isso e espero que você não morra.

Tarefa 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

Graças a Deus. Isso me levou um pouco para descobrir. Os números das etiquetas estão uma bagunça e, portanto, refletem isso. Não vou tentar explicar isso, a menos que alguém pergunte.

Tarefa 3

DO WRITE IN .5
DO WRITE IN .6

DO (1) NEXT

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

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

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

Este é um pouco mais simples. Por causa da estranheza da INTERCAL, você precisa digitar os números assim:

THREE FIVE

Por exemplo, para obter o MDC de 42 e 16, digite:

FOUR TWO
ONE SIX

Também imprime o número em algarismos romanos ... porque é INTERCAL para você!


2
Não deveria ser 19 7 2? (Entendo se você está um pouco tonto depois de escrever isso: P) Sua resposta é considerada inválida devido a esse erro, o que seria uma pena.
Marinus

@ marinus Obrigado! Fixo!
precisa saber é o seguinte

5
POR FAVOR, explique. (Quando você tiver tempo, é claro.;)
DLosc

1
INTERCAL é o meu idioma favorito que eu nunca aprendi!
CJ Dennis

1
PLEASE GIVE UP. Eu já fiz isso .-.
RedClover

23

1967 - APL

Em 1957, na Universidade de Harvard, Ken Iverson começou a desenvolver uma notação matemática para manipulação de array. Durante a década de 1960, sua notação foi desenvolvida em uma linguagem de programação na IBM. A primeira implementação parcial foi criada em 1963 e foi usada até no ensino médio para ensinar aos alunos sobre funções transcendentais. Uma implementação completa e utilizável teve que esperar até 1965. Por dois anos, foi usada apenas internamente pela IBM. Em 1967, a IBM lançou ao público um intérprete de APL que rodava no computador IBM 1130, que havia sido concluído em 1966. Você pode entender como é um pouco difícil escolher um ano para ele; no entanto, acho que deveria ser 1967, como este é o primeiro ano, uma implementação completa foi disponibilizada ao público. Se alguém realmente discordar, eu poderia mudar.

O código fonte do APL \ 360 está online , assim como um emulador. É isso que eu usei para testar esses exemplos. Data de 1967 e, juntamente com o APL \ 1130 (para o IBM 1130 acima mencionado), é mais ou menos o verdadeiro original. Como esperado, é muito primitivo. Falta suporte para detalhes como letras minúsculas, qualquer operador trabalha apenas com funções internas e o conjunto de funções internas é muito escasso (em particular, é apenas or e não é o dobro gcd). A descrição original e completa está disponível aqui , no entanto, notei que a versão que eu tinha nem sequer é completa com relação a esse documento, faltando entre outras.

Forneci os programas no formato Unicode (para que você possa lê-los) e na codificação original (para que você possa recortá-los e colá-los na janela APL do emulador).

Inacreditavelmente, esses programas são executados corretamente, sem nenhuma alteração (exceto a codificação) nas versões modernas do Dyalog, NARS2000 e GNU APL. Acho que encontrei o caminho para escrever APL portátil: apenas finja que é 1967!

Tarefa 1:

Unicode:

⎕←'APL WAS MADE IN 1967!'

APL \ 360:

L[Kapl was made in 1967ÝK

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

Tarefa 3:

Eu resolvi isso da maneira recursiva padrão. Em teoria, você poderia fazer algo inteligente e orientado a matriz, como a resposta J; na prática, no entanto, isso tem uso de memória O (N) e supera rapidamente o hardware e o software da 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

Isso é incrível.
11285 Alex A.

22

1996 - Ocaml

Estava esperando mais de um dia para alguém preencher 1996, para que eu pudesse preencher Ruby. Bem, por que não aprender OCaml então, parece semelhante ao haskell ...

Olá Mundo

print_endline "OCaml was made in 1996!";;

ASCII

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

Cordas mutáveis!

GCD

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

Não ==e infix mod, isso é fofo


Sinto muito, eu enchi em Ruby :)
Fiber Zero

4
+1 para aprender um idioma apenas para responder a esse desafio. :)
Alex A.

Você também aprendeu F #! (é OCaml no CLR mais alguns extras).
Robert Fraser

22

2005 - Prelúdio

O prelúdio é uma linguagem muito divertida, cujo código fonte consiste em várias "vozes" executadas em paralelo e nas quais eu realmente gosto de resolver problemas . Pretende ser a representação ASCII da sua língua irmã Fugue , que na verdade leva arquivos .midi como seu código-fonte e codifica as instruções encontradas no Prelude como intervalos nas melodias das vozes.

O prelúdio é bastante minimalista, mas Turing está completo (desde que você esteja usando pelo menos duas vozes). Como eu disse, as vozes (linhas de código) são executadas simultaneamente, coluna por coluna. Cada voz opera em sua própria pilha, que é inicializada com um número infinito de zeros. O Prelude suporta as seguintes instruções:

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

Algumas notas adicionais:

  • As vozes são cíclicas, portanto, ^na voz superior, copia a voz inferior (e vice-versa).
  • Múltiplos ?e !na mesma coluna são executados de cima para baixo.
  • Conforme a especificação da linguagem , ?e !ler e escrever caracteres com o código de caractere correspondente. No entanto, o interpretador Python também possui uma opção em seu código para imprimir os próprios números. Para fins de teste, na verdade, estou usando uma versão modificada que também pode ler números em vez de caracteres. Mas o consenso por aqui é que a entrada / saída numérica pode realmente ser fornecida como valores de bytes, portanto, essas modificações não são necessárias para criar programas válidos que lidem com números.
  • Correspondendo (e )não precisa estar na mesma voz. A voz usada para a condição é sempre a que (aparece. Portanto, a posição vertical do )é totalmente irrelevante.
  • Devido à natureza da execução simultânea do Prelude, qualquer instrução na mesma coluna que a (é executada apenas uma vez antes do início do loop e independentemente de o loop ser inserido. Da mesma forma, qualquer instrução na mesma coluna que a )é executada no final de cada iteração, independentemente de o loop ser encerrado após essa iteração.

Primeiro, mostrarei os três programas sem muito comentário. Você pode encontrar explicações abrangentes abaixo.

Os programas

"Olá Mundo!" Variante

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

Se você estiver usando o interpretador Python, verifique isso NUMERIC_OUTPUT = False.

ASCII Art N

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

Para facilitar o uso, este programa se beneficia da leitura de entradas como números, mas a saída não deve ser numérica. Portanto, se você estiver usando o interpretador Python modificado, defina

NUMERIC_INPUT = True
NUMERIC_OUTPUT = False

GCD

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

É melhor usado com todas as entradas / saídas numéricas, ou seja,

NUMERIC_INPUT = True
NUMERIC_OUTPUT = True

Explicações

"Olá Mundo!" Variante

Isso é bastante direto. Estou usando três vozes para gerar sucessivamente os códigos de caracteres para todos os caracteres Prelude was made in 2005!. Começo pela computação 8 + 9*8 = 80, que é o código de caractere de P:

 9(1-)
 8 8+

Depois disso, geralmente copio o código de caractere anterior e adiciono ou subtrai a diferença para o próximo. Aqui está o código, mas cada um deles é !substituído pelo caractere que está sendo impresso (e _pelos espaços e %pelos dígitos):

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

A final 55+!imprime uma nova linha à direita, apenas porque é melhor.

Como observação lateral, o número de vozes é bastante arbitrário para esta tarefa, mas 3 é bastante conveniente, porque é o maior número no qual cada voz pode acessar diretamente uma a outra.

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#

Com 5 vozes, esse é definitivamente um dos programas mais complexos que escrevi até agora. As vozes têm aproximadamente os seguintes objetivos:

  1. Apenas uma voz auxiliar que armazena N-1para uso no loop interno.
  2. Essa é uma espécie da voz "principal", que lê a entrada, contém uma chave importante e também contém o loop externo (ou seja, aquele sobre as linhas).
  3. Isso armazena um espaço 32conveniente para impressão.
  4. Isso contém o loop interno (aquele sobre as colunas).
  5. Isso armazena um 78para imprimir convenientemente Ns.

Vamos analisar o código parte por parte. Primeiro, estou criando o 32as -4 + 9*4e o 78as6 + 9*8 :

9(1-)
4-4+

6 8+

Agora, estou imprimindo uma única N(porque sempre precisamos de uma) enquanto lê a entrada Ne o armazenamento N-1e N-2nas duas primeiras vozes:

      v2-
     ?1-

     v!

A seguir, há um "loop" condicionado N-1. No final do loop, a segunda voz é sempre reduzida para 0e o loop sai após a primeira iteração. Então, essencialmente, apenas isso if(N > 1){...}. Após o loop, imprimimos uma nova linha final à direita. Para recapitular, agora temos a seguinte estrutura:

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

Dentro desse condicional, primeiro N-2espaços e um único Npara concluir a primeira linha e também armazenamos N-1na primeira voz para uso futuro:

         (1-)v         
          v!  

             v!

Agora, a verdadeira carne do código. Primeiro, há um loop externo, que imprime N-1linhas. Para cada linha, primeiro imprimimos uma nova linha e um N. Depois, repetimos os N-2tempos, imprimindo espaços ou Ns (mais sobre isso mais tarde). E finalmente imprimimos outro N:

               1-55+!  

                v1-v!(               )v!
               v#

Finalmente, a parte divertida: imprimir cada linha (e obter a posição Ncorreta). Não há realmente um if / else no Prelude, então eu tenho que construí-lo usando dois loops em vozes diferentes. A condição pode ser facilmente obtida subtraindo a variável de loop interno e externo - obtemos0 se queremos imprimir Ne algo diferente de zero se queremos imprimir um espaço.

A idéia básica de um if / else no Prelude é colocar um loop após o valor relevante - o código "if" (ou diferente de zero) e sair imediatamente pressionando a 0. Em outra voz, você mantém um valor diferente de zero e outro loop após o loop "if". Durante o loop "if", você coloca um zero em cima dessa outra voz, para impedir que o "else" seja executado. Existe alguma flexibilidade em você colocar valores zero em cima de valores diferentes de zero ou simplesmente descartar o valor diferente de zero se houver um zero abaixo, mas essa é a ideia geral. Você também pode precisar fazer uma limpeza depois, se quiser continuar usando a voz relevante. É assim que o código se parece:

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

E é isso!

GCD

Esta é "apenas" uma implementação iterativa do algoritmo euclidiano. Mas o módulo no Prelude é um pouco chato, principalmente porque você não pode verificar facilmente se um número é positivo ou negativo. Este código utiliza uma implementação de signum que escrevi há algum tempo . Ou seja, uma grande parte do código apenas transforma um número em -1, 0ou 1. Isso pode ser facilmente transformado em uma condição para números positivos ou negativos, adicionando ou subtraindo 1.

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

Então, temos quatro vozes dessa vez. A primeira voz simplesmente rastreia be contém a principal condição de terminação (ou seja, o loop sai quando bse torna 0). A segunda voz contém ae com a ajuda das vozes três e quatro a % b, antes de trocar o resultado pelo anterior b. Finalmente, as !impressões aquando b == 0.

Vejamos a parte do sinal primeiro:

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

O número de entrada né encontrado na primeira dessas vozes (a segunda voz no programa completo). O resultado terminará na voz inferior. As outras duas vozes devem estar vazias (ou seja, preenchidas com zeros). Observe que, se n == 0ambos os loops forem ignorados e a voz inferior ainda contiver 0exatamente o que queremos.

Se nfor diferente de zero, o primeiro loop pequeno será inserido. Pressionamos o zero para sair imediatamente, colocamos duas cópias nna voz do meio e uma 1na voz de baixo. Agora, a idéia básica é incrementar uma das cópias nenquanto diminui a outra cópia naté que uma delas atinja zero. Ao fazê-lo, a 1voz inferior apaga seu sinal o tempo todo (o que é facilmente feito subtraindo-o de 0baixo da pilha). Isso é configurado para que, quando um dos números chegar a zero, a voz inferior conterá o sinal correto.

Agora o módulo é implementado subtraindo bde aaté o resultado ser negativo. Quando isso acontece, adicionamos um bnovamente. É esse pedaço:

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

Observe a construção if / else na parte inferior, que é semelhante à que usei para a Tarefa 2.


2
Isso realmente deve fazer parte de um tutorial do Prelude.
Alex A.

21

2007 - Raspadinha

Scratch é uma linguagem criada pelo MIT para fins educacionais. Eu estive muito envolvido com isso por 5 anos; mais sobre isso mais tarde.

Tudo isso pode ser visto aqui .

Estou muito apressado agora e explicarei os trechos mais tarde. Espero que eles sejam muito auto-explicativos.

Tarefa 1

insira a descrição da imagem aqui

Tarefa 2

insira a descrição da imagem aqui

Tarefa 3

insira a descrição da imagem aqui


Ainda é tarde?
dfeuer 14/03

21

1972 - C

Todos nós sabemos sobre C, não é? C foi criado no Bell Labs, juntamente com o Unix. O Unix foi amplamente escrito em C. Todos os derivados modernos do Unix ainda são amplamente escritos na sintaxe de C. C influenciou muitas e muitas linguagens de programação. É provavelmente a linguagem de programação mais antiga que ainda é amplamente utilizada para novos desenvolvimentos.

C em si é um descendente de B, que espero que também termine nesta lista. Não havia linguagem de programação 'A': B é uma variante do BCPL, que por sua vez é uma CPL reduzida. Nenhuma dessas línguas foi muito popular. No entanto, BCPL era o idioma em que o primeiro programa "Hello World" foi escrito. Outro fato interessante é que B tinha ambos /* */e //comentários, mas C descartou os //comentários. Mais tarde, eles foram reintroduzidos em C com o padrão C99.

Os programas C aqui foram testados com o compilador Unix V5 C, de 1974. Este foi o compilador C mais antigo que eu pude encontrar e começar a trabalhar, e esses programas não serão compilados em um compilador C moderno. (Uma das alterações feitas é que os operadores de mutação +=costumavam ser escritos =+.)

#include <... >ainda não existia. Nem grande parte da biblioteca padrão. Eu tive que escrever o meu atoi. Examinei alguns dos códigos-fonte da V5 para descobrir quais coisas eram permitidas e quais não eram. A versão que usei foi a primeira a incluir structs, mas como não os usei e a sintaxe parece não ter mudado muito até a V7 (como K&R C), isso também pode funcionar com versões anteriores.

Fiz o possível para escrever meu código no mesmo estilo que o código-fonte V5 usa. (Não que isso seja terrivelmente consistente.)

Procure aqui links para o Unix V5, um emulador, e instruções sobre como executá-lo em um computador moderno.

Tarefa 1

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

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

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

Uau, nunca percebi o quanto C mudou ... De onde você tirou esse compilador?
precisa saber é o seguinte

1
O compilador é o incluído no Unix V5. Há um link na descrição para uma postagem no blog que mostra onde obter os arquivos e como executá-los em um computador moderno. (Está aqui ). Depois de executá-lo, você pode obter o código nele cat > file.c. (Termine com Ctrl-D, como sempre). Além disso, C mudou menos do que você pode pensar: se você trocar o =*e =+nas atoifunções para os equivalentes modernos *=e +=, um GCC moderna vai compilá-los bem e eles correm, também. Quase nenhum aviso, até.
marinus

1
minnie.tuhs.org/cgi-bin/utree.pl?file=V2/c é o compilador C mais antigo que eu pude encontrar (da V2, datada de 72).
Oberon

20

2009 - Idris

Idris é uma linguagem funcional pura, tipicamente dependente, que enfatiza ser praticamente utilizável para aplicativos do mundo real, além de oferecer as possibilidades de prova extremamente rigorosas que são possíveis com os tipos dependentes.

Tarefa 1

module Main

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

Tarefa 2

module InN

import Data.Fin
import Data.Vect

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

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

Este não é um programa, mas apenas uma função (mais precisamente, valor dependente ), produzindo a letra N desejada como uma matriz bidimensional.

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

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

Tarefa 3

module gcd

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

Note que eu tive que escolher o nome gcd'porque, como gcdjá está definido no prelúdio de Idris.

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

Isso parece que eles tomaram Haskell, trocados :e ::, e mudou _para Z.
wchargin

@WChargin Zé realmente o construtor de 0 : Nat. O sublinhado é usado em Idris, assim como em Haskell.
deixou de girar no sentido anti

oh, bem, lá vai você! :)
wchargin

19

2014 - Pyth

Como temos o CJam, também podemos ter o Pyth para completar :)

Pyth é uma língua de golfe da @isaacg, compilada no Python. É notável por ser processual e por usar a notação de prefixo. Pyth apareceu pela primeira vez em junho de 2014 .

"Olá Mundo!" Variante

"Pyth was made in 2014!

Observe a falta de uma cotação de fechamento, que é opcional se um programa Pyth terminar em uma sequência.

ASCII Art N

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

Experimente online . O Python equivalente é:

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

Ou expandido (a primeira e a terceira linhas estão implícitas):

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

GCD

=GvwWQAGQ,Q%GQ)G

Este programa usa o algoritmo euclidiano e recebe dois números separados por uma nova linha. Experimente 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é ainda mais curto se usarmos o built-in para o GCD. Isso é equivalente a print(gcd(*eval(input())))(receber dois números separados por vírgula como entrada).


Drat - Eu ia fazer Pyth xP
theonlygusti

@isaacg Eu não posso deixar de me perguntar, e poderia perguntar aqui: pyth foi inspirado por pyg de alguma forma, forma ou formato?
ɐɔıʇǝɥʇuʎs

Eu já tinha visto o PYG antes de fazer Pyth, e isso pode ter influenciado a abordagem do conceito 1 caractere - 1. No entanto, se alguma coisa inspirou Pyth, provavelmente foi um script de golfe.
Isaacg

17

1964 - Dartmouth BASIC

BASIC é uma família de linguagens de programação de alto nível e uso geral cuja filosofia de design enfatiza a facilidade de uso. Em 1964, John G. Kemeny e Thomas E. Kurtz projetaram o idioma BASIC original no Dartmouth College, em New Hampshire. Eles queriam permitir que estudantes de outras áreas além da ciência e da matemática usassem computadores.

Estou vendo este manual no BASIC de 1964 e este emulador do Darthmouth Time Sharing System em que ele foi executado. O servidor ainda está ativo, mas, infelizmente, o registro de uma conta parece impossível. Por enquanto, esses programas devem, teoricamente, funcionar:

Tarefa 1

10 PRINT "BASIC WAS MADE IN 1964"
20 END

Tarefa 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

Saída algo como:

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

Observe como a entrada é digitada como parte do programa ( 70 DATA 5); o READmodo de instrução no topo busca dados a partir daí. Não há concatenação de strings, mas a seção 3.1 do manual descreve comoPRINT resultados são gravados em "zonas" tabuladas na saída.

Tarefa 3

A versão lenta do algoritmo de Euclides:

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

Saída:

2

Finalmente, alguém fez o BASIC.
Marinus

16

2010 - WTFZOMFG

WTFZOMFG é uma linguagem esotérica baseada em Brainfuck. Foi feita por Jay Songdahl em 2010. "WTFZOMFG" é a abreviação de "O que é essa função? Esquilos maliciosos de arquivos otimizados pelo Zen!" .

Aqui está um compilador para sistemas * nix .

Tarefa 1

'WTFZOMFG was made in 2010!\n"

Tarefa 2

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

Explicação:

Desculpa. Não sou bom em escrever explicações.

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

Tarefa 3

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

Algoritmo euclidiano. WTFZOMFG não tem um comando para mod, então eu tenho que usar d(dividir), m(multiplicar) e s(subtrair).


16

2009 - Ir

Go é uma linguagem de programação desenvolvida pelo Google. O desenvolvimento começou em 2007, mas o Go foi anunciado em novembro de 2009.

Go é uma linguagem de tipo estatístico, influenciada por C, que enfatiza concisão, simplicidade e segurança.

Tarefa 1:

package main
import "fmt"

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

A primeira linha declara o pacote do código. Mesmo um exemplo simples de impressão de uma linha precisa fazer parte de um pacote. E o executável é sempre chamado main.

Tarefa 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 tem uma declaração de variável bastante concisa ( i := 0é a mesma que var i int = 0) e o compilador determina o tipo. Geralmente, esse é um recurso mais comum em idiomas dinâmicos. Usando essa notação curta, também é muito fácil atribuir funções a variáveis ​​( f := func(x int) int {/* Code */}) e criar Closures.

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

Aqui você pode ver a a, b = b, a%bsintaxe, o que é muito bom. Eu não sei o nome exato, mas em Python é chamado desempacotar tupla. Usando da mesma maneira, você pode retornar vários valores de uma função (func f() (int, string) { return 42, "Hallo"} ).

Outra coisa que acontece nesse código é o loop. O loop for é o único loop no Go. Loops while ou loops while não existem. Mas você pode facilmente criar um equivalente para o loop while for condition {}ou um loop infinito for {}.


16

1991 - Python

História do idioma

No final dos anos 80, Guido van Rossum começou a conceber o Python como um hobby. Seu nome vem do Flying Circus de Monty Python, um programa de televisão britânico de que Rossum é fã. A primeira implementação do Python começou em 1989 e foi lançada em 1991. Ela ganhou popularidade ao longo dos anos, tornando-se o idioma de escolha para muitos cursos introdutórios de ciência da computação.

"Olá Mundo!" Variante

print("Python was made in 1991!")

Observe os parênteses ao redor da entrada para print . Embora essa sintaxe funcione no Python 2, normalmente no Python 2 você omitiria esses parênteses. No entanto, eles são necessários no Python 3. Conforme sugerido por Zach Gates, os parênteses são usados ​​o tempo todo para garantir que o código apresentado aqui funcione entre versões.

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

As funções são definidas usando def. A concatenação de strings é realizada usando +e repetição de strings com* .

GCD

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

Observe que o Python requer espaço em branco estruturado.


16

1968 - Algol 68

Algol 68 foi definido pelo Grupo de Trabalho 2.1 do IFIP como sucessor do Algol 60.

É uma linguagem orientada à expressão na qual tudo tem um valor. Também é ortogonal, no qual você pode usar qualquer construção de qualquer maneira. Isso significa que as expressões podem estar no RHS e no LHS de uma atribuição, por exemplo.

Todas as estruturas de controle têm uma forma abreviada e uma forma longa usando expressões. Também permite as definições de operadores.

Os objetivos do idioma são citados como:

Os principais objetivos e princípios de design do ALGOL 68:

  • Completude e clareza da descrição
  • Design ortogonal,
  • Segurança,
  • Eficiência
  • Verificação do modo estático
  • Análise independente de modo
  • Compilação independente
  • Otimização de loop
  • Representações - em conjuntos de caracteres mínimos e maiores

Esses programas foram testados com o interpretador Algol 68 Genie , que é uma implementação completa da linguagem.

Alguns recursos que os programadores modernos podem achar diferentes é que declarações vazias não são permitidas. Você não pode simplesmente adicionar em ;qualquer lugar. Você precisa usar a SKIPinstrução se não quiser explicitamente nada. Também permitiu a codificação de programas concorrentes com muita facilidade. O Algol 68 também usou, notavelmente, palavras-chave anteriores como terminadores, como esac , od , fi etc.

O idioma tinha uma representação usada para escrever o código que usava muitas fontes representando palavras-chave em negrito e identificadores em itálico , por exemplo. Na época, e provavelmente ainda, nenhum compilador implementou esse recurso do design. A linguagem permitia várias representações concretas diferentes de programas usando os modos stropping . Isso permitiu que os programas fossem preparados usando conjuntos de caracteres limitados, como os encontrados nos computadores na década de 1960. Considere o pequeno fragmento do programa, que seria representado como:

se eu < 0 , pule fi

Isso pode ser preparado para um compilador no modo prime stropping como:

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

No modo de dispersão de pontos , isso seria:

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

Em caso modo stropping isso seria:

IF i < 0 THEN SKIP FI

Eu gosto muito desse idioma, pois trabalhei em uma das implementações do compilador, além de programar nele exclusivamente por muitos anos.

Tarefa 1

print (("Algol 68 foi produzido em 1968!", nova linha ))

O ponto a ser observado aqui são os parênteses duplos. Isso ocorre porque print é uma função que recebe um único argumento, que é uma matriz de comprimento variável da união de todos os tipos. Os parênteses internos são o construtor da matriz. É assim que o polimorfismo é tratado nessa linguagem fortemente tipada.

No modo de remoção de estrias:

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


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

Tarefa 2

     int n ;
     ler ( n ));
     para i de 1 para n fazer
          para j de 1 para n do
               ¢ aqui usamos uma cláusula IF abreviada ¢
               print ((( j = 1 OR j = i OR j = n |
                    "N"
               |
                    ""
               )))
          od ;
     print (( nova linha))
     od

No modo de remoção de estrias:

 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

Tarefa 3

     ¢ podemos definir nossos próprios operadores em Algol 68 ¢
     op % = ( int a , b ) int :
          (( b = 0 |
               a
          |
               b % ( a mod b )
          ));
     int i , j ;
     leia (( i , j ));
     print (( i % j , nova linha ))

No modo de remoção de estrias:

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
Estes foram provavelmente os primeiros programas Algol 68 que escrevi e executei em mais de 30 anos. Eu achei tão comovente que realmente me levou às lágrimas. Eu nunca percebi um "Olá, mundo!" programa poderia ser tão emocional!
Brian Tompsett - #

1
Eu estava tão ansioso pelos Idiomas dos anos 60 e estava pronto com BCPL, Simula, CORAL66, Fortran 66, PL / 1, SNOBOL4, POP-1 e um bote inteiro mais, apenas para descobrir que as regras são minhas. esperar 5 anos de línguas ... Pelo menos há um sulco rico para alguém arar.
Brian Tompsett - #

É muito legal ver as diferenças entre o Fortran66 (confusão total de violência nos cartões perfurados), o APL (confusão estranha de símbolos de superpotência) e o Algol68, que é realmente muito bonito. Hoje, você precisaria procurar em línguas esotéricas para encontrar uma variedade de abordagens diferentes ... naquela época, isso era bastante popular, não era?
deixou de girar no sentido contrário

Obviamente, o Relatório Revisado não foi publicado até eh, 1976, foi? Pelo menos esse é o ano dos direitos autorais que Springer dá. E a varredura que encontrei menciona 1978.
Rhialto

[1] A. van Wijngaarden (ed.), Bl Mailloux, 1.EL Peck, CBA Koster, Relatório sobre a linguagem algorítmica ALGOL 68, Numer. Matemática. 14 (1969) 79-218; também em 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, Relatório revisado sobre a linguagem algorítmica ALGOL 68, Acta Informat. 5 (1975) partes 1-3 (reimpressões publicadas por Springer, Berlim, e também como Mathematics Center Tract 50 pelo Mathematisch Centrum, Amsterdam); Também no SIGPLAN Avisos 12 (5) (1977)
Brian Tompsett -

16

1962 - SNOBOL

A "linguagem orientada e simbólica". A princípio, aparentemente chamado de Intérprete de Expressão Simbólica, 'SEXI', que teve que ser alterado para impedir que os nerds da era dos anos 1960 corassem ao enviar seus trabalhos. História real.

Esse foi um dos primeiros idiomas que conseguiu lidar com strings e padrões de forma nativa. De fato, a primeira versão do SNOBOL tinha a string como seu único tipo de dados. A matemática foi então feita pela análise. A implementação inicial foi feita no IBM 7090. Parece que já faz muito tempo, pelo menos, não consegui encontrá-lo. O que encontrei foi o artigo original que o descrevia, bem como um intérprete SNOBOL3 em Java, que pode ser executado em um computador moderno .

O primeiro SNOBOL tinha praticamente apenas correspondência de padrões e aritmética básica. O SNOBOL 3 adicionou funções e alterou a E / S, mas, de outra forma, parece ter permanecido compatível com versões anteriores. O SNOBOL 4 mudou a sintaxe e, a partir daí, tornou-se o Icon , que mantém o padrão correspondente, mas quase se parece com uma linguagem de programação "normal".

Os programas que escrevi usam apenas a funcionalidade descrita no documento original, portanto, devem funcionar com o SNOBOL original, com exceção da E / S, que fiz no estilo SNOBOL3 para que o interpretador Java possa executá-los. No artigo, parece que a diferença é que o SNOBOL1 usa correspondência de padrões com uma SYSvariável especial , enquanto o SNOBOL3 usa variáveis ​​de entrada e saída:

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

Fazer essas substituições deve levá-lo ao SNOBOL 'real' 1. É claro que você não pode executá-lo.

Tarefa 1

START   SYSPOT = 'SNOBOL WAS MADE IN 1962!'

Tarefa 2

Isso mostra matemática, manipulação de strings e controle de fluxo. SNOBOL3 tem funções úteis, como EQverificar a igualdade; o SNOBOL original não, então eu não os usei.

* 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     

Tarefa 3

Primeiro, o chato. A única coisa digna de nota é a verificação menor que a, mostrando exatamente como o SNOBOL orientado a cadeias realmente era: (B - A) '-'significa "o resultado de BA contém um sinal de menos?". O SNOBOL3 também pode LE(B,A), mas o SNOBOL 1 não pode (pelo menos o artigo não menciona).

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

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

Obviamente, quando você tem um idioma inteiramente baseado em seqüências de caracteres e correspondência de padrões, seria uma pena não usar realmente a correspondência e substituição de padrões. Portanto, aqui está um desses GCDs baseados em unário, incluindo rotinas para a conversão de e para unário.

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

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


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

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

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

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

FIN     START

Excelente trabalho em segundo plano! Não há muito para 1961 - parece que COMIT é tudo o que temos ...
Brian Tompsett - #

15

2012 - TypeScript

O TypeScript é uma linguagem de programação livre e de código aberto desenvolvida e mantida pela Microsoft.

O principal objetivo é: qualquer navegador. Qualquer host. Qualquer sistema operacional. Código aberto. Foi lançado em outubro de 2012

Olá TypeScript

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

Arte ASCII

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

GCD

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

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

experimente online e faça screencast .


4
Você esqueceu de mencionar uma coisa: TypeScript é um superconjunto de Javascript com poucas alterações de sintaxe e permite (?) Variáveis ​​e argumentos de tipo forte.
Ismael Miguel

1
Ó meu deus, algo de código aberto da MS!
Mega Man

15

2011 - Dardo

Dart é uma linguagem de programação de código aberto desenvolvida pelo Google que é desenvolvida como um substituto para o Javascript (apesar de compilar com o javascript). Foi revelado pelo Google em 2011 durante a conferência GOTO.

"Olá Mundo!" Variante:

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

ASCII Art N:

O método Bruteforce é executado em 0 (n²), mas não deve realmente importar, a menos que você use um número gigante.

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

GCD

método Euclid simples portado do Snap! exemplo acima.

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
Eu não acho que você possa produzir uma arte ASCII × n em menos de O (n²).
Paŭlo Ebermann 6/04/2015

@ PaŭloEbermann Não estou familiarizado com a grande notação O ou como calcular a complexidade, mas o exemplo da Julia parece que não é O (n²).
Nzall 06/04

@AlexA. A função println () imprime uma sequência de n caracteres. Eu acho que a chamada de função precisa de pelo menos tempo O (n) para executar. No loop, então O (n²) para todo o programa.
Paŭlo Ebermann 6/04/2015

@AlexA. Acho que o que Ebermann está falando é que você tem operações de concatenação de N strings na sua função de impressão. nós dois fazemos concatenações de n2 strings em nossas funções. Eu as faço uma vez por iteração de loop interno, você as faz para cada println ().
Nzall 06/04

1
Se isso não fosse artístico, seria O (n) exibir um N. (desenhe 3 linhas na tela, cada linha é O (n), portanto, O (n) complexidade). Ou, você poderia dizer, tornando o N tem O (N) complexidade ... hehe
rodolphito

15

2010 - Ferrugem

Rust é uma linguagem de programação compilada, de múltiplos paradigmas, de propósito geral, desenvolvida pela Mozilla Research. Ele foi projetado para ser uma "linguagem prática, segura e simultânea", suportando estilos de funcionalidade pura, ator simultâneo, procedimento imperativo e orientação a objetos. Wikipedia

Tarefa1

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

Tarefa2

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

Explicação:

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

cuida da impressão apenas na vertical (esquerda e direita |) e na diagonal ( \)

Tarefa 3

implementação simples de Euclidean_algorithm

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

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

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

Você poderia adicionar um trecho mostrando como inserir dois números inteiros separados por espaço a partir do stdin?
Fibra Zero

3
Rust foi "feito em" 2010? Timeline das linguagens de programação diz que sim, mas o próprio artigo diz que ele só foi anunciado em 2010 (na verdade, de 2011, como evidenciado por referência ) e que a versão 0.2 foi lançado em 2012.
EMBLEMA

1
@SampritiPanda, dê uma olhada em haste.bin
raw

1
Parece um pouco moderno. Ele pode compilar a primeira versão de trabalho publicada do <s> lançado </s> do compilador?
Vi.

15

2015 - Muffin MC

O Muffin MC é uma macro-linguagem completa, divertida (mas séria), funcional e minimalista de Turing, escrita por Franck Porcher ( http://franckys.com ) em meados de fevereiro de 2015, por necessidade como uma ferramenta (rápida) para capacitar um planilha a ser usada como o único controlador front-end a pilotar e conduzir todas as operações relacionadas a inventário associadas a um site de comércio baseado em Prestashop para uma nova marca de moda do Tahitian: Mutiny Tahiti ( http://mutinytahiti.com - em breve lançado).

Muffin MC é um acrônimo para MU minúsculo F unctional F lexible IN linha M acro C ommand idioma.

Para atender aos nossos requisitos, os principais recursos do Muffin MC foram projetados com base em construções semânticas integradas de primeira classe flexíveis e eficientes, como iteradores , avaliação preguiçosa , multifuncionais , produto de seqüência de caracteres .

O Muffin MC tem suas raízes na programação funcional (pragmática), FLisp e Perl. Ele suporta totalmente a recursividade (sem qualquer otimização), é digitado dinamicamente e com escopo dinâmico (ligação superficial). Ele oferece a seus usuários apenas uma estrutura de dados, além dos átomos básicos dos tipos de dados (átomos, seqüências de caracteres, números): listas!

A semântica da lista de muffin MC (tipo de) empresta semântica de conjunto de potência , ou seja:

  1. Todas as operações do Muffin MC produzem uma lista, possivelmente vazia.
  2. O acesso a qualquer elemento de lista individual sempre gera uma lista de um valor feita desse elemento (pense nele como um singleton).
  3. A lista vazia é o elemento neutro nas operações da lista.

Para se reconciliar com isso, o seguinte pode ajudar:

  • Pode-se visualizar uma lista como o elemento do conjunto de poder da lista que tem a maior cardinalidade.
  • Visualize o elemento de uma lista como o elemento do conjunto de poder da lista que é o singleton feito desse elemento.
  • Visualize uma lista vazia como o conjunto vazio; isto é, o único elemento do conjunto de potência do conjunto vazio.

Como tal, acessar um elemento de lista vazio gera a lista vazia, e não um erro! De fato, o Muffin MC se esforça para lançar o menor número possível de erros, estendendo assim a semântica de muitas operações tradicionais.

Tarefa 1

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

#(...)é o comando macro do Muffin MC para aplicar uma função em uma lista de argumentos não avaliada, aqui a função interna say, emprestada do Perl.

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

Tarefa 2

Defina a função 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()formulário de trabalho mais curto (88 bytes):

=(f'(=(* x#(2-)I I(*($(x)" ")N)g'(#(.#(I$(x)))))#(say?(#(==$(_1)1)N"N#(map g#(..))N"))))
  • =(var val...)é o comando macro do Muffin MC para definir uma variável ou reatribuí-la.

  • $(var)é o comando macro do Muffin MC para acessar o valor de uma variável. Naturalmente, aceita o formulário $(v1 v2 ...)para acessar muitas variáveis ​​ao mesmo tempo.

  • =(* var1 val1 var2 val2 ...)é a extensão do comando macro do Muffin MC=(...) para lidar com atribuições paralelas.

  • Variáveis _1, _2, ... têm escopo dinâmico (mecanismo de ligação superficial) e são definidas automaticamente para vincular aos argumentos da função. Emprestadas do Perl5, as variáveis ​​do sistema #(número de argumentos) e @(lista de argumentos) também são definidas automaticamente.

  • Funções são simplesmente variáveis ​​ligadas a qualquer número de instruções do Muffin MC .

Esta solução interessante vem da combinação de dois recursos naturais do Muffin MC :

  1. O comando macro Muffin MC I(...) , para definir iteradores de ciclo, usados ​​posteriormente com a forma funcional #(my-iterator want-number-of-values),

  2. O muffin MC -produto cadeia construo, uma extensão da interpolação variável natural, o que, dado qualquer cadeia "F1 F2 F3...", onde a F i s são ou muffin MC literais corda ou muffin MC comando de macro (aka formas funcionais), irá produzir o maior número de cadeias de caracteres como dado pelo produto cardinal (F1) x cardinal (F2) x ....

Por exemplo, dada xa variável que contém 2 valores, diz aeb, ey outra variável que possui 3 valores, diz 1 2 3, a avaliação da sequência "x=$(x) y=$(y))"produzirá 6 valores diferentes, a saber, nessa ordem:

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

Este é um dos recursos altamente desejáveis ​​do projeto MUTINY para o qual o Muffin MC foi projetado.

Executá-lo !

#(ascii-art 1)

N


#(ascii-art 3)

N N  
NNN  
N N 


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

N   N
NN  N
N N N
N  NN
N   N

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

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

Como funciona

Nosso algoritmo é baseado nos seguintes itens:

Atendendo à ascii-art (n), {n = 2p + 1 | p inteiro, p> = 0}, a arte a ser gerada compreende n seqüências de n caracteres, entre as quais duas, a mais à esquerda e a direita, são fixas e sempre as mesmas: 'N'. Isso permite reduzir o problema de produzir apenas as cordas do meio. Por exemplo, dado n = 5, gostaríamos de produzir as 5 seqüências do meio a seguir, cada uma composta de caracteres n-2 (substituímos o espaço por um '_' para melhor visualização):

    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 |
                                _ _ _
  • Tais cadeias médias podem ser facilmente produzidas pedalando pela sequência de 4 elementos ('_' '_' '_' 'N')em 5 grupos de 3; dado n, na entrada da função, essa sequência é composta de caracteres n-2 '_', seguidos pelo caractere 'N'. Andar de bicicleta por essa sequência não requer nada além de incorporar a sequência em um iterador interno do Muffin MC I(sequence) (um iterador que alterna para sempre sua seqüência inicial de valores).

  • Em seguida, simplesmente produzimos as cadeias intermediárias, de comprimento n-2, solicitando ao nosso iterador que nos forneça seus próximos valores n-2 (n-2 caracteres), que são concatenados juntos para produzir a cadeia intermediária esperada.

  • As n seqüências do meio são produzidas repetindo n vezes o processo acima, usando um mapa para coletar os n resultados (n seqüências de caracteres de n-2).

  • Nós usamos um outro Muffin poderosa MC construção built-in, ou seja, o produto corda , para produzir as cordas Final N: "N#(map...)N".

  • E é isso !

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

Tarefa 3

Defina a função gcd():

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

gcd()é a forma mais curta real (37 bytes - ganho de 2 bytes graças ao Rodolvertice)

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

Executá-lo !

#(gcd 225 81)

produz 9.

É isso aí.

Obrigado pelo bom jogo e, possivelmente, pelo seu interesse. O idioma está disponível para qualquer pessoa que queira brincar, usá-lo ou até estendê-lo. Basta pedir e terei o maior prazer em enviá-lo.

Felicidades

Franck


PS. A implementação atual do Muffin MC está no Perl5. O código-fonte tem cerca de 2000 linhas do Perl moderno, incluindo comentários, e é fornecido com um conjunto de testes sem regressão, o que é ótimo para aprender construções e semânticas práticas do Muffin MC .


Muito bom! A forma mais curta da ascii-art tem um nome de função abreviado, mas o GCD mais curto não. Isso é intencional, porque, se não for, você pode cortar outros 2 bytes. 1
rodolphito

Claro, e é intencional. Eu devo ? sim, vamos fazê-lo;) Obrigado pelo post e sua apreciação.
Franck Porcher #

1
Como você está tentando se livrar de caracteres extras (e porque eu posso ser uma gramática incorrigível), você pode (deve) remover o espaço na frente do ponto de exclamação para a primeira tarefa. Esse espaço está correto no afaik francês, mas não no inglês.
Amos M. Carpenter
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.