Языки программирования на протяжении многих лет

168

В этой задаче пользователи по очереди выполняют три довольно простых задачи кодирования на языках программирования, которые могут быть постепенно стареющими.

В первом ответе должен использоваться язык программирования, созданный в 2015 году. Если есть хотя бы один ответ из языка 2015 года, в ответах могут использоваться языки программирования, сделанные в 2014 году. Аналогичным образом, ответы, использующие языки 2013 года, не допускаются. пока не будет хотя бы одного ответа 2014 года.

Как правило, использование языка программирования года Y не допускается до тех пор, пока не будет представлен ответ с использованием языка года Y + 1. Единственное исключение - Y = 2015.

Нахождение года вашего языка

Чтобы ответить на этот вопрос, вы должны знать год, в который ваш язык программирования был «сделан». Это, конечно, субъективный термин; некоторые языки были разработаны в течение нескольких лет, и многие языки продолжают обновляться каждый год. Пусть год, в который был «сделан язык», станет первым годом, когда внедрение этого языка появилось в широкой публике.

Например, Python был «сделан в 1991 году» , хотя его разработка продолжалась с 1989 года, а версия 1.0 не была выпущена до 1994 года.

Если этот год все еще субъективен, просто используйте свой здравый смысл, чтобы выбрать наиболее подходящий год. Не увязайте в небольших разногласиях по поводу выбора года. Пожалуйста, предоставьте ссылку на источник, который говорит, когда ваш язык был сделан.

Различные версии или стандарты языка программирования (например, Python 1, 2, 3) считаются одним и тем же языком с одним и тем же начальным годом.

Таким образом, если ваш язык не является 2015 годом, вы можете отправить свой ответ только после того, как будет представлен ответ, языком которого является год, предшествующий вашему.

Если действительный ответ того же года, что и ваш, уже существует, вы можете ответить. Неважно, был ли ваш язык разработан ранее или позже в этом году.

Задачи

Вы должны выполнить Задачи с 1 по 3. Задача 0 не является обязательной.

Эти задачи были более или менее выбраны, чтобы соответствовать трем важным аспектам программирования: обеспечение вывода (Задача 1), циклическое выполнение (Задача 2) и рекурсия (Задача 3).

Задача 0 - История языков (необязательно)

Напишите хотя бы параграф, объясняющий историю выбранного вами языка программирования: кто его разработал, почему, как и т. Д. Это особенно рекомендуется, если вы лично были рядом, когда появился этот язык, и, возможно, даже сыграли свою роль в его разработке. Не стесняйтесь рассказывать личные анекдоты о влиянии языка на вас или вашу работу, или что-то в этом роде.

Если вы слишком молоды, чтобы много знать об истории своего языка без особых исследований, рассмотрите возможность оставить заметку для пожилых пользователей, в которой говорится, что они могут отредактировать ваше сообщение и добавить его в историю из первых рук.

Задача 1 - «Привет, мир!» Вариант

Напишите программу, которая печатает

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

в стандартную область вывода вашего языка (стандартный вывод для самых последних языков).

Например, если бы язык был Python, вывод был бы:

Python was made in 1991!

Задача 2 - ASCII Art N

Напишите программу, которая позволяет пользователю вводить нечетное положительное целое число (вы можете предположить, что ввод всегда действителен) и печатает букву N в формате ASCII, созданную с использованием символа N.

Если входное значение равно 1, выходное значение равно:

N

Если входное значение равно 3, выходное значение равно:

N N
NNN
N N

Если входное значение равно 5, выходное значение равно:

N   N
NN  N
N N N
N  NN
N   N

Если входное значение равно 7, выходное значение равно:

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

Шаблон продолжается так. Вывод может содержать завершающие пробелы.

Задача 3 - GCD

Напишите программу, которая позволяет пользователю вводить два положительных целых числа (вы можете предполагать, что ввод всегда действителен) и печатает их наибольший общий делитель . Это определяется как наибольшее положительное целое число, которое делит оба числа без остатка. Его можно легко рассчитать с помощью евклидова алгоритма .

Примеры:

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

Вы можете использовать встроенную функцию, но попробуйте выяснить, была ли она в первой версии вашего языка. Если нет, попробуйте не использовать его.

правила

  • Вы можете отвечать несколько раз, но каждый новый ответ должен использовать язык, составленный не менее чем за 5 лет до языка в вашем последнем ответе. Поэтому, если вы ответили языком 2015 года, вы не сможете ответить снова, пока не будут разрешены языки 2010 года. Если вы начнете с ответа 2010 года, вы не сможете сделать ответ 2015 года своим вторым ответом, потому что 2015 год не раньше 2010 года.
  • Если возможно, напишите свой код так, чтобы он работал в самой первой версии вашего языка (или как можно более старой версии). (Это не является обязательным требованием, поскольку поиск старых компиляторов / интерпретаторов для некоторых языков может быть затруднен.)
  • Воздержитесь от публикации языка, который уже был опубликован, за исключением тех случаев, когда в опубликованном ответе есть значительные ошибки или у вас совсем другой способ выполнения задач.
  • Гольф ваш код это хорошо, но не обязательно.
  • Завершающий перевод строки в вывод любой программы - это нормально.
  • Для задач 2 и 3 все входные значения ниже некоторого разумного максимума, такого как 2 16, должны работать (как минимум 256).
  • Ваш язык должен был существовать до того, как этот вопрос был опубликован.
  • Очень старые языки программирования могут иметь разные формы ввода и вывода, чем мы думаем сегодня. Это отлично. Выполняйте задания в меру своих возможностей в контексте вашего языка.

счет

Оценка вашего представления:

upvotes - downvotes + (2015 - languageYear) / 2 

Таким образом, 0,5 добавляется к подсчету голосов за каждый год до 2015 года, что дает преимущество старым языкам. Представление с самым высоким счетом выигрывает.

Список ответов

В приведенном ниже фрагменте стека перечислены все действительные ответы в зависимости от их языкового года.

Вы должны начать свой пост с этой строки Markdown, чтобы убедиться, что она указана правильно:

#[year] - [language name]

Например:

#1991 - Python

Название языка может быть в ссылке (это будет та же ссылка в списке ответов):

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

Ответы, которые не соответствуют этому формату или имеют год, который еще не разрешен, или получены от пользователя, который уже ответил за последние 5 лет, помечаются как недействительные.

<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
Это должно помочь.
swish
20
В Википедии есть список для всего: этот для неэзотерических языков по годам.
Санчиз
2
Должна ли задача 3 действительно использовать рекурсию или достаточно, чтобы она давала правильный результат? Если мне нужно написать свою собственную функцию GCD, я обычно просто использую цикл, но я написал рекурсивный специально для этой задачи. Есть много представленных ответов, которые просто используют цикл.
CJ Деннис
5
Я чувствую, что хочу сделать второй аккаунт, чтобы пройти через 1971 год.
marinus
5
Если мы сможем вернуть его в 1952 году, у меня есть кто-то, кто раскручивает историческую машину, которая может делать решения 1951 года (Pegasus) и тестировать их!
Брайан Томпсетт - 莱恩 莱恩

Ответы:

173

2013 - Dogescript

Dogescript - это язык, созданный в 2013 году Заком Брюггеманом. Это не более чем синтаксическая замена Javascript, чтобы он читался как внутренние монологи меметического Shiba Inus.

Привет дож

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

ASCII Art

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

НОД

such gcd_doge much doge, dooge
    rly dooge
              gcd_doge(dooge, doge % dooge)
  but
    rly doge smaller 0
           -doge
    but
          doge
  wow
        wow
рассекать
источник
113
Вау, такой +1. Очень ответ. Многое качество.
Алекс А.
27
Я присоединился к Codegolf, чтобы поддержать этот ответ!
Дерек Томес
21
Я даже не могу прочитать GCD с открытым лицом
Коул Джонсон
16
Я не могу не читать gcd_doge как good_dog. Помощь
Ян
Фантастика. Однако, согласно LANGUAGE.md, двойные кавычки не поддерживаются. Хотелось бы, чтобы объяснение s[i]немного тоже!
Доктор
66

2015 - Сетчатка

Retina - это язык программирования на основе регулярных выражений, который я написал, чтобы иметь возможность конкурировать в задачах PPCG с ответами только на регулярные выражения, без лишних накладных расходов при вызове регулярного выражения в некотором главном языке. Сетчатка завершена по Тьюрингу. Чтобы доказать это, я реализовал системный решатель с 2 тегами, а также Правило 110 . Он написан на C #, поэтому он поддерживает как .NET-вариант (по умолчанию), так и ECMAScript-вариант (с помощью флага).

Retina может работать в нескольких режимах, но наиболее подходящим для вычислений (и полного по Тьюрингу) является режим замены. В режиме замены вы даете Retina четное количество исходных файлов. Затем они объединяются в пары, причем первая из каждой пары является регулярным выражением, а вторая заменой. Затем они выполняются по порядку, манипулируя вводом шаг за шагом. Регулярному выражению также может предшествовать конфигурация (ограниченная с помощью `). Наиболее важная опция (которая делает Retina Turing-complete) заключается в том +, что Retina применяет замену в цикле, пока результат не перестанет меняться. В следующих примерах я также использую ;, что подавляет вывод на промежуточных этапах.

В каждом из следующих представлений каждая строка помещается в отдельный исходный файл. (В качестве альтернативы вы можете использовать новую -sопцию и поместить все строки в один файл.) Пустые файлы / строки представлены как <empty>. Файлы / строки, содержащие один пробел, представлены как <space>.

Объяснения довольно длинные, поэтому я перенес их в конец поста.

Программы

"Привет, мир!" Вариант

<empty>
Retina was made in 2015!

ASCII Art N

Это предполагает, что STDIN завершается с новой строки.

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

НОД

Это требует, чтобы STDIN не заканчивался символом новой строки.

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

Пояснения

"Привет, мир!" Вариант

Это довольно тривиально. Он не требует ввода (т. Е. Пустой строки), ничего не соответствует и заменяет его на Retina was made in 2015!. Можно также заставить это работать для произвольного ввода, заменяя образец, [\s\S]*например. Это бы отбросило STDIN и заменило бы все это выводом.

ASCII Art N

Это имеет довольно много этапов. Идея состоит в том, чтобы преобразовать входные данные в унарные, создать блок N x N из Ns, а затем «вырезать» два треугольника. Давайте пройдемся по отдельным этапам. Помните, что ;просто подавляет промежуточные выходы, но +заставляет замену применяться в цикле.

;`^
#

Просто: добавьте a #к входу. Это будет использоваться в качестве маркера при конвертации в унарный.

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

Это преобразует одну цифру в унарный. Он берет уже преобразованные цифры (\d*)и повторяет их 10 раз. Затем он принимает следующую цифру и добавляет соответствующее количество цифр. Фактическое значение цифр на данном этапе не имеет значения. Когда #достигает конца числа, регулярное выражение больше не совпадает, и преобразование завершено. Например, номер 127будет обработан как

#127
1#27
111111111122#7
1111111111221111111111221111111111221111111111221111111111221111111111221111111111221111111111221111111111221111111111227777777#

где последняя строка содержит ровно 127 цифр символов.

;`#
<empty>
;`\d
N

Два простых этапа, которые избавляются от этого, #а затем преобразуют все цифры в N. В следующем 7примере я буду использовать входные данные . Итак, теперь у нас есть

NNNNNNN

Следующий этап

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

заменяет каждую Nна всю строку (помните, что она содержит завершающий символ новой строки), а также удаляет сам конечный символ новой строки. Следовательно, это превращает один ряд в квадратную сетку:

NNNNNNN
NNNNNNN   
NNNNNNN
NNNNNNN
NNNNNNN
NNNNNNN
NNNNNNN

Теперь верхний треугольник. Во-первых, мы начинаем с того, что превращаем N в правом нижнем углу в пробел:

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

Взгляд в будущее гарантирует, что мы модифицируем правильное N. Это дает

NNNNNNN
NNNNNNN   
NNNNNNN
NNNNNNN
NNNNN N
NNNNNNN
NNNNNNN

И сейчас

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

является регулярным выражением, которое соответствует Nнад или в верхнем левом углу пробела и заменяет его пробелом. Поскольку замена повторяется, это, по сути, заливка, которая превращает 3-й октант из исходного пространства в большее количество пространств:

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

И, наконец, мы повторяем то же самое с нижним треугольником, но используем другой символ, чтобы уже существующие пробелы не вызывали неправильную заливку:

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

устанавливает семя:

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

затем

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

выполняет заливку

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

И наконец

S
<space>

Превращает их Sв пространства, и мы сделали:

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

НОД

GCD в унарном языке на самом деле очень тривиально с регулярным выражением. Большая часть этого состоит из десятичного в унарное и унарное в десятичное преобразование. Это можно сделать более компактно, но это не кодекс, так что ...

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

Эти этапы, по сути, такие же, как и выше, за исключением того, что оба входных числа преобразуются, и результат использует 1s вместо Ns (не то, что это имеет значение). Так что, если вход был 18 24, то это произвело бы

111111111111111111 111111111111111111111111

В настоящее время

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

это все вычисления GCD. Мы сопоставляем общий делитель, фиксируя число 1s, а затем используя обратные ссылки, чтобы гарантировать, что оба числа могут быть записаны путем повторения этой строки (и ничего больше). Из-за того, что в движке регулярных выражений работает возврат (то есть, .+это жадный алгоритм), он всегда будет автоматически давать наибольший общий делитель. Поскольку совпадение охватывает всю строку, мы просто напишем первую группу захвата, чтобы получить наш GCD.

Наконец, унарное в десятичное преобразование ...

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

Это обратное унарному расширению ранее. Мы находим наибольшее кратное 10, которое вписывается в текущую строку. Затем мы выбираем следующую цифру на основе остатка и делим кратное число на 10, перемещая маркер по цифрам.

#|:.*
<empty>

И, наконец, просто шаг очистки, чтобы избавиться от маркера, разделителя и вспомогательных цифр.

Мартин Эндер
источник
Я думаю, что вы должны добавить инструкцию для преобразования числового ввода в унарную строку и инструкцию для преобразования одинарной строки обратно в числовой ввод. Преобразование с чистым регулярным выражением - это круто, но слишком неуклюже.
n15h ata̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳
8
+1 Я был почти уверен, что представление 2015 года будет языком для использования CodeGolf.
Ноль волокна
@ n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳ Я думал об этом раньше. Я думаю, что для большинства гольф-кодов, я бы, вероятно, просто взял унарный ввод (если в задаче явно не указано «десятичное» или что-то ...). Я думал сделать то же самое для этого, но это не гольф-код, и я хотел показать, что я могу также обрабатывать десятичный ввод и вывод.
Мартин Эндер
6
Превосходная работа. Сетчатка действительно крутая. И, кроме того, это действительно здорово видеть бриллиант рядом с твоим именем! :)
Алекс А.
Забавно, что хотя в этом конкурсе предпочитают старые языки, этот самый младший все еще выигрывает =)
Клавдиу
60

2013 - Snap !

Snap ! это язык на основе Scratch , сделанный в университете Беркли. Это обновление до Scratch с первоклассными данными и пользовательскими блоками (функциями). Как и в Scratch, он основан не на тексте, а на визуальных «блоках», которые объединяются.

Snap ! , написанный на JavaScript, является преемником BYOB, который был написан на Squeak Smalltalk. Snap ! была бета-версия для общественного потребления в марте 2013 года .

Snap ! на самом деле не эзотерический язык. Он используется как язык программирования для курса AP CS « Красота и радость вычислений» (BJC) в Беркли и других.

Я помог с тестированием и прочим.

Вариант "Hello World"

ASCII Art "N"

введите описание изображения здесь

Это использует stdlib для некоторых блоков.

Довольно простой цикл здесь. Принимает вход. Затем мы просто складываем все вместе и говорим это (результат для n = 5):

введите описание изображения здесь

Я позволил себе использовать 2 пробела вместо 1, потому что Snap! не говорит вещи в монопространстве.

НОД

Евклидов алгоритм не очень быстрый, но работает и довольно прост. (Извините, я сделал опечатку в имени блока. Теперь я закрыл вкладку без сохранения. Она просто останется.)

введите описание изображения здесь

Это определение функции будет затем производить этот блок:

введите описание изображения здесь

Scimonster
источник
3
Это выглядит как программирование в Алисе ...
mbomb007
4
Вот что вы получаете с блочными языками. Кстати, многие языки похожи друг на друга. ;)
Scimonster
1
Даже в Scratch есть мод-функция, поэтому я предполагаю, что вы можете сделать функцию GCM / GCD более быстрой с помощью блока, основанного на if (b == 0), чем на другом GCM (b, a% b)
Alchymist
55

2007 - ЛОЛКОД

История языка

LOLCODE был создан в 2007 году Адамом Линдси, исследователем из Университета Ланкастера. Его синтаксис основан на мемах lolcats, популяризированных Cheezburger, Inc.

"Привет, мир!" Вариант

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

Значения читаются как строки (YARNs) из stdin, используя GIMMEH. Их можно преобразовать в числовые (NUMBR), умножив на 1.

Значения выводятся в стандартный вывод с помощью VISIBLE. По умолчанию добавляется новая строка, но ее можно отключить, добавив восклицательный знак.

НОД

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 выполняет конкатенацию строк.

Алекс А.
источник
13
Наконец, язык, который каждый может понять.
ASCIIThenANSI
26
IM IN YR toilet UPPIN YR buttХорошие имена переменных
Коул Джонсон
13
@ColeJohnson: Я всегда стараюсь выбирать имена переменных , которые имеют смысл в ситуации , а не x1, x2и т.д.
Alex A.
2
Веселое. Я не должен читать это на работе.
Алан Гувер
@AlanHoover: Очевидно, что LOLZ важнее, чем Jobz.
Алекс А.
43

1982 - PostScript

PostScript - это язык для создания векторной графики и печати.

Adobe была основана в 1982 году, и их первым продуктом был PostScript. Язык использовался в принтерах: принтер интерпретирует команды для создания растрового изображения, которое затем распечатывается на странице. Это было очень распространенным компонентом лазерных принтеров в 1990-х годах. Но очевидно, что он сильно загружает процессор на принтере, и, поскольку компьютерные процессоры стали более мощными, имело больше смысла выполнять растеризацию на компьютере, чем на принтере. PostScript в значительной степени исчез на потребительских принтерах, хотя все еще существует на многих более высококачественных принтерах.

Стандарт, заменивший PostScript, - это малоизвестный формат, называемый PDF.

PostScript вышел из моды к тому времени, когда я начал программировать, но я немного научился, когда учился в университете, как еще один способ создания документов для TeX. Он сильно отличался от других языков программирования, которые я использовал (обратная инфиксная запись, стек, печать на страницу вместо консоли), но было приятно стряхнуть этот старый язык для развлечения.

Поскольку PostScript является языком печати, более целесообразно использовать его для печати чего-либо, а затем отправлять вывод на консоль.

Задание 1

/Courier findfont
12 scalefont
setfont
newpath

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

Первые несколько строк настраивают холст для рисования. Затем movetoкоманда говорит PS рисовать в определенной позиции и showпечатает строку на странице. Обратите внимание, что скобки отмечают строку в PostScript, а не кавычки.

Задача 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

Я написал функцию для рисования «ASCII art» N, но функции PostScript не могут получить аргумент. Вместо этого вы помещаете свои аргументы в стек, а затем возвращаете их обратно. Это /x exch defлиния.

Пример: предположим , что стек 8 9 2. Сначала мы помещаем имя /xв стек, так что стек есть 8 9 2 /x. exchОператор меняет местами два значения стека, так что теперь стек 8 9 /x 2. Затем defвыскальзывает два верхних значения стека и определяет /xзначение 2. Стек сейчас 8 9.

Когда я начал использовать PostScript, меня это немного смутило. Я читал о стеке как о теоретической концепции, но впервые использовал его на практике.

Остальная часть функции - это некоторый код для рисования: начинайте с правого нижнего угла, заполняя строку по порядку слева направо и по диагонали.

Задача 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

Опять же, я использовал форму алгоритма Евклида, но я забыл, что PostScript имеет встроенный оператор по модулю, поэтому мне пришлось написать свой собственный. Это оказалось полезным напоминанием об ограничениях стекового программирования. Моя первая реализация moduloбыла основана на рекурсии:

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

это нормально, пока вы не попытаетесь запустить его, когда xон большой и yмаленький (например, 5689 и 2). В стеке может быть только до 250 элементов, поэтому я дул далеко за пределы стека. К сожалению. Я должен был вернуться к чертежной доске на этом.

Сам код GCD довольно прост. Но так же, как функции не могут принимать аргументы, они не имеют возвращаемых значений. Вместо этого вы должны поместить результат в стек, где кто-то другой может выложить его позже. Это то, что делают строки aand b a gcd: когда они закончили оценку, они помещают значение в стек.

Если вы поместите весь код в документ и распечатаете его, это будет выглядеть так:

введите описание изображения здесь

alexwlchan
источник
8
Хаха, я люблю фотографию напечатанного клочка бумаги. Чувствует себя подходящим для 1982 года.
Алекс А.
1
Кроме того, спасибо за ваше описание того, как вы получили (буквальное) переполнение стека - теперь я более интуитивно понимаю, почему языки имеют максимальную глубину рекурсии.
DLosc
2
@ Алекс: Да, но распечатка с точечной матрицей (с отверстиями по бокам бумаги) была бы еще более уместной . ;-)
Амос М. Карпентер
@ AmosM.Carpenter: не совсем, я не думаю, что какой-либо матричный принтер когда-либо поддерживал PostScript. Это всегда было довольно привязано к лазерным принтерам.
ниндзя
41

2009 - > <>

Вдохновленный Befunge,> <> (Fish) - это двумерный язык на основе эзотерических стеков, т. Е. Поток программ может быть вверх, вниз, влево или вправо. Начальная версия> <> признаки многопоточности , где [и ]создала и закончила темы, но для простоты причины этих инструкции были изменены , чтобы создавать и удалять новые стеки соответственно.

Текущий официальный переводчик для> <> можно найти здесь . К сожалению, ссылка на старого переводчика на Esolang Wiki не работает.

"Привет, мир!" Вариант

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

Обратите внимание, что строка записана в обратном направлении -> <> технически не имеет строк, а единственным типом данных является странное сочетание char, int и float. "переключает разбор строк, помещая каждый символ в стек, пока не будет выполнено закрытие ".

Затем вторая половина кода увеличивает длину стека l, проверяет, равен ли он нулю, ?!и если да, то программа завершается ;. В противном случае указатель инструкции продолжается, выводя вершину стека oперед выполнением bb+0., что приводит к телепортации указателя в положение (22, 0)непосредственно перед lсозданием цикла.

ASCII Art N

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

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

   \                                                         <   /

С интервалом для ясности. Вы можете попробовать это в новом онлайн-переводчике здесь и увидеть, как указатель команд вращается - просто не забудьте ввести число в текстовое поле «Начальный стек». Если вы работаете через интерпретатор Python, используйте -vфлаг для инициализации стека, например

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

Для этой программы мы помещаем ввод nв регистр &и нажимаем 0, что мы будем называть i«итерациями». Остальная часть программы представляет собой гигантский цикл, который выглядит следующим образом:

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

Затем мы повторяем цикл с самого начала.

Стрелки ^>v<изменяют направление потока программы, а зеркала /\отражают направление потока программы.

НОД

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

Вот пример того, как может выглядеть программа> <> для игры в гольф. Еще раз, вы можете попробовать это в онлайн-интерпретаторе (например, введите два значения через запятую в поле «Начальный стек» 111, 87) или с помощью -vфлага интерпретатора Python, например

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

Эта программа использует евклидов алгоритм. Вот GIF, который я подготовил ранее:

введите описание изображения здесь

Обратите внимание, что> <> является тороидальным, поэтому, когда выполняется нижняя левая vинструкция, указатель инструкции опускается вниз, оборачивается и снова появляется сверху.


Редактировать: заставив код работать полностью справа налево , @randomra удалось побрить три байта с

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

Думаю, я не играл в гольф достаточно :)

Sp3000
источник
27
И так я узнал, что имя ><>палиндром.
Зев Айзенберг
33

2012 - Элемент

Это язык, который я изобрел в начале 2012 года как простой язык для игры в гольф. Под этим я подразумеваю, что перегрузка операторов практически отсутствует. Операторы также проще и их меньше, чем большинство современных языков для игры в гольф.

Наиболее интересными особенностями этого языка являются его структуры данных. Есть два стека и хеш, которые используются для хранения информации.

M-стек - это основной стек, где выполняются арифметические и большинство других операций. Когда данные вводятся или печатаются, это то, куда они идут или извлекаются.

C-стек является стеком управления. Это где логическая арифметика имеет место. Верхние значения c-стека используются циклами If и While в качестве условия.

Хэш - это место, где хранятся переменные. ;И ~хранить и извлекать данные из хэша, соответственно.

Элемент очень слабо типизированный язык. Он использует способность Perl свободно интерпретировать числа как строки и наоборот.

Пока я в этом, я мог бы также включить всю документацию для языка. Вы можете найти оригинальный переводчик 2012 года, написанный на Perl, прямо здесь . Обновление: я создал более удобную версию, которую вы можете найти прямо здесь .

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 \

Задача 1 - Распечатать текст

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

Одна из самых неудобных частей языка - отсутствие разделителей строк, поэтому в этой строке требуются escape-символы. В `конце печатает строку.

Задача 2 - ASCII Art N

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

Здесь вы увидите некоторые манипуляции со стеком. Чтобы облегчить форматирование объяснения, я заменим символ новой строки на Lи пробел на 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

После некоторой экстремальной игры с этим ответом я нашел 39-байтовое решение, хотя оно намного сложнее.

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

Задача 3 - GCD

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

Это стековый метод.

__                 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
PhiNotPi
источник
29

2012 - Юлия

История языка

Джулия была разработана в 2012 году Джеффом Безансоном, Стефаном Карпински и Вирал Шахом, в то время как Джефф учился в Массачусетском технологическом институте (MIT) под руководством профессора Алана Эдельмана. Они были мотивированы стремлением к языку программирования, который был бы открытым, быстрым и динамичным (среди прочего) при сохранении простоты использования в различных приложениях. Продуктом стала Джулия, свежий подход к высокопроизводительным научным вычислениям.

"Привет, мир!" Вариант

println("Julia was made in 2012!")

Печать на STDOUT в Юлии довольно проста!

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

Код имеет отступ для удобства чтения, но Юлия не накладывает никаких ограничений на пробелы.

НОД

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

Последняя вещь, перечисленная в функции, возвращается неявно.

Алекс А.
источник
27

1988 - Mathematica

Или я должен назвать это Wolfram Language ?

Задача 0

Создатель Mathematica - Стивен Вольфрам, основатель и генеральный директор Wolfram Research. До разработки Mathematica он был физиком. В физике было огромное количество алгебраических вычислений, поэтому он стал пользователем Macsyma .

Вольфрам получил докторскую степень в 1979 году, когда ему было 20 лет. Он подумал, что ему нужен лучший CAS, чем Macsyma, чтобы заниматься физикой, поэтому он начал писать SMP («Программа символьной манипуляции»). Первая версия SMP была выпущена в 1981 году. SMP была предшественницей Mathematica. Хотя это оказало глубокое влияние на Mathematica, ни один из его кодов никогда не использовался для Mathematica.

В 1986 году Вольфрам решил написать «окончательную вычислительную систему». Он начал писать код в 1986 году и основал Wolfram Research в 1987 году. Наконец, Mathematica 1.0 была выпущена 23 июня 1988 года.

Mathematica 1.0

Я не нашел Mathematica 1.0. На самом деле Mathematica 1.0 не имела ни версии для Windows, ни для Linux. Но я нашел Mathematica 2.0 на китайском сайте. Это все еще может быть запущено на Windows XP.

Mathematica 2.0

Задание 1

Print["Mathematica was made in 1988!"]

Или просто:

"Mathematica was made in 1988!"

Задача 2

В сегодняшней Mathematica мы можем написать:

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

Так же, как Юлия и R , это матричное решение. В Mathematica вы можете определить разреженную матрицу, используя сопоставление с образцом.

Однако он SparseArrayбыл представлен в Mathematica 5.0, поэтому мы не можем использовать его в Mathematica 1.0.

Вот решение, которое работает в 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];
]

Мы не можем писать, f[i_, 1 | i_ | n] = "N"потому что Alternativesбыл представлен в Mathematica 2.0.

Задача 3

Мы можем просто использовать встроенную функцию:

gcd = GCD

Или мы можем использовать определение GCD:

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

Или мы можем использовать LCM , хотя чаще всего LCM вычисляется из GCD:

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

Или мы можем использовать евклидов алгоритм с сопоставлением с образцом:

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

Или как анонимная функция:

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

Все вышеперечисленные функции были введены в Mathematica 1.0.

alephalpha
источник
3
Это гораздо лучший ответ, чем мой. Я удалю свою.
Мартин Эндер
25

1999 - XSLT

World Wide Web Consortium (W3C) создал XSLT для преобразования XML в HTML, текст и т.д. Следующие примеры предполагают ввод заключен в <input>..</input>тегах.

Задание 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>

Этот прост. Он соответствует inputтегу на верхнем уровне и заменяет его желаемым выводом.

Задача 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>

Этот определяет 2 рекурсивных шаблона, loopи spaces. loopс параметрами iи nсгенерирует желаемый результат n, начиная с позиции i. spacesс параметром nбудет генерировать nпробелы.

Задача 3

Вход для этого должен быть в <input><num>..</num><num>..</num></input>тегах.

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

Это просто рекурсивный шаблон, gcdкоторый использует евклидов алгоритм.

LegionMammal978
источник
И они говорят, что INTERCAL странно!
kirbyfan64sos
2
@ kirbyfan64sos Чтобы быть справедливым, это не должно использоваться для этого материала в любом случае ...
LegionMammal978
24

2014 - CJam

CJam был создан пользователем PPCG aditsu и был выпущен в апреле 2014 года .

"Привет, мир!" Вариант

"CJam was made in 2014!"

CJam автоматически печатает содержимое стека в конце программы

ASCII Art N

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

Объяснение кода:

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

Принимает высоту / ширину N в качестве ввода через STDIN. Попробуйте онлайн здесь

НОД

l~{_@\%}h;

Принимает два числа в качестве ввода через STDIN. Попробуйте онлайн здесь

оптимизатор
источник
Я понимаю, что это не [код-гольф], но вы можете сократить программу ASCII-art N до ri_S*0'NtW'Nta1$*\,Sf*'Nf+..e>N*современного CJam.
Esolanging Fruit
24

1990 - Haskell

Haskell - популярный (или я должен сказать: самый популярный ?) Чисто функциональный язык. Он выделяется из основного потока своей необычной моделью оценки (по умолчанию все лениво или, технически, не строго) и своей системой типов на основе Хиндли-Милнера, которая даже сейчас остается одной из самых мощных.

Задание 1

main = putStrLn "Haskell was made in 1990!"

Задача 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

Демонстрация, распечатайте весь бесконечный список (пока пользователь не прекратит работу или мир не закончится ...)

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

...

Конечно, вы можете легко добраться до одного из них, получив доступ только к одному элементу из бесконечного списка:

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

Задача 3

gcd' :: Integer -> Integer -> Integer
gcd' a 0 = a
gcd' a b = gcd' b $ a`mod`b
перестал поворачиваться против часовой стрелки
источник
23

1972 - ИНТЕРКАЛ

А ты думал, что Фортран и Кобол были странными. Это безумие!

Задание 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

Я не буду пытаться объяснить систему ввода и вывода INTERCAL; Просто прочитайте это и надеюсь, что вы не умрете.

Задача 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

Боже мой Это заняло у меня немного времени, чтобы понять. Номера этикеток - беспорядок и поэтому отражают это. Я не буду пытаться объяснить это, если кто-то не спросит.

Задача 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

Это немного проще. Из-за ... странности INTERCAL, вы должны ввести цифры, как это:

THREE FIVE

Например, чтобы получить GCD 42 и 16, я бы ввел:

FOUR TWO
ONE SIX

Он также печатает число римскими цифрами ... потому что это INTERCAL для вас!

kirbyfan64sos
источник
2
Разве это не должно быть 19 7 2? (Я могу понять, если у вас закружилась голова после написания этого: P) Ваш ответ считается недействительным из-за этой ошибки, что было бы позором.
Marinus
@marinus Спасибо! Исправлена!
kirbyfan64sos
5
Пожалуйста, объясните. (Когда у вас будет время, конечно.;)
DLosc
1
INTERCAL - мой любимый язык, который я никогда не изучал!
CJ Деннис
1
PLEASE GIVE UP, Я сделал это уже .-.
RedClover
23

1967 - APL

В 1957 году в Гарвардском университете Кен Айверсон начал разработку математической записи для манипулирования массивами. В 1960-х его нотация была превращена в язык программирования в IBM. Первая частичная реализация была создана в 1963 году, и она даже использовалась в старшей школе для обучения студентов трансцендентным функциям. Полная, пригодная для использования реализация должна была ждать до 1965 года. В течение двух лет она использовалась только внутренне IBM. В 1967 году IBM выпустила публичный интерпретатор APL, работавший на компьютере IBM 1130, который был закончен в 1966 году. Вы можете понять, как трудно выбрать год для этого, однако, я думаю, что это должен быть 1967 год, поскольку это первый год, полная реализация была сделана доступной для общественности. Если кто-то действительно не согласен, я могу это изменить.

Исходный код для APL \ 360, онлайн , как и эмулятор. Это то, что я использовал для проверки этих примеров. Он датируется 1967 годом, и наряду с APL \ 1130 (для вышеупомянутого IBM 1130) это более или менее настоящий оригинал. Как и следовало ожидать, это очень примитивно. В нем отсутствует поддержка таких тонкостей, как строчные буквы, любые операторы работают только со встроенными функциями, а набор встроенных функций очень редок (в частности, есть только or и не удваивается, как gcd). Оригинальное полное описание доступно здесь , однако я заметил, что версия, которую я имел, даже не полная в отношении этого документа, которой нет среди других.

Я предоставил программы как в формате Unicode (чтобы вы могли их прочитать), так и в оригинальной кодировке (чтобы вы могли вырезать и вставить их в окно APL эмулятора).

Невероятно, но эти программы работают правильно без каких-либо изменений (кроме кодировки) в современных версиях Dyalog, NARS2000 и GNU APL. Так что я думаю, что нашел способ написать переносной APL: просто притворись, что это 1967 год!

Задание 1:

Unicode:

⎕←'APL WAS MADE IN 1967!'

APL \ 360:

L[Kapl was made in 1967ÝK

Задача 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'

Задача 3:

Я решил это стандартным рекурсивным способом. Теоретически, вы могли бы сделать что-то умное и ориентированное на массив, как ответ J; на практике, однако, он использует O (N) памяти и быстро перегружает аппаратное и программное обеспечение эпохи 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
Мэринус
источник
Это круто.
Алекс А.
22

1996 - Окамль

Ждал больше суток, чтобы кто-нибудь заполнил 1996 год, чтобы я мог заполнить Ruby. Ну, почему бы не изучить OCaml тогда, похоже на haskell ...

Привет, мир

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

Изменчивые строки!

НОД

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

Нет ==и инфикс mod, это мило

рассекать
источник
Извините, я залил Ruby :)
Zero Fiber
4
+1 за изучение языка, чтобы ответить на этот вызов. :)
Алекс А.
Вы только что выучили F # тоже! (это OCaml на CLR плюс некоторые дополнения).
Роберт Фрейзер
22

2005 - Прелюдия

Prelude - очень забавный язык, исходный код которого состоит из нескольких «голосов», которые исполняются параллельно и в которых мне действительно нравится решать проблемы . Он предназначен для представления ASCII его родного языка Fugue , который фактически принимает файлы .midi в качестве исходного кода и кодирует инструкции, найденные в Prelude, в качестве интервалов в мелодиях голосов.

Прелюдия довольно минималистична, но Тьюринг завершен (при условии, что вы используете как минимум 2 голоса). Как я уже сказал, голоса (строки кода) выполняются одновременно, столбец за столбцом. Каждый голос работает в своем собственном стеке, который инициализируется бесконечным числом нулей. Prelude поддерживает следующие инструкции:

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

Некоторые дополнительные заметки:

  • Голоса циклические, поэтому ^верхний голос копирует с нижнего голоса (и наоборот).
  • Несколько ?и !в одном столбце выполняются сверху вниз.
  • Согласно спецификации языка , ?и !читать и писать символы с соответствующим кодом символа. Однако интерпретатор Python также имеет в своем коде переключатель для печати самих чисел. В целях тестирования я на самом деле использую модифицированную версию, которая также может читать цифры вместо символов. Но консенсус здесь заключается в том, что числовой ввод / вывод фактически может быть задан в виде байтовых значений, поэтому эти модификации не являются необходимыми для создания допустимых программ, работающих с числами.
  • Соответствующие (и )не должны быть на одном голосе. Голос, используемый для условия, всегда тот, где (появляется. Следовательно, вертикальное положение )совершенно не имеет значения.
  • Из-за природы одновременного выполнения Prelude любая инструкция в том же столбце, что и a (, выполняется только один раз перед началом цикла и независимо от того, введен ли цикл. Точно так же любая инструкция в том же столбце, что и a ), выполняется в конце каждой итерации, независимо от того, будет ли цикл завершен после этой итерации.

Сначала я покажу вам три программы без особых комментариев. Вы можете найти подробные объяснения ниже.

Программы

"Привет, мир!" Вариант

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

Если вы используете интерпретатор Python, убедитесь в этом 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#

Для удобства использования эта программа получает преимущества от чтения ввода в виде чисел, но вывод не должен быть числовым. Так что если вы используете модифицированный интерпретатор Python, установите

NUMERIC_INPUT = True
NUMERIC_OUTPUT = False

НОД

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

Это лучше всего использовать со всеми числовыми входами / выходами, т.е.

NUMERIC_INPUT = True
NUMERIC_OUTPUT = True

Пояснения

"Привет, мир!" Вариант

Это довольно просто. Я использую 3 голоса, чтобы последовательно генерировать коды символов для всех символов в Prelude was made in 2005!. Я начинаю с вычислений 8 + 9*8 = 80, которые представляют собой код символа P:

 9(1-)
 8 8+

После этого я в основном просто копирую предыдущий код символа и добавляю или вычитаю разницу к следующему. Вот код, но с каждым !заменяется символом, который печатается (и _для пробелов и %для цифр):

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

Финал 55+!печатает завершающий перевод строки только потому, что он лучше.

Как примечание, количество голосов для этой задачи довольно произвольно, но 3 довольно удобно, потому что это наибольшее число, при котором каждый голос может напрямую получить доступ к голосу друг друга.

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#

С 5 голосами, это определенно одна из самых сложных программ, которые я написал до сих пор. Голоса примерно имеют следующие цели:

  1. Просто вспомогательный голос, который хранится N-1для использования во внутреннем цикле.
  2. Это своего рода «основной» голос, который читает ввод, содержит важный переключатель, а также содержит внешний цикл (т. Е. Цикл над строками).
  3. Это 32позволяет удобно печатать пробелы.
  4. Содержит внутренний цикл (тот, что над столбцами).
  5. Это сохраняет 78для удобной печати Nс.

Давайте рассмотрим код по частям. Во-первых, я создаю 32как -4 + 9*4и 78как 6 + 9*8:

9(1-)
4-4+

6 8+

Теперь я печатаю один N(потому что он всегда нужен) во время чтения ввода Nи сохранения N-1и N-2первых двух голосов:

      v2-
     ?1-

     v!

Далее есть условная петля N-1. В конце цикла второй голос всегда уменьшается до 0, и цикл завершается после первой итерации. Так что по сути, это только if(N > 1){...}. После цикла мы печатаем один завершающий перевод строки. Напомним, что теперь у нас есть следующая структура:

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

Внутри этого условия мы сначала N-2пробелы и один Nдля завершения первого ряда, и мы также сохраняем N-1первый голос для будущего использования:

         (1-)v         
          v!  

             v!

Теперь настоящее мясо кода. Во-первых, есть внешний цикл, который печатает N-1строки. Для каждой строки мы сначала печатаем новую строку и N. Затем мы зациклим N-2время, печатая либо пробелы, либо Ns (подробнее об этом позже). И наконец мы печатаем другое N:

               1-55+!  

                v1-v!(               )v!
               v#

Наконец, самое интересное: печать каждой строки (и получение Nправильной позиции ). На самом деле в Prelude нет if / else, поэтому я должен создать его сам, используя два цикла для разных голосов. Условие может быть легко получено путем вычитания переменной внутреннего и внешнего цикла - мы получаем, 0если хотим печатать, Nи что-то ненулевое, если хотим печатать пробел.

Основная идея if / else в Prelude состоит в том, чтобы поставить цикл после соответствующего значения - кода «if» (или отличного от нуля) и немедленно выйти из него, нажав a 0. В другом голосе вы сохраняете ненулевое значение и еще один цикл после цикла «если». Во время цикла «if» вы ставите ноль поверх этого другого голоса, чтобы предотвратить выполнение «else». Существует некоторая гибкость в том, помещаете ли вы нулевые значения поверх ненулевых значений или просто отбрасываете ненулевое значение, если ниже ноль, но это общая идея. Возможно, вам также придется выполнить некоторую очистку после этого, если вы хотите продолжать использовать соответствующий голос. Вот как выглядит код:

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

Вот и все!

НОД

Это «просто» итеративная реализация евклидова алгоритма. Но модуль в Prelude немного раздражает, в основном потому, что вы не можете легко проверить, является ли число положительным или отрицательным. Этот код делает использование сигнум реализации я написал некоторое время назад . Т.е. большая часть кода просто превращает число в -1, 0или 1. Это можно легко превратить в условие для положительных или отрицательных чисел путем сложения или вычитания 1.

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

Так что на этот раз у нас четыре голоса. Первый голос просто отслеживает bи содержит основное условие завершения (т. Е. Цикл завершается, когда bстановится 0). Второй голос содержит aи с помощью голосов три и четыре вычисления a % b, прежде чем поменять местами результат с предыдущим b. Наконец, !печатает aкогда b == 0.

Давайте сначала посмотрим на часть signum :

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

Номер ввода nнаходится на первом из этих голосов (второй голос в полной программе). Результат закончится на нижнем голосе. Ожидается, что два других голоса будут пустыми (то есть заполнены нулями). Обратите внимание: если n == 0оба цикла пропускаются, а нижний голос все еще содержит то 0, что мы хотим.

Если nне ноль, вводится первый маленький цикл. Мы нажимаем ноль, чтобы немедленно выйти из него, помещаем две копии nв средний голос и 1в нижний голос. Теперь основная идея состоит в том, чтобы увеличивать одну из копий n, уменьшая другую, nпока одна из них не достигнет нуля. При этом 1нижний голос постоянно переворачивает свой знак (что легко сделать, вычтя его из- 0под стека). Это настроено так, что когда одно из чисел достигает нуля, нижний голос будет содержать правильный знак.

Теперь по модулю реализуется вычитание bот aдо отрицательного результата. Когда это произойдет, мы добавим еще bраз. Вот это немного:

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

Обратите внимание на конструкцию if / else внизу, которая похожа на ту, которую я использовал для Задачи 2.

Мартин Эндер
источник
2
Это действительно должно быть частью учебника Prelude.
Алекс А.
21

2007 - Царапина

Scratch - это язык, созданный MIT для образовательных целей. Я был очень связан с этим в течение 5 лет; Подробнее об этом позже.

Все это можно посмотреть здесь .

Я очень спешу прямо сейчас и объясню фрагменты позже. Надеюсь, они все же говорят сами за себя.

Задание 1

введите описание изображения здесь

Задача 2

введите описание изображения здесь

Задача 3

введите описание изображения здесь

Scimonster
источник
Это еще позже?
dfeuer
21

1972 - С

Мы все знаем о Си, не так ли? C был создан в Bell Labs вместе с Unix. Unix был в основном написан на C. Все современные производные Unix все еще в основном написаны на C. Синтаксис C повлиял на многие, многие языки программирования. Это, вероятно, самый старый язык программирования, который все еще широко используется для новых разработок.

Сам C является потомком B, который, я надеюсь, также окажется в этом списке. Не было никакого языка программирования 'A': B - это вариант BCPL, который, в свою очередь, является сокращенным CPL. Ни один из этих языков никогда не был очень популярен. Тем не менее, BCPL был языком, на котором была написана первая программа «Hello World». Другим интересным фактом является то, что у B были /* */и //комментарии и комментарии, но C отбросил //комментарии. Позже они были вновь введены в C со стандартом C99.

Здесь C-программы тестировались на C-компиляторе Unix V5 с 1974 года. Это был самый старый C-компилятор, который я смог найти и приступить к работе, и эти программы не будут компилироваться на современном C-компиляторе. (Одно из внесенных изменений заключается в том, что операторы мутации, такие как +=раньше, были написаны =+.)

#include <... >еще не существовало. Ни один не сделал большую часть стандартной библиотеки. Я должен был написать свой собственный atoi. Я просмотрел некоторый исходный код V5, чтобы выяснить, какие вещи были разрешены, а какие нет. Версия, которую я использовал, была первой, чтобы включить structs, но так как я не использовал их, и синтаксис, кажется, не сильно изменился до V7 (как K & R C), это могло бы работать и с более ранними версиями.

Я приложил все усилия, чтобы написать свой код в том же стиле, который использует исходный код V5. (Не то чтобы это ужасно непротиворечиво.)

Посмотрите здесь ссылки на Unix V5, эмулятор, а также инструкции по получению его работы на современном компьютере.

Задание 1

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

Задача 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]));
}

Задача 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])));
}
Мэринус
источник
Ух ты, я так и не понял, насколько сильно изменился Си ... Откуда ты взял этот компилятор?
kirbyfan64sos
1
Компилятор входит в состав Unix V5. В описании есть ссылка на пост в блоге, который показывает, где взять файлы и как их запустить на современном компьютере. (Это здесь ). После того, как вы запустили его, вы можете получить на него код, используя cat > file.c. (Конец с Ctrl-D, как всегда). Кроме того , C изменился меньше , чем вы могли бы подумать: если вы своп =*и =+в atoiфункциях для современных эквивалентов *=и +=, современный GCC компилирует их просто отлично , и они бегут, тоже. Вряд ли каких-либо предупреждений, даже.
марин
1
minnie.tuhs.org/cgi-bin/utree.pl?file=V2/c - самый ранний компилятор C, который я смог найти (из V2, датированного 72 годом).
Оберон
20

2009 - Идрис

Idris - это чисто функциональный язык с зависимой типизацией, который подчеркивает, что фактически может использоваться практически для реальных приложений, кроме того, что предлагает чрезвычайно строгие возможности проверки, которые достижимы с зависимыми типами.

Задание 1

module Main

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

Задача 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

Это не программа, а просто функция (точнее, зависимое значение ), производящая искомую букву N в виде двумерного массива.

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

Задача 3

module gcd

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

Обратите внимание, что мне пришлось выбрать имя, gcd'потому что, как gcdоно уже определено в прелюдии Idris.

Type checking ./gcd.idr
*gcd> gcd' 8 12
4 : Nat
*gcd> gcd' 12 8
4 : Nat
*gcd> gcd' 234 876
6 : Nat
перестал поворачиваться против часовой стрелки
источник
Это похоже , что они взяли Haskell, места :и ::, и изменены _в Z.
wchargin
@WChargin Zна самом деле конструктор 0 : Nat. Подчеркивание используется в Идрисе так же, как в Хаскеле.
перестал поворачиваться против часовой стрелки с
о, ну вот и все! :)
wchargin
19

2014 - Pyth

Поскольку у нас есть CJam, у нас также может быть Pyth для полноты :)

Pyth - это язык игры в гольф от @isaacg, который составлен из Python. Он примечателен процедурностью и использованием префиксных обозначений. Pyth впервые появился около июня 2014 года .

"Привет, мир!" Вариант

"Pyth was made in 2014!

Обратите внимание на отсутствие закрывающей кавычки, которая является необязательной, если программа Pyth заканчивается строкой.

ASCII Art N

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

Попробуйте онлайн . Эквивалент Python:

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

Или расширенный (первая и третья строки неявны):

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

НОД

=GvwWQAGQ,Q%GQ)G

Эта программа использует евклидов алгоритм и принимает два числа, разделенных новой строкой. Попробуйте онлайн .

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

i.uQеще короче, если мы используем встроенный для GCD. Это эквивалентно print(gcd(*eval(input())))(принимая два числа через запятую в качестве входных данных).

Sp3000
источник
Драт - я собирался сделать
Pyth
@isaacg Я не могу не задаться вопросом, и с таким же успехом могу спросить здесь: вдохновлял ли Pyth каким-либо образом, формой или формой?
Aprıʇǝɥʇuʎs
@ ɐɔıʇǝɥʇuʎs Я видел PYG до создания Pyth, и это, возможно, повлияло на концептуальный подход «1 символ - 1». Однако, если что-то вдохновляло Пита, это, вероятно, был сценарий для гольфа.
Исаак
17

1964 - Дартмутский бейсик

BASIC - это семейство языков программирования высокого уровня общего назначения, философия дизайна которых подчеркивает простоту использования. В 1964 году Джон Дж. Кемени и Томас Е. Курц разработали оригинальный язык BASIC в Дартмутском колледже в Нью-Гемпшире. Они хотели, чтобы студенты в других областях, помимо естественных наук и математики, могли использовать компьютеры.

Я смотрю на это руководство по бейсику 1964 года и на эмулятор Darthmouth Time Sharing System, на котором он работал. Сервер все еще работает, но, к сожалению, регистрация учетной записи кажется невозможной. Пока эти программы теоретически должны работать:

Задание 1

10 PRINT "BASIC WAS MADE IN 1964"
20 END

Задача 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

Вывод что-то вроде:

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

Обратите внимание, как ввод вводится как часть программы ( 70 DATA 5); READпуть инструкции в верхней части извлекает данные оттуда. Конкатенация строк отсутствует, но в разделе 3.1 руководства описано, как PRINTрезультаты записываются в табличные «зоны» на выходе.

Задача 3

Медленная версия алгоритма Евклида:

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

Выведение:

2
Линн
источник
Наконец-то кто-то сделал бейсик.
Marinus
16

2010 - WTFZOMFG

WTFZOMFG - это эзотерические языки, основанные на Brainfuck. Это было сделано Джеем Сонгдалем в 2010 году. «WTFZOMFG» - это сокращение от «Что это за функция? ,

Вот компилятор для * nix систем .

Задание 1

'WTFZOMFG was made in 2010!\n"

Задача 2

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

Объяснение:

Сожалею. Я не умею писать объяснения.

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

Задача 3

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

Евклидов алгоритм WTFZOMFG не имеет команды для мода, поэтому я должен использовать d(делить), m(умножить) и s(вычитать).

alephalpha
источник
16

2009 - Go

Go - это язык программирования, разработанный Google. Разработка началась в 2007 году, но Go был объявлен в ноябре 2009 года.

Go - это статически типизированный язык, на который влияет C, который подчеркивает лаконичность, простоту и безопасность.

Задание 1:

package main
import "fmt"

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

Первая строка объявляет пакет кода. Даже простой пример, когда печать одной строки должна быть частью одной упаковки. И исполняемый файл всегда вызывается main.

Задача 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 имеет довольно краткое объявление переменной (так i := 0же, как var i int = 0), и компилятор определяет тип. Обычно эта функция чаще встречается в динамических языках. Используя эту короткую запись, также очень легко назначать функции для переменных ( f := func(x int) int {/* Code */}) и создавать замыкания.

Задача 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))
}

Здесь вы можете увидеть a, b = b, a%bсинтаксис, который действительно хорош. Я не знаю точного имени, но в Python это называется распаковка кортежей. Используя тот же способ, вы можете вернуть несколько значений из функции ( func f() (int, string) { return 42, "Hallo"}).

Еще одна вещь, происходящая в этом коде - это цикл. Цикл for - единственный цикл в Go. Циклы while или do-while-loop не существуют. Но вы можете легко создать эквивалент для цикла while for condition {}или бесконечного цикла for {}.

Jakube
источник
16

1991 - Питон

История языка

В конце 1980-х Гвидо ван Россум начал разрабатывать Python как хобби. Его название происходит от летающего цирка Монти Пайтона, британского телешоу, поклонником которого Россум. Первое внедрение Python началось в 1989 году и было выпущено в 1991 году. За последние годы его популярность возросла, и он стал языком выбора для многих вводных курсов по информатике.

"Привет, мир!" Вариант

print("Python was made in 1991!")

Обратите внимание на круглые скобки вокруг ввода в print. Хотя этот синтаксис работает в Python 2, обычно в Python 2 эти скобки опускаются. Однако они требуются в Python 3. Как предполагает Zach Gates, круглые скобки используются повсеместно, чтобы гарантировать, что код, представленный здесь, будет работать в разных версиях.

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

Функции определены с помощью def. Конкатенация строк выполняется с использованием +и повторения строк с *.

НОД

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

Обратите внимание, что Python требует структурированного пробела.

Алекс А.
источник
16

1968 - Алгол 68

Algol 68 был определен рабочей группой IFIP 2.1 как преемник Algol 60.

Это язык, ориентированный на выражения, в котором все имеет ценность. Он также ортогональн, в котором вы можете использовать любую конструкцию любым способом. Это означает, что выражения могут быть, например, в RHS и LHS присвоения.

Все управляющие структуры имеют сокращенную форму, а также длинную форму с использованием выражений. Это также позволяет определения операторов.

Цели языка цитируются как:

Основные цели и принципы дизайна ALGOL 68:

  • Полнота и ясность описания
  • Ортогональный дизайн,
  • Безопасность,
  • КПД
  • Проверка статического режима
  • Независимый от режима синтаксический анализ
  • Независимая подборка
  • Циклическая оптимизация
  • Представления - в минимальных и больших наборах символов

Эти программы были протестированы с помощью интерпретатора Algol 68 Genie , который является полной реализацией языка.

Некоторые особенности, которые современные программисты могут найти разными, заключаются в том, что пустые операторы не допускаются. Вы не можете просто добавить ;везде. Вы должны использовать это SKIPутверждение, если хотите явно ничего не иметь. Это также позволило очень легко кодировать параллельные программы. Алгол 68 также, в частности, использовал обратные ключевые слова в качестве терминаторов, таких как esac , od , fi и т. Д.

Язык имел представление, используемое для написания кода, который использовал много шрифтов, представляющих ключевые слова, выделенные жирным шрифтом , и идентификаторы, выделенные курсивом , например. В то время, и, вероятно, до сих пор, ни один компилятор не реализовал эту функцию дизайна. Язык допускает несколько разных конкретных представлений программ, использующих режимы обрезки . Это позволило программам быть подготовленными с использованием ограниченных наборов символов, которые можно было найти в компьютерах в 1960-х годах. Рассмотрим короткий фрагмент программы, который будет представлен в виде:

если я < 0, то пропустить фи

Это может быть подготовлено для компилятора в режиме простого обрезания как:

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

В режиме точечного обтекания это будет:

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

В случае режима обрезки это будет:

IF i < 0 THEN SKIP FI

Мне очень нравится этот язык, так как я работал над одной из реализаций компилятора, а также программировал на нем исключительно много лет.

Задание 1

печать ((«Алгол 68 был сделан в 1968 году!», перевод строки ))

Здесь следует отметить двойные скобки. Это связано с тем, что print - это функция, которая принимает единственный аргумент, который является массивом переменной длины объединения всех типов. Внутренние скобки - это конструктор массива. Вот как полиморфизм обрабатывается в этом строго типизированном языке.

В случае стропинга:

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


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

Задача 2

     int n ;
     читать (( n ));
     для i от 1 до n сделать
          для j от 1 до n сделать
               ¢ здесь мы используем сокращенное предложение IF ¢
               print ((( j = 1 ИЛИ j = i ИЛИ j = n |
                    "N"
               |
                    ""
               )))
          od ;
     печать (( новая строка))
     од

В случае стропинга:

 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

Задача 3

     ¢ мы можем определить наши собственные операторы в Algol 68 ¢
     op % = ( int a , b ) int :
          (( b = 0 |
               a
          |
               b % ( a mod b )
          ));
     int i , j ;
     читать (( i , j ));
     печать (( i % j , новая строка ))

В случае стропинга:

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
Вероятно, это были первые программы на Алголе-68, которые я написал и выполнил за последние 30 лет. Я нашел это настолько трогательным, что это действительно привело меня к слезам. Я никогда не понимал "Привет, мир!" Программа может быть такой эмоциональной!
Брайан Томпсетт - 莱恩 莱恩
1
Я так с нетерпением ждал Языки 60-х и был готов к BCPL, Simula, CORAL66, Fortran 66, PL / 1, SNOBOL4, POP-1 и еще целому плоту, только чтобы обнаружить, что правила таковы, что у меня есть ждать 5 лет языков ... По крайней мере, есть богатая борозда, которую кто-то еще может пахать.
Брайан Томпсетт - 莱恩 莱恩
Действительно здорово видеть различия между Fortran66 (полный беспорядок насилия с перфокартами), APL (странный беспорядок символов сверхдержав) и Algol68, который на самом деле довольно красив. Сегодня вам нужно заглянуть в эзотерические языки, чтобы найти такое разнообразие подходов ... тогда это было довольно распространенным явлением, не так ли?
перестал поворачиваться против часовой стрелки
Конечно, пересмотренный отчет не был опубликован до 1976 года, не так ли? По крайней мере, это год авторского права, который дает Springer. И скан, который я нашел, упоминает 1978 год.
Риальто
[1] A. van Wijngaarden (ed.), Bl Mailloux, 1.EL Peck, CBA Koster, Доклад об алгоритмическом языке ALGOL 68, Numer. Математика 14 (1969) 79-218; также в Kibenietika 6 (1969) и 7 (1970). [2] A. van Wijngaarden, Bl Mailloux, 1.EL Peck, CBA Koster, M: Sintzoff, CBLindsey, LGLT Meertens и RG Fisker, пересмотренный отчет по алгоритмическому языку ALGOL 68, Acta Informat. 5 (1975), части 1-3 (перепечатки опубликованы издательством Springer, Berlin, а также в качестве математического центра Tract 50 издательством Mathematisch Centrum, Амстердам); также в уведомлениях SIGPLAN 12 (5) (1977)
Брайан Томпсетт - 莱恩 莱恩
16

1962 - СНОБОЛ

«Стринг-ориентированный и символический язык». Сначала, по-видимому, он назывался «интерпретатор символических выражений», «SEXI», который затем нужно было изменить, чтобы не дать покрасневшим ботаникам эпохи 1960-х при представлении их работы. Правдивая история.

Это был один из первых языков, который мог иметь дело со строками и шаблонами изначально. Действительно, первая версия SNOBOL имела строку как единственный тип данных. Математика была тогда сделана, анализируя. Первоначальная реализация была сделана на IBM 7090. Кажется, она давно прошла, по крайней мере, я не смог ее найти. Что я нашел, так это оригинальную статью, описывающую это, а также интерпретатор SNOBOL3 на Java, который может работать на современном компьютере .

Первый SNOBOL имел в основном только сопоставление с образцом и базовую арифметику. SNOBOL 3 затем добавил функции и изменил ввод / вывод, но в остальном, похоже, остался обратно совместимым. SNOBOL 4 изменил синтаксис, и оттуда он превратился в Icon , который поддерживает сопоставление с образцом, но в остальном выглядит почти как «нормальный» язык программирования.

В написанных мною программах используются только функциональные возможности, описанные в оригинальной статье, поэтому они должны работать с исходным SNOBOL, за исключением ввода-вывода, который я сделал в стиле SNOBOL3, чтобы интерпретатор Java мог их запускать. Из статьи видно, что различие заключается в том, что SNOBOL1 использует сопоставление с шаблоном со специальной SYSпеременной, тогда как SNOBOL3 использует входные и выходные переменные:

  • Входные данные:
    • 1 SYS .READ *DATA*
    • 3 DATA = SYSPPT
  • Выход:
    • 1 SYS .PRINT 'A STRING' AND VARIABLES
    • 3 SYSPOT = 'A STRING' AND VARIABLES

Сделав эти замены, вы получите «настоящий» SNOBOL 1. Конечно, тогда вы не сможете его запустить.

Задание 1

START   SYSPOT = 'SNOBOL WAS MADE IN 1962!'

Задача 2

Это показывает математику, обработку строк и управление потоком. SNOBOL3 имеет полезные функции, такие как EQпроверка равенства; оригинальный СНОБОЛ не сделал, поэтому я не использовал их.

* 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     

Задача 3

Во-первых, скучный. Единственное, что следует отметить, это проверка меньше, чем, точно показывающая, как на самом деле был ориентированный на строки SNOBOL: (B - A) '-'означает «содержит ли результат BA минус?». SNOBOL3 тоже может LE(B,A), а SNOBOL 1 - нет (по крайней мере, в статье это не упоминается).

* 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

Конечно, когда у вас есть язык, полностью основанный на строках и сопоставлении с образцом, было бы стыдно не использовать сопоставление и замену образца. Таким образом, вот одна из тех унарных основанных GCD, включая процедуры для преобразования в унарные и из них.

* 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
Мэринус
источник
Отличная справочная работа! Не много для 1961 года - похоже, COMIT - это все, что у нас есть ...
Брайан Томпсетт - 莱恩 莱恩
15

2012 - TypeScript

TypeScript - это бесплатный язык программирования с открытым исходным кодом, разработанный и поддерживаемый Microsoft.

Основная цель: любой браузер. Любой хост. Любая ОС. Открытый исходный код. Выпущена в октябре 2012

Привет TypeScript

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

ASCII Art

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

НОД

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

попробуйте это онлайн , и показ этого.

vrluckyin
источник
4
Вы забыли упомянуть одну вещь: TypeScript - это расширенный набор Javascript с небольшим количеством изменений синтаксиса и допускает (?) Строго типизированные переменные и аргументы.
Исмаэль Мигель
1
Боже мой, что-то с открытым исходным кодом от MS!
Мега Человек
15

2011 - Дарт

Dart - это язык программирования с открытым исходным кодом, разработанный Google, который разработан в качестве замены Javascript (хотя он компилируется в javascript). Он был представлен Google в 2011 году во время конференции GOTO.

"Привет, мир!" Вариант:

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

ASCII Art N:

Метод грубой силы работает с 0 (n²), но это не должно иметь большого значения, если вы не используете гигантское число.

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

НОД

простой метод Евклида, перенесенный из Snap! пример выше.

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);
            }
        }
    }
}
Nzall
источник
5
Я не думаю, что вы можете вывести ASCII-изображение × n меньше, чем O (n²).
Пажло Эберманн
@ PaŭloEbermann Я не очень хорошо знаком с большими обозначениями O или с тем, как вычислять сложность, но пример Джулии выглядит так, как будто это не O (n²).
Nzall
@AlexA. Функция println () печатает строку из n символов. Я думаю, что для вызова функции требуется как минимум время O (n) для выполнения. В цикле O (n²) для всей программы.
Паŭло Эберманн
@AlexA. Я думаю, что Эберманн говорит о том, что в вашей функции печати есть N операций конкатенации строк. мы оба делаем n² конкатенации строк в наших функциях. Я делаю их один раз за каждую итерацию внутреннего цикла, вы делаете их для каждого println ().
Nzall
1
Если бы это не было ascii art, было бы O (n), чтобы отобразить N. (рисуйте 3 строки на экране, каждая строка - O (n), следовательно, O (n) сложность). Или, можно сказать, рендеринг N имеет сложность O (N) ... хе-хе
rodolphito
15

2010 - ржавчина

Rust - это универсальный мультипарадигмальный скомпилированный язык программирования, разработанный Mozilla Research. Он разработан, чтобы быть «безопасным, параллельным, практическим языком», поддерживающим чисто функциональный, конкурентно-действующий, императивно-процедурный и объектно-ориентированный стили. Википедия

Задание 1

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

Task2

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

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

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

Объяснение:

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

заботится о печати только по вертикали (слева и справа |) и по диагонали ( \)

Задача 3

простая реализация 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;
}
wasikuss
источник
Не могли бы вы добавить фрагмент, показывающий, как ввести два целых числа через пробел из стандартного ввода?
Ноль волокна
3
Был ли Rust "сделан" в 2010 году? Временная шкала языков программирования говорит об этом, но в настоящей статье говорится, что она была анонсирована только в 2010 году (фактически 2011 год, о чем свидетельствует ссылка ), и что версия 0.2 была выпущена в 2012 году.
EMBLEM
1
@SampritiPanda, взгляните на hastebin.com/raw/lapekowogu
wasikuss
1
Выглядит немного современно. Может ли он скомпилировать его в первой <s> выпущенной </ s> опубликованной рабочей версии компилятора?
Ви.
15

2015 - Маффин MC

Muffin MC - полный по Тьюрингу, забавный (но серьезный), функциональный и минималистичный макроязык, написанный Франком Порчером ( http://franckys.com ) в середине февраля 2015 года из-за необходимости в качестве (быстрого) инструмента для расширения возможностей электронная таблица, которая будет использоваться как единственный интерфейсный контроллер для пилотирования и управления всеми операциями, связанными с инвентарем, связанными с торговым сайтом в Prestashop для нового таитянского модного бренда: Mutiny Tahiti ( http://mutinytahiti.com - скоро будет запущен).

Muffin MC является аббревиатурой MU крошечного F Функционального F lexible В линии M Acro C ommand языка.

Чтобы удовлетворить наши требования, основные функции Muffin MC были разработаны на основе гибких и эффективных встроенных семантических конструкций первого класса, таких как итераторы , ленивые вычисления , мультифункциональные функции , строковый продукт .

Muffin MC берет свое начало в (прагматическом) функциональном программировании, FLisp и Perl. Он полностью поддерживает рекурсивность (без какой-либо оптимизации), динамически типизирован и динамически ограничен (мелкое связывание). Он предлагает своим пользователям только одну структуру данных, кроме основных типов данных атомов (атомы, строки, цифры): списки!

Muffin MC семантика списка (вид) заимствует на семантике набора мощности , то есть:

  1. Все операции Muffin MC дают список, возможно, пустой.
  2. Доступ к любому отдельному элементу списка всегда дает список из одного значения, составленный из этого элемента (воспринимайте его как одноэлементный).
  3. Пустой список является нейтральным элементом в операциях со списком.

Чтобы с этим смириться, может помочь следующее:

  • Можно представить список как элемент набора мощности списка, который имеет наибольшее количество элементов.
  • Визуализируйте элемент списка как элемент набора мощности списка, который является единственным элементом, сделанным из этого элемента.
  • Визуализируйте пустой список как пустой набор; то есть единственный элемент набора мощности пустого набора.

Таким образом, доступ к пустому элементу списка приводит к пустому списку, а не к ошибке! Действительно, Muffin MC старается выбросить как можно меньше ошибок, расширяя таким образом семантику многих традиционных операций.

Задание 1

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

#(...)макрокоманда Muffin MC для применения функции в списке непроверенных аргументов, здесь встроенная функция say, заимствованная из Perl.

#(say 1 2 3 ...) функционально идентичен map {say $_} (1,2,3,...)

Задача 2

Определите функцию 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()Кратчайшая рабочая форма (88 байт):

=(f'(=(* x#(2-)I I(*($(x)" ")N)g'(#(.#(I$(x)))))#(say?(#(==$(_1)1)N"N#(map g#(..))N"))))
  • =(var val...)макрокоманда Muffin MC для определения переменной или ее переназначения.

  • $(var)макрокоманда Muffin MC для доступа к значению переменной Он естественно принимает форму $(v1 v2 ...)для доступа ко многим переменным одновременно.

  • =(* var1 val1 var2 val2 ...)является расширением макрокоманды Muffin MC=(...) для работы с параллельными назначениями.

  • Переменные _1, _2, ... динамически ограничены (механизм поверхностного связывания) и автоматически устанавливаются для привязки к аргументам функции. Заимствованные из Perl5, системные переменные #(количество аргументов) и @(список аргументов) также устанавливаются автоматически.

  • Функции - это просто переменные, связанные с любым количеством операторов MC Muffin .

Это интересное решение происходит из сочетания двух естественных встроенных функций Muffin MC :

  1. Макрокоманда Muffin MC I(...) для определения циклических итераторов, которые впоследствии используются с функциональной формой #(my-iterator want-number-of-values),

  2. Сдобы MC -струнной продукт конструкция, расширение естественной переменной интерполяции, который, принимая любую строку "F1 F2 F3...", где F я s являются либо булочка MC строковые литералы или булочка MC макрокоманды (ака функциональные формы), будет производить столько же строк , как дается произведение кардинал (F1) х кардинал (F2) х ....

Например, если задана переменная xa, которая содержит 2 значения, говорит a и b, а y, а другая переменная, которая содержит 3 значения, говорит, 1 2 3, то при вычислении строки "x=$(x) y=$(y))"будет получено 6 различных значений, а именно в таком порядке:

  • "Х = ау = 1"
  • "Х = ау = 2"
  • "Х = ау = 3"
  • "Х = с = 1"
  • "Х = от = 2"
  • "Х = от = 3"

Это одна из самых желанных функций проекта MUTINY, для которой был разработан Muffin MC .

Запустить его !

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

Как это работает

Наш алгоритм основан на следующем:

Учитывая вызов ascii-art (n), {n = 2p + 1 | p integer, p> = 0}, искусство для генерации содержит n строк из n символов, среди которых два, самый левый и самый правый, являются фиксированными и всегда одинаковыми: «N». Это позволяет уменьшить проблему при создании только средних струн. Например, при n = 5 мы бы пропустили 5 следующих средних строк, каждая из которых состоит из n-2 символов (мы заменили пробел на '_' для лучшей визуализации):

    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 |
                                _ _ _
  • Такие средние струны можно легко получить, циклически повторяя последовательность из 4 элементов ('_' '_' '_' 'N')в 5 группах по 3; При заданном n входе функции такая последовательность состоит из n-2 символов '_', за которыми следует символ 'N'. Для циклического перемещения по этой последовательности ничего не требуется, кроме как встраивать последовательность во встроенный итератор Muffin MC I(sequence) (итератор, который постоянно циклически повторяет свою начальную последовательность значений).

  • Затем мы просто создаем средние строки длиной n-2, запрашивая у нашего итератора следующие n-2 значения (n - 2 символа), которые объединяются для получения ожидаемой средней строки.

  • N средних строк получают, повторяя n раз вышеописанный процесс, используя карту для сбора n результатов (n строк из n-2 символов).

  • Мы используем еще один мощный сдобы MC встроенный в конструкцию, а именно строку продукта , чтобы получить окончательные строки п: "N#(map...)N".

  • Вот и все !

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

Задача 3

Определите функцию gcd():

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

gcd()«s реальная кратчайшая форма (37 байт - 2bytes усиление благодаря Rodolvertice)

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

Запустить его !

#(gcd 225 81)

дает 9.

Вот и все.

Спасибо за хорошую игру и, возможно, за ваш интерес. Язык доступен для любого, кто хотел бы поиграть, использовать его или даже расширить его. Просто попросите об этом, и я буду рад отправить его.

ура

Franck


PS. Текущая реализация Muffin MC находится в Perl5. Исходный код содержит около 2000 строк современного Perl, включая комментарии, и поставляется в комплекте с нерегрессионным набором тестов, который отлично подходит для изучения практических конструкций и семантики Muffin MC .

Франк Порчер
источник
Действительно мило! Самая короткая форма ascii-art имеет сокращенное имя функции, а самая короткая GCD - нет. Это намеренно, потому что, если это не так, вы можете сбрить еще 2 байта. +1
родольфит
Конечно, и это намеренно. Нужно ли мне ? да, давайте сделаем это;) Спасибо за пост, и ваша оценка.
Франк Порчер
1
Поскольку вы пытаетесь избавиться от лишних символов (и потому что я могу быть неисправимой грамматикой), вы можете (должны) удалить пробел перед восклицательным знаком для первой задачи. Это место правильно по-французски, но не по-английски.
Амос М. Карпентер