Витрина языков


508

Примечания

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

  • Это уже не , и длина фрагментов не ограничена подсчетом голосов. Если вы знаете эту ветку ранее, пожалуйста, ознакомьтесь с изменениями.

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

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

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

  • Ответы могут содержать один (и только один) фактоид, то есть пару предложений без кода, которые описывают язык.

  • Помимо фактоида, ответы должны состоять из фрагментов кода, которые могут (но не обязательно) программы или функции.

  • Фрагменты не должны быть связаны. На самом деле, фрагменты, которые слишком связаны, могут быть избыточными.

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

  • Ответы, содержащие более нескольких фрагментов кода, должны использовать фрагмент стека, чтобы свернуть все, кроме фактоида и одного из фрагментов.

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

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

Текущие ответы, отсортированные в алфавитном порядке по названию языка

$.ajax({type:"GET",url:"https://api.stackexchange.com/2.2/questions/44680/answers?site=codegolf&filter=withbody",success:function(data){for(var i=0;i<data.items.length;i++){var temp=document.createElement('p');temp.innerHTML = data.items[i].body.split("\n")[0];$('#list').append('<li><a href="/a/' + data.items[i].answer_id + '">' + temp.innerText || temp.textContent + '</a>');}}})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script><base href="http://codegolf.stackexchange.com"><ul id="list"></ul>

Ответы:


413

Mathematica

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

Список растет довольно долго. Я начал удалять менее интересные фрагменты, и теперь я начну пропускать фрагменты. См. Историю изменений для полного списка фрагментов до 41. Для некоторых реальных драгоценных камней, проверьте фрагменты 81 , 64 , 44 , 23 , 19 , 12 и 8 .

Длина 143 и 144 фрагмента

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

Рассмотрим двойной маятник на стержне (то есть маятник, прикрепленный к другому). Каждый стержень имеет единичную длину, а каждый из двух весов маятника имеет единичную массу. Я также использовал удельную гравитацию, чтобы сократить уравнение. Следующий фрагмент из 143 символов решает уравнения движения Лагранжа для такой системы (в терминах углов маятника и угловых моментов). Вывод можно найти в этом PDF , хотя это довольно простое упражнение, если вы знакомы с лагранжевой механикой.

Это довольно нечитаемо, потому что мне пришлось много играть в гольф:

d@t@t;NDSolve[{#''@t==-#4#2''[t]Cos@d-##3#2'@t^2Sin@d-Sin@#@t&@@@{{θ,φ,1,.5},{φ,θ,-1,1}},θ@0==2,φ@0==1,θ'@t==φ'@t==0/.t->0},{θ,φ},{t,0,60}]

Важно то, что Mathematica сразу отображает миниатюрный график того, как примерно выглядят решения:

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

Хорошо, но это немного отстой. Мы хотим знать, как на самом деле выглядит движение маятника. Итак, вот фрагмент из 144 символов, который оживляет маятник, отслеживая траекторию нижнего маятника:

Graphics@{Line@{{0,0},p=θ~(h={Sin@#@#2,-Cos@#@#2}&)~t,p+φ~h~t},White,{0,0}~Circle~2.2}~Show~ParametricPlot[θ~h~u+φ~h~u,{u,0,t}]~Animate~{t,0,60}

Полученная анимация выглядит так:

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

Мне пришлось немного обмануть: если вы строите за пределами t = 30, ParametricPlotпо умолчанию используется слишком мало точек, и линия становится довольно неровной. Но большая часть интересной динамики происходит после этого времени, поэтому я использовал опцию, PlotPoints -> 200чтобы вторая половина анимации выглядела более плавной. В этом нет ничего особенного, и первая половина все равно будет выглядеть неразличимой.

Я думаю, что это будет мой последний фрагмент, если я не придумаю что-то действительно ошеломляющее. Надеюсь, вам понравилось это!

Длина фрагмента 100

GeoGraphics[{GeoStyling[Opacity[0.5]], NightHemisphere[]}, GeoBackground -> GeoStyling["ReliefMap"]]

Я думал о некоторых хороших Geoфункциях для фрагмента 100, но в конечном итоге я нашел что-то действительно изящное в Tweet-a-Program , которое мне просто нужно было украсть. Выше приведено очень красивое изображение солнечной карты Земли на текущее время и день путем наложения полупрозрачной формы ночного полушария на карту рельефа:

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

Длина фрагмента 81

CellularAutomaton[{{0,2,3,If[0<Count[#,1,2]<3,1,3]}[[#[[2,2]]+1]]&,{},{1,1}},i,n]

Обещаю, это последний клеточный автомат. Но вот тут есть Wireworld из 81 персонажа. На этот раз я не закодировал правило в одно число, а) потому что я думаю, что это было бы смехотворно огромным (я не удосужился это выяснить) и б) показать вам еще одно использование CellularAutomaton. На этот раз правило просто указывается как чистая функция, которая получает окрестность ячейки и возвращает новое значение ячейки. Это гораздо более выполнимый подход для клеточных автоматов с более чем 2 цветами / состояниями.

Во всяком случае, я настроил пример из Википедии в i(два тактовых генератора, генерирующих сигналы, и вентиль XOR) и позволил ему выполнить около 50 шагов:

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

Если вам интересно, фактическое построение сюжета и анимации могло быть фрагментом 77:

ListAnimate[ArrayPlot[#,ColorRules->{0->Black,1->Blue,2->Red,3->Yellow}]&/@w]

Длина фрагмента 69

DSolve[r^2*R''[r]+2r*R'[r]-R[r]==0&&(R[r]==1&&R'[r]==2/.r->1),R[r],r]

Вернемся к чему-то полезному. Помимо нормальных систем уравнений, Mathematica также может решать системы дифференциальных уравнений. Выше технически это только одно дифференциальное уравнение с граничными условиями, но вы также можете представить его как систему из трех уравнений. Аналогично интегрирующим функциям DSolveдля точных решений, тогда как NDSolveбудет решать систему численно. Вышесказанное дает единственное решение

{{R[r] -> 1/2 r^(-(1/2) - Sqrt[5]/2) (1 - Sqrt[5] + r^Sqrt[5] + Sqrt[5] r^Sqrt[5])}}

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

Длина 64 фрагмента

CellularAutomaton[{224,{2,{{2,2,2},{2,1,2},{2,2,2}}},{1,1}},i,n]

Я обещал тебе больше CellularAutomatonволшебства! Этот фрагмент вычисляет игру жизни Конвея с начальным условием iдля nшагов и дает результат для всех промежуточных временных шагов.

Несколько слов о параметрах: 2это количество состояний ячейки. {{2,2,2},{2,1,2},{2,2,2}}дает веса для 9 ячеек в окрестности 3х3. Это гарантирует, что сама ячейка отличается от суммы 8 соседей. {1,1}говорит, что правило CA зависит от ячеек на 1 шаг в любом направлении. И, наконец, 224актуальное правило обновления, закодированное в одно число. Выяснить это число может быть немного сложно, но в документации есть довольно полезное руководство . Для более сложных автоматов, одно число не будет сокращать его (потому что число будет огромным). Может быть, мы доберемся туда завтра! ;)

В любом случае, если я вставлю случайную сетку в i200 nи отправлю результат через анимацию ArrayPlot, мы увидим, что она действительно работает:

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

Длина 59 фрагмента

SphericalPlot3D[Re[Sin[θ]Cos[θ]Exp[2I*φ]],{θ,0,π},{φ,0,2π}]

Помните полярный сюжет из фрагмента 26? Мы можем сделать то же самое в 3D! (На самом деле есть две функции: RevolutionPlot3Dдля цилиндрических полярных и SphericalPlot3Dсферических полярных.) Как и Graphics3Dвсе трехмерные графики, в Mathematica автоматически вращаются, поэтому вам не нужно беспокоиться о хорошем угле обзора камеры. Вышеприведенный график изображает нечто вроде сферической гармоники (хотя и не совсем) и выглядит так:

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

Длина 52 фрагмента

Manipulate[Plot[x^2a+x*b,{x,-3,3}],{a,.1,3},{b,0,3}]

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

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

Длина 48 фрагмента

Import["http://www.google.com/doodles","Images"]

Importэто довольно мощная команда. Он используется как для загрузки файлов с диска, так и из Интернета. Он знает довольно много различных форматов файлов, и для некоторых из них (например, HTML-страниц) он может фактически извлекать данные сразу. Выше загружает все изображения со страницы каракули Google.

Длина фрагмента 45

EdgeDetect@ExampleData@{"TestImage","Splash"}

Время для некоторой обработки изображений. Mathematica поставляется с целым рядом примеров данных, включая изображения (например, Lena), текстуры, 3D-модели и фрагменты аудио. Сначала мы загружаем одну из них:

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

Хотите обнаружить края? Это единственный вызов функции:

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

Длина 44 фрагмента

ArrayPlot@CellularAutomaton[110,{{1},0},100]

Наконец, у меня достаточно символов, чтобы использовать их, CellularAutomatonа также отобразить результат. :) Насколько я знаю, CellularAutomatonэто единственная функция в Mathematica, связанная с CA. Но Стивен Вольфрам, похоже, считает себя парнем номер один, когда дело доходит до клеточных автоматов, поэтому эта функция невероятно мощная. Выше показано в значительной степени его простое использование. Это моделирует одномерный клеточный автомат на 100 шагов - и он на самом деле будет возвращать состояние автомата на каждом из этих шагов, поэтому результат будет двухмерным. Правило является первым параметром, который может быть либо детально указан в списках, либо просто закодирован в одно число. Для этого примера я выбрал довольно известное правило Тьюринга, Правило 110 . {{1},0}определяет начальное условие: одиночный1на фоне нулей. Возможно, я продемонстрирую еще больше возможностей CellularAutomatonв будущем, когда у меня будет больше доступных символов: он может имитировать CA в более высоких измерениях, используя большие окрестности и с более чем двумя состояниями.

ArrayPlotЕще одна хорошая утилита для построения графиков, которая просто отображает 2D-список в виде сетки сплошных цветов, указывающих их значение. В простейшем случае, 0это mappend для белого и 1черного. Результатом фрагмента является:

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

Длина фрагмента 43

HighlightGraph[graph,FindVertexCover@graph]

Прошло много времени с тех пор, как я упомянул графики. В Mathematica встроено множество общих теоретических задач, а также хорошие инструменты визуализации. Выше, для данного graph, найдет минимальное покрытие вершины графа, а затем визуализирует граф с выделенными вершинами. Например , если graphэто PetersenGraph[7,2]обратно из сниппета 18, мы получим:

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

Длина 42 фрагмента

Animate[Plot[Sin[t-x],{x,0,10}], {t,0,10}]

В Mathematica довольно просто анимировать вещи (и они даже не должны быть изображениями). Вы просто даете ему выражение, которое будет оцениваться для каждого фрейма, и набор параметров, которые должны варьироваться в зависимости от фрейма. Вышесказанное просто оживляет сюжет движущейся синусоиды. Анимация будет выглядеть примерно так: GIF:

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

Длина 40 фрагмента

SortBy[PlanetData[#, "EscapeVelocity"]&]

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

И да, есть еще одна приятная *Dataфункция - вышеупомянутые будут сортировать имена планет по скоростям убегания планет .

Длина 39 фрагмента

f[1]=1
f[2]=1
f[n_]:=f[n]=f[n-1]+f[n-2]

Я обещал сделать функцию Фибоначчи более эффективной. Этот фрагмент показывает, как тривиально запоминание в Mathematica. Обратите внимание, что все, что изменилось, является дополнительным f[n]=в третьей строке. Поэтому, когда fвызывается для нового значения (скажем f[3]), то f[3]=f[3-1]+f[3-2]будет оцениваться. Это вычисляет f[2]+f[1], затем присваивает его f[3]=, а не с :=!), И в конечном итоге возвращает значение для нашего начального вызова. Поэтому вызов этой функции добавляет новое определение для этого значения, которое, очевидно, является более конкретным, чем общее правило, и, следовательно, будет использоваться для всех будущих вызовов fс этим значением.

Помните, что другая функция Фибоначчи заняла 4 секунды для 30 значений? Это требует 3 секунд для 300 000 значений.

Длина 37 фрагмента

l//.{a___,x_,b___,x_,c___}:>{a,x,b,c}

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

{a___,x_,b___,x_,c___}:>{a,x,b,c}это правило. x_с единственным подчеркиванием - это шаблон, который ссылается на одно произвольное значение (которое само может быть списком или подобным). a___является шаблоном последовательности (см. также фрагмент 15), который относится к последовательности из 0 или более значений. Обратите внимание, что я использую x_дважды, это означает, что эти две части списка должны быть одинаковыми. Таким образом, этот шаблон соответствует любому списку, который содержит значение дважды, вызывает этот элемент xи вызывает три последовательности вокруг этих двух элементов a, bи c. Это заменяется на {a,x,b,c}- то есть второй xотбрасывается.

Теперь //.будет применяться правило до тех пор, пока шаблон больше не будет соответствовать. Таким образом, приведенный выше фрагмент удаляет все дубликаты из списка l. Тем не менее, это немного мощнее, чем это: //.применяет правило на всех уровнях. Таким образом, если он lсам содержит списки (любой глубины), дубликаты из этих подсписков также будут удалены.

Длина 36 фрагмента

f[1]=1
f[2]=1
f[n_]:=f[n-1] + f[n-2]

Время новых языковых возможностей! У Mathematica есть несколько приятных моментов в определении функций. Для начала вы можете предоставить несколько определений функций для одного и того же имени, для разных чисел или типов аргументов. Вы можете использовать шаблоны, чтобы описать, к какому типу аргументов относится определение. Кроме того, вы даже можете добавить определения для отдельных значений. Затем Mathematica выберет наиболее конкретное применимое определение для любого вызова функции и оставит неопределенные вызовы без оценки. Это позволяет (помимо прочего) писать рекурсивные функции гораздо более естественным образом, чем использование Ifпереключателя для базового случая.

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

Таким образом, вышеприведенное, конечно, просто функция Фибоначчи. И очень неэффективный в этом. Вычисление первых 30 чисел занимает около 4 секунд на моей машине. Вскоре мы увидим, как мы можем улучшить производительность, даже не избавляясь от рекурсивного определения.

Длина 35 фрагмента

StreamPlot[{x^2,y},{x,0,3},{y,0,3}]

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

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

Длина 34 фрагмента

Solve[a*x^4+b*x^3+c*x^2+d*x==0, x]

Mathematica также может решать уравнения (или системы уравнений, но у нас сейчас очень много символов). Результат, как обычно, будет символическим.

{
  {x -> 0}, 
  {x -> -(b/(3 a)) - (2^(1/3) (-b^2 + 3 a c))/(3 a (-2 b^3 + 9 a b c - 27 a^2 d + Sqrt[4 (-b^2 + 3 a c)^3 + (-2 b^3 + 9 a b c - 27 a^2 d)^2])^(1/3)) + (-2 b^3 + 9 a b c - 27 a^2 d + Sqrt[4 (-b^2 + 3 a c)^3 + (-2 b^3 + 9 a b c - 27 a^2 d)^2])^(1/3)/(3 2^(1/3) a)}, 
  {x -> -(b/(3 a)) + ((1 + I Sqrt[3]) (-b^2 + 3 a c))/(3 2^(2/3) a (-2 b^3 + 9 a b c - 27 a^2 d + Sqrt[4 (-b^2 + 3 a c)^3 + (-2 b^3 + 9 a b c - 27 a^2 d)^2])^(1/3)) - ((1 - I Sqrt[3]) (-2 b^3 + 9 a b c - 27 a^2 d + Sqrt[4 (-b^2 + 3 a c)^3 + (-2 b^3 + 9 a b c - 27 a^2 d)^2])^(1/3))/(6 2^(1/3) a)}, 
  {x -> -(b/(3 a)) + ((1 - I Sqrt[3]) (-b^2 + 3 a c))/(3 2^(2/3) a (-2 b^3 + 9 a b c - 27 a^2 d + Sqrt[4 (-b^2 + 3 a c)^3 + (-2 b^3 + 9 a b c - 27 a^2 d)^2])^(1/3)) - ((1 + I Sqrt[3]) (-2 b^3 + 9 a b c - 27 a^2 d + Sqrt[4 (-b^2 + 3 a c)^3 + (-2 b^3 + 9 a b c - 27 a^2 d)^2])^(1/3))/( 6 2^(1/3) a)}
}

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

Длина 33 фрагмента

Dynamic@EdgeDetect@CurrentImage[]

Спасибо Benwaffle за эту идею. CurrentImage[]загружает текущее изображение вашей веб-камеры. EdgeDetectпревращает изображение в черно-белое изображение, края которого белые, а остальные черные (см. пример 45). Настоящее удовольствие Dynamicдоставляет само обновление выражения. Таким образом, результатом этого будет потоковая передача изображений с вашей веб-камеры и обнаружение на них живого края.

Длина 32 фрагмента

NumberLinePlot[x^2<2^x,{x,-2,5}]

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

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

Стрелка указывает, что область продолжается до бесконечности. Белые кружки указывают, что это открытые интервалы (конечные точки не являются частью интервала). Для закрытых концов круги будут заполнены.

Длина фрагмента 28

Graphics3D@{Sphere[],Cone[]}

Время для 3D-графики. Вышеприведенный объект отображает наложенную сферу и конус с параметрами по умолчанию, которые выглядят как хрустальный шар:

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

В Mathematica вы можете нажать и перетащить этот маленький виджет, чтобы повернуть его.

Длина 27 фрагмента

CountryData["ITA", "Shape"]

Больше *Data! CountryDataдовольно безумно Получение формы страны даже не верхушка айсберга. Существует так много данных о странах, что вы могли бы написать целую книгу об этой функции. Как ... есть FemaleLiteracyFraction. Вы также можете запросить эти данные для разных моментов времени. Для полного списка, см. Ссылку.

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

Длина 26 фрагмента

PolarPlot[Sin[5θ],{θ,0,π}]

Время для более интересного сюжета. PolarPlotэто просто график в полярных координатах. Вместо указания y для данного x, вы указываете радиус r для данного угла θ:

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

Длина 25 фрагмента

{{1,5},{2,3},{7,4}}.{8,9}

Наконец-то у нас достаточно символов для векторной математики. Вышеприведенное вычисляет умножение матриц матрицы 2x3 и строки 2-вектора:

{53, 43, 92}

Длина 23 фрагмента

Rotate[Rectangle, Pi/2]

Хех. Хехе. Вы думаете, что знаете, что это делает. Но ты не. Rectangleсама по себе это просто именованная функция. Чтобы получить объект, представляющий прямоугольник, вам нужно вызвать эту функцию с некоторыми параметрами. Как вы думаете, что происходит, когда вы пытаетесь вращаться Rectangle? Этот:

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

Длина 22 фрагмента

30~ElementData~"Color"

Еще одна из встроенных *Dataфункций. Да, для химических элементов, вы не просто получаете такие вещи, как их атомный номер, температуру плавления и название ... вы можете получить их цвет при комнатной температуре. Выше приведен цвет цинка:

SlateGray

Длина 21 отрывка

Integrate[E^(-x^2),x]

У нас была дифференциация некоторое время назад. Время для интеграции. Mathematica может обрабатывать как определенные, так и неопределенные интегралы. В частности, Integrateдаст вам точное решение, и оно может иметь дело с тонной стандартных интегралов и методов интеграции (для числовых результатов, есть NIntegrate). Если вы знаете свое исчисление, вы заметите, что вышеприведенный гауссовский интеграл на самом деле не имеет замкнутой формы, неопределенного интеграла ... если только вы не рассматриваете функцию ошибки как замкнутую форму, то есть. Mathematica возвращает:

1/2 Sqrt[π] Erf[x]

Длина 20 фрагмента

"Sun"~StarData~"Age"

Вернуться к встроенным данным . Должно быть как минимум две дюжины *Dataфункций для всего, о чем вы только могли подумать. Каждый из них берет идентификатор для объекта, для которого вы хотите получить данные, и свойство (или список свойств) для извлечения. Выше приведен только один из самых коротких, что вы можете получить Sun, Starи Ageвсе это довольно короткий, потому что я не мог дождаться, чтобы показать эту функцию.

Ах да, и я уже упоминал, что Mathematica (начиная с 9) поддерживает величины с единицами измерения? (Подробнее об этом позже.) Выше оценивается:

Quantity[4.57*10^9, "Years"]

который отображается как

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

Длина 19 фрагмента

MandelbrotSetPlot[]

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

Математическая графика

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

Длина 18 фрагмента

PetersenGraph[7,2]

Начиная с Mathematica 8, он понимает, что такое граф, поэтому он поставляется со всеми видами функций, связанных с теорией графов. И это была не Mathematica, если бы она не включала тонну встроенных модулей. Выше генерируются данные графика для обобщенного графа Петерсена . Он создает фактическую структуру данных, которой можно манипулировать, но Mathematica немедленно отображает эти графические данные ... графически:

Математическая графика

Длина 17 фрагмента

Plot[x^x,{x,0,2}]

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

Математическая графика

Длина фрагмента 15

{##4,#,#2,#3}&

Это показывает две наиболее мощные функции (а также полезные для игры в гольф). Все это безымянная чистая функция , сравнимая с lambdas в Python или Procs в Ruby. Чистая функция просто завершается &. Этот оператор имеет очень низкий приоритет, так что он обычно включает в себя почти все, что от него осталось. С аргументами чистой функции ссылаются #, иногда следуют другие вещи. Первый аргумент - это #или #1, второй - #2и так далее.

Другая особенность Sequences. Это в основном как знаки на других языках. Последовательность подобна списку без списка вокруг него - это буквально просто последовательность значений, которую можно использовать в списках, аргументах функций и т. Д., ##В частности, это последовательность всех аргументов чисто функций. ##2последовательность всех аргументов, начиная со второго Так что, если мы назвали вышеупомянутую функцию f, и назвали ее как

f[1,2,3,4,5]

Мы бы получили

{4,5,1,2,3}

поэтому функция поворачивает входные аргументы на 3 элемента влево. Обратите внимание, что ##4упомянутые 4,5были сведены в список.

Длина 12 фрагмента

D[x^y^x,x,y]

Частичная дифференциация. Dбудет дифференцировать первое выражение последовательно по отношению к другим его аргументам, давая в результате символическое выражение. Таким образом, выше указано d² (x ^ y ^ x) / dxdy (где d s являются частичными), о которых Mathematica сообщает:

x^y^x (y^(-1 + x) + y^(-1 + x) Log[x] + x y^(-1 + x) Log[x] Log[y]) + 
  x^(1 + y^x) y^(-1 + x) Log[x] (y^x/x + y^x Log[x] Log[y])

Длина 9 фрагмента

Exp[I*Pi]

Мы еще не сделали никакой сложной арифметики! Как видите, на πсамом деле был просто псевдоним для Pi. Во всяком случае, вышеприведенное на самом деле правильно вернет целое число -1 .

Длина 8 фрагмента

Sunset[]

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

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

Длина 7 фрагмента

9!/43!!

Этот фрагмент демонстрирует несколько классных вещей.

Mathematica не только имеет встроенный факториальный оператор !, но также имеет двойной факториал !!(который умножает все остальные числа от nнуля до 1). Кроме того, он поддерживает целые числа произвольной точности. 43!!Будет оцениваться точно, вплоть до последней цифры. Кроме того, рациональные числа также будут оценены точно. Таким образом, поскольку в числителе и знаменателе присутствуют целые числа, Mathematica максимально сократит дроби, а затем предоставит вам

128/198893132162463319205625

Конечно, вы можете использовать float, когда захотите, но в целом, если ваш ввод не содержит float, ваш результат будет точным.

Длина 4 фрагмента

Here

Пора нам начать с богатства сумасшедших встроенных модулей Mathematica. Вышесказанное делает то, что говорит на жестяной банке и (для меня) оценивает GeoPosition[{51.51, -0.09}].

Длина 3 фрагмента

x-x

Просто для демонстрации оригинального Factoid : все вышеперечисленное работает, даже если xоно еще не определено, и фактически приведет 0к этому.

Длина 2 фрагмента

3x

Умножение через сопоставление! Если ясно, что идентификатор заканчивается, а другой начинается, вам не нужны *пробелы или даже пробелы для их умножения. Это работает практически со всем, включая строки и переменные, которые еще не имеют значений. Очень удобно для игры в гольф. ;)

Длина 1 фрагмента

π

Угадай, что это Пи? И на самом деле, это не какое-то приблизительное представление с плавающей точкой, это именно Pi - так что все виды сложных и тригонометрических функций, в которых это используется, дадут точные результаты, если они известны.

Factoid

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


19
Фрагмент 23 довольно любопытен. Если бы вы это сделали Translate[Scale[Rectangle, 80], {0, 0, 100}], Rectangleпоявилось ли бы огромное слово, плавающее перед вашим монитором?
Увлечения Кельвина

53
@ Calvin'sHobbies Только что попробовал ... выбрал неудачное zсмещение ... ударил меня прямо в лицо.
Мартин Эндер

45
Официальный сайт Mathematica должен обязательно ссылаться на это.
Caridorc

7
@ durron597 Сохраняя его как символ и информируя все тригонометрические и сложные функции о том, что делать с π.
Мартин Эндер

16
Как только я увидел, что легендарный Мартин Бюттнер опубликовал ответ Mathematica, я понял, что у меня нет шансов выиграть конкурс популярности. Вы, сэр, настоящий волшебник.
Алекс А.

187

Печально известный язык программирования Шекспира

Язык программирования Шекспира был создан в 2001 году двумя шведскими студентами, Карлом Хассельстремом и Йоном Ослундом, и объединяет, как заявляют авторы ,

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

Ответы идут сверху вниз. Кроме того, часто я вижу ссылки на старые или предыдущие фрагменты.

( ссылка для себя: редактировать )

Factoid:

Код Шекспира напоминает, как и следовало ожидать, пьесу Шекспира, где переменные - это символы в пьесе, и их значение изменяется по мере того, как они «оскорбляются» или хвалят ».

Длина 1 фрагмента:

I

Код Шекспира разделен на Деяния, а сами действия разделены на Сцены для причинно-следственных связей. Определение Act как Act Iозначает, что он будет первым фрагментом кода, который будет запущен, в каждом примере - но не только.

Длина 2 фрагмента:

as

Используется для сравнения двух «символов».

Длина 3 фрагмента:

day

К настоящему времени у вас может возникнуть ощущение, что SPL очень многословен. И странно. И ты еще ничего не видел. dayв SPL - 1. Все «положительные» и «нейтральные» существительные считаются так же 1, как и все «отрицательные» -1.

Длина 4 фрагмента:

rich

Что такое rich? Прилагательное. В SPL прилагательные делают значение существительного, к которому они привязаны, умноженным на два. Смотрите реализацию на фрагменте 14.

Длина 5 фрагмента:

Act I

Реализация первого фрагмента. Всем действиям может быть дан заголовок, например Act I: Hamlet must die!, поскольку все, что находится после римской цифры, игнорируется анализатором.

Длина 6 фрагмента:

better

У каждого языка есть условия, и SPL не является исключением. За исключением того, что это язык с длинным синтаксисом (и я упоминал, что он странный?), Его условные выражения будут длинными. С Офелией спросить Джульетту Am I better than you?- все равно что разговаривать if (Ophelia > Juliet)на большинстве "обычных" языков И, конечно, вы можете спросить наоборот: Am I not better than you?это эквивалент if (Ophelia < Juliet). И вы уже можете догадаться, как =переводится на SPL: as good as- использование фрагмента кода 2.

Тем good/betterне менее, это не единственный способ сравнения в этом шексперианском языке, вы можете использовать любое прилагательное. Тот же принцип фрагмента 3 применим и здесь: «положительные» прилагательные имеют значение >, а «отрицательные» означают <.

Длина 7 фрагмента:

Juliet:

Это вызов переменной; после этого его / ее инструкции / декларации / все, что последует.

Ограничение SPL состоит в том, что он имеет ограниченное количество переменных: «Ромео», «Джульетта», «Гамлет», «Офелия», «Макбет» и т. Д. - несколько примеров «символов», которые появятся в шексперианской программе.

Длина 8 фрагмента:

[Exeunt]

[Exeunt]ставится, когда все «персонажи» покидают «сцену». Надеюсь, позже я смогу подробнее рассказать о взаимодействии между персонажами. Обычно это последняя инструкция в любой программе SPL, хотя [Exeunt]она не является терминальным «символом» языка. Для другого примера см. Фрагмент 27.

Длина фрагмента 9:

as bad as

Девять символов просто для представления простого =фрагмента 2. Я упоминал, что SPL странный? Смотрите фрагмент 30 для примеров. (и да, есть более одного способа вывести его)

Длина фрагмента 10:

difference

Необычный способ представления -, вычитание. Вы можете выполнять математические операции над SPL, даже если вам, возможно, понадобится целый день, чтобы понять это правильно.

Фактоид (поскольку мне удалось каким-то образом достичь десяти фрагментов кода, давайте сделаем небольшой перерыв и сделаем еще один фактоид о SPL)

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

Еще один сайт для запуска кода SPL - это тот, который работает путем внутреннего перевода кода SPL на другой эзотерический язык: Oracle PL / SQL.

Длина фрагмента 11:

[Exit Romeo]

Да! Наконец я могу говорить о взаимодействии между персонажами! Чтобы изменить его значение или взаимодействовать с другими, на сцене должен быть «персонаж» - вход с [Enter Romeo]. Если символ адресован, но отсутствует, возникает ошибка во время выполнения, и программа останавливается. Потому что в SPL значение переменных задается количеством имен, которые они хвалят - или оскорбляют - другими персонажами на сцене. Я чувствую, что должен привести пример, чтобы очистить некоторую путаницу, которую может создать мое отстойное объяснение, но, возможно, лучше отложить несколько отрывков.

Длина фрагмента 12:

Remember me.

SPL довольно "базовый", хорошо - но у него есть стеки! Когда, например, Ромео говорит Джульетте «помнить его», он на самом деле говорит своему любимому, чтобы он вложил ценность Ромео в ее стек. Выделение значения выполняется с помощью Recall your happy childhood!или Recall your love for me, или, по сути, с любого предложения, начинающегося с Recall- остальное - просто художественная чушь, как фрагмент 22.

Длина 13 фрагмента

Let us return

Шекспировский способ иметь goto. И здесь пригодятся Деяние и Сцены. Если Ромео скажет Джульетте we shall return to Act II(да, опять же, есть несколько способов написать это), программа перейдет к этой конкретной части кода. Это также замечено рядом с условными заявлениями.

Длина фрагмента 14

my little pony

Да, это была серия еще в 80-х. Здесь это 2*1. Почему? Потому что ponyа (несколько) положительное существительное и littleприлагательное. Итак, вспоминая фрагменты 3 и 4, мы имеем little = "2 *"и pony = "1".

Длина фрагмента 15

Speak thy mind!

В программе SPL вы увидите это (или Speak your mind!, что то же самое) много . Это в основном выводит значение каждого «символа» в виде цифры, буквы или чего-либо еще, в зависимости от набора символов, используемого вашим компьютером. Есть также, Open your mind.что делает почти то же самое, хотя вывод только в числовой форме.

Длина 16 фрагмента

You are nothing!

Когда кто-то говорит вам это в реальной жизни, вы будете чувствовать себя подавленным. Когда Офелия рассказывает об этом Гамлету в шекспировском программировании, Гамлет чувствует себя бесполезным. Что это значит? Это Hamlet = 0.

Длина 17 фрагмента

Ophelia, a wench.

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

Но что значит "девка"? Значит ли это, что это конкретное (и классное) имя типа данных? Ну ... я не хочу вас разочаровывать, но это ничего не значит: все, что находится после запятой, игнорируется парсером, а это означает, что вы можете поместить туда самый вопиющий из всех, что вы только можете себе представить.

Длина 18 фрагмента

lying sorry coward

-4для всех земных существ. Почему? Потому что 2*2*(-1) = -4.

Длина 19 фрагмента

Romeo:
 Remember me.

Наконец!!! Я наконец могу вывести полную инструкцию правильного синтаксиса (пусть и короткую)! Вот как вы используете фрагмент 12: сначала вы объявляете, кто говорит, а затем на следующей строке пишете «диалог». Обычно на сцене только два «персонажа», чтобы парсер не расстроился и не запутался. Когда вам нужен еще один «персонаж», вы берете его со сцены и заменяете его новым.

Длина 20 фрагмента

cube of thy codpiece

Я хотел бы разработать немного больше для этого, но, по правде говоря, вещи, которые я придумаю, все еще слишком коротки для этой длины фрагмента. И, таким образом, я принесу вам это, которое в итоге оказывается -1- потому что (-1) 3 = -1 (и codpieceявляется «отрицательным» существительным, так как они неудобны и все). SPL понимает несколько более сложных арифметических операций , как - то экспоненциации и квадратные корни.

Factoid (еще один, так как мы достигли еще одной вехи)

«Программа Hello World» на шексперианском языке имеет 89 строк и более 2400 символов в длину, как показано здесь .

Длина 21 отрывка

Listen to your heart.

В фрагменте 15 вы что-то вывели; здесь вы вводите номер в программу. Если вы хотите ввести символ, вы будете использовать Open your mind.вместо этого. И, само собой разумеется, это значение будет сохранено в «персонаже», с которым мы разговариваем.

Длина 22 фрагмента

Recall your childhood!

Выделение целого числа из стека осуществляется с помощью этого, как объяснено во фрагменте 12. Когда Офелия в каждом случае говорит Гамлету вышеупомянутое предложение, это заставляет Гамлета взять целое число из его стека и принять это значение.

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

Длина 23 фрагмента

Are you better than me?

Реализация фрагмента 6. Когда «персонаж» задает такой вопрос другому, то, что он / она делает, эквивалентно if (x > y)более распространенным языкам программирования. Выполнение этой инструкции должно быть отложено до тех пор, пока у меня не появится больше символов.

Длина 24 фрагмента

[Enter Romeo and Juliet]

Да, «символы» могут вводиться парами. Не обязательно, чтобы один «персонаж» выходил на сцену, а за ним следовал другой.

Длина 25 фрагмента

remainder of the quotient

25 символов просто чтобы написать %. 25 символов для остатка от деления. И использовать это? Ну, это еще больше - см. Фрагмент 75.

Длина 26 фрагмента

Let us return to scene II.

Вот он, gotoв SPL, который работает так, как и следовало ожидать в языке программирования. Дело в том, что вы можете прыгать между сценами в одном действии и между действиями; но вы не можете прыгать между сценами в разных действиях.

Длина 27 фрагмента

[Exeunt Ophelia and Hamlet]

Когда более одного «персонажа» покидают сцену, вместо того Exit, чтобы поддерживать традиции театрального характера SPL, используется латинское слово «Exeunt». Иногда его можно заменить просто фрагментом 8.

Длина фрагмента 28

Scene I: Ophelia's flattery.

Объявление сцены. Как вы уже можете ожидать, если вы справляетесь со мной, важен бит Scene I, остальное - художественный пух.

Были сделаны некоторые компиляторы (такие как этот, который компилирует из SPL в C, написанный на Python ), которые вместо этого ссылаются на текст после нумерации Act / Scene. Хотя более логично (в конце концов, во время пьесы, когда персонажи говорят такие строки, как «давайте вернемся к акту I», может показаться глупым), я придерживаюсь оригинального пути.

Длина 29 фрагмента

You pretty little warm thing!

Да, еще одна константа (поскольку нам нужно больше символов для выполнения арифметических операций). Этот равен 8, потому что 2*2*2*1 = 8.

Длина фрагмента 30

You are as cowardly as Hamlet!

Сказать это, например, Ромео, значит это Romeo = Hamlet. Как фрагмент 9.

Фактоид (да, еще один ориентир достигнут!)

Этот язык был создан для назначения в курсе синтаксического анализа - таким образом, авторы не создали компилятор SPL. Более того: кажется, что авторы SPL разорвали свои связи с их созданием, поскольку с 2001 года в языке ничего не изменилось ...

Длина 31 фрагмент

Am I as horrid as a flirt-gill?

Да, я знаю, это несколько повторяющий фрагмент 23, хотя здесь мы сравниваем «персонажа», который говорит с «флирт-жаброй» (если хотите, если хотите if (Ophelia == -1)). Дело в том...

Длина 32 фрагмента

If so, let us return to scene I.

... теперь я могу представить thenSPL, условный переход и Shakesperian способ реализации циклов. Например, вы можете заставить Ромео принять значение 0, увеличить его значение, выполняя какое-то другое задание, и остановиться, когда он достигнет 10, после чего продолжить работу с программой.

Длина 33 фрагмента

If not, let us return to scene I.

Просто напоминание о том, что вместо этого мы можем перейти к другой сцене, если проверенное нами условие ложно .

Длина 34 фрагмента

Open your mind! Remember yourself.

Две инструкции подряд, яппи! Первый читает символ, второй помещает его в стек памяти другого символа.

Длина 35 фрагмента

Act I: Death!

Scene I: Oh, shit.

Правильный способ объявления Акта и Сцены. Добавьте художественную кашу со вкусом.

Длина 36 фрагмента

Thou art as sweet as a summer's day!

Другой способ сказать, что «персонаж», с которым говорят, получит значение 1- потому что летние дни приятны и приятны.

Длина 37 фрагмента

Art thou more cunning than the Ghost?

Офелия, задавая этот вопрос Гамлету, значит переводить его на менее читаемый язык программирования if (Hamlet > the Ghost). Да, это снова фрагмент 23, но он показывает, что вам не нужно спрашивать «персонажей», лучше ли они друг друга: любой другой вопрос тоже подойдет.

Длина фрагмента 38

[Enter the Ghost, Romeo and the Ghost]

Да, я дважды называю «персонаж» - потому что я хотел, чтобы программа выдала мне ошибку. Вызов «персонажа», который уже находится на сцене, или указание того, кто отсутствует для выхода, вызовет большое горе у анализатора / компилятора.

Длина 39 фрагмента

the sum of a fat lazy pig and yourself!

Полная инструкция выглядит лучше, я дам вам это, но ... вот наша первая арифметическая операция! Что все это значит, на самом деле? Ну, pigэто грязное животное (хотя и вкусное), так что оно эквивалентно -1, имеет два прилагательных, что означает « fat lazy pigравно» 2*2*(-1) = -4. Но как насчет yourself? Это рефлексивный пронум, а не имя и прилагательное. Хорошо, помните, что SPL основан на диалогах между «персонажами»; таким образом, yourselfотносится к другому «персонажу» на сцене. Итак, мы подходим к концу и обнаруживаем, что «сумма жирной ленивой свиньи и вас самих» на самом деле -4 + x.

Длина 40 фрагмента

the sum of a squirrel and a white horse.

Да, другая сумма, но эта проще, чем фрагмент 39. Это просто 1 + 2- 3если моя математика верна.

Фактоид (все еще со мной после этих сорока фрагментов художественного пуха? Вы заслуживаете приза.)

SPL в его версии 1.2.1 можно скачать здесь .

Длина фрагмента 41

Juliet:
 Speak thy mind!

[Exit Romeo]

Иногда «персонажей» вызывают только на сцене, чтобы изменить их значение - что в реальной игре было бы довольно странно. Во всяком случае, здесь, Джульетта заставляет своего любимого Ромео напечатать его сохраненную ценность, после чего он покидает сцену.

Длина 42 фрагмента

Speak YOUR mind! You are as bad as Hamlet!

Снова две инструкции в одной строке (у нас может быть несколько, но длина фрагмента пока не позволяет); здесь у нас есть «персонаж», говорящий другому выводить его значение и предполагать, какое значение имеет Гамлет. Смешение? Может статься.

Длина фрагмента 43

Am I as horrid as a half-witted flirt-gill?

Джульетта, спрашивающая об этом, не означает, что она имеет низкое уважение (хотя это может быть в реальной жизни); это просто другой if, как фрагменты 23 и 37. О, я почти забыл: это переводится как if (Juliet == -2).

Длина 44 фрагмента

You are as evil as the square root of Romeo!

Да, квадратные корни - это зло, разве ты не знал? В любом случае, эта инструкция достаточно проста, чтобы понять, что она делает: приписывает «произносимому» символу значение квадратного корня из значения, хранящегося в Romeo.

Длина фрагмента 45

Hamlet:
 Art thou more cunning than the Ghost?

Фрагмент 37 правильно написан с персонажем, который говорит линию.

Длина 46 фрагмента

the product of a rural town and my rich purse.

Хорошо ... в любом случае, SPL может быть единственным языком в мире, который позволяет вам умножать города с помощью кошельков. Это означает, (2*1)*(2*1)что, если я не очень ошибаюсь, равно 4.

Длина фрагмента 47

Romeo:
 Speak your mind.

Juliet:
 Speak YOUR mind!

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

Длина 48 фрагмента

You lying fatherless useless half-witted coward!

Переводя это напрямую 2*2*2*2*(-1). -16, правильно?

Длина 49 фрагмента

Scene V: Closure.

Hamlet:
 Speak your mind!

[Exeunt]

Пример того, как завершить программу в SPL. Вы можете объявить сцену специально для нее (хотя это и не обязательно), затем Гамлет просит другого «персонажа» вывести свое значение, затем они все покидают сцену. И да, все они должны покинуть сцену.

Длина фрагмента 50

Othello, a young squire.
Lady Macbeth, an old fart.

Более «характерная» презентация, перед правильной инструкцией. Как всегда, единственное , что имеет значение для компилятора Othelloи Lady Macbeth, поэтому остальная часть линии для захватов ...

Еще одна вещь: «персонажи» не должны быть связаны друг с другом, чтобы появиться в программе SPL - так что вы можете иметь Ромео, Отелло и Гамлета в одной игре.

Factoid (полвека из этих вещей? Фу! После этого я думаю, что я буду ненавидеть Уильяма Шекспира ...)

Переводчик SPL на C, упомянутый недавно и разработанный создателями SPL, был основан на Flex и Bison .

Длина фрагмента 51

Othello:
 Recall your great dreams. Speak your mind!

(Так надоели Ромео, Джульетта и Гамлет ... давай приведем Отелло, для разнообразия!)

RecallКак вы можете догадаться, это ключ здесь. «Персонаж», к которому обращается Отелло, возьмет значение из своего стека, примет это значение и затем выведет его.

Длина 52 фрагмента

Thou art as pretty as the sum of thyself and my dog!

Еще одна сумма. Йон. Предполагая, что это адресовано Гамлету, это значит Hamlet = Hamlet + 1. Или Hamlet += 1. Или Hamlet++.

Длина 53 фрагмента

Romeo:
 You are as vile as the sum of me and yourself!

Ах, да, кое-что я забыл упомянуть раньше: говорящие «персонажи» могут упоминать себя в своих строках.

Длина 54 фрагмента

Juliet:
 Is the sum of Romeo and me as good as nothing?

Еще один пример предыдущего фрагмента, включенного в условие. Итак, что мы имеем здесь if (Romeo + Juliet == 0).

Длина 55 фрагмента

Juliet:
 You are as lovely as the sweetest reddest rose.

Итак, здесь, Джульетта хвалит «персонажа», с которым она разговаривает (допустим, это Ромео, ради Шекспира), заявляя, что ему 4 года. Да, еще одно присвоение ценностей.

Длина 56 фрагмента

Othello:
 You lying fatherless useless half-witted coward!

Фрагмент 48 правильно сделан, с «характером». Если вам лень прокручивать вверх (как мне бы хотелось), это означает, что тот, кого оскорбляют, получает значение -16.

Длина 57 фрагмента

Romeo:
 If not, let us return to Act I. Recall thy riches!

Я уже объяснил, как условия работают на SPL в целом; Тем не менее, необходим более встроенный анализ. У нас нет elseздесь: в каждом примере, в этом примере, если условие не выполнено, программа вернется к Акту I; но если бы это было правдой, то оно продолжало бы до следующей инструкции, то Recallесть извлечения из стека, то есть.

Длина 58 фрагмента

Romeo:
 You are as disgusting as the square root of Juliet!

Взяв фрагмент 44 и представив, как должна быть представлена ​​инструкция. Если бы это был диалог между Ромео и Отелло, то мы могли бы перевести это на Java как Othello = Math.sqrt(Juliet).

Длина 59 фрагмента

Othello:
 You are as vile as the sum of yourself and a toad!

Хорошо, если Отелло говорит с Ромео, это будет эквивалентно Romeo+(-1); Romeo--, для краткости. Довольно простой, правда? Это SPL для вас.

Длина фрагмента 60

Is the quotient between the Ghost and me as good as nothing?

Короче говоря, if (The Ghost/Hamlet == 0)предполагая, что «я» принадлежит Гамлету.

Длина фрагмента 61

Thou art as handsome as the sum of yourself and my chihuahua!

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

Длина фрагмента 62

twice the difference between a mistletoe and a oozing blister!

Да, да, больше арифметических операций. Грубо говоря, эти 62 байта SPL могут быть переведены в 2*(1-2*(-1)). Это был бы потрясающий язык для игры в гольф, верно? Правильно.

Длина 63 фрагмента

You lying stupid fatherless rotten stinking half-witted coward!

Сниппет 48 , выводимый -16, это один равна -64: 2*2*2*2*2*2*(-1).

Длина 64 фрагмента

your coward sorry little stuffed misused dusty oozing rotten sky

Из того, что я понимаю о SPL, это совершенно законно. У вас есть много оскорбительных прилагательных, которые превращаются в «положительные» существительные. Поскольку у прилагательных нет особого различия, отрицательны они или нет (их единственное значение - умножение числа справа на два), у нас могут быть совершенно глупые предложения, подобные этому. Что эквивалентно 256. Потому что 2*2*2*2*2*2*2*2*1=256.

Длина 65 фрагмента

You are nothing! You are as vile as the sum of thyself and a pig.

Хм, так много ненависти, не так ли? Итак, то, что мы имеем здесь, эквивалентно, y=0; y=y+(-1);вероятно, могло бы быть «игрой в гольф» You are a pig!, но хе.

Длина 66 фрагмента

You are as beautiful as the difference between Juliet and thyself.

Итак, вычти Джульетту из себя, а? Это довольно просто расшифровать: Romeo=Juliet-Romeo;при условии, что с Ромео разговаривают.

Длина 67 фрагмента

Juliet:
 Am I better than you?

Romeo:
 If so, let us proceed to Act V.

Как большинство условий работают на SPL. Вы проверяете выражение и, если оно верно (или нет: см. Фрагмент 33), вы переходите к другой части программы; в противном случае вы перейдете к следующему предложению.

Длина 68 фрагмента

The Ghost:
 You are as small as the sum of yourself and a stone wall!

Да, да, я становлюсь немного однообразным. Но SPL такой. Как я уже говорил ранее, его выражения представляют собой смесь арифметических операций. Таким образом, это очередное приращение - stone wallнейтральное «существительное».

Длина фрагмента 69

Thou art as disgusting as the difference between Othello and thyself!

Вместо суммы у нас есть вычитание между двумя персонажами, Отелло и тем, с кем разговаривают.

Длина фрагмента 70

You are as handsome as the sum of Romeo and his black lazy squirrel!

Вернемся к дополнениям, да - назови меня формульной, хе. Мы переводим это в Romeo + 2*2*1.

Длина фрагмента 71

Scene I: Dialogues.

[Enter Juliet]

Othello:
 Speak your mind!

[Exit Juliet]

Сцена может быть такой маленькой, как эта. Julietвыходит на сцену, Отелло говорит ей, чтобы вывести ее сохраненное значение, затем она снова выходит из сцены.

Длина фрагмента 72

twice the difference between a mistletoe and an oozing infected blister!

Еще одна арифметическая операция - потому что SPL изобилует ими. Мы можем перевести это на 2*(1-2*2*(-1)).

Длина 73 фрагмента

You are nothing! Remember me. Recall your unhappy story! Speak your mind!

Четыре инструкции подряд ?! На самом деле я горжусь собой. В любом случае, давайте предположим, что это диалог между Ромео и Джульеттой (и он говорит): это означает, что значение Джульетты начинается с 0; затем Джульетта поместит значение Ромео в свой стек памяти, вытолкнет его и выведет его в введенной форме. Просто, правда?

Длина фрагмента 74

You are as sweet as the sum of the sum of Romeo and his horse and his cat!

Да, да, скучный пример, я знаю. Но это так X = (Romeo + 1) + 1.

Длина фрагмента 75

Is the remainder of the quotient between Othello and me as good as nothing?

Ну, это довольно просто. Если ваши навыки декодирования работают со сбоями, это означает if (Othello % X == 0).

Длина 76 фрагмента

Thou art as rich as the sum of thyself and my dog! Let us return to scene I.

Прыжок из фрагмента 26 с выражением перед ним. A gotoна SPL не всегда находится рядом с условием, это может быть так - и, конечно, этот тип gotoвсегда будет найден в конце действия или сцены, поскольку инструкции после него никогда не будут скомпилированы / выполнены. Первая команда довольно проста: x=x+1.

Длина 77 фрагмента

[Exit Hamlet]

[Enter Romeo]

Juliet:
 Open your heart.

[Exit Juliet]

[Enter Hamlet]

Итак, у нас на сцене Джульетта и Гамлет; но мы нуждаемся в ценности от Ромео. Таким образом, чтобы избавить компилятор от очень неприятной головной боли, сначала мы убираем Гамлета со сцены (хотя это могла быть Джульетта), мы просим Ромео выйти на сцену, Джульет дает ему инструкцию вывести номер (см. объяснение фрагмента 21), затем Ромео выходит из сцены и Гамлет возвращается. Довольно просто и просто.

Длина фрагмента 78

The Ghost:
 Speak thy mind.

Lady Macbeth:
 Listen to thy heart! Remember thyself.

Итак, Призрак (покойный отец Гамлета) говорит Леди Макбет вывести ее значение, в то время как она приказывает Призраку прочитать число и положить его в свой стек.


32
Это невероятно интересно, и ваша фотография профиля идеально подходит, он выглядит именно так, как я представляю, как выглядел бы программист SPL.
переиздание

3
@overactor Я не знаю, быть оскорбленным или гордым быть похожим на Гамби. ^ _ ^
Родольфо Диас

9
Странно, но это НЕ самый неясный пример для чтения здесь ... и кажется, что он связан с "наименее практичным".
HRRambler

6
ROFL здесь +1, чтобы помочь вам в пути - еще раз прорваться к Родольфо!
HRRambler

3
@RodolfoDias Вы можете начать. Я жду, чтобы увидеть их. У вас 120 голосов "за".
ghosts_in_the_code

176

болтушка

Factoid

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

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

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

1 кодел

1 кодел

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

Пиксель в этом случае может быть любого цвета для точно такого же эффекта.

2 кодекса

2 кодекса

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

Поток Progam перемещается назад и вперед между двумя кодексами, так как единственный выход из каждого - в другой. Команды в пите выполняются путем перемещения из одного кодека или региона в другой, в зависимости от разницы в оттенках и яркости двух областей. Команда inputявляется движением слева направо, а затем addсправа налево. По первой addкоманде ничего не произойдет, поскольку в стеке есть только одно значение, а в спецификации сказано, что команды без достаточного количества доступных значений игнорируются.

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

3 кодекса

3 кодекса

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

Опять же это бесконечный цикл. Программа начинается с путешествия слева направо, что делает inputзатем output. Программа будет продолжать течь в том же направлении, когда это возможно. На светло-зеленом коделе единственный выход - начать движение в обратном направлении. При движении назад справа налево он пытается выполнять команды subtractи выполнять addкоманды, но стек пуст, поэтому они становятся неактивными.

4 кодекса

4 кодекса

Распечатывает 2 на стандартный вывод на неопределенный срок.

Функционально не особенно интересная программа, но теперь, когда у нас наконец-то есть составное количество кодов, мы можем продемонстрировать немного более продвинутый поток, чем слева направо. Когда поток программы пытается выйти из кодела, он сначала пытается выбрать текущее направление. Если это невозможно (в данном случае из-за края изображения), он поворачивается на 90 градусов по часовой стрелке и пытается выйти снова. В этом случае программа обходит по часовой стрелке 1 кодель за раз, pushдважды вставляя 1 в стек, addобъединяя их вместе, а затем outputполучая результат.

5 кодексов

5 кодексов

Повторно читает символ за раз из стандартного ввода и отслеживает сумму их значений Юникода.

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

Здесь мы впервые видим белый код, который позволяет программному потоку скользить по нему без выполнения инструкций. Пурпурный и синий кодеки делают всю работу здесь. Переход от синего к красному ничего не делает, потому что он пересекает белый кодел посередине. 2 красных - просто pushномер 1 в стеке, и popон отступает, проходя слева направо, затем справа налево через них, а затем через белый кодек, поэтому никакие инструкции не выполняются.

6 кодексов

6 кодексов

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

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

7 кодексов

7 кодексов

Еще одна эхо-программа с другим внешним видом.

Здесь мы видим наши первые блоки коделя, превышающие размер 1. В блоке Piet любой смежный блок коделей того же цвета рассматривается как один блок. Размер блока не имеет значения, кроме как при выполнении pushинструкции, поэтому эта программа обрабатывается точно так же, как версия с 3 кодами, за исключением разных цветов.

8 кодеков

8 кодеков

Читает число из стандартного ввода и выводит квадрат в стандартный вывод, несколько раз.

Поток управления является основным шаблоном по часовой стрелке, как и в программе с 4 кодами. Начиная с верхнего левого, операции в порядке являются input, duplicate(выталкивает дополнительную копию верхнего значения стека в стек), multiply, output. Затем он pushпомещает значение 1 в стек, скользит по белому, чтобы команда не выполнялась, и затем popвыводит эту единицу из стека при переходе от нижнего левого к верхнему левому коделу. Это возвращает его в начало программы с пустым стеком, и оно повторяется.

9 кодеков

9 кодеков

Добавляет 1 + 2 = 3, а затем завершается.

Теперь, когда у нас есть программа с более чем 2-мя кодами в обоих измерениях, мы наконец можем установить область, которая будет удерживать программу и завершать ее, вместо того, чтобы зацикливаться вечно. Первая операция, перемещающаяся из красной кодовой области в темно-красную область, имеет значение push1, затем программа поворачивается и опускается в светло-красный кодовую область в середине и pushполучает значение 2. Выполняется переход от светло-красного к светло-желтому. addоперации. Нижняя светло-желтая полоска приводит к завершению программы, поскольку у нее нет возможности вытечь, поскольку все углы заблокированы.


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

12 кодеков

12 кодеков

Наконец, программа, которая делает что-то, что может считаться полезным (хотя это все еще немного натянуто). Читает 2 числа из стандартного ввода последовательно, а затем выводит их сумму, и делает это многократно.

Программа проходит слева направо по 4 цветным полосам, inputsвыполняемым 2, после чего следует addкоманда. Затем он перемещается в правый нижний код и выполняет операцию output, а затем идет влево через белую область обратно к началу.

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

15 кодов

15 кодов

Читает число из стандартного ввода и выводит его квадрат.

Это использует несколько приемов, чтобы получить симметричный вид программы, которая на самом деле что-то делает. Крайняя левая красная полоса имеет другой цвет на нижней коделе, чем остальные, и использует тот факт, что (по крайней мере для меня) эти 2 оттенка красного выглядят очень похожими. программа переместится из более светлой красной области прямо в голубую коделлу, а затем прямо через середину программы в светло-зеленый справа, где она захвачена. Он выполняет input, duplicate, multiplyи outputоперации.

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

20 кодеков

20 кодеков

Читает числа из стандартного ввода до тех пор, пока не будет прочитан 0, после чего он выводит сумму всех введенных чисел и завершает работу.

Наконец-то у нас достаточно места для управления потоком в форме pointerоперации. В 4 codels вдоль верхней выполнить input, duplicateи notоперации, а затем другую notоперацию перехода от пурпурного в верхнем правом углу на 2-codel желтого ниже него. notОперация выталкивает верхнее значение из стека и нажимает 1 , если верхнее значение было 0, и 1 в противном случае. Поэтому double notзаменяет любое ненулевое значение на 1. Перемещение от желтой полосы вниз к темно-синему выполняет pointerоперацию, которая выталкивает верхнее значение из стека и перемещает указатель направления по часовой стрелке столько раз.

Если верхнее значение равно 1 (т. Е. Мы не ввели ноль), указатель направления укажет влево, перейдя к пурпурным кодам для addоперации (которая будет игнорироваться в первый раз из- за наличия только одного значения в стеке) и затем через белый обратно к началу программы.

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

25 кодексов

25 кодексов

Обратный отсчет! Считывает число из стандартного ввода, а затем печатает обратный отсчет до 1, чтобы выводить одно число за раз. Например, если прочитано 5, будет напечатано 54321.

Первая операция от голубого до желтого цвета input. Тогда желтый - это то место, где начинается программа «цикл». Желтый> Пурпурный> Синий - это duplicateтогда an output, поэтому он печатает верхнее значение в стеке, но сохраняет копию. Перемещение вниз по правой стороне, мы pushзначение 1 в стек затем выполнить subtraction, уменьшая наше введенное значение на 1. Далее идет duplicate, notи другое notперемещение от светло - пурпурные в нижнем правом углу на темно - желтый рядом с ним. Это та же самая проверка нуля / нуля, что и в предыдущей программе. Перемещение влево в светло-синий кодел выполняет pointerоперацию, которая либо переместится влево в темный голубой цвет, чтобы завершить программу, если мы закончили, либо до желтого, чтобы перезапустить наш цикл без начального ввода, но исходное значение уменьшилось на 1

Все 3 красных кодекса являются декоративными и могут быть любого цвета.

30 кодов

30 кодов

Генератор Фибоначчи. Распечатывает условия последовательности Фибоначчи на стандартный вывод и не останавливается.

Это первое знакомство с rollоператором, а также первый случай, когда размер области больше 1 используется с pushоператором для получения определенного значения в стеке.

Как всегда, начинается движение в верхнем левом углу. Первые 2 операции pusha 1 на стеке, а затем outputего, так как последовательность Фибоначчи начинается с двух 1, но основной цикл программы будет печатать только 1 раз. Затем он pushпомещает еще 2 единицы в стек, чтобы попасть в темный пурпурный цвет в правом верхнем углу, чтобы запустить основной цикл программы.

Двигаясь вниз по правой стороне мы duplicateи outputраспечатываем следующий член последовательности, затем duplicateснова получаем копию текущего значения последовательности. Перемещение влево по дну выполняет 2 pushоперации. Так как светло-красная область в нижнем правом углу имеет 3 кода, размер первого помещает в pushстек 3 вместо 1.

Перемещение в голубой цвет - это rollоперация. Это выталкивает верхние 2 значения из стека и выполняет число бросков, равное первому извлеченному значению, на глубину, равную второму вытолкнутому значению. В этом случае он выполнит 1 бросок на глубину 3. Бросок на глубину nберет верхнее значение стека (наше дублированное текущее значение) и скрывает его в nглубине. Наш стек сейчас только на 3 глубины, поэтому он похоронит верхнее значение внизу.

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

Желтый шаблон в середине никогда не используется.

54 кодекса

54 кодекса

Печать "привет!" вытащить

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

Программа начинается с push5 из голубой области слева. Отсюда он течет прямо вдоль вершины с 6 duplicateоперациями, чтобы заполнить стек связкой 5 с. Далее push1, subtractчтобы положить 4 на вершину стека, затем 2 multiplyоперации, чтобы положить 4 * 5 * 5 = 100 на вершину стека. Тогда duplicateна 2 100 с.

Теперь программа отскакивает от черного и начинает работать влево вдоль дна. Pushоперации 3 и 2, а затем a, rollчтобы похоронить 2 100s под 5. Далее следует push1, вычтите и добавьте, чтобы получить 100 + 5-1 = 104 на вершине стека, что является юникодом "h". Следующие 2 операции: push1, pointerчтобы обойти угол и начать движение прямо по центру, а затем outputвывести «h».

Далее стоит add100 + 5 = 105 сверху стека и outputвыведите «i». Стек теперь содержит две 5-ки. Push1, add, multiplyдает (1 + 5) * 5 = 30. Наконец push3 и addза 33, и outputза трейлинг "!". Затем программа проходит через оставшееся пустое пространство и заканчивается зеленым цветом справа.


5
Ах да, ждал этого :)
Sp3000

Чем это отличается от языка 2D персонажей? Это просто способ передать значения ячеек.
JDługosz

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

13
Если мы говорим о функциональной эквивалентности, вы можете спросить: «Чем это отличается от машины Тьюринга?» но тогда вы могли бы задать этот же вопрос кошке, или планете Юпитер, или любому другому языку ...
trichoplax

3
Пример с 9 кодами выглядит как мини-покебол. Приятно.
The_Basset_Hound

154

> <> (Рыба)

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

Factoid:

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

Длина 1 фрагмента:

X

Xявляется недопустимой командой в> <>, поэтому выводится сообщение об ошибке something smells fishy.... Фактически, это единственное сообщение об ошибке в> <>, независимо от того, является ли причина делением на ноль или попыткой вытолкнуть пустой стек.

Длина 2 фрагмента:

1n

Поток программы в> <> начинается сверху слева и изначально направо. 1помещает 1 в стек, а затем nпечатает его как число (в отличие от символа ASCII). Но> <> программы являются тороидальными, а это означает, что указатель инструкции оборачивается, когда достигает конца строки. Итак, после того, как nмы переносим начало, нажимаем 1, печатаем, переносим начало, нажимаем 1, печатаем ... и мы в конечном итоге печатаем 1s навсегда!

Длина 3 фрагмента:

"o;

Здесь "разбирается строка, oвыводится как символ ASCII и ;завершает программу. Но что на самом деле делает программа в целом?

Ну, во-первых, мы начинаем анализ строки, помещая каждый символ, который мы видим, в стек, пока не найдем закрытие ". Мы нажимаем an o, затем a ;... и переносим указатель инструкций обратно в начало. Но теперь мы на "так мы остановить строки синтаксического анализа, и , наконец , мы выполняем oи ;в обычном режиме для печати в верхней части стека ( ;) и заканчиваются.

Да, мы просто использовали один и тот же символ кавычки для начала и окончания строки!

Длина 4 фрагмента:

42n;

Исходя из того, что мы видели до сих пор, вы можете ожидать, что это вызовет 42, выведет как число, а затем завершится. Но все инструкции в> <> являются одинарными символами, поэтому на самом деле они помещают 4 и 2 , затем выводят вершину стека как число (только 2) и завершаются.

Длина 5 фрагмента:

<v
;>

Помните,> <> это двумерный язык. Это означает, что должны быть способы изменить направление выполнения программы!

Как и в случае с Befunge, вы можете сделать это с помощью стрелок >^v<. Чтобы проиллюстрировать, как они работают, давайте посмотрим на вышеуказанную программу:

  • Поток программы изначально направлен
  • < заставляет программу двигаться влево - мы идем налево и поворачиваемся к v
  • v заставляет программу течь вниз - мы идем вниз к >
  • > заставляет программу двигаться вправо - мы идем вправо и оборачиваемся к ;
  • Наконец, мы прекращаем.

Длина 6 фрагмента:

";"00p

Еще одна интересная особенность> <> - это рефлексивность - программа может изменять свой собственный исходный код на лету!

Здесь мы нажимаем ;, а затем два нуля. pЗатем всплывает три верхних элемента y, x, v( yбудучи в верхней части стека) и места vна позиции x,y. Другими словами, pв этой программе точка с запятой ставится в точку 0,0, превращая код в ;;"00p. Это затем позволяет программе завершиться, поскольку указатель инструкции теперь оборачивается и выполняет вновь помещенное ;.

Длина 7 фрагмента:

\7*n;
6

В отличие от Befunge,> <> также имеет зеркала ( \/|_#), которые отражают направление выполнения программы. Итак, вот мы:

  • Начинаем направо, но \отражаем нас вниз
  • Нажмите 6 и заверните
  • Ударить задом \и отразиться вправо
  • Нажмите 7
  • Умножьте два верхних стека
  • Вывести и прекратить

Перемещение по горизонтали через _зеркало или по вертикали через |зеркало не допускается.

Длина 8 фрагмента:

"r00g>o<

Вполне возможно, самая простая> <> квинна, если разрешено выдавать ошибку. Две новые инструкции здесь:

  • r: Перевернуть стек
  • g: Get - поп y, xи нажать символ в x,yстек (аналог в p)

Используя трюк обтекания строк, программа сначала выдвигает, а r00g>o<затем снова нажимает первую кавычку. Стек затем переворачивается, давая <o>g00r. После этого мы нажимаем на символ 0,0, чтобы ", чтобы дать <o>g00r". Наконец, мы ловим oмежду двумя стрелками, выводим верхнюю часть стека, пока ничего не осталось, и не получаем ошибку.

Длина фрагмента 9:

x0\>
\1n>

x(нижний регистр) перемещает указатель команд в случайном направлении, и программа демонстрирует эту функциональность, печатая случайные биты навсегда. Попробуйте следовать за стрелками и зеркалами, чтобы понять, как это работает! (Не забудьте проверить все четыре направления, в том числе вверх и влево)

Длина фрагмента 10:

;a comment

Нет синтаксиса комментариев в> <> - он не нужен. Просто напишите, что вы хотите где угодно и убедитесь, что это не выполняется как код!

Длина фрагмента 11:

1!X2!X+!Xn;

!это батут, который пропускает инструкции. Это особенно полезно при использовании ?, в условном батут , который выскакивает на вершину стека и выполняет следующую инструкцию , если совал элемент не равен нулю. Мы увидим, как это работает позже.

Приведенный выше код печатает 3, пропуская Xs, только выполняя 1! 2! +! n;.

Длина фрагмента 12:

01v
ao>:@+:n

Печатает числа Фибоначчи навсегда, начиная со второго 1, по одному в каждой строке. Новые команды:

  • a: Нажмите 10, что нам нужно для перевода строки. a-fнажмите 10 до 15 соответственно.
  • :: Дубликат вершины стека
  • @: Поверните три верхних элемента стека, например [5 4 3 2 1] -> [5 4 1 3 2].

Трассировка для первых нескольких итераций:

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

Длина фрагмента 13:

i:d=?v
l?!;o>

Программа TAC, которая считывает строку ввода и выводит ее в обратном порядке. Спасибо @tomsmeding за фрагмент.

=выскакивает два верхних элемента и нажимает 1, если они равны, иначе 0. Первая строка продолжает читать на входе до тех пор, пока не будет найден символ 13 ASCII (возврат каретки), после чего он переместится на вторую строку.

l?!;oПетля является важной конструкцией в> <> , который выводит весь стек. В отличие от этого >o<, это не вызывает никаких ошибок. Вот как это работает:

  • l толкает длину стека
  • Мы проверяем длину с ?:
    • Если длина была ненулевой, то выполняется следующая инструкция !, пропуская;
    • Если длина была нулевой, то мы не выполняем !и не завершаем из-за;

Обратите внимание, что на самом деле ничего не происходит, пока вы не нажмете возврат каретки.

Длина фрагмента 14:

32.

   X67*n;

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

.хлопки y, xи телепортирует указатель команд на x,yподдержание направления. Обратите внимание, однако, что вам нужно переместиться на один квадрат раньше, чем вы хотите - указатель инструкции обновляется перед выполнением следующей инструкции. Таким образом, здесь указатель инструкции попадает на недопустимый объект X, но все в порядке, поскольку указатель перемещается в 6перед продолжением выполнения.

.позволяет конвертировать большинство> <> программ в одну строку, но почему вы хотите потерять удовольствие от 2D? :)

Длина фрагмента 15:

01+:aa*=?;:nao!

Печатает числа 0по 99одному в каждой строке. Эта программа демонстрирует аккуратное использование !батута - чтобы гарантировать, что начальный 0 нажимается только один раз.

Длина фрагмента 16:

"r00g!;oooooooo|

Правильный квин, который не выдает ошибок, вдохновлен квин на странице esolang .

Если вы задались вопросом, как изменить предыдущую квину (фрагмент № 8), чтобы она не вызывала ошибку, и подумали: «Почему бы мне просто не добавить кучу oинструкций?», То вы могли бы понять, что для каждого oдобавляемого вами нужно вывести другое o! Эта квинна аккуратно решает проблему, помещая |зеркало в конце, что позволяет использовать каждый из oних дважды .

Если переключиться на одинарные (которые также являются для струнного разборе), то альтернативный Куайн , который не использует gэто

'r3d*!;oooooooo|

Длина фрагмента 17:

b2,63,.

   17,n;

У нас есть сложение ( +), вычитание ( -), умножение ( *), по модулю ( %) ... но как насчет деления? Он есть, но, поскольку /он уже является зеркалом, ,вместо этого разделению был присвоен символ. Интересно, что деление является делением с плавающей запятой , а не целочисленным делением!

Вышеупомянутая программа исследует некоторое неопределенное поведение, пытаясь перейти к 11/2, 6/3. Intepreter Python кажется , хорошо , если первая координата не является целым числом (хотя он прыгает в неправильном месте), но дроссели , если второй нет.

Длина фрагмента 18:

123456${{$}nnnnnn;

Мы видели, rчто переворачивает стек и @вращает три верхних элемента. Вот еще несколько команд, которые перемещают элементы в стеке:

  • $: Поменяйте местами два верхних элемента
  • {: Сдвинуть весь стек влево
  • }: Сдвиг всего стека вправо

Чтобы показать, как это работает, вот трассировка программы:

123456 ------> 123465 ------> 234651 ------> 346512 ------> 346521 ------> 134652
       $ Swap        { L shift      { L shift       $ Swap        } R shift

Затем мы выводим, давая 256431.

Длина 19 фрагмента:

"reward"4[roooo]oo;

До сих пор я говорил "стек", "стек" ...

Хотя большинство программ используют только один стек,> <> может иметь несколько стеков! Вот соответствующие инструкции:

  • [: Выскакивает xи перемещает верхние xэлементы в новый стек
  • ]: Удаляет текущий стек и перемещает его значения в базовый стек.

Вот след для вышеуказанной программы:

       [r e w a r d]       Push "reward"
4[     [r e] [w a r d]     Move four elements to a new stack
r      [r e] [d r a w]     Reverse the current stack
oooo   [r e] []            Output "ward"
]      [r e]               Remove the current stack, no values to move
oo     []                  Output "er", giving "warder" altogether

Обратите внимание, что простое нажатие rewardи последующий вывод его снова ooooooприведет к печати drawerиз-за природы стеков «первым пришел, последним вышел».

Длина 20 фрагмента:

aa*5+\
7a*2+\
oo;  \

Небольшая известная особенность> <> заключается в том, что, как и в Python, обратные слеши могут использоваться для продолжения строки во многих случаях. *

Приведенный выше код функционально такой же, как

aa*5+7a*2+oo;

* Отказ от ответственности: причина, почему это работает, может или не может быть по совершенно другой причине

Длина 22 фрагмента:

1&fv ;n&<
&1->:0=?^:&*

В дополнение к стекам> <> также имеет регистры (по одному для каждого стека), которые можно использовать для хранения значений. Вызов &в первый раз перемещает верхнее значение стека в регистр, а &повторное выполнение возвращает значение назад. Это может быть очень полезно при накоплении значения, например, сумм и факториалов.

Программа выше вычисляет факториал f(15), печатая 1307674368000. Вот след для fзамены на 4:

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

Длина 24 фрагмента:

"Hello, World!"rl?!;of0.

У нас достаточно символов для любимой программы каждого! Здесь мы используем .телепорт для петли вывода.

Длина фрагмента 25:

0i:0(?v$a*$"0"-+!
   ;n~<

К сожалению,> <> позволяет читать из STDIN только один символ за раз, что делает чтение в цифрах немного сложным. Для ввода, состоящего из цифр 0-9, эта программа по сути является atoi, преобразующей строку цифр из STDIN в число в стеке (которое затем печатается).

Еще одно замечание, что в EOF iпомещает -1 в стек. Это облегчает проверку EOF, сравнивая с использованием 0 (или «меньше чем».

Этот фрагмент также использует ~, который выскакивает и отбрасывает верхний элемент стека.

Длина 33 фрагмента:

i>:nao:1=?;\
 ^  ,2v?%2:/
 ^+1*3<

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

Программа считывает один символ ASCII и запускает 3x+1алгоритм в своей кодовой точке (In> <> символы в основном являются целыми числами). Каждый шаг алгоритма печатается, пока мы не нажмем 1.

Вот трассировка для первых нескольких итераций с вводом a(кодовая точка 97):

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

Длина 44 фрагмента:

a&>i:0(?v"+"$\
/&^?=0l< "a*"/
\:1+&2p/\0
n
;

Я не чувствую, что выполнил pкоманду, просто применив ее всего один раз назад во фрагменте № 6, так что здесь другая функция atoi. Что классного в этом? Программа записывает выражение, необходимое для вычисления числа, при чтении ввода!

Таким образом, для ввода вроде 573после того, как все символы прочитаны, конец третьей строки будет выглядеть примерно \0a*5+a*7+a*3+573!

Еще раз, ожидается, что ввод будет состоять только из цифр. Проследите GIF здесь .

Длина фрагмента 74:

>i:'A'(?v:'N'(?v:'['(?v\
  :'a'(?v:'n'(?v:'{'(?v\
^      o<    +d<  -d-d<o

Если вам удалось попасть сюда, то вы можете согласиться со мной, когда я скажу, что это одна из самых читаемых программ ROT13. Учитывая голец c1, мы находим первый символ c2в AN[an{такой , что c1 < c2, а затем применить соответствующее смещение путем добавления / удаления d(13). Обратите внимание, что [и {символы непосредственно после Zи zсоответственно.

Попробуйте в консоли и наблюдайте, как буквы преобразуются по мере ввода!

(Вы можете также передать данные во входные данные, но, поскольку я пропускаю проверку EOF, :0(?;она остановится с ошибкой, когда попытается вывести -1 в виде символа)


Идея для 13 фрагмента: i:d=?v NEWLINE o;!?l<- печатает строку ввода назад
tomsmeding

12
Я хотел бы отдать это больше голосов, теперь я вдохновлен начать учиться> <> ...
Робобенкляйн

6
+1 за начало сверху и спуск (а также просто потому, что это интересно читать).
mbomb007

5
@ mbomb007 обидно, однако, что порядок не может идти влево / вправо и
переноситься в конец

Ваш фрагмент длины 8 был бы настоящим квинем, если бы вы написали something smells fishy...на следующей строке.
wizzwizz4

148

C - редактировать

Спасибо за голоса! По сравнению с другими языками и тем, что они могут делать в ограниченных байтах, C выглядит устаревшим, суетливым и слишком зависимым от разработчика. Во многих отношениях это так: скриптовые языки и языки более высокого уровня с автоматическим управлением памятью намного более выразительны и быстрее в производстве, чем С когда-либо будет.

Так почему функция C?

Тайна, скрывающаяся за всеми этими языками сценариев, заключается в том, что интерпретаторы, вероятно, написаны на C (или в последнее время на C ++ или Java). Первые компиляторы C ++ фактически скомпилированы в C-код. Фактически, пока не существует рынка для прямого компилятора, обычно экономически выгоднее написать компилятор для генерации C, а затем скомпилировать его.

Если вы работаете на очень маленьких платформах, может быть, даже без операционной системы, вы, вероятно, работаете на C. В наши дни почти каждое устройство имеет встроенный микроконтроллер, без сомнения, запрограммированный на C. Когда им это нужно маленький и быстрый, C это путь. (Также ВЕРНО, для мазохистов.)

Знание C делает вас настолько близким к металлу, насколько это возможно, не вдаваясь в ассемблер, и помогает вам на других языках. У вас есть хорошая идея, как, вероятно, работает виртуальная функция C ++. Когда вы пишете эти рекурсивные функции передачи по значению в PHP, вы знаете, что внутренне он выполняет большое количество выделения и копирования памяти, поэтому вы инстинктивно пробуете передачу по ссылке. Обратные вызовы и ссылки не пугают разработчиков на C, хотя, возможно, Haskell делает.

Как упомянули Керниган и Ричи в предисловии к классическому языку программирования Си , 2-е издание, Си не является большим языком и плохо обслуживается большой книгой. Я пытаюсь следовать этому совету: примеры выполняют двойную, тройную или более обязанность, если это возможно.

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

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

Factoid

С породами.

Фрагмент длины 0

Самая короткая в мире самовоспроизводящаяся программа http://www.ioccc.org/1994/smr.hint

Длина 1 фрагмента

;

C делает различие между компиляцией и компоновкой. Многие объекты в C просто компилируются и связываются позже - примером являются статические и динамические библиотеки.

Другие объекты просто включены и не генерируют код самостоятельно.

Вышеуказанная точка с запятой, безусловно, будет компилироваться в объектный код и ничего не делать!

Длина 2 фрагмента

x;

C, будучи более старым языком программирования, прошел несколько итераций. Самое раннее в широком использовании было разработано Керниганом и Ричи и сокращенно K & R. K & R C делает много предположений о вашем коде, если вы явно не предоставляете их.

В частности, в K & R C предполагается, что приведенный выше код является глобальным целым числом, xинициализированным равным 0. При его компиляции в режиме K & R будет создан объектный файл, который предоставляет любой программе, ссылающейся на эту переменную, для его использования.

Длина 3 фрагмента

??/

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

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

Длина 4 фрагмента

f();

Опять же, с K & R, вышеприведенное «заполняется», что означает при компиляции, что «существует глобальная связь с функцией f, которая будет предоставлена ​​позже, которая принимает фиксированное, но неопределенное количество аргументов и возвращает целое число».

Обратите внимание на принципиальные различия между этим и f;.

Длина 5 фрагмента

s="";

K & R C известен тем, что он действительно прощающий. После компиляции этот код предоставит целое число sдля глобальной связи, которое инициализируется начальным адресом пустой строки (я думаю). K & R тихо обрабатывает все приведения, включая усечение, если целое число недостаточно велико для хранения адреса.

Именно такие конструкции породили много труднодоступных ошибок и послужили источником вдохновения для соревнований IOCCC.

Длина 6 фрагмента

o=042;

Гоча даже старых таймеров, ведущий 0 в буквальном числе означает, что следующие цифры находятся в восьмеричной базе. Приведенный выше код после компиляции предоставит целое число oдля глобальной связи, инициализированной до десятичной 34.

Эта особенность C укусила многих разработчиков, стремящихся дополнить свои номера, чтобы они выстраивались в линию красиво и ровно!

Длина 7 фрагмента

f(){f;}

Приведенный выше код является функцией с телом. Но что это делает? Он получает адрес функции и ничего с этим не делает! Обычно то, что возвращает функция, не определено. Такой бессмысленный код часто может компилироваться без предупреждения.

Длина 8 фрагмента

main(){}

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

Это чудо программы, которая ничего не делает, кроме как возвращает 0, будет компилироваться до значительного размера и связываться в различных подпрограммах времени выполнения Си. Вы можете скомпилировать и связать с многословием, установленным на full, чтобы увидеть, что происходит под капотом.

Длина 9 фрагмента

#define Z

Основой заголовочных файлов C является #defineдиректива препроцессора. Программы на С составляются на разных этапах, и на одном из этих этапов эти определения заменяются их фактическими значениями.

Когда аргумент отсутствует, С будет означать 1, таким образом , выше , будет заменить 1везде , где Zиспользуется в исходном коде.

Вышеупомянутое, как правило, будет помещено в заголовочный файл и #includeпри необходимости будет d

Длина фрагмента 10

enum{P,Q};

enumКлючевое слово обеспечивает способ иногда типобезопасный определить ряд констант. Как и определения, они часто используются в заголовочных файлах. Приведенный выше код будет содержать Pцелое число от 0 Qдо 1.

Длина фрагмента 11

volatile v;

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

Длина 12 фрагмента

#pragma once

#pragma once является нестандартной, но широко поддерживаемой директивой препроцессора, указывающей на то, что текущий исходный файл включается только один раз в одну компиляцию.

Традиционный и полностью поддерживаемый метод заключается в использовании средств #includeзащиты с недостатками добавленного кода и возможных конфликтов имен.

Длина 13 фрагмента

w(){for(;;);}

В C существует множество соглашений, и одним из них является представление бесконечных циклов. В этом случае for(;;)указывает на отсутствие инициализации, проверку на выход, которая по умолчанию равна 1, что означает «истина», т. Е. Не прерывать, и отсутствие зацикливания кода.

Иногда можно сделать все внутри () и сам цикл не нуждается в теле. В этом случае фиктивная точка с запятой добавляется в конце.

В приведенном выше коде, когда он скомпилирован, он предоставит функцию, которая войдет в плотный цикл занятости - один из «нет» в разработке программного обеспечения - и никогда не вернется.

Длина фрагмента 14

int a[]={1,2};

Массивы в C не нуждаются в указанной длине. Пустые квадратные скобки []говорят компилятору «разобраться самому». Однако в C, в отличие от других языков, нет встроенного способа предотвращения доступа к массиву за пределами этих границ, что приводит к метафоре «стреляй себе в ногу», которой славится C.

Приведенный выше код при компиляции предоставит глобальный изменяемый массив aиз двух целых чисел, инициализированный 1 и 2.

Длина фрагмента 15

const long k=7;

constSpecifer является более поздним дополнением к C заимствован из C ++. Общий вопрос интервью: «Имеет ли смысл определять переменную как volatile const?». constнаряду с enumи inlineпредназначены для уменьшения зависимости от#define которая имеет проблемы с типом безопасности.

Длина 16 фрагмента

extern void **q;

externиспользуется, чтобы указать, что переменная объявлена ​​в другом месте. void *Типа является стандартным универсальным типом в C, то есть он не должен быть явно брошен или отлит из в операторах присваивания. **Последовательность операторов означает указатель на указатель, который часто дует умы новичков, но вполне допустимо и часто используется C.

Длина 17 фрагмента

double d=4/3-1/3;

Если бы вы напечатали вышеизложенное, результат был бы один, и вы бы подумали, супер! Изменить на double d=4/3-2/3;и каков ответ? Это все еще один! C использует целочисленную арифметику для вычисления 4/3 → 1 и 2/3 → 0, а 1 - 0 → 1!

Длина 18 фрагмента

main(){puts("!");}

Наконец мы добрались до некоторого кода, который действительно что-то делает! putsявляется фаворитом игроков в гольф C, потому что он не требует заголовочный файл для использования.

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

Длина 19 фрагмента

#include <stdlib.h>

Включение заголовочных файлов часто является личной подписью разработчиков. Многие включают libи ioнезависимо от того, нужны ли они. Некоторые упорядочивают заголовочные файлы так, чтобы длины увеличивались или уменьшались. Большинство поставлено <>раньше "". Лично я использовал эту подпись в свои дни TA, чтобы проверить на мошенничество среди студентов: та же подпись заголовка? Присмотритесь!

Длина 20 фрагмента

char*p=(char*)0x300;

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

В приведенном выше коде адрес порта определен как шестнадцатеричный 300. Вы можете получить доступ к значению порта, используя *p, как, *p=0xff;чтобы включить все биты или v=*p;получить текущее значение.

Длина 21 отрывка

int w=sizeof(double);

sizeofОператор обеспечивает размер в байтах типа. С именами переменных скобки не требуются, например double d;int w=sizeof d;.

Длина 22 фрагмента

asm("xorl %ecx,%ecx");

Как asmиспользовать, определяется компилятором. Выше приведен пример встроенного кода Linux gcc на платформе Intel.

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

На совместимых системах приведенный выше код будет скомпилирован, и это будет в буквальном смысле изолированная инструкция по сборке без обычных средств доступа к ней! Кстати xor R,R, это общая идиома языка ассемблера для быстрой очистки реестра.

Длина 23 фрагмента

union u{char c;int i;};

A unionпредоставит как минимум достаточно места для самого большого элемента. Может показаться, что он используется в сочетании с void *предоставлением общего «непрозрачного» типа в определенных библиотеках. В этом случае объединение обычно будет частью более крупной структуры, причем структура имеет поле для идентификации типа объединения.

Длина 24 фрагмента

/*INTS*/int i,j,k;//INTS

Оригинальный комментарий C был ограничен как /* comment */, и заимствовал // comment to end of lineформат из C ++.

Длина 25 фрагмента

int main(void){return 1;}

Это более совместимая версия фрагмента длины 8 выше. Тип возвращаемого значения и типы функций указаны, и он имеет явно возвращаемое значение.

Соглашение в C состоит в том, чтобы использовать возвращаемое значение 0для успеха и 1для неудачи, или если вы хотите быть строго совместимым EXIT_SUCCESSи EXIT_FAILUREкак определено в stdlib.h.

Длина 26 фрагмента

typedef struct{int x,y;}P;

typedefчрезвычайно полезен, в частности typedef struct. В современных терминах это можно назвать «объект-ориентация-свет».

После включения вышесказанного код можно использовать Pкак обычный тип в объявлениях и функциях с полной проверкой типов. В отличие от C ++, вы не можете определять операторы, такие как +, * или <<, следовательно, «object-direction-light».

Длина 27 фрагмента

#define C(x,y)(((x)+1)*(y))

C имеет удобный макрос- #defineсинтаксис.

Распространенной ошибкой новичка является пропуск внутренних и / или внешних скобок, что приводит к трудно обнаруживаемым ошибкам приоритета операторов.

Длина фрагмента 28

struct f{int s:1,e:8,m:23;};

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

Выше приведен пример структуры данных с плавающей запятой IEEE одинарной ширины.

Длина 36 фрагмента

f(unsigned x){return!!x&!(x&(x-1));}

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

Лучший пример этого, который я могу придумать, - определить, является ли целое число степенью двух {1, 2, 4, 8, ...}. Те, кто не знаком с C, будут выполнять циклы и сдвиги и всякие вещи для времени выполнения O (log (n)), неплохо, но выше - функция, которая будет делать то же самое во время выполнения O (1). Я оставлю это в качестве упражнения для читателя, чтобы подтвердить, что это работает, но это действительно ...

!!Конвенции часто используется , чтобы заставить целое число от ненулевых и нуля до 1 и 0 соответственно. Многие разработчики C любят использовать такие приемы (часто в отличие от тех, кто ценит ясность кода).

Разработчики Super C могут подтвердить, что все вышеперечисленное будет работать на оборудовании с одним дополнением и подписанным оборудованием. Для тех, кто интересуется, вы почти наверняка будете работать на оборудовании с двумя дополнениями прямо сейчас. Только действительно удачливым (или неудачливым, в зависимости от вашей точки зрения) нужно беспокоиться об этом!

Длина 48 фрагмента

#include<complex.h>
double complex c=3.0+I*4.0;

C99 включает в себя поддержку комплексных чисел. Как вы можете видеть из кода, он принимает форму модификатора для реального типа. Вы также можете использовать, int complex c=3+I*4;но внутренне это приводит к типу с плавающей точкой. Приведенный выше код компилируется в GCC , используя gcc -std=c99 -c length-48.c.

Если вы хотите увидеть больше внутренних компонентов, попробуйте скомпилировать с ключом -E. Для моей версии gcc объявление выше становится double _Complex c=3.0+(__extension__ 1.0iF)*4.0;. Обратите внимание, что сложный тип является значительным дополнением к языку, а не просто несколькими дешевыми макросами.

Это просто тизер, когда мы получаем более 125 символов, тогда мы можем по-настоящему повеселиться с комплексными числами!

Длина фрагмента 51

#include <math.h>
main(){double d=sqrt(sin(3.2));}

По разным причинам C не автоматически связывается со стандартными математическими функциями, такими как sin, cos, tan, sqrt и т. Д. Поэтому, если они используются, но не связаны, разработчику будет предоставлена ​​ошибка компоновщика, неопределенная ссылка на 'sqrt' , или какая-то другая ошибка.

В gcc приведенный выше код будет компилироваться и ссылаться с помощью gcc length-51.c -lm.

Примечание sin(3.2)вернет отрицательное число, квадратный корень которого недопустим в реальном домене. В C NaNвозвращается специальное значение , указывающее на эту ошибку, которую программа может игнорировать!

В C99 есть много новых функций обработки исключений, которые обеспечивают очень безопасный и детальный контроль над этими видами математических ошибок, которые практически никто не использует!

Длина 63 фрагмента

static int w;static int X(int x){static int s=0;s^=x;return s;}

Или отформатировано более разумно:

static int w;
static int X(int x)
{
    static int s=7;
    s^=x;
    return s;
}

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

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

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

В последнем случае staticуказывает, что целое число sсохраняет свое значение между вызовами функций. Первый раз Xвызывается, sбудет его начальное значение 7, когда он эксклюзивно OR сx , новое значение будет сохранено.

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

Гоча в C - это конфликты с глобальными переменными. До wи Xфактически определены как static, если они определены где-то глобально, то wи Xбудет ссылаться на глобальные объекты вместо.

Здесь qи wне может быть инициализировано одно и то же значение, потому wчто для установки используется глобальное значение q:

static int q = w;
static int w;

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

Здесь qи wбудет инициализировано то же значение:

static int w;
static int q = w;

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

В C99 staticполучил другое использование, например, int Y(int a[static 10]);что означает, что есть функция, Yкоторая принимает массив по крайней мере 10 целых чисел.

Длина фрагмента 74

void f(register int*p,register int*q,register int l){while(l--)*p++=*q++;}

Или выложил красиво:

void f(register int *p, register int *q, register int l)
{
    while (l--)
        *p++ = *q++;
}

Ключевое слово registerдает подсказку компилятору, что использование аппаратных регистров было бы здесь полезно. Вышеупомянутая функция скопирует lцелые числа из qвp , используя, если возможно, аппаратные регистры.

Иногда ускорения могут быть значительными. Например, в семействе микропроцессоров 68K, строка *p++ = *q++может быть переведена в одну инструкцию MOVE.W (Ap)+,(Aq)+вместо шести или восьми, если вы не используете register. Микропроцессор 68K имел явные пост-инкрементные и пре-декрементные режимы, поэтому опытный разработчик, если бы он знал платформу, адаптировал код с помощью x++и --yпротив ++xи y--.

В наши дни компиляторы в основном игнорируют register, за исключением того, что не разрешают брать адреса из них (например, в приведенном выше случае &lможет вызвать ошибку компилятора).

Длина 88 фрагмента

#include<stdio.h>
int f(int x){return(x>1)?x*f(x-1):1;}int main(){printf("%d\n",f(12));}

Или с более разумным расположением:

#include <stdio.h>

int f(int x)
{
    return (x > 1)? x * f(x - 1): 1;
}

int main()
{
    printf("%d\n", f(12));
}

Ах, рекурсия! Фрагмент - это полная программа для компиляции, компоновки и запуска. Функция fвычисляет факториал своего аргумента x, используя рекурсивную формулу f (x) = x * f (x - 1). Факториалы очень быстро растут, поэтому, например, f(12)это наибольшее значение, которое вы можете получить в 32-разрядном целом числе со знаком.

Для примера действительно рекурсивного кода, посмотрите на наивные реализации функции Аккермана .

Умные компиляторы могут оптимизировать функцию, используя подсказку inlineи «развернуть» функцию, когда константы предоставляются в качестве аргументов так, чтобы:

f(12)

становится:

12 * 11 * 10 * 9 * 8 * 7 * 6 * 5 * 4 * 3 * 2 * 1

Без каких-либо вызовов функций требуется!

Другие компиляторы могут реорганизовать функцию:

int f(int x)
{
    return (x < 2)? 1: f(x - 1);
}

И реализовать то, что называется хвостовой рекурсией. Фактически это заменяет последний вызов функции простым переходом и позволяет этой функции справиться с возвратом. Преимущество заключается в меньшем разбивании стека, более быстром и меньшем объеме кода.

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

Длина 117 фрагмента

#include<stdio.h>
int main(int c,char**v){int a,b;sscanf(v[1],"%d%*[\t ,]%d",&a,&b);printf("%d\t%d\n",a,b);return 0;}

Или же:

#include <stdio.h>

int main(int c, char **v)
{
    int a, b;

    sscanf(v[1], "%d%*[\t ,]%d", &a, &b);
    printf("%d\t%d\n", a, b);

    return 0;
}

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

В приведенном выше фрагменте он будет принимать данные командной строки, анализировать два целых числа, разделенных пробелами, табуляцией или запятыми, и выводить их. Он использует более новый scanfспецификатор, %*[\t ,]который будет: [\t ,]извлекать все табуляции, пробелы и запятые и: *игнорировать их.

Я помню, как пересматривал некоторый код C ++, где разработчик делал все «чистым» способом C ++ <<и арсеналом таких методов, как findи substr. Это было по крайней мере дюжина строк, и он все еще не мог обрабатывать запятые как разделители. Я заменил весь этот неуклюжий код одной sscanfстрокой, как указано выше!

Длина 132 фрагмента

#include<stdio.h>
int main(int c,char**v){while(--c){++v;printf("|%s|\n|%5s|\n|%-5s|\n|%.5s|\n|%5.5s|\n",*v,*v,*v,*v,*v);}return 0;}

Или же:

#include <stdio.h>

int main(int c, char **v)
{
    while (--c)
    {
        ++v;
        printf("|%s|\n|%5s|\n|%-5s|\n|%.5s|\n|%5.5s|\n", *v, *v, *v, *v, *v);
    }

    return 0;
}

Функции printf, sprintf, fprintfспецификаторы и т.д. использовать формат , чтобы определить ширину и отступы на выходе.

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

> main xyz 123456
|xyz|                                                                                                                                                
|  xyz|                                                                                                                                              
|xyz  |                                                                                                                                              
|xyz|                                                                                                                                                
|  xyz|                                                                                                                                 
|123456|                                                                                                                                             
|123456|                                                                                                                                             
|123456|                                                                                                                                             
|12345|                                                                                                                                              
|12345| 

Обратите внимание, что .5вывод для спецификатора ограничен не более чем пятью символами, в то время как ведущий 5обеспечивает вывод не менее пяти символов с -указанием выравнивания по левому краю. Объединяя их, вы получите ровно пять символов.


4
Я не думаю, что было требование добавлять новый фактоид для каждого upvote :)
Оптимизатор

28
Обычная культура в C - игнорировать предупреждения компиляции , я не думаю, что это близко к истине!
Шахбаз

4
Если у вас большой проект и вы рассматриваете несколько компиляторов, попытка устранить все предупреждения может оказаться бесполезной.
feersum

5
Это отлично
Кик

4
Я программист на Си, и я не боюсь Хаскелла.
Шахбаз

138

машинный код x86

Factoid:

Машинный код x86 - это собранная версия сборки x86, на которой фактически работает процессор. Он был разработан еще тогда, когда память и пространство хранения были дорогими, и был спроектирован так, чтобы быть несколько обратно совместимым вплоть до Intel 8008. Одной из целей было сохранение небольшого размера исполняемого кода, а также использование инструкций переменной длины и архитектуры CISC, чтобы помочь достичь этого (что имело недостаток в том, что усложняло работу на современных процессорах). Это, наряду с простой структурой сборки и машинного кода в целом, дает программам x86 возможность быть чрезвычайно компактными.

Длина 1:

Теперь для первой программы:

0xC3

Откройте шестнадцатеричный редактор, введите этот байт и сохраните его как test.com.

Теперь у вас есть действующая программа MS-DOS, которая немедленно возвращается, ничего не делая, поскольку 0xC3 - это инструкция «RET». Это, однако, показывает еще один интересный аспект игры в гольф с x86: формат файла .com. Этот исполняемый формат не имеет абсолютно никакого заголовка - файл просто загружается в память, начиная с адреса 0x100, а затем начинается выполнение с 0x100. Это означает, что байты не потрачены на метаданные!

Длина 2:

Наша следующая программа:

0x4D 0x5A

или «MZ» в ASCII.

Хорошо, я немного обманул, это действительно бесполезная программа, так как она соответствует инструкции

DEC     BP
POP     DX

Которые на самом деле не полезны для запуска программы .com. На самом деле, в этом и заключается смысл этих двух значений - ни один разумный файл .com не должен начинаться с них! Размер файлов .com был ограничен 65280 байтами (64 КБ - 0x100), поэтому, когда начали появляться программы большего размера, необходимо было разработать новый формат. Это был формат файла .exe, который имеет заголовок. Однако MS-DOS необходимо было сохранить расширение .com на некоторых компонентах для обратной совместимости, поэтому ему нужен был способ определить, действительно ли файл .com был .exe. В качестве этого магического числа они выбрали строчку «MZ», и по сей день, если вы откроете файл .exe (или .dll) Windows в шестнадцатеричном редакторе, вы увидите, что они начинаются с этих двух байтов. Меня удивляет, что даже самая современная программа для Windows начинается с ограничения совместимости с 70-х годов.

Длина 3:

Теперь для бесконечного цикла:

41 E2 FD

Что переводится как

start:
inc cx
loop start 

Эта программа увеличивает значение CX (для начала> 0), затем выполняет инструкцию цикла. Цикл является отличным примером инструкции CISC, поскольку он объединяет 3 простые операции в одну специальную операцию: он уменьшает значение CX, проверяет, равно ли оно 0, и переходит на целевую метку, если нет. Существуют также формы цикла, которые проверяют другие флаги в дополнение к окончанию, когда CX равен 0. Мы могли бы сделать просто «начало скачка» для 2-байтового бесконечного цикла, но это было более интересно.

Длина 4:

Программа, которая минимально полезна:

40 CD 10 C3

Переведено на сборку:

inc ax    ; 1 byte
int 10h   ; 2 bytes
ret       ; 1 byte

Эта программа устанавливает консоль в 40x25 символов, очищает экран, а затем возвращается в командную строку. AX установлен в нужный нам видео режим (1), затем вызывается прерывание BIOS 10h, чтобы фактически установить режим видео и очистить окно перед возвратом. Ожидайте увидеть больше этих прерываний BIOS в будущем.

Длина 5:

Теперь мы можем реализовать программу паузы:

B4 01 CD 21 C3

Переведено на сборку:

mov ah,1  ; 2 bytes
int 21h   ; 2 bytes
ret       ; 1 byte

Эта программа говорит BIOS подождать, пока клавиша нажата, и вывести ее на экран перед возвратом. Это также демонстрирует, как на x86 некоторые регистры могут быть частично прочитаны или записаны. В этом случае мы устанавливаем старший байт AX (AH) в 1. На 32-битных процессорах вы также можете работать с младшими 16 битами, не затрагивая старшие 16 бит. Эта возможность изменения частичных регистров может быть полезна для программистов на ассемблере, но имеет недостатки для современных процессоров, пытающихся выполнить неупорядоченное выполнение , поскольку они могут вводить ложные зависимости данных.

Длина 9:

Теперь чтобы отобразить вывод:

68 00 B7 07 AB 40 79 FC C3

Переведено на сборку:

; These two instructions set up ES, the 'extra segment'
push 0xb700 ; 3 bytes
pop  es     ; 1 byte
label:
stosw       ; 1 byte, Store Word - Copy AX to [ES:DI] then add 2 to DI
inc  ax     ; 1 byte
jns  label  ; 2 bytes, Jump Not Signed - Jump unless the sign flag is set (when inc AX yields 0x8000
ret         ; 1 byte

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

16-битные программы могут адресовать только до 64 КБ напрямую. Чтобы обойти это, x86 использовал «сегменты» - специальные регистры, которые были бы умножены на 16 и добавлены ко всем доступам к памяти, чтобы дать 20 бит адресуемой памяти. Программа может изменить значения этих регистров сегмента, чтобы получить доступ к большему количеству памяти - или специальным областям памяти: эта программа модифицирует дополнительный сегмент для записи в видеопамять. Различные типы доступа к памяти использовали разные регистры сегментов, что позволяло коду, данным и стеку быть доступными в разных порциях памяти одновременно. Сегмент по умолчанию также может быть переопределен для многих инструкций.

Длина 20:

Давайте сделаем что-то узнаваемое - мы будем использовать «Правило 90» для рисования треугольников Серпинского.

B0 13 CD 10 68 0F A0 1F AC 31 C2 88 94 3E 01 87 D3 93 EB F4

В сборе:

mov al,13h      ; 2b
int 10h         ; 2b - Set the video mode to 13h

push    0xA00F  ; 3b
pop     ds      ; 1b - Set the data segment to video memory

start:          ; This loop runs 'Rule 90' to draw Sierpinski triangles
lodsb           ; 1b - load al with [ds:si] then increment si

xor     dx,ax   ; 2b - xor the left and right values of the previous row of pixels
mov     [si+318],dl ;4b - store result to memory

xchg    dx,bx   ; 2b - swap register values
xchg    ax,bx   ; 1b - swapping with ax is 1 byte shorter

jmp     start   ; 2b - infinite loop

Пример вывода: Треугольники Серпинского

Для этой программы мы используем несколько известный «Режим 13» - графический режим, который имеет разрешение 320х200 с 256 цветами. Он использовался многими популярными играми для DOS , такими как Doom.

Длина 21

Давайте посмотрим, кто изготовил процессор, на котором мы работаем.

0F A2 66 60 BB EE FF B9 0C 00 8A 17 43 B4 02 CD 21 E2 F7 FF E1

Переведено на сборку:

cpuid         ; 2b  CPU ID - retrieve processor information based on the value in AX. For AX=0,
              ;     the 12 bytes in EBX, ECX, and EDX are loaded with a vendor identification string
pushad        ; 2b  Push all registers on the stack (32 bit version)
mov  bx,0xffee; 3b  Start of the vendor identification string on the stack
mov  cx,12    ; 3b  12 characters to print
print:    
mov  dl,[bx]  ; 2b  Character to print
inc  bx       ; 1b  Advance string position
mov  ah,2     ; 2b  Set AH to the 'Print character to STDOUT' value
int  21h      ; 2b  Call the bios interrupt to print
loop print    ; 2b  Decrement CX and jump if it is not zero
jmp  cx       ; 2b  Instead of restoring the stack, just jump right to the exit point

Пример вывода:

c:\misc>cpuid.com
GenuineIntel

Эта программа использует инструкцию CPUID для получения информации о процессоре, на котором она работает, в частности, строке идентификации поставщика. Большинство людей увидят «GenuineIntel» или «AuthenticAMD», если только у них нет необычного производителя ЦП или они работают на определенных виртуальных машинах.

Длина 26

Теперь мы можем делать интересные анимации

B0 13 CD 10 C4 07 BB 40 01 59 99 89 F8 F7 F3 31 D0 AA E2 F6 26 FE 05 47 EB FA

В сборе

mov al,13h     ;2b
int 10h        ;2b Enter Video Mode 13h

les ax,[bx]    ;2b Set ES to (roughtly) video memory
mov     bx,320 ;3b Set up  BX asdivisor
pop     cx     ;1b Zeroize CX

start:
cwd            ;1b Sign extend AX to DX, AX will never have the sign bit set so this zeroizes DX in 1 byte
mov     ax,di  ;2b Copy video memory pointer
div     bx     ;2b Divide by width to get AX = Y pos, DX = X pos
xor     ax,dx  ;2b X pos ^ Y pos
stosb          ;1b Store and increment video pointer
loop    start  ;2b CX starts at 0, so this will loop until it wraps around

cycle:
inc     byte [es:di];3b Increment value in video memory to animate
inc     di     ;1b Increment video memory pointer
jmp     cycle  ;2b Infinite loop 

И результат будет выглядеть так:

Марширующий XOR

Функция X pos ^ Y pos производит интересный фрактал, особенно когда анимирован

Длина 27

Вы можете не только создавать текст и графику в небольшой x86-программе .com, но и создавать звук и музыку:

BA 31 03 B0 3F EE BA 30 03 B0 93 EE B4 01 CD 21 3C 1B EE 3C 1B B0 7F EE 75 EC C3

В сборе:

    mov dx,0x331            ; value for the midi control port
    mov al,0x3F             ; command value to set midi mode to UART
    out dx,al               ; output the command to the midi control port
play_loop:
    mov dx,0x330            ; value for the midi data port
    mov al,0x93             ; midi instrument value (piano)
    out dx,al               ; output to midi data port
    mov ah,1
    int 0x21                ; read character from stdin, with echo
    cmp al,27               ; test if it is escape
    out dx,al               ; output the ascii value as the midi note to play
    mov al,0x7F             ; note duration
    out dx,al               ; output note duration
    jne play_loop           ; loop if escape was not pressed
    ret  

Эта программа использует миди-карту для превращения клавиатуры в пианино. Для этого миди-карта устанавливается в режим UART, в котором миди-ноты воспроизводятся сразу после их получения. Затем программа ожидает нажатия символа и выводит значение ASCII в качестве примечания для миди-карты. Программа работает до тех пор, пока не будет нажата escape.

Длина 29

Давайте использовать систему итеративных функций для генерации фрактала Кривая Дракона:

B0 13 CD 10 89 D0 01 CA 29 C1 D1 FA D1 F9 73 03 83 E9 7A B4 01 CD 16 B8 02 0C 74 E6 C3

Переведено на сборку:

mov  al,13h
start:
int  0x10    ; This does double duty, setting the video mode to 13h at program start,
             ; and calling the 'draw pixel at coordinates' interrupt when looping
mov  ax,dx   ; The next couple instructions are our IFS, the algorithm is aproximately
add  dx,cx   ; f(y) = 0.5x + 0.5y
sub  cx,ax   ; f(x) = 0.5x - 0.5y OR f(x) = 0.5x - 0.5y - 1
sar  dx,1    ;
sar  cx,1    ;
jnc  skip    ; This jump handles pseudo-randomly switching between the two functions for x,
             ; based on if the previous value of x was odd or not.
sub  cx,122  ; Magic number, chosen since it provides sufficent 'randomness' for a filled in
             ; fractal and a good scale to the fractal. 102 and 130 also work.
skip:
mov  ah,1
int  0x16    ; Get keyboard state, zero flag will be set if no key has been pressed
mov  ax,0xC02; Set up AH for the draw pixel function when int 0x10 is executed,
             ; AL = color, CX = column, DX = row
jz   start   ; Loop if a key hasn't been pressed
ret  

Выход:

Кривая Дракона

Нажатие неуправляемой клавиши приведет к выходу из программы. Это основано на Fire Coral от Desire на Pouet.net.

Длина 52

Эта программа представляет собой двойную функцию, она показывает немного сопроцессора с плавающей запятой x87 и самоизменяющийся код.

B3 07 D9 E8 B1 11 DE 0E 32 01 E2 FA BE 0A 24 56 B1 09 DF 34 AC D4 10 
86 E0 05 30 30 50 E2 F5 44 B4 2E 50 89 E2 B4 09 CD 21 FE 06 03 01 4B
75 D2 CD 20 0A 00

При запуске программа выведет несколько математических констант:

1.00000000000000000
3.32192809488736235
1.44269504088896341
3.14159265358979324
0.30102999566398120
0.69314718055994531
0.00000000000000000

Это One, Log2 (10), Log2 (e), Pi, Log10 (2), Log e (2) и ноль.

В сборе:

орг 100ч

mov     bl,7         ;Counter for the total number of constants to print
start:
fld1                 ;Floating point constant to load on the FP stack,
                     ;start with 1 since it's op-code is the lowest

mov     cl,17        ;Multiply the constant by 10, 17 times to get the
mult:                ;printing part as an integer
fimul   word[ten]
loop    mult

mov     si,10+'$'*256;ASCII new line (10) and the end-of-string ($)
                     ;characters. These are used both as
push    si           ;a constant memory location, and stored to the
                     ;stack to format and printing

mov     cl,9         ;print 18 digits (9 pairs)
fbstp   [si]         ;store the integer part of the floating point
                     ;number on top of the FP stack as a packed
                     ;binary-coded decimal number (1 digit/nibble),
                     ;and then pop the number off the FP stack

convert:
lodsb                ;load a pair of packed digits

db 0xd4,16 ; AAM 16  ;ASCII Adjust For Multiply instruction using
                     ;non-standard base 16. This puts AL/16 in AH,
                     ;and AL%16 in AL, unpacking the digit pair.

xchg    ah,al        ;Swap the digit order
add     ax,'00'      ;Convert the digits to ASCII values
push    ax           ;Store digits on the stack
loop    convert

inc     sp           ;AX now holds the 1st 2 digits to print,
mov     ah,'.'       ;so to insert a decimal point, the 2nd digit
push    ax           ;is replaced with a '.', the stack pointer
                     ;is adjusted to overwrite 1 byte, and then
                     ;AX is pushed on the stack

mov     dx,sp        ;Load DX with the start of the print string
mov     ah,9         ;Load AH with the 'Print String' constant
int     21h          ;Call the 'Print String' interrupt to display
                     ;the constant

inc     byte[start+1];Self-modifying code - increment the load
                     ;floating point constant op-code to iterate
                     ;through all of them

dec     bx
jnz     start        ;Exit when all 7 constants have been printed
int     20h


ten: dw  10

Первоначально математика с плавающей запятой в системах x86 была обработана дополнительным сопроцессором x87, и только в 486 году она была перенесена на тот же чип. X87 также имел довольно другую архитектуру, основанную на стеке, с 8 80-битными доступными регистрами. Он также имел множество режимов округления, точности и маскируемых исключений, которые можно было установить.

Эта программа печатает значения для семи констант, запеченных в процессорах. Может показаться странным, что пространство инструкций будет потрачено впустую на простых константах, таких как 0 и 1, но имейте в виду, что набор инструкций был создан, когда памяти было мало, и эти инструкции обычно на 2 байта меньше, чем эквивалентные операции. Программа также использует скрытую инструкцию FBSTP -Store BCD Integer and Pop. Когда разрабатывался x86, операции с числами BCD были более распространенными, и x86 / x87 имеет несколько инструкций, специально предназначенных для упрощения математики BCD, таких как инструкция AAM «ASCII Adjust for Multiple», также используемая в программе.

В модели незащищенной памяти, используемой ранними программами x86, нет различий между данными и кодом. Из-за этого, легко перебирать последовательно закодированные инструкции «Load Constant», просто увеличивая соответствующее значение.

Длина 64

Перекрестная публикация моей записи о вызове Мандельброта , может быть написана программа, которая отображает цветной фрактал Мандельброта размером 320x200 всего в 64 байта.

B0 13 CD 10 C4 07 99 89 F8 B9 40 01 F7 F1 83 E8 64 FE CE 31 DB 31 F6 
89 F5 0F AF F3 01 F6 0F AF DB 70 19 0F AF ED 70 14 01 EB 70 10 29 EB
29 EB C1 FB 06 01 D3 C1 FE 06 01 C6 E2 DB 91 AA EB C6

В сборе:

mov al,13h ; set up graphics mode 13
int 10h

les ax,[bx]; trick to set video memory

FillLoop:
cwd
mov ax,di  ; di is the current position on screen
mov cx,320 ; convert di int x,y screen coordinates
div cx     ; CX is the iteration counter, exit the loop if it hits
           ; zero before the value escapes.
sub ax,100 ; center the fractal vertically
dec dh     ; center the fractal horizontally

xor bx,bx
xor si,si

MandelLoop: ; Fairly standard Mandelbrot routine,
mov bp,si   ; exits if the values overflow
imul si,bx
add si,si
imul bx,bx
jo MandelBreak
imul bp,bp
jo MandelBreak
add bx,bp
jo MandelBreak
sub bx,bp
sub bx,bp

sar bx,6   ; We use fixed point math with the lowest 6
add bx,dx  ; bits being the fractional portion, so this
sar si,6   ; rescales the values after multiplication
add si,ax

loop MandelLoop

MandelBreak:
xchg ax,cx ; Write the escape itteraction as the color
stosb
jmp FillLoop

Конечный результат - это изображение:

Фрактал Мандельброта

Эта программа использует математику с фиксированной точкой для генерации фрактала, поскольку она занимает меньше байтов. Младшие 6 битов из 16-битных регистров считаются дробной частью числа, а значения пересчитываются после умножения.


7
Из всех языков, которые можно увидеть на PPCG, я этого не ожидал.
Алекс А.

23
Ух ты. Плюс другие персонажи, чтобы сделать этот комментарий. Но серьезно. Ух ты.
krs013

2
@ Майкл Иденфилд Вот для чего предназначен DOSBox!
Sir_Lagsalot

1
20 байтов Серпинского очень впечатляют.
qwr

1
Я считаю себя хорошим программистом, но когда я смотрю на это, я должен признать свое поражение.
Стефан Бийзиттер,

121

Haskell

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

Читатели, которые не знают Haskell: мне ясно? Когда мне не ясно? Я не могу сказать.

Длина 86 фрагмента

Складной экземпляр для нашей древовидной структуры данных (фрагмент 23). Foldable - это класс типов - например, класс (/ группа) типов. Они параллельны интерфейсам в Java. Они по существу обобщают типы, объединяя типы, которые имеют общие характеристики; например, они могут быть добавлены вместе ( Monoid), контейнеры (Functor ), могут быть напечатаны как текст ( Showкоторый мы уже встречали в showфункции) и так далее. Этот объединяет типы данных, которые похожи на список в том смысле, что они могут быть перебраны или сведены в список.

В этом фрагменте мы определяем экземпляр с помощью определения foldr, которое по существу перебирает тип данных справа налево. Теперь мы можем использовать кучу общего предварительно написанного кода. Сначала мы определяем вспомогательную функцию для получения одноэлементного дерева, чтобы избежать всего беспорядка:s a = N E a E . В настоящее время:

sum (N (s 3) 7 (N E 5 (s 8))     === 23
product (N (s 3) 7 (N E 5 (s 8)) === 840
toList (N (s 3) 7 (N E 5 (s 8))  === [3,7,5,8]

и так далее.

Вот изображение нашего дерева:

7
| \
3  5
    \
     8

Длина фрагмента 70

primes=sieve[2..] where
 sieve(p:xs)=p:sieve(filter(\x->x`mod`p/=0)xs)

Это простое сито!

(примечание: /=это то, что!= есть на других языках)

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

Опять же, мы здесь работаем с бесконечными списками - но вычисления со временем остановятся, если вам не нужно вычислять бесконечное количество простых чисел.

take 4 primes === [2,3,5,7]

Длина 68 фрагмента

Наконец, Quine!

main=do putStr s;print s where s="main=do putStr s;print s where s="

Когда вы впервые читаете это, вы можете подумать, что в выводе этой квинны будут отсутствовать кавычки, и зачем писать putStrодин раз и один раз?print ? Звучит так же.

В Haskell putStr- это функция, которая просто печатает содержимое строки, которую получает в stdout; printТем не менее, печатает вещи на стандартный вывод. Итак, print 4эквивалентно putStr "4\n", но putStr 4бессмысленно - 4не строка! Поэтому, когда printполучает значение, оно сначала преобразует его в строку, а затем печатает эту строку. Обычно способ конвертировать вещи в строки - это найти способ записать его в коде. Итак, способ, которым вы бы записали строку abcв строку в коде на Haskell "abc", так что на print "abc"самом деле печатает "abc", а не abc.

К счастью, у меня сейчас достаточно голосов, мне не придется играть в гольф

Длина 33 фрагмента:

main=go 0
go n=do print n;go(n+1)

Важно отметить, что мы не использовали цикл. Хаскелл не зацикливается. Хаскелл рекурсивно У Хаскелла нет петель. Это глубже: Хаскелл даже не имеет потока управления . Как, спросите вы? Ну, это не нужно.

На с деталями. Эта программа печатает бесконечно возрастающую последовательность целых чисел, начиная с 0. goПечатает их, начиная с ввода, затем mainвызывает ее 0.

doэто особая синтаксическая сила Haskell. В этом сценарии он просто объединяет действия ввода-вывода, как это >>делается (см. Фрагмент 22).

Длина 26 фрагмента:

map f=foldr(\x y->f x:y)[]

Это определяет mapфункцию, вероятно, знакомую каждому, использующую foldr. Обратите внимание на то, что , хотя мы не объявляли mapтипа «s, компьютер каким - то образом знает его тип (a -> b) -> [a] -> [b], т.е. данную функцию от aдо b, и список aс, возвращает списокb с.

Как он узнал ?? ;-)

Длина фрагмента 25:

main=putStr"Hello World"

Стандартный Hello World. Обратите внимание на типы: mainимеет тип IO ()и putStrимеет типString -> IO () (функция от строк до действий ввода-вывода, которые ничего не возвращают).

Длина 23 фрагмента:

data T a=E|N(T a)a(T a)

Это стандартное определение дерева. Насколько проще, чем все эти строки, требуется определить дерево на Java, C или чем-то еще.

(см. фрагмент 10)

Давайте разберемся с этим:

data- это объявление объявляет тип данных. T a- дерево, содержащее элементы типа a. Это тип, который мы определяем. =- каждое значение T aбудет любым из следующих, разделенных трубкой |. E- одно из возможных значений T s- пустое дерево. N (T a) a (T a)- другое возможное значение дерева - узел. Каждый узел состоит из левого дочернего (T a)элемента ( a), элемента ( ) и правого дочернего элемента ( ).(T a) ).

Длина 22 фрагмента:

main=putStrLn"y">>main

Функция Haskell yes. >>является оператором, который объединяет и упорядочивает два действия ввода / вывода. Имеет тип>> :: IO a -> IO b -> IO b .

mainопределяется рекурсивно сам по себе, как действие ввода-вывода, которое сначала печатает, "y"а затем делает всеmain делает сам.

Длина фрагмента 18:

fix f=r where r=f r

Лучшее определение для fix. (См. Фрагмент 14.) Проблема с первым определением fix f = f(fix f)состоит в том, что каждый раз, когда мы вызываем вызовы, fix f fixвспоминает fix f, что вызывает fix fгенерацию бесконечных копий одного и того же вычисления. Эта версия исправляет это, определяя r(результат), чтобы быть результатом; как таковой f r = r. Итак, давайте определимся r = f r. Теперь мы вернемся r.

Длина фрагмента 17:

f n=product[1..n]

Это функциональный способ определения факториала.

Длина фрагмента 16:

f n=(\x->x+x+x)n

(\x -> x + x + x)является лямбда (кто-то думал, что \напоминает письмо.).

(\x -> x + x + x) nприменяется лямбда n(это точно так же, как n + n + n).

fфункция умножения на три (также f = (*3))

Длина фрагмента 15:

sum=foldl (+) 0

Это определяет sumфункцию с помощью сгиба. Сгиб - это, в основном, цикл по элементам списка с одним аккумулятором.
foldlпринимает в качестве аргументов некоторую функцию fи некоторое начальное значение xдля аккумулятора и списка xs. Функция fдолжна получить в качестве входных данных предыдущее значение аккумулятора и текущее значение списка, и она возвращает следующий аккумулятор.
Затем сворачивание перебирает значения списка, применяя fк предыдущему аккумулятору, а затем возвращает последний аккумулятор.

Другой способ думать о сгибах подобен «вставкам» сгиба fмежду значениями списка и с начальным аккумулятором с одной из сторон. Например, foldl (*) 1 [4,2,5]оценивает до 1 * 4 * 2 * 5.

Длина фрагмента 14:

fix f=f(fix f)

yКомбинатор. Обычно его называют, fixпотому что он находит точку фиксации уравнения f x = x. Обратите внимание, что x = infinite loopиногда это может быть решением, поэтому fix (\x -> x^2 + 5*x + 7)не решит уравнение, x^2 + 4*x + 7 = 0а вместо этого вернет бесконечный цикл.

Вы также можете заметить, что не всегда x = infinite loopрешение проблемы из-за лени Хаскелла.

Эта версия - утечка времени и пространства; мы переопределим его в более длинном фрагменте.

Длина фрагмента 13:

f=sum.map(^2)

Это определяет функцию, f которая дает список возвращает сумму его квадратов. Это функция состав функции sum и функцииmap(^2) , что , в свою очередь , является функцией map применяется к функции (^2) (далее квадрат функции ), которая , в свою очередь сечение функции ^ (фрагменты были введены во фрагменте 2, а композиция - во фрагменте 3). ).

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

Кстати, технически каждая функция с двумя или более аргументами является функцией, которая возвращает функции в качестве выходных данных (это называется каррированием).

Длина фрагмента 10:

data B=T|F

Это определение логических значений Haskell с разными именами. Логический тип называется B.
Это определение вводит два конструктора: true ( T) и false ( F).
Этот фрагмент кода в основном говорит компилятору , что каждый логический ( B) является либо истинным ( T) или ЛОЖЬ ( F), или другими словами, B=T|F.

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

Длина фрагмента 9:

main=main

Эта бессмысленная программа определит mainбыть главной. Поскольку Haskell ленив, значения, для оценки которых требуется бесконечный цикл, могут использоваться свободно, если мы не используем их фактическое значение. Такие значения, которые содержат бесконечные циклы, такие как наша main, называются «основаниями».

Интересным фактом является то, что компилятор GHC Haskell может обнаруживать подобные бесконечные циклы и генерировать исключение (!) При его запуске.

Длина 8 фрагмента:

f(x:_)=x

Это определяет функцию, fкоторая, при непустом списке, вернет свою голову.

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

Шаблоны в этом фрагменте:

  • _: шаблон, который соответствует чему-либо и не привязывает переменную.
  • x: шаблон, который связывает что-либо и привязывает его к переменной x.
  • :: этот паттерн попадает в дочерние паттерны, то есть один для головы и один для хвоста. Если список не пустой, он сопоставляет их с головой и хвостом.

Сопоставление с образцом высоко обобщено. Фактически, простое определение новых типов данных автоматически вводит шаблоны для работы с ними.

Длина 5 фрагмента:

x=2:x

Вау, так много можно объяснить по этому поводу.

Во-первых, Хаскелл ленив. Это означает, что подвыражения будут оцениваться только в случае крайней необходимости.

Примечание: этот фрагмент кода не показывает назначение, но определение. У Хаскелла нет назначения.

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

Бесконечные списки в Haskell представляют собой смесь итераторов и обычных связанных списков: они действуют как оба (итерация по диапазону будет использовать постоянную память, например).

Длина 4 фрагмента:

2:[]

Этот фрагмент просто кодирует список синглтонов [2]. :является оператором Cons в Haskell. Фактически, синтаксис обычного списка - это просто синтаксический сахар для оператора cons и литерала пустого списка. Это тесно связано с тем, как Haskell работает с сопоставлением с образцом и типами данных (особенно с концепцией конструктора).

Длина 3 фрагмента:

f.g

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

Длина 2 фрагмента:

1-

Когда этот код заключен в круглые скобки (по синтаксическим причинам), он называется «разделом». Затем эта функция, которая задает некоторое число, «заполняет» пустое место и возвращает один минус это число. Это понятие иногда полезно в функциональном языке, таком как Haskell, где в противном случае потребуется лямбда.

Длина 1 фрагмента:

1

В Haskell, 1может быть как Int, Float, Double, Wordи так далее. Фактически, вы можете написать код для определения версии 1любого типа и использовать ее свободно.
это делается также в JavaScript, Python и т. д., но в отличие от них, это делается с полной безопасностью типов.

Factoid:

Первоначально комитет по Haskell намеревался назвать язык «Curry» в честь имени Haskell B. Curry, но решил сменить название на Haskell, поскольку могут возникнуть некоторые каламбуры. Только позже они заметили сходство Хаскелла с «Паскалем» и «Хасслом»!


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

Покажите его во фрагменте и добавьте в объяснение.
Мартин Эндер

f=0:1:zipWith(+)f(tail f) -- 25 chars, функция, которая возвращает вычисляемый ленивым список чисел Фибоначчи.
chamini2

тьфу, я добавил кучу фрагментов и затем мой компьютер выключился
гордый haskeller

@proudhaskeller Сохранение op. Я никогда не делал этого лично, но если вам нужно выполнить большое редактирование за один раз, вы можете выполнить редактирование во внешнем документе с сохранением, а затем вставить его, когда оно будет завершено.
mbomb007

99

C #

C # - это забавное, безумное сочетание функций из Java, C, Haskell, SQL и множества других языков, и оно предоставляет множество действительно приятных функций и API. Здесь также известно, что он довольно многословен, но посмотрим, что мы можем сделать!

Я проигнорирую обычный обязательный шаблон:

class Program { public static void Main(string[] args) { ... } }

Длина 1:

;

Команды заканчиваются точкой с запятой в C #! Пустая строка имеет совершенно правильный синтаксис.

Длина 5:

x=5f;

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

Длина 7 (байт):

s=@"
";

Если вы префиксом строкового литерала ставите знак @, он становится строковым литералом «дословно». Обычные строковые литералы анализируют escape-последовательности, такие как '\ n', в специальные символы, но буквальные литералы этого не делают, что позволяет использовать символ обратной косой черты, не экранируя его. Они также могут включать возврат строки, как показано. Это может сэкономить вам несколько байтов в гольфе или сделать ваши строковые литералы из нескольких строк более читабельными. Просто следите за отступами, включенными в строку.

Длина 8:

()=>x=y;

Это выражение является анонимной функцией. Он возвращает объект типа, Actionкоторый можно передать, а также вызвать как функцию. Анонимные функции наследуют область, в которой они были объявлены, и тянут любые локальные переменные в этой области с собой куда угодно.

Длина 9:

(a)=>a.p;

Вот еще одна анонимная функция, которая использует параметр и возвращаемое значение. Выражение возвращает объект типа Func(сам Func возвращает тип a.p. Вы будете Funcмного использовать для взаимодействия с Linq.

Длина 10:

enm.Any();

Это наше первое знакомство с Linq! Linq - это набор методов расширения, которые можно вызывать для любого перечислимого объекта (реализующего интерфейс IEnumerable) - например, Arrayand List. IEnumerable использует ленивую оценку: он просматривает коллекцию по одному элементу за раз, не зная о коллекции в целом - она ​​может быть даже бесконечной!

Вот что Anyприходит - возвращается, trueесли Enumerable содержит хотя бы 1 элемент. Намного лучше, чем вычислять всю длину.

Длина 11:

var a=1.5f;

varКлючевое слово указывает компилятору автоматически определять тип a.aв этом случае будет напечатано как Single. Очень удобно для кодового гольфа, так как оно короче почти любого названия типа, хотя многие не любят использовать его в производственном коде.

Длина 15:

yield return 0;

Вот сумасшедшее утверждение, с которым вы можете быть менее знакомы. Вы знаете, что объекты могут быть перечисляемыми, наследуя IEnumerable, но знаете ли вы, что функции могут быть перечисляемыми? Объявите функцию с возвращаемым типом IEnumerableи делайте это yield returnстолько раз, сколько хотите. Когда вы получаете Enumerator для функции, при каждом вызове GetNextпрограмма будет выполнять весь код до следующего yield return, возвращать это значение и затем делать паузу, пока вы не выполните его снова. Вы используете yield breakдля завершения итерации.

Длина 16:

[Obsolete]int a;

Этот фрагмент показывает атрибут. Атрибут - это вид тега, который вы можете прикрепить к любому объявлению в вашем коде. Некоторые инструктируют компилятор делать определенные вещи, такие как этот, который выдает устаревшее предупреждение, если вы вызываете a. Вы можете создать свой собственный, расширяя Attribute, и вы можете запросить их, используя Reflection (возможно, об этом позже). Вы можете перейти к мета и ограничить, какие объявления атрибут может использоваться с AttributeUsageатрибутом.

Длина 17

c.Count(t=>t==3);

Вот удобный метод игры в гольф. Учитывая, Funcчто отображает элемент перечисляемого cв bool, он возвращает количество элементов, cдля которых это Funcвозвращается true. Гораздо приятнее, чем писать цикл.

Длина 18:

foreach(T t in c);

Это цикл для каждого. Со всеми этими разговорами о перечисляемых вещах, это очень необходимая структура. foreachявляется синтаксическим сахаром, который устанавливает Enumerator для c(который должен быть перечисляемым) и выполняет итерацию по одному элементу tза раз. Вы можете изменить или изучить каждый отдельный элемент, но изменение самой коллекции приведет к аннулированию перечислителя.

Длина 19

c.Select(t=>t.a/2);

Это ваша функция «карта», для любителей функционального программирования. Выбор - хороший краткий способ выполнить произвольное преобразование (определенное Funcпереданным в) каждому элементу перечислимого. Он возвращает IEnumerable, который будет выплевывать «преобразованные» элементы при его итерации.

Длина 21

Console.Write("Hi!");

Эта строка записывает некоторый текст в stdout и, вероятно, является одной из главных причин, по которой C # не используется для игры в гольф!

Длина 23

typeof(T).GetMethods();

C # поддерживает очень мощную функцию под названием Reflection. Отражение позволяет вам исследовать структуру вашего кода во время выполнения. Например, этот вызов вернет массив всех методов указанного типа. Вы можете исследовать эти методы, вызывать их или даже изменять значения полей и свойств. Атрибуты (см. Длину 16) являются хорошим способом пометить части вашего кода для использования с Reflection.

Длина 25

from t in c select t.a/2;

Это SQL? В коде C #? Довольно близко. Это выражение делает то же самое, что и длина 19.

Длина 27

for(var l;;l=new object());

C # - это язык для сбора мусора, что означает, что любая память, которую вы выделяете (используя newключевое слово), может быть автоматически освобождена, если нет ссылок на нее. Этот код будет работать долго и счастливо, хотя я никогда не освобождаю созданную память явно. Сборка мусора, тем не менее, имеет свои затраты - поищите в Интернете, чтобы узнать больше.

Длина 29

var e=Enumerable.Range(0,99);

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

Длина 31

public int pr{get;private set;}

Здесь мы можем показать простое «свойство», функцию ООП и другую отличительную черту C #. Если вы когда-либо использовали Java, вы, вероятно, создали методы 'get' и 'set' для поля, чтобы отделить их доступность или выполнить код при его изменении. Ну, C # позволяет вам объявить этот код прямо над полем, а также установить отдельные модификаторы доступа для получения и установки. Этот конкретный фрагмент автоматически создает метод получения и установки по умолчанию, но делает его закрытым.

Длина 32

public static void m(this T o){}

Этот фрагмент демонстрирует функцию C #, которая хороша для разработки API. Применяя thisмодификатор к первому параметру статического метода, этот метод становится методом «расширения». Как только это объявлено, T.mтеперь его можно вызывать для любого объекта типа T, как если бы это был фактически метод T. Это можно использовать для добавления новых функциональных возможностей в любой существующий класс, без изменения или даже доступа к его исходному коду.

Длина 38

int f(int a,ref int b,out int c){c=0;}

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

Длина 42

Console.Write("It is \{DateTime.Now()}.");

Новый стандарт C # 6 может сэкономить некоторые символы, когда вам нужно вывести собранные строки, используя интерполяцию строк. Эта функция позволяет писать любое выражение в фигурных скобках внутри строкового литерала, и строка будет автоматически собрана со значениями этих выражений во время выполнения.

Длина 48

IEnumerable f(){for(int a=0;;)yield return a++;}

Теперь достаточно персонажей, чтобы сделать что-то с реальной целью! Этот метод использует некоторые идеи, которые мы исследовали выше, для создания бесконечного Enumerable, который будет просто возвращать целые числа, один за другим, начиная с 0. Помните, что C # использует ленивые вычисления с Enumerables, поэтому бесконечная последовательность вполне допустима - вы можете повторяйте столько последовательности, сколько хотите, и прерывайте ее в любое время.

Длина 56

int p{get{return mP;}set{mP=Math.Max(value,0);}};int mP;

Вот еще один пример «свойства» (см. Фрагмент 31). Вот, я на самом деле определены различные фрагменты кода для getи setвместо того , чтобы использовать автоматические те , как и раньше. В этом примере демонстрируется, как можно использовать свойство для проверки значения, назначенного переменной - здесь значение не может становиться меньше 0. Другие полезные варианты использования свойств включают уведомление о событии при изменении значения или перестроение кэшированных значений. это может быть основано на этом.

Длина 65

int v;public static implicit operator int(Program o){return o.v;}

Эта функция называется неявным приведением. Это своего рода метод расширения в том смысле, что это статический код, который работает с определенным классом (см. Фрагмент 32). Однако, неявное приведение не используется, вызывая его - оно используется просто, рассматривая Programобъект как целое число (например int i=new Program()). Когда вы сделаете это, объект будет автоматически преобразован в тип, в котором вы его используете, на основе кода в неявном приведении. В соответствии с передовой практикой это следует делать только тогда, когда в результате преобразования не теряется информация.


1
Давайте посмотрим, что вы сможете сделать с этими персонажами ... ;-)
гордый haskeller

9
Я бы сказал, что это ближе к java, чем к C, на самом деле
гордый haskeller

Отметил. Я думаю, что у нас почти достаточно, чтобы сделать немного Linq - приходя сегодня вечером!
BMac

открытый статический неявный оператор int (MyClass o) {return o.objVal;} // 65. С этим кодом эта строка действительна: MyClass o1 = new MyClass (10); int o2 = o1; // o2 сейчас 10 msdn.microsoft.com/en-us/library/85w54y0a.aspx
Zukki

Больше фрагментов, пожалуйста
Cyoce

98

Ява


Длина 44 фрагмента

Object a=System.out.append("Hello, World!");

Печатает Hello, World!на STDOUT.

Длина фрагмента 43

float[][][][][]a=new float[5][3][7][2][10];

aсодержит 10 массивов, каждый из которых содержит 2 массива, каждый из которых содержит 7 массивов, каждый из которых содержит 3 массива, каждый из которых содержит 5 floatс.

Длина 42 фрагмента

interface A{static void main(String[]a){}}

Полная программа. Поскольку все в по interfaceсути public, мы можем опустить слово publicиз основного метода.

Длина 36 фрагмента

class A{class B extends A{B.B.B b;}}

Aимеет внутренний класс B. Это означает, что мы можем объявить переменную типа A.B.

Но Bэто подкласс A, который означает , что он имеет все методы, поля и внутренние классы в A. Таким образом, мы можем ссылаться и на тип B.B.

В этом коде мы продвигаемся дальше и даем Bпеременную экземпляра типаB.B.B .

Мораль: следование горячим вопросам о SO может научить вас множеству интересных, хотя и бессмысленных, приемов.

Длина 35 фрагмента

l.stream().map("a"::equals).count()

Если lэто список строк, это говорит нам, сколько из них равно "a".

Длина 34 фрагмента

public static void main(String[]a)

Подпись метода основного метода программы. Еще 11 персонажей, и мы можем сделать полную программу!

Длина 33 фрагмента

enum D {NORTH, EAST, SOUTH, WEST}

NORTH, EAST, SOUTH, И WESTвсе константы типа D.

Длина 32 фрагмента

Files.readAllBytes("hello.txt");

Читает весь файл, возвращая byte[]содержимое.

Длина 31 фрагмент

new String(new char[]{'h','i'})

Эквивалент "hi". Полезно, если "ключ сломан.

Длина фрагмента 30

new JFrame().setVisible(true);

Создает новую видимую рамку, в которую вы можете поместить другие компоненты.

Длина 29 фрагмента

throws ClassNotFoundException

Вынуждает каждый метод, который вызывает это, использовать try-catch блок, либо передать ошибку в стек. Проверенные исключения являются одним из самых противоречивых решений разработчиков Java.

Длина фрагмента 28

int f(int x){return f(x-1);}

Эта функция не работает вечно; на самом деле, на типичном компьютере это занимает меньше секунды. Спасибо, переполнение стека.

Длина 27 фрагмента

Object a=new String[]{"a"};

Создает новый массив строк.

Длина 26 фрагмента

Object.class.newInstance()

Создает новый Object .

Длина 25 фрагмента

((Supplier)()->-~0).get()

Лучше всего избегать жестких констант. Это объектно-ориентированный способ получения значения 1без использования каких-либо констант, кроме0 .

Длина 24 фрагмента

(Function<Long,?>)x->x+1

Функция преемника.

Длина 23 фрагмента

l.removeIf(x->x%10==0);

Если l список целых чисел, это удаляет все значения, кратные 10.

Длина 22 фрагмента

int i=(new int[7])[5];

Создает новый массив из семи целых чисел и получает пятый элемент.

Длина 21 отрывка

Arrays.asList(2L,"a")

Создает ArrayList с этими элементами.

Длина 20 фрагмента

System.out.print(s);

Печать s.

Длина 19 фрагмента

import java.util.*;

Позволяет сжатое использование классов , таких как List, Map, Scanner, Timerи Random.

Длина 18 фрагмента

Math.addExact(x,y)

Добавляет два целых числа xи y. Если происходит переполнение, метод генерирует исключение, а не дает неправильный ответ.

Длина 17 фрагмента

Double.MIN_NORMAL

Наименьшее положительное значение типа double, где старший бит значенияи равен 0.

Длина 16 фрагмента

System.in.read()

Читает один символ из консоли.

Длина фрагмента 15

Long.reverse(x)

Обращает биты в двоичном представлении x.

Длина фрагмента 14

int x=050+120;

xтеперь 160, поскольку все, что начинается с 0, рассматривается как восьмеричное.

Длина 13 фрагмента

private C(){}

Закрытый конструктор не позволяет другим классам создавать его экземпляры. Этот шаблон используется SystemиMath классов, среди других. Закрытый конструктор также может использоваться для принудительного применения шаблона Singleton.

Длина 12 фрагмента

static class

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

Длина фрагмента 11

throw null;

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

Длина фрагмента 10

int[]a,b[]

Определяет две переменные: aи b. aимеет тип int[]и bимеет тип int[][].

Длина 9 фрагмента

switch(x)

Идет в место, в зависимости от стоимости x.

Длина 8 фрагмента

break a;

Вырывается из блока с надписью a .

Длина 7 фрагмента

goto x;

gotoКлючевое слово зарезервировано в C, C ++ и Java. Если xэто метка, то этот код отправляет программу на соответствующую метку - на C и C ++. Но это Java, это вызывает загадочное RuntimeException. На самом деле, нет никакого способа использовать gotoключевое слово в Java.

Длина 6 фрагмента

\u003b

Завершает заявление. Ява странная .

Длина 5 фрагмента

a-=-a

Удваивает a, вычитая его отрицание.

Длина 4 фрагмента

a&=b

Устанавливает значение aв побитовый и из aи b.

Длина 3 фрагмента

...

Любое количество аргументов, объединенных в массив.

Длина 2 фрагмента

<>

Позволяет компилятору выяснить, какой тип вы имеете в виду. Очень не-Java-как.

Длина 1 фрагмента

@

Указывает аннотацию, позволяющую отображать дополнительную информацию о методах и классах.

Factoid

В Java бесконечные циклы иногда вызывают ошибки компилятора. Например, цикл while(true);не может быть прерван без выхода из метода, поэтому любой код после этого вызовет ошибку «недостижимый оператор». Как отметил @Optimizer, таким образом будут ловиться только некоторые бесконечные циклы.


5
В Java бесконечные циклы не вызывают ошибку компилятора. Ваша IDE обнаруживает их и выдает ошибку. В Java просто есть концепция операторов Rereachable, поэтому, если while(true);в вашем коде есть что-то похожее , все, что будет помещено после этой строки, приведет к ошибке компиляции оператора Unreachable. Логика обнаружения таких утверждений очень строгая, поэтому она не распознает все бесконечные циклы любым способом
Оптимизатор

4
Вы только что проголосовали, я думаю, это означает, что вам придется удалить фрагмент! ;) (Понижение было за "Ява странная")
Саймон Форсберг

1
Кажется, что фрагмент # 36 является рекурсивным и может быть расширен до бесконечности: class A{class B extends A{B.B.B.B.B.B.B b;}}все еще компилируется.
Натикс,

3
Upvoted, чтобы помочь вам сделать полную программу;)
durron597

1
But it Java, [goto] triggers a mysterious RuntimeExceptionНеправильно. gotoдаже не компилируется.
Дорукаяхан

93

питон

Теперь начнем с самого нового для вашего удобства! Чтобы прочитать длину 30, начиная с самой ранней первой, перейдите к истории изменений.

Если у кого-то есть предложения, не стесняйтесь комментировать.

Длина 52:

i=0
while s[i-n:]:print(' '*n+s)[i:n+i];i+=1;i**7**7

Взято из моей записи в конкурсе « Поддельный текст» . sи nдолжны быть установлены в строку и целое число заранее. На самом деле он не работает должным образом в бесплатном интерпретаторе Python 2, который я использовал, поэтому я добавил круглые скобки (' '*n+s)[i:n+i], и вы можете увидеть, как он работает в интерпретаторе Python 3 здесь .

Длина 43:

#-*-coding:rot13-*-
cevag h"Una fubg svefg"

В Python вы можете кодировать исходный код с помощью определенного кодека. Это показывает, как источник может быть написан в Rot13. Общий синтаксис таков: # -*- coding: <codec-name-goes-here> -*-.

Вот это переводится:

#-*-coding:rot13-*-
print u"Han shot first"

В uуказывает , что следующая строка литерал является строкой Unicode. Это необходимо, если вы хотите, чтобы ваши строки также были в Rot13, иначе каждая строка в источнике легко читается, несмотря на шифрование. В качестве альтернативы, вы можете использовать .encode("Rot13")после каждой строки (не забывайте также использовать Rot13 для этого.) Согласно этой статье , некоторые альтернативные кодировки это «base64», «uuencode», «zlib» или «bz2».

Длина 33:

import cmath
print cmath.sqrt(-1)

Это модуль Python для сложных (мнимых) чисел . Эта печать 1j, так как Python соответствует техническим стандартам и использует в jкачестве мнимой единицы, хотя я предпочитаю i, который чаще всего используется в математике, а также с использованием jи kв дополнение к iдля кватернионов , но я отвлекся. Ознакомьтесь с порядком ошибок / изменений здесь (он не будет изменен).

Длина 30:

f=lambda n:n*f(n-1)if n else 1

Теперь мы определяем нашу собственную факториальную функцию, используя рекурсию и троичное if-else! Насколько я знаю, это так же, как в Python. Это также можно записать следующим образом: f=lambda n:n and f(n-1)*n or 1демонстрация пары булевых операторов Python (также выполненных из 30 символов). См. Фрагмент длиной 15 для получения информации о lambdaсинтаксисе.

Длина 29:

import math
math.factorial(7)

Находит факториал 7, возвращая 5040.

Длина 25:

import math
print math.pi

Модуль математики Python предоставляет множество полезных функций и констант. Вот пи. Возвращает 3.14159265359. (В приведенном выше коде я считал символ новой строки как символ.)

Длина 24:

f=lambda y:lambda x:x**y

Это пример закрытия. Вызов cube = f(3)создаст кубическую функцию, которую затем можно будет вызвать с помощью print cube(24)печати 13824.

Длина 19:

print"Hello World!"

Наконец, достаточно места, чтобы напечатать какой-нибудь основной вывод! Здесь не требуется места, поскольку кавычки и скобки также являются разделителями. Это будет работать только в Python 2, так как Python 3 изменил printвызываемую функцию, как и любую другую функцию. В Python 3 используйте print("Hello World!"). Для получения дополнительной информации о функции печати и разнице между Python 2 и 3, смотрите Что нового в Python 3.0 .

Длина 16:

[x*3 for x in l]

Еще раз, предположим l, это список или любой другой итерируемый объект, такой как строка или генератор. Это утверждение известно как понимание списка . Это намного короче, чем использование стандарта для структуры цикла. Здесь он возвращает список со всеми числами, умноженными на 3. ТАКЖЕ, строки можно умножать! Таким образом, любая строка в списке будет добавлена ​​(присоединена к себе) такое количество раз.

Длина 15:

import this #:)

На самом деле это фрагмент длины 11, но я понял, что забыл продемонстрировать (потрясающее) пасхальное яйцо Питона ! При импорте этого модуля печатается The Zen of Python (см. Factoid.) Интересный факт: модуль this.pyбыл закодирован в rot13, который, я надеюсь, я расскажу позже.

Длина 14:

lambda x:x**.5

Это определяет функцию квадратного корня, используя lambdaсинтаксис Python для литерала функции. Функциональные литералы в Python могут содержать только выражения, но не операторы. Эта лямбда-выражение может быть присвоено переменной, передано функции или выполнено в соответствии с (lambda x:x**.5)(9)возвращаемым значением 3.0. Использование показателей для квадратного корня является альтернативой импорту sqrtфункции в mathмодуле.

Длина 13:

1 if x else 0

Это пример троичного оператора Python if. Это было добавлено в Python 2.5, чтобы отговорить кодировщиков от ручного внедрения его с помощью логических операций. Здесь 1возвращается, если xоценивается True, в противном случае 0возвращается.

Длина 12:

s=input(">")

Это напечатает >текст подсказки и позволит пользователю ввести значение. Python 2 интерпретирует любое введенное значение, поэтому любая строка нуждается в кавычках. Python 3 изменил это, поэтому введенный ввод не интерпретируется автоматически. Чтобы ввести ввод, не интерпретируя его в Python 2, используйте raw_input(). В Python 2 input()эквивалентно eval(raw_input()).

Длина 11:

eval("2e3")

2e3это научное обозначение для поплавка 2 х 10³. evalФункция интерпретирует и оценивает любую строку как выражение. В этом случае он имеет тот же результат, что и использование литерала 2e3или float("2e3"). Это возвращается 2000.0.

Длина 10:

range(013)

Эта функция возвращает список целых чисел от 0восьмеричного значения 013, которое является 11(исключительным), что означает, что список будет [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]. Функция принимает до трех параметров , аналогичных sliceфункции мы рассмотрели ранее: range(start, stop[, step]). Разница в том, что только с одним параметром параметр представляет значение остановки.

Обратите внимание, что Python 3.x не имеет эквивалента. Это rangeпохоже, но на самом деле то же самое, что и в Python 2 xrange, возвращая объект генератора вместо списка.

Длина 9:

a,b = b,a

Многократное назначение. Это простая, но элегантная функция, позволяющая назначать несколько значений одновременно. В предоставленном фрагменте он поменяется местами aи b. А как насчет порядка оценки, спросите вы? Все выражения справа от оператора присваивания оцениваются перед выполнением любого присваивания. Это превосходит многие языки, которые требуют промежуточного присваивания временной переменной.

Длина 8:

#comment

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

Длина 7:

l[::-1]

Снова при условии, lчто это список, он вернет список в обратном порядке. Третий аргумент указывает размер шага. Поскольку все три аргумента могут быть отрицательными значениями, отрицательный размер шага означает итерацию в обратном порядке. Пустые первый и второй аргументы показывают, что мы перебираем весь список.

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

Длина 6:

l[-6:]

Это называется операцией среза . Если lэто список, он вернет новый список, содержащий последние шесть элементов lсписка. -6представляет начальный индекс (6 с конца), а двоеточие означает продолжение до конечного индекса после него (который мы оставили пустым, поэтому до конца.) Если бы наш список содержал числа от 1 до 10, это вернуло бы [5, 6, 7, 8, 9, 10].

Длина 5:

1<x<5

Одна из замечательных возможностей Python - это возможность цепочки операторов сравнения. Во многих других языках это будет напечатано как 1 < x && x < 5. Это становится еще лучше, если учесть несколько сравнений: 1 < x < y < 5это совершенно верно!

Длина 4:

0256

Целое число с ведущим нулем является буквальным восьмеричным значением. Это хороший трюк и для обфускации кода. Это возвращает десятичное значение 174. В Python 3.x восьмеричное значение будет записано как 0o256.

Длина 3:

`3`

Выражение выражения в обратных галочках такое же, как использование repr(), которое возвращает строковое представление объекта. Функция пытается вернуть строку таким образом, чтобы при передаче в качестве аргумента evalфункции она возвращала исходный объект. Это не то же самое, что использование str(), хотя результаты иногда совпадают. Для этого ввода '3'возвращается в обоих случаях. Это мой любимый код-гольф!

Работает только в Python 2!

Длина 2:

[]

Пустой список

Длина 1:

_

Символ подчеркивания является широко используемым одноразовым именем переменной. Однако, если вы используете оболочку Python (интерактивный интерпретатор), она содержит результат последнего выполненного оператора (и вернет его снова.) Также, согласно этому потоку , она также используется для поиска перевода в i18n.

Фактоид : Python - это язык, похожий на Java и C. Он был построен с определенной философией дизайна (взято из " PEP 20 - Дзен Python ":

  • Красиво лучше, чем некрасиво
  • Явное лучше, чем неявное
  • Простое лучше сложного
  • Сложный лучше, чем сложный
  • Читаемость имеет значение

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


В любой момент! Я больше не буду добавлять фрагменты (не смог устоять перед длиной 9!), Так как вы уже отлично справляетесь с этим. Удачи!
Насер-ш

1
длина 6: он вернется [5, 6, 7, 8, 9, 10](последние 6 чисел в списке)
Винсент

Длина 16: lне должен быть списком, это может быть любой итеративный объект; кортежи, списки и генераторы, например, все работы
nasser-sh

@ Sp3000: я использовал его с проблемами [с ограниченными источниками].
Робби Уксиз

4
Нет любви к старому доброму import antigravity?
шифр

87

JavaScript

Это идет от новейшего к старому. Ссылка для себя: [ править ]

Длина фрагмента 51:

console.log(require('fs').readFileSync(__filename))

На этот раз Node.JS quine, хотя и не сможет выполнить требования «строгого quine» из-за чтения собственного исходного кода.

Длина фрагмента 50:

a=new XMLHttpRequest;a.open('GET','file');a.send()

В заключение! AJAX-запрос (с использованием Vanilla.JS ). Мы инициализируем, открываем и отправляем запрос, но мне не хватило места, чтобы добавить обработчики и фактически сделать что-нибудь с результатом.

Длина 49 фрагмента:

msg=new SpeechSynthesisUtterance('Hello World!');

Подготовьте вокал «Hello World!». Это будет немного больше работы, чтобы фактически говорить это. Мы также можем настроить громкость, высоту звука, скорость и акцент. Посмотрите API Синтеза речи на HTML5Rocks . Еще не поддерживается Firefox, конечно, не IE .

Длина 48 фрагмента:

function repeat(){setTimeout(repeat,48)}repeat()

Имитация с setIntervalпомощью рекурсивного setTimeoutING.

Длина фрагмента 47:

module.exports=function MyModule(a) {this.a=a};

Снова NodeJS, но принцип везде одинаковый в JS. Это очень простая функция конструктора, которая создает объект с одним свойством ( a). Установка module.exportsэкспортирует функцию для использования путем ее require()включения.

Длина 46 фрагмента:

canvas.getContext('2d').fillRect(46,46,46,46);

Это требует <canvas id="canvas"></canvas>элемента. Он использует тот факт, что элементы с идентификаторами заполняются как глобальные переменные, поэтому элемент доступен как canvasиз JS. Затем мы заполняем его квадратом 46x46 при x = 46, y = 46.

Длина фрагмента 45:

JSON.parse(require('fs').readFileSync('jsn'))

Вернуться к узлу Здесь мы анализируем файл JSON с именем jsnиз текущего каталога.

Длина 44 фрагмента:

(a=document.createElement('a')).href="/url";

Опираясь на # 39. Теперь мы создаем элемент и назначаем атрибут. Это все еще не в DOM все же.

Длина фрагмента 43:

sq=[1,2,3,4,5].map(function(n){return n*n})

Создает массив из первых 5 квадратов, используя map().

Длина 42 фрагмента:

six="1+5",nine="8+1";eval(six+' * '+nine);

Это работает по тому же принципу, что и этот , но JS не хватает #defineи поэтому оказывается более уродливым. Это возвращает, конечно, ответ на жизнь, вселенную и все .

Длина фрагмента 41:

c=function(){var i;return function(){}}()

Начало закрытия. cтеперь это функция (внутренняя) с доступом к внутренней переменной i, но она ничего не делает.

Длина 40 фрагмента:

$('p').click(function(){$(this).hide()})

Мы полностью отбрасываем эти абзацы и используем jQuery.

Длина 39 фрагмента:

script=document.createElement('script')

Это начало добавления нового внешнего скрипта. Создайте пустой <script>элемент и сохраните ссылку на него.

Длина фрагмента 38:

document.getElementsByClassName('abc')

Найдите все .abcэлементы в документе. Конечно, с JQuery это только $('.abc')...

Длина фрагмента 37:

b=JSON.parse(JSON.stringify(a={3:7}))

Создает два одинаковых, но разъединенных объекта a, и b. Если бы вы сделали

a={a:1};
b=a;
b.a=3;

вы бы в конечном итоге a=={a:3}, потому что aи bуказывают на тот же объект. Мы используем JSON, чтобы отделить их.

Длина 36 фрагмента:

(function f(){return "("+f+")()"})()

Куайн . Он печатает свой собственный исходный код.

Длина 35 фрагмента:

document.body.style.display="none";

Смотрите № 32. Этот просто скрывает документ, не перезаписывая содержимое.

Длина 34 фрагмента:

Object.prototype.toString.call(34)

Вызов Object.prototype.toString- это хороший способ определить тип объекта. Пока 34..toString()есть "34", фрагмент есть [object Number].

Фрагмент длины 33: (кредит для этого идет анонимному пользователю )

+0%-0.&(v\u0061r=~void[{}<<!(0)])

Думаете, это не правильный JavaScript? Лучше попробуйте ... (используйте Chrome);)

Длина фрагмента 32:

document.body.innerHTML="hacked"

Halp! Hazxxors! Одиннадцать !! 11!

Длина 31 фрагмента:

a=[];for(i=0;i<31;i++)a.push(i)

Не шучу, я так долго ждал, чтобы иметь возможность использовать forцикл! Этот создает массив от 0 до 30.

Длина фрагмента 30:

new Date().getDay()==1?"S":"E"

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

Длина 29 фрагмента:

Object.keys(window).push('i')

Object.keys(window)получит массив глобальных переменных (свойств window). .push()добавит элемент в этот массив. Думаешь это эквивалент window.i=undefined? Нет!

Длина фрагмента 28:

setTimeout("a=confirm()",28)

Ожидание 28 миллисекунд не очень полезно, за исключением создания нового потока.

Длина 27 фрагмента:

document.querySelector('a')

Обидно, что имена DOM такие длинные. Я мог получить только одну ссылку здесь.

Длина 26 фрагмента:

JSON.stringify({twenty:6})

Смотрите № 16. Теперь мы получаем настоящий JSON - строку.

Длина фрагмента 25:

new Badge("Good Answer");

Предполагается, Badge()что это функция-конструктор, принимающая аргумент ... Значок Good Answer был только что создан!

Длина 24 фрагмента:

do {alert(24)} while(!1)

Я на самом деле не do..whileочень много использую, но некоторые делают. Если бы это был обычный whileцикл, он ничего бы не предупредил, потому что он всегда ложный. do..whileвсегда будет работать хотя бы один раз, поэтому мы увидим 24.

Длина 23 фрагмента:

window.parent==self.top

Все они относятся к одному и тому же объекту, общеизвестному как window. Если вы вызываете функцию в обычном режиме, она также есть this. Это 5 способов доступа к глобальному объекту!

Длина 22 фрагмента:

for(i in self)alert(i)

Оповещение всех глобальных переменных. Так и случилось self==window. (Смотрите следующий фрагмент.)

Длина фрагмента 21:

"2"+1==21 && 2+1=="3"

О, смотрите, это снова правила кастинга JS. Это утверждение верно, кстати.

Длина 20 фрагмента:

Math.random()<.5?0:1

Выберите случайное число от 0 до 1 и округлите, используя троичный оператор. Хотя было бы проще использовать Math.round...

Длина 19 фрагмента:

[1,2,3].map(i=>i*i)

Этот новый. Мол, действительно новый. Он использует функции стрелок ES6 для вычисления квадратов 1, 2 и 3. В настоящее время он поддерживается только Firefox.

Длина фрагмента 18:

location.href="/";

Как # 15, но на этот раз, он идет на домашнюю страницу PPCG, а не SE.

Длина фрагмента 17:

(function(){})()

Это фрагмент из 14, но лучше! Теперь это IIFE.

Длина фрагмента 16:

obj={not:'json'}

Это объясняет одну из моих любимых мозолей. Это объект , а не JSON ! JSON - это формат обмена данными, основанный на объектах JavaScript, но в более строгом формате.

Длина фрагмента 15:

open('//s.tk/')

Представь это. Откройте домашнюю страницу SE, используя перенаправление http://s.tk/ .

Длина фрагмента 14:

function f(){}

W00t! Функция! Жаль, что нет места, чтобы сделать что-нибудь.

Длина фрагмента 13:

Math.random()

Генерация случайного числа от 0 до 1. Хотите определить свои собственные пределы? Везет, как утопленнику. (Не совсем, это просто.)

Длина фрагмента 12:

new Date<=12

Это утверждение никогда не было правдой в JS. JS не был создан до 95 года (см. Фактоид), намного позже 01.01.1970 00: 00: 00.012.

Длина фрагмента 11:

Math.PI*121

Площадь круга с радиусом 11.

Длина фрагмента 10:

if('j')9+1

Если вы не заметили, мне нравится делать что-то с номером фрагмента в коде. Этот возвращает 10 и использует j, десятую букву алфавита.

Длина фрагмента 9:

[9].pop()

Сделайте массив из одного элемента. popидет ласка 9.

Длина 8 фрагмента:

document

Основа для всей работы DOM. Но мы ничего не можем сделать, потому что это слишком долго. :( Иди jQuery!

Длина 7 фрагмента:

alert()

О, парень! Вызов функции! Наконец-то я смог сделать что-то!

Длина 6 фрагмента:

var x=6

На основании № 3. Гораздо лучше, хотя, потому что теперь глобальное явное . :П

Длина 5 фрагмента:

[][5]

Даже короче чем void 0получить undefined. Кстати: ''.aеще короче; всего 4 символа.

Длина 4 фрагмента:

+"4"

Это создаст номер 4из строки "4". Вы можете повторно использовать те же самые 4 символа в другом порядке, чтобы сделать обратное!

Длина 3 фрагмента:

x=3

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

Длина 2 фрагмента:

{}

Что это делает? Если вы сказали, создает литерал объекта, вы не правы. Это на самом деле пустой блок. Откройте консоль и попробуйте! Возвращается undefined, нет {}.

В 2018 году {}в консоли Chrome фактически возвращается пустой объект.

Длина 1 фрагмента:

1

Вот и все. Любое число является допустимым выражением JS.

Фактоид: JavaScript изначально назывался LiveScript. В то время (1995) он был изменен на JavaScript, чтобы извлечь выгоду из популярности Java. Лично им следовало сохранить старое имя; С тех пор JavaScript был источником путаницы. Фактически, Java и JavaScript примерно так же похожи, как «машина» и «ковер» .


1
Фрагмент 33 не работает на Firefox. Действительно ли это действительно JS?
Ориоль

Я нахожу строковое преобразование и повторный анализ объекта, чтобы скопировать его так грязно. ECMAScript 6 вводит Object.assign, так что фрагмент 37 становится b = Object.assign({ }, a = {3 : 7}).
Ориоль

@Oriol Да, хорошо, только Firefox поддерживает это прямо сейчас, поэтому мы должны пока придерживаться грязного пути. По крайней мере, это лучше, чем eval(uneval(a)), верно? ;)
Scimonster

О № 38, всегда есть document.querySelectorAll("element#id.classname[attribute]:not(somethingwedontwant)"). (Поддерживает любой действительный селектор CSS).
Mateon1

Сам фрагмент # 40 не так интересен, но комментарий бесценен.
Scimonster

85

р

Фактоид: язык программирования R начинался как реализация языка программирования S для GNU. Он в основном используется для статистики и связанных приложений.

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


Длина 32:

`[.data.frame`(swiss,3,2,drop=F)

Это выглядит немного загадочно ... и это действительно так! Есть гораздо лучший способ написать это:

swiss[3, 2, drop = FALSE]

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

> `[.data.frame`(swiss,3,2,drop=F)
             Agriculture
Franches-Mnt        39.7

В swissкадре данных поставляется с R , как некоторые другие , которые мы видели до сих пор. Он содержит показатели рождаемости и социально-экономические показатели для 47 франкоязычных провинций Швейцарии примерно с 1888 года. Третий ряд - для провинции Франш-Мнт, а второй столбец - процент мужчин, занимающихся сельским хозяйством в качестве профессии в каждой провинции. Так, в 1888 году 39,7% мужчин в провинции Франш-Мнт Швейцарии работали в сельском хозяйстве.

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

drop=Аргумент говорит R , хотите ли вы его уроните результат в меньшей размерности , если это возможно. Действительно, если мы скажем drop=TRUE, мы получим это:

> `[.data.frame`(swiss,3,2,drop=T)
[1] 39.7

Если раньше результатом был фрейм данных, то теперь R дает нам двойное число.


Длина 31:

print(fortune("hadleywickham"))

fortune()Функция от всезнающего fortunesпакет, который предоставляет различные мудрые цитаты из различных мудрых людей. Этот фрагмент предоставит вам следующий драгоценный камень от Хэдли Уикхэма (23), напечатав на консоли:

That's a casual model, not a causal model - you can tell the difference by looking
for the word "excel".
    -- Hadley Wickham (commenting on an Excel chart showing student's SAT score
       increases with family income, without considering future covariates)
       http://twitter.com/#!/hadleywickham (February 2012)

Длина 30:

pie(rep(1,12),col=rainbow(12))

Кто не любит хорошую круговую диаграмму? pie()Функция будет служить вам до свежеиспеченной круговой диаграммы на основе вектора чисел. rep()создает вектор, повторяя первый элемент r раз, где r - второй аргумент. col=Параметр указывает , pie()как цвет ломтиков. Магическая функцияrainbow() генерирует вектор заданной длины, содержащий шестнадцатеричные коды для «одинаково расположенных» цветов радуги.

Здесь у вас есть базовая диаграмма «Количество каждого цвета на этой диаграмме»:

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


Длина 29:

summary(lm(mag~depth,quakes))

Здесь происходит несколько вещей, поэтому давайте делать их по одному шагу за раз.

quakesпредставляет собой набор данных, который поставляется с R. Он содержит информацию о 1000 сейсмических событиях магнитудой более 4,0 по шкале Рихтера вблизи Фиджи с 1964 года. Два столбца в наборе данных mag- это величина землетрясения, и depth, которая равна глубина эпицентра в километрах.

lm()Функция, как указано в сниппета 28, подходит для линейных моделей. Он возвращает lmобъект или, точнее, объект класса lm. Есть два способа указать предиктор (или независимую переменную) и ответ (или зависимую переменную), и я выбрал метод формулы. Это принимает форму response ~ predictor. Несколько предикторов указываются как y ~ x1 + x2. Объекты в формуле оцениваются в контексте, представленном в следующем аргументе.

Таким образом, то, что lm(mag ~ depth, quakes)происходит, это подгонка линейной модели с использованием обычной регрессии наименьших квадратов, где величина - это отклик, а глубина - предиктор. Он знает, что magи depthесть, потому что мы сказали, что они пришли quakes.

summary()является универсальной функцией, используемой в основном для суммирования результатов подобранных моделей. Он вызывает метод, специфичный для класса своего аргумента. Поскольку мы передали lmобъект, он фактически вызывает функцию с именем summary.lm().

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

> summary(lm(mag~depth,quakes))

Call:
lm(formula = mag ~ depth, data = quakes)

Residuals:
     Min       1Q   Median       3Q      Max 
-0.72012 -0.29642 -0.03694  0.19818  1.70014 

Coefficients:
              Estimate Std. Error t value Pr(>|t|)    
(Intercept)  4.755e+00  2.179e-02 218.168  < 2e-16 ***
depth       -4.310e-04  5.756e-05  -7.488 1.54e-13 ***
---
Signif. codes:  0***0.001**0.01*0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 0.3921 on 998 degrees of freedom
Multiple R-squared:  0.05319,   Adjusted R-squared:  0.05225 
F-statistic: 56.07 on 1 and 998 DF,  p-value: 1.535e-13

Заметьте, как первое, что он говорит вам, это вызов функции? Это потому, что lm()функция использует match.call(), как мы это сделали в фрагменте 28!


Длина 28:

f<-function(x,y)match.call()

Функции R часто любят отслеживать, что вы им говорите. Действительно, иногда отправляемая вами команда возвращается вам как атрибут возвращаемого объекта. (Примером является то lm(), что создаются линейные модели.) Вызов точных инструкций выполняется с помощью match.call()внутри функции. Это фиксирует или соответствует интерпретированному вызову функции.

Здесь мы определили функцию, f()которая принимает два аргумента, а затем сообщает вам, что она видела.

> f(1,2)
f(x = 1, y = 2)

Это в первую очередь полезно при разработке функций для общего пользования (а не только для вас), как при разработке пакетов. Если вы хотите увидеть пример match.call()в дикой природе, посмотрите на исходный код для lm()отправки stats:::lm. Первое, что он делает, - фиксирует вызов функции с помощью match.call().


Длина 27:

install.packages("ggplot2")

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

install.packages()делает именно то, что предполагает его название. Он отправляется на поиски пакетов, использующих зеркало CRAN (Comprehensive R Archive Network) по умолчанию, а затем устанавливает их в вашей системе, где R может их найти. Вы также можете установить пакеты из локального исходного кода.

Помните фрагмент 23, где мы использовали ggplot2пакет? Этот пакет не поставляется с R, но всего за 27 символов вы можете воплотить все свои ggplot2мечты, установив его.


Длина 26:

filled.contour(t(volcano))

Набор volcanoданных поставляется с R. Это матрица, содержащая топографическую информацию о вулкане Маунгавхау (или гора Эдем) в Окленде, Новая Зеландия. Строки матрицы соответствуют линиям сетки, идущим с востока на запад, а столбцы - линиям сетки, идущим с юга на север.

Ради дезориентации давайте поменяем местами направления, чтобы столбцы были теперь восток-запад, а ряды - юг-север. Мы можем сделать это с помощью транспонирования матрицы, выполненного с помощью t(). И почему бы не сделать контурную карту, пока мы на ней? filled.contour()делает именно это

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


Длина 25:

pmatch("s",c("n","size"))

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

Здесь приведен фрагмент реального использования этой функции. Вспомните фрагмент 13, где мы использовали эту sample()функцию. Он принимает аргументы n, size, replaceи prob, а требует только первые два. В фрагменте 13 мы использовали s=сокращенную запись для size=. Что на самом деле происходит в фоновом режиме, это что-то вроде этого фрагмента, где то, что мы предоставили, сравнивается с ожидаемым. Поскольку «s» соответствует «размеру» однозначно, вполне допустимо использовать его в s=качестве сокращения.


Длина 24:

`(`=function(x)9;2*(3-1)

Прекрасный пример того, что вы не должны делать! Когда-либо!

Вы можете назначать символы как функции, если вы определяете их в обратном тике при определении функции. Здесь мы сказали R, что (это функция, которая всегда возвращает 9 независимо от ввода. Как и во многих других языках, ;может использоваться для включения двух команд в одну строку. Итак, что мы сказали R, это определить функцию (, а затем распечатать 2*(3-1).

Теперь любой человек скажет вам, что 2 * (3-1) должно быть 4, потому что вы делаете 3-1 = 2, тогда 2 * 2 = 4. Но мы сказали R, что все, что в скобках, равно 9. Итак, пока 3-1 = 2, теперь мы имеем (3-1) = 9. Тогда мы получим 2 * (3-1) = 2 * 9 = 18.

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


Длина 23:

qplot(Na,y=RI,data=fgl)

Наконец достаточно голосов за (очень) простой ggplot2пример. ggplot2Пакет является реализацией R Грамматики графики, созданная легендарным R божеству Hadley Wickham . В целом, синтаксис сильно отличается от базовой графики R и требует некоторого привыкания. Тем не менее, qplot()это более простой интерфейс для некоторых основных функций пакета и имеет синтаксис, похожий на plot()базовый R. Но в отличие от многих примеров, которые я вам показал, qplot()не поддерживает частичное совпадение имен параметров функции.

Набор fglданных поставляется из MASSпакета. Содержит измерения свойств фрагментов криминалистического стекла. Здесь мы используем переменные Na, которые представляют собой процентное содержание натрия (Na) по массе и RIкоторый является показателем преломления стекла.

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


Длина 22:

unique(presidential$n)

unique()Функция возвращает вектор , содержащий уникальные значения из своего входного вектора в порядке , в котором они появляются на входе. Набор presidentialданных поставляется с ggplot2пакетом (27). (Спасибо Jemus42 за исправление!) Его описание:

Имена каждого президента, даты начала и окончания срока их полномочий, а также их партия из 10 президентов США от Эйзенхауэра до Буша У.

presidentialявляется фреймом данных, а фреймы данных содержат столбцы так же, как списки содержат элементы. Столбцы ссылаются по имени, используя $. Этот конкретный набор данных имеет столбец nameс именем президента. Но подождите, мы только уточнили n! На самом деле, это еще один пример частичного сопоставления (13, 16), поэтому nон полностью правдив.

Отправка этого имеет интересный результат:

[1] "Eisenhower"  "Kennedy"  "Johson"   "Nixon"  "Ford"  "Carter"
[7] "Reagan"      "Bush"     "Clinton"

Обратите внимание, как пишется имя Линдона Б. Джонсона ... Упс.

(Примечание: через год после публикации мне стало известно, что опечатка Джонсона исправлена. RIP юмор.)


Длина 21:

integrate(dexp,0,Inf)

R имеет встроенную функцию для адаптивной квадратуры функций одной переменной на конечном или бесконечном интервале. В R бесконечность указывается как Infдля + бесконечность и -Infдля -infinity. dexp()Функция является функцией распределения вероятности для экспоненциального распределения. Так как поддержка экспоненциального распределения равна [0, + бесконечность) и распределения вероятностей интегрируются в 1, мы ожидаем, что результат будет 1. Вот, ожидаемый результат!

1 with absolute error < 5.7e-05

Длина 20:

deriv(~cos(x^3),"x")

R может делать символические производные! Это возвращает:

expression({
    .expr1 <- x^3
    .value <- cos(.expr1)
    .grad <- array(0, c(length(.value), 1L), list(NULL, c("x")))
    .grad[, "x"] <- -(sin(.expr1) * (3 * x^2))
    attr(.value, "gradient") <- .grad
    .value
})

Просматривая это, вы можете увидеть, как она анализирует функцию и использует правило цепочки. Все, что должна выполнять функция, взявшая за первый год исчисление! Первым аргументом deriv()функции является выражение R (которое является фактическим типом R) в терминах некоторой переменной, в данном случае x. Второй аргумент - это имя переменной, по которой берется производная "x".

Хотите увидеть что-то действительно аккуратное? Присвойте вышеуказанное переменной, скажем dx. Определите переменную xкак числовой вектор. Тогда отправь eval(dx). R оценивает производную в x!


Длина 19:

c(matrix(1,3,3),"a")

В R, c()сокращение от «объединить» или «объединить», создает вектор из своих аргументов. Элементы векторов должны быть одного типа и иметь длину 1. Но вместо того, чтобы злиться на вас из-за этого, R сгладит элемент со структурой, в данном случае матрицу, и приведёт все к одному типу.

Если аргументы c()содержат только один тип, преобразование типов не происходит, например, если все аргументы являются логическими ( TRUEи FALSE), вектор будет всем логическим. Если он содержит логику и цифры, это будут все цифры. Если он содержит символ и прочее, он будет полностью символическим. Итак, наш фрагмент дает нам это:

> c(matrix(1,3,3),"a")
[1] "1" "1" "1" "1" "1" "1" "1" "1" "1" "a"

Обратите внимание, что матрица 3 на 3 была сглажена, и добавление «а» превратило все в символы.


Длина 18:

(1-1/3-1/3-1/3)==0

Урок точности машин. Это возвращается FALSE.


Длина 17:

example(readline)

example()Функция даст вам пример того , как использовать любую встроенную функцию. Если вам нужно выяснить, как использовать readline(), R имеет самодовольный ответ для вас.

> example(readline)

readln> fun <- function() {
readln+   ANSWER <- readline("Are you a satisfied R user? ")
readln+   ## a better version would check the answer less cursorily, and
readln+   ## perhaps re-prompt
readln+   if (substr(ANSWER, 1, 1) == "n")
readln+     cat("This is impossible.  YOU LIED!\n")
readln+   else
readln+     cat("I knew it.\n")
readln+ }

readln> if(interactive()) fun()
Are you a satisfied R user?

Путь быть скромным, р.


Длина 16:

acf(lh,t="part")

acf()Функция возвращает функцию автокорреляции для временных рядов. lhэто набор данных, который поставляется с R. Его описание:

Регулярные временные ряды, дающие лютеинирующий гормон в образцах крови с 10-минутными интервалами от человеческой женщины, 48 образцов.

В этом примере частичное совпадение используется дважды : один раз с параметром функции и один раз со значением строки, переданным параметру. Полное имя параметра typeи общепризнанные ценности "correlation", "covariance"и "partial". Достаточно только строки должен быть обеспечен , чтобы определить его однозначно, поэтому мы можем использовать "part"для "partial", что дает нам частичную функцию автокорреляции (PACF).

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


Длина 15:

p3d(bunny,p=99)

Снова мы видим печально известного зайчика (11). onionПакет дает нам еще более хороший способ просмотра самый полезный набор данных когда - либо, используя функцию замышляет 3D p3d(). Это вызывает базовую графическую функцию persp()в фоновом режиме, которая принимает вращательный аргумент phi. Используя частичное совпадение имен параметров (13), мы можем указать только p=вместо phi=.

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


Длина 14:

stats:::rgamma

R с открытым исходным кодом, но вам не нужно быть волшебником для просмотра исходного кода; Вы можете просто ввести имя пакета и функцию, код которой вы хотите просмотреть, разделив их тремя двоеточиями ( :::). Это дает вам код, который определяет rgamma()функцию, которая генерирует случайные отклонения от гамма-распределения. Отправка этого дает:

function (n, shape, rate = 1, scale = 1/rate)
{
    if (!missing(rate) && !missing(scale)) {
        if (abs(rate * scale - 1) < 1e-15)
            warning("specify 'rate' or 'scale' but not both")
        else stop("specify 'rate' or 'scale' but not both")
    }
    .External(C_rgamma, n, shape, scale)
}
<bytecode: 0x00000000098cd168>
<environment: namespace:stats>

Обратите внимание, что он использует функцию .External(). Это вызывает функции, написанные на других языках, обычно C и Fortran, языках, которые составляют большую часть основы R. Поиск этого исходного кода требует немного волшебства. Редактировать: @Vlo указал, что простые смертные действительно могут просматривать базовый код C, который вызывается .Internal()и .Primitive()использует pryrпакет. Спасибо, @Vlo!


Длина 13:

sample(9,s=4)

Это выглядит не так уж много, но это пример мощной концепции в R: частичное соответствие параметров функции . Именованные параметры в sample()функции есть size, replaceи prob, но вам нужно всего лишь указать достаточное количество букв именованного параметра, чтобы однозначно идентифицировать его. Таким образом sample(), вы можете использовать s=вместо, size=так как никакие другие имена параметров не начинаются с буквы "s". Код здесь выбирает случайную выборку размером 4 из целых чисел от 1 до 9.


Длина 12:

LETTERS[-pi]

Существует встроенный вектор с именем, LETTERSкоторый содержит все заглавные буквы английского алфавита. В отличие от многих других языков, вы можете индексировать вектор, используя число с плавающей запятой. Ничего слишком захватывающего не происходит; R просто берет целую часть. Использование -предшествующего индекса вектора удаляет элемент с этим индексом из вектора. piявляется встроенной константой, содержащей - как вы уже догадались - иррациональное число π. Таким образом, это удаляет элемент 3 из вектора и возвращает «A» - «Z», опуская «C».


Длина 11:

plot(bunny)

В onionпакете есть набор данных с именем bunny. С его помощью вы получите наиболее полезную графику всех времен:

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


Длина 10:

????sample

Скажем, вы ДЕЙСТВИТЕЛЬНО запутались в этой sample()функции, и вам крайне нужна помощь. Вместо того, чтобы обычно ?sampleподнимать страницу руководства по R, вы набираете четыре знака вопроса. R слышит ваше положение и пытается помочь ...

Contacting Delphi...the oracle is unavailable.
We apologize for any inconvenience.

Увы.


Длина 9:

isTRUE(1)

Сначала это выглядит так, чтобы игнорировать соглашение в остальной части базового пакета R и разделить isследующее слово в имени функции с .. Однако это относится только к логической проверке того, имеет ли аргумент определенный тип, как показано ниже (8). В этом случае мы проверяем, не является ли это TRUEтипом. Здесь используется строгое определение TRUE, т. Е. 1 не является «истинным» в обычном смысле. isTRUE(1)возвращается FALSE.


Длина 8:

is.na(8)

В отличие от большинства других языков программирования, .является допустимым символом в именах функций и переменных. Он не обозначает какой-либо метод или иерархию; это просто часть имени. is.na()Функция проверяет , оценивает ли ее аргумент NA(отсутствует) и возвращает TRUEили FALSE.


Длина 7:

stop(7)

Это выдает ошибку с вводом в качестве сообщения об ошибке. Если вызывается внутри функции, выполнение функции останавливается. Но вызов его вне функции не остановит скрипт. В этом случае на выходе есть Error: 7.


Длина 6:

x < -1

Хотя это может показаться тривиальным, оно вызывает серьезную критику оператора присваивания, <-а именно: значение меняется в зависимости от расположения пробелов. Как уже упоминалось, x <- 1присваивает 1 к x. Разделение <и -с одним пробелом, как указано выше, превращает его в логический тест на то x, меньше ли -1. По этой причине многие предпочитают =для назначения.


Длина 5:

x<<-1

По аналогии с <-исключением <<-всегда назначает переменную глобальной области независимо от текущей области.


Длина 4:

x<-1

R использует <-для присвоения переменных в текущей области. Этот фрагмент присваивает значение 1 для x.


Длина 3:

!0i

!Оператор R для «нет» , и 0iэто комплексное число 0+0i, АКА 0 в комплексной плоскости. Отправка этого оператора возвращает, TRUEпоскольку 0 ложно.


Длина 2:

NA

Это возвращает специальное значение R NA, которое обозначает «недоступно», обозначая пропущенное значение.


Длина 1:

T

Это возвращается TRUE. В R Tи Fсинонимы для логических значений TRUEи FALSE, соответственно.


Yay R "!"(T)!
Вл

@Vlo: "!"(T)оценивает в FALSE. Однако утверждение «Yay R» никогда не бывает ложным. ;)
Алексей Александрович

Как я могу поддержать больше для большего количества записей ???? «Обнаружение , что исходный код действительно занимает немного колдовства» тривиальна .Internalи .Primitive->pryr::show_c_source(.Primitive("sum"))
Vlo

@Vlo: я не слышал о pryrпакете. Очень круто! Спасибо что подметил это. Я рад, что вам нравятся записи, спасибо за поддержку. :)
Алекс А.

2
@ Jemus42 Ах, похоже, тебе нужно сделать data(bunny)сначала.
Алекс А.

75

Brainfuck

Фактоид: Brainfuck (также известный как brainf * ck) был экспериментальным эзотерическим языком для создания самого маленького интерпретатора языка, полного тьюринга, когда-либо созданного Урбаном Мюллером, и в настоящее время является самым известным языком в своем роде. Он имеет всего восемь команд, прост в освоении, но сложен в использовании.

Brainf * ck имеет базовую память на ленте с 30000 ячеками и подвижным указателем и может отображаться следующим образом:

0 0 0 0 0 0
    ^

С ^символом, представляющим указатель, и 0, представляющими значения для каждой ячейки.

Brainfuck имеет восемь инструкций:

Instruction  C Equivalent              Description
+            mem[ptr]++;               Add one to the value under the cell
-            mem[ptr]--;               Subtract one from the value under the cell
>            ptr++;                    Go on cell to the right
<            ptr--;                    Go on cell to the left
,            mem[ptr] = getchar();     Read a ASCII character from input and put the result in the value under the cell
.            putchar(mem[ptr]);        Write a ASCII character to the output using the value under the cell
[            while (mem[ptr]) {        Start a while loop: Continue to matching ']' when value under the cell is 0
]            }                         End a while loop: Go back to matching '[' when value under the cell is NOT 0

Brainfuck для C:

#include <stdlib.h>

int main(void) {
    unsigned char* mem = calloc(30000, sizeof(unsigned char));
    unsigned int ptr = 0;

    // Put your brainfuck code here, converted to the matching expressions under "C equivalent"

    return 0;
}

Длина 1 фрагмент

Прочитайте один символ и поместите его в текущую ячейку.

,

Память (с входом: abc)

0 0 97 0 0 0
    ^

Длина 2 Фрагмент

Добавьте один к текущей ячейке и сдвиньте указатель вправо.

+>

Память

0 0 1 0 0 0
      ^

Длина 3 Фрагмент

Удалить один из текущей ячейки, пока она не станет нулевой; Установите текущую ячейку на ноль

[-]

Возможная память:

Память: (до)

0 0 100 0 0 0
    ^

Память: (после)

0 0 0 0 0 0
    ^

Длина 4 Фрагмент

Комментарии: В brainfuck все, что не является инструкцией, игнорируется. По этой причине следующая программа является полностью допустимой (но пустой) программой brainfuck:

Hey!

Длина 5 Фрагмент

Простая кошачья программа (запись ввода в вывод)

,[.,]

Спасибо Томсмеду за его комментарий

Длина 6 Фрагмент

Переместите значение текущей ячейки в ячейку справа (если предположить, что ячейка справа равна 0, в противном случае это добавит значение текущей ячейки к значению ячейки справа):

[>+<-]

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

Память: (до)

10 0 100 0 0 0
     ^

Память: (после)

10 0 0 100 0 0
     ^

Длина 25 Фрагмент

Повторите ввод шести символов и распечатайте его, а затем каждый символ ASCII (N-1) .. 1 (где N - это значение первого входного символа).

,>,>,>,>,>,.<.<.<.<.<[.-]

Длина 53 Фрагмент

main(){i=0;j=0;if(i>=0){if(j<=i)i+=1;i-=1;}return 0;}

Эта минимизированная C-программа также является замаскированной программой Brainfuck, и наоборот! На самом деле, они (почти) делают то же самое. Вот код Brainfuck без «комментариев» (код C).

><+-

Позвольте мне объяснить код Brainfuck (и код C). Как видите, он использует две ячейки ( iи j). Увеличивает первую ячейку (увеличивается iна 1). Затем он уменьшает ту же ячейку (уменьшается iна 1).

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


2
,[.,]- 5 символов, программа для кошек
Томсминг

13
Это может быть лучший "Brainfuck 101", который я когда-либо видел.
hoosierEE

длина 6: это поместит сумму в правую ячейку и обнулит левую. Не двигайся, верно?
Филип Хаглунд

Добавлена ​​фиктивная переменная длины 6, чтобы лучше объяснить концепцию. Программа фактически добавит ячейку № 3 в ячейку № 4 и сделает ячейку № 3 0.
YoYoYonnY

58 голосов - не могли бы вы обновить? :)
Конор О'Брайен

65

C ++

Благодаря своему препроцессору, шаблонам, лямбдам, чертам типов и множеству других сложных функций, которые никто никогда не сможет понять в полной мере, C ++ переоткрывается каждым новым поколением своего стандарта. Используя многочисленные способы сделать что-то во время компиляции, можно написать ноль служебных абстракций, таких как библиотека, которая позволяет физическим единицам присоединяться к числовым типам данных, чтобы проверять их устойчивость во время компиляции (например, вы не можете назначить результат kg* mдля N)

Длина 1

#

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

Длина 2

%:

Конечно, не у всех есть #ключ, поэтому C ++ (ну, он действительно унаследовал его от древнего C) щедро позволяет вам писать его с помощью этого альтернативного токена (он же digraph )

Длина 3

??=

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

Длина 4

auto

Является одним из более новых (начиная с C ++ 11) изобретений, упрощающих работу с универсальным кодом. Он предназначен для определения типа выражения, а начиная с C ++ 14 его можно использовать даже для определения лямбда-параметров и возвращаемого типа функций.

Длина 5

 catch

Это ключевое слово, также известное из многих других языков, присутствующее в C ++, но хороший идиоматический программист C ++ почти никогда не использует его. Со своими конструкторами и деструкторами в идиоматическом C ++ используется принцип, широко называемый RAII (Resource Acquisition is Initialization) или как мне иногда хочется назвать его более подходящим образом: SBRM (Scope Bound Resource Management). Благодаря таким классам, как интеллектуальные указатели, можно привязать время жизни динамически распределенных ресурсов (то есть не только памяти!) К другим объектам. Когда они выходят из области видимости (например, из-за брошенного исключения), эти объекты автоматически очищают ресурсы. Это позволяет исключить безопасный и простой в использовании код, который не требуется использовать catch.

Длина 6

[](){}

[]{}()

Как упомянул Стефан в комментариях, вы можете использовать []{}как самый короткий лямбда-объект, поэтому это самая короткая форма для вызова лямбда-выражения. Следующий текст для старой версии:

вероятно самая короткая форма лямбды. Лямбды в C ++ - это объекты (определенного типа реализации), которые могут захватывать часть области, в которой они созданы (синтаксис [] контролирует это), и могут вызываться (синтаксис () контролирует это). Их код (часть {}) имеет доступ к этим переменным, как если бы они находились в их области видимости. С их опциональный тип возврата удержания и автоматический параметр вычет введен в C ++ 14, они инструмент использовать для всех стандартных алгоритмов библиотеки , которые ожидают вызываемым (например, третий параметр станд :: сортировка).

Длина 7

virtual

Это ключевое слово для начала использования полиморфизма во время выполнения в C ++, одном из базовых блоков объектно-ориентированного программирования. Это следует принципу «не платите за то, что вы не используете», поскольку на других языках все функции по умолчанию являются виртуальными. Будучи языком с множеством парадигм, люди, думающие «C ++ является объектно-ориентированным», могут удивиться, увидев программы или библиотеки, которые почти не используют это ключевое слово, например, потому что они следуют общему принципу программирования.

Длина 8

override

Совместная работа с ключевым словом virtual overrideявляется одним из более поздних дополнений в C ++, чтобы заставить компилятор работать больше за вас. Используя его, вы выражаете намерение переопределить виртуальную функцию в базовом классе, и компилятор выдаст ошибку, если вы допустили ошибку, и у этого класса нет указанной функции. В общем, это считается хорошим стилем, если ваш код выражает намерение, а не возиться с битами.

Длина 9

constexpr

Будучи также более поздним дополнением к C ++, constexprпозволяет программисту выражать для функций или переменных, что они известны во время компиляции и должны быть вычислимы во время компиляции. Это позволяет использовать эти функции в контекстах, которые требуют выражения времени компиляции (например, в качестве параметров шаблона или размеров массива). Многие стандартные библиотечные функции (если это возможно) уже являются constexpr, поэтому их можно использовать здесь.

Длина 10

for(i:c){}

Является ли полный цикл над контейнером или контейнероподобной конструкцией, которая поддерживает std::beginи std::endполучает итераторы (включая массивы в стиле C). Это в основном эквивалентно for(auto __i = std::begin(c); __i != std::end(c); ++__i){ auto& i = *__i; }. Это позволяет легко зацикливаться в общем коде.

Длина 11

void f()&&;

Это новый способ объявления функций-членов и свойств объекта, к которому они могут быть вызваны. В предыдущих версиях C ++ у нас была только возможность void f() const;указать компилятору, чтобы он мог вызывать функцию для const-объектов (поэтому без const вы не можете вызывать их для неконстантных объектов). Таким же образом у нас теперь есть &&синтаксис для ссылок на r-значения, которые используются для возможности вызова этих функций для r-значений.

Длина 12

int main(){}

Это, вероятно, самая короткая полная программа, которую вы можете скомпилировать и запустить. Он ничего не сделает и вернет 0. Этот возврат является одним из многих особых случаев, с которыми вы можете столкнуться в C ++. Обычно возврат ничего не является неопределенным поведением, но для функции точки входа main возвращение ничего не означает возвращение 0.

Длина 13

auto f()->int

это довольно новый способ объявить тип возвращаемого значения функции. Обычно вы бы этого не делали, если вы уже знаете тип, но в универсальном программировании существует множество ситуаций, когда тип зависит от параметров шаблона и переменных, которые вы используете. Делая это таким образом, вы получаете несколько более легкий доступ к этим параметрам, чем template<class T> auto f( const T& t ) -> decltype(t.foo())вместоtemplate<class T> decltype(std::declval<T>().foo()) g( const T& t ) { return t.foo(); }


2
Я бы предложил использовать ;в качестве альтернативного фрагмента из 1 символа, потому что это не макрос препроцессора, и тот факт, что вы можете иметь 1-символьный оператор в C ++, кажется странным.
Джо З.

1
[](){}не самая короткая форма лямбды: поскольку список параметров пуст, его можно опустить. Отсюда []{}самая короткая лямбда. Тривиально, []{}()это самое короткое исполнение лямбды ;-) ideone.com/k8fAvs
stefan

@stefan: действительно, я всегда забываю это, так как это не похоже на функцию;) Я добавил это к ответу.
PlasmaHH

@PlasmaHH Я абсолютно ненавижу это, потому что действительно это не похоже на функцию .. ;-)
stefan

59

Regex

Длина 2 фрагмента

[]

JavaScript : пустой класс символов, который ничего не соответствует.

PCRE , Java , Pythonre , Ruby (протестировано на версии 2.0): синтаксическая ошибка.

Длина 1 фрагмента

.

., называемый dot-all, доступен во всех вариантах, на которые мне довелось взглянуть.

Что это соответствует?

I̧n͟ g̨͜e҉̡͞n̵͢e͜͝r̷͝a͘l̢҉, ̡͟ ̕̕ ̴.̸̴̢̛́ ̸̡̢m͞ąt̴̨c͞h̛e͢͡s̶͘ ͘a҉n̛͜͠ỳ̸ ͢c̵̡hár͘͝a̕͢ćt͘͠e͏̀͠r̷̀ ̴̕͢ex͝͞͞c҉ep̀t̛ ̕f̴҉o͟͜r̴͢ ͞n͏ę͟w̢̕͜ ͡l͝i̸̧n͢͡

JavaPattern : в режиме по умолчанию точка-все соответствует любой кодовой точке, кроме этих 5 кодовых точек \r\n\u0085\u2028\u2029. При UNIX_LINESвключенном режиме (но без DOTALL) точка-все соответствует любой кодовой точке, кроме \n. При DOTALLвключенном режиме точка-все соответствует любой кодовой точке. Начиная с Java 5, Patternработает с кодовой точкой, поэтому астральные символы сопоставляются точкой.

Pythonre (протестирован на 2.7.8 и 3.2.5, может отличаться на 3.3+): в режиме по умолчанию точка-все соответствует любой кодовой единице UTF-16 (от 0000 до FFFF включительно), за исключением \n. re.DOTALLснимает исключение и .сопоставляет любую кодовую единицу UTF-16. В этих версиях reработает с кодовыми единицами UTF-16, поэтому .удается сопоставить только одну кодовую единицу символов в астральной плоскости.

.NET : То же, что и Python. Точечный режим в .NET называется Singleline.

JavaScript (C ++ 11 <regex>) : в режиме по умолчанию точка-все соответствует любой кодовой единице UTF-16, за исключением этих 4 кодовых точек \n\r\u2028\u2029. При установленном sфлаге точка-все соответствует любой единице кода UTF-16. JavaScript также работает с кодовыми единицами UTF-16.

PCRE : В зависимости от варианта сборки, dot-all может исключать \r, \nили \r\n, или все 3 последовательности CR LF, или любую последовательность новой строки Unicode в режиме по умолчанию. В режиме по умолчанию механизм работает с кодовой единицей (может быть 8, 16 или 32-битной кодовой единицей), поэтому точка-все соответствует любой кодовой единице, за исключением последовательностей новой строки. В режиме UTF механизм работает с кодовой точкой, поэтому точка-все соответствует любой кодовой точке, за исключением последовательностей новой строки. Точечный режим называется PCRE_DOTALL.

PHP (протестирован на ideone): PCRE, скомпилирован как библиотека UTF-8 и \nявляется единственной последовательностью новой строки по умолчанию. Dot-all режим доступен через sфлаг.

Postgres : в режиме по умолчанию точка-все соответствует любой кодовой точке без исключения.

Ruby (протестировано на версии 2.0.0): в режиме по умолчанию .соответствует любой кодовой точке, кроме \n. Режим Dot-all доступен через mфлаг (!).

s Флаг используется для обозначения кодировки Windows-31J в Ruby.


Factoid

Ŗ͞e̡͟҉ǵ͟͢e̴̢͘͡x̡́͞ ̛̀҉҉̢c҉̷̨a̸̛͞n҉̛͠ ̷̸̀p̴͠͡҉̵ą̧͜͢r̸̸̷̢͝s̢̀͡e̷̷̷͘͞ ̨̧̀H̨̧͜͜T̷͞M̷̛͜L͢.̴̡́ Повторите за мной. R̶̶̢̧̰̞̻̮̳̦̥ͭͯ̓̈ͯͤ̇͊͊͟ĕ̹̩̪͈͈͍̗͎̝͚̽̈ͨ̐̽ͪͮ̍͐ͮͧ̔̏̓ͣĝ̵̢̢̖̤̜̭͔͊͒ͦ͛ͤ͗ͬͧͪ̾͘͟eͦ̄ͭ̑̾҉̨̨̝̬̹̘̭͔͟͢x̣̻͓̠͈͕̥̜͚̝̫͚̳̾̍ͦ̑̈̋̌̉͊ͮ͗̄̆̒̚̚ ̸̦͈̥̬̺͇ͧͧ͐ͮ̌ͤ̈̒̆ͣ̈̏̔͊̐ç̨̬̪̳̦͎̖͕̦͔ͨ̿̓̈ȁ̸̳̺̠̭ͮ̓̐͘̕͜͡ņ̨̫͔͍̬̤̘͎͚̣̟̦͍̜ͭͭ̈ͦ̈̽͗ͥ̑͝͡ PARSE ͉̭̫̰͔̝͓̼̮͚̻͎͎͉̐͗͗͊̇ͣ͒͗͑̆͐̐ͬ͛ͮ͝H̢̥͕̼͓̫͙̺̼̮ͣͦ̍ͨ͒̔̌T̪̦̻̦͖̞̤͒̑ͭ̐̑ͭͣ͐̒̉͊͜͜M̞̪͇͕̩͉͗ͧ̌ͯ͋̉̍ͭ̓̇̐̌͜͠Ĺ̷̨̳̘̯͚͓͛͌ͭ̉̍.ͯ͆̊ ͯ̇̓̏͐ͪ̋̈͑̕҉̷̠̰̼̤


35
Я чувствую себя плохо для любого, кто не получает справку фактоида.
Робобенкляйн

6
@robobenklein Я знаю секретное лекарство от твоей боли: просто просвети нас!
flawr

24
@flawr Для тех, кто не знает знаменитый вопрос: первый ответ на stackoverflow.com/questions/1732348/… именно то, что вы ищете.
Робобенкляйн

1
Вы можете прочитать текст Zalgo, но не принимайте их слишком серьезно в обоих направлениях. Совершенно неверно слепо идти по пути Зальго, но текст Залго не ошибается все время.
n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳

12
@ n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳, вы не собираетесь использовать все эти голоса, чтобы показать нам, как анализировать HTML?
mbomb007

57

J

PS: фрагменты теперь связаны с tryJ.tk, позволяя вам поиграть с ними, работающими на JavaScript в вашем браузере, без установки J.

PPS: я обменял заказ; это имеет больше смысла для присоединяющихся людей и для дальнейшего использования.

PPS: я думаю, из-за нехватки времени я добавлю один фрагмент в день

Factoid:

J является потомком APL (см. Здесь для семейной истории) минус смешной набор символов.

Длина 1 фрагмента

_

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

Длина 2 фрагмента

a.

a.называется Алфавит , содержащий все 1-байтовые символы. Таким образом, J не содержит функции вроде atoi, так как они являются простыми поисками в алфавите:a. i. 'z' =122

Длина 3 фрагмента

i.9

i.предназначен для целых чисел, когда используется монадически (т.е. только один аргумент, правильный, обычно называемый y). При двойном использовании он служит индексом , как в примере выше.

Длина 4 фрагмента

!!6x

J поддерживает произвольные целочисленные и рациональные числа точности . Это вычисляет факториал факториала 6 (1747-значное число).

Длина 5 фрагмента

^.^:_ 

Плотный ... Во-первых, глаголы (как J вызывает функции) организованы по темам. Все глаголы связаны с возведением в степень. ^для возведения в степеньexpкогда используется монадически, ^.для логарифмов . ^:это специальное соединение Power (функция более высокого порядка), которое применяет функцию несколько раз. Когда аргумент right равен infinity ( _), он выполняет свой левый аргумент (в пример ^.) на собственном выводе, пока не сходится. По сути, ^.^:_это решение глагола x = ln(x)применительно к любому аргументу, кроме 1, приводящее к 0.318132j1.33724.

Длина 6 фрагмента

^0j1p1

или эквивалентно

^o.0j1

Идентичность Эйлера в J. Как указано выше, ^есть exp(). Помимо произвольных прецизионных целых и рациональных чисел, он также поддерживает степени пи и комплексных чисел, а также их комбинации в виде литералов. 0j1p1значит (0 + j) * pi ^ 1.

Длина 7 фрагмента

+/&.:*:

Глагол, принимающий 2-норму любого вектора. Это демонстрирует 2 вещи:

  • Вставить Наречие превращает Добавить глагол +в Sum, вставив его между каждым элементом своего аргумента. Отсюда (0+1+2+3) = +/ i.4.

  • Соединение Under при использовании в качестве v &.: u yэквивалентно vi u v y, где viнаходится аверс (обычно обратный).

Да, J знает о функциональных инверсиях. Сочетание этих слов делает глагол во фрагменте эквивалентным %: @: (+/) @: *:или, например, sqrt(sum(y.^2))в Matlab.

Длина 8 фрагмента

$#:I.@:,

Вилка состоит из 3 -х глаголов без каких - либо ссылок на аргументы. Это позволяет то, что в J называется молчаливым (бессмысленным) программированием. Вилка f g hв монадическом случае (как в этом примере) эквивалентна (f y) g (h y). Что касается вилок, многомерные массивы являются неотъемлемой частью J. «Индексы» возвращают индексы единиц в векторе, но не распространяются на более высокие измерения как таковые. В этом примере используются Shape , Antibase и I.@:,3 зубца форка, реализующих I. для массивов более высокой размерности, например:

 ($#:I.@:,) 5 = i. 5 5 NB. indices of 5 in i. 5 5

Длина 9 фрагмента

<"1 i.4 6 

Массированные массивы - это тип данных в J, позволяющий объединять разнородный контент (как тип, так и размер) в одно значение. Монадические < боксы это аргумент. Ранг является центральным понятием в J и позволяет автоматически расширять глаголы в направлении массивов более высоких измерений. И существительные и глаголы имеют звание.

Ранг существительного - это число измерений любого существительного, которое глагол $@$может вам сказать. Например i. 2 3 4, это массив ранга 3.

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

Глагол работает с существительными клетками ранга, равного рангу глагола, и заменяет результаты в rank-verb rankрамке существительного . Ранг глагола может быть ограничен, используя соединение ранга , как это делается здесь, боксируя ячейки (строки) ранга 1 вместо работы на ранг _, т.е. бокс весь массив. Больше информации о ранге можно найти здесь .

Длина фрагмента 10

<./ .+~^:_

Этот фрагмент представляет собой глагол, вычисляющий кратчайший путь над взвешенным орграфом. Он вводит минимум ( <./) и соединение точек . Точечное соединение является обобщением матричного произведения, которое можно записать в виде +/ . *. Как правило, u . vэквивалентно тому, u@(v"(1+lv,_))где lv - левый ранг глагола v. Или в словах «u применяется к результату v в списках« левых ячеек аргумента »и правого аргумента в toto». (Смотри выше для рангов)

Таким образом, внутренний глагол <./ .+~заменяет элемент y(i,j)на минимум y(i,k)+y(k,j)для всех k.

^:_ повторяет этот шаг до сходимости.

Пример, показывающий исходное и кратчайшее пути:

(]; <./ .+~^:_ ) wtm=: _6]\0 2 5 _ _ _ _ 0 4 1 3 _ _ _ 0 _ _2 _ _ _ 4 0 _ 5 _ _ _ _1 0 6 _ _ _ _ _ 0

Длина фрагмента 11

<.@o.10x^99

Этот фрагмент представляет специальный код : некоторый код J поддерживается кодом, специально написанным для определенного варианта использования, распознаваемым во время анализа и оптимизированным; либо для более высокой точности (как в данном случае) или более высокой производительности (см. Специальные комбинации )

Эта фраза дает 99 цифр числа Пи (хотя смещено 99 знаков после запятой). Специальный код зависит от точной формулировки, то, что обычно эквивалентно, не так точно, как код фрагмента: <.o.10x^99 теряет расширенную точность.

Длина 12 фрагмента

($-.1:)($,)]

Время от времени вы попадаете в ситуации, когда из-за выбора, сделанного в данных, на пути выполняются одноэлементные измерения. Эта удобная утилита, называемая squeeze в Matlab, выжимает все одноэлементные измерения. Левый зубец вилки ($-.1:)возвращает все измерения без таковых, в то время как средний ($,) преобразует выровненный массив в сохраненные размеры. Правильный знак ]служит только для того, чтобы сделать это форком, и ссылается на правильный аргумент.

Длина 13 фрагмента

1 :'-u%u d.1'

Метод Ньютона находит приближение корня дифференцируемой функции. Это явное наречие применяется к функции, для которой ищется корень, и представляет собой один шаг итерационной процедуры. uявляется аргументом, относящимся к функции и заменяемым в момент применения наречия. d. это конъюнкция, производная функции символически, и может быть заменена на то, D.что делает то же самое численно (но отличается при применении к функциям более высокого ранга). Результатом является хук, вычитающий вилку ( uразделенную на ее производную) из аргумента.

Например:

(_2 + *:) (1 :'-u%u d. 1')^:_ ] 1 NB. root of x^2-1; ] is there to avoid combining _ and 1 into an array.

Длина фрагмента 14

(%-.-*:)t.i.10

Первые 10 чисел ряда Фибоначчи по разложению Тейлора x / (1 - x - x^2). Анализируя крюк %-.-*:дает (y % (-.-*:) y) = (y % ( (1 - y) - *: y).

Длина фрагмента 15

(#{.+//.)!/~i.9

Еще один взгляд на серию Фибоначчи. На этот раз под другим углом; начиная с треугольника Паскаля '! /~i.9'.

/при использовании двоично означает Table , применяя глагол, с которым он связан, между каждой ячейкой своих аргументов, получая таблицу операций между аргументами x и y. В этом случае !используется двоично, как комбинация (или вне) . ~делает глагол рефлексивным , т.е. используйте его правый аргумент в качестве левого тоже.

Наречие /.нечетное, оно применяет свой глагол вдоль антидиагоналей массива (т.е. попробуйте </.!/~i.5здесь )

Таким образом, этот фрагмент содержит суммы по 9 первым антидиагоналам в треугольнике Паскаля, что является очередным случаем ряда Фибоначчи.

Длина 16 фрагмента

;/@~.,. <"0@#/.~:

Хорошо, я добавил пробел, чтобы добраться до 16 :). Этот фрагмент демонстрирует разветвление с использованием Key : перечисление всех элементов в аргументе и их частоты.

x u/. yприменяется к у U кусковых где х является уникальным, или в J: (=x) u@# y, где =находится Self-Классифицировать , который генерирует булев массив , содержащий 1 - е в местах , где они появляются в nub ~. Здесь он применяется рефлексивно, следовательно, выполняет Tally для каждого уникального элемента в y, считая количество появлений.

Поскольку большинство глаголов в J поддерживают порядок кусочков (порядок появления новых уникальных предметов, в отличие, например, от uniqueMatlab, который сортирует свой аргумент), это можно использовать для склеивания предметов на их частоты, как это делается здесь. ;/@~.используется для создания списка всех элементов в штучной упаковке.

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

Длина 17 фрагмента

*./ @:(#&>)@C.@A.

J поддерживает несколько примитивов специально для перестановок:

  • Анаграмма А. Монадически он находит индекс Анаграммы, двоично, он применяет перестановку, указанную индексом анаграммы в левом аргументе, к правому аргументу.
  • Цикл - Перестановка С. преобразует между прямым и циклическим представлением перестановок.

Этот фрагмент представляет собой глагол, который принимает индекс анаграммы слева (от 0 до !#y) и правый аргумент y - массив для перестановки. После этого он вычисляет LCM *./ длин цикла #&>, т.е. период, после которого вы получаете исходный массив:

]n=: (p=:?!9) *./ @:(#&>)@C.@A. i.9 NB. period of a random permutation
p&A.^:n i.9 NB. applies permutation n times.

Длина 21

<:@(#/.~)@(i.@#@[,I.)

Этот маленький глагол происходит из дополнения "stats / base" и называется гистограммой. . Это делает именно то, что, учитывая список запусков бина, суммирует все вхождения данных в интервале, ]bn-1,bn]где bn является началом номера бина n.

Он использует индекс интервалаI. для нахождения интервала:

Если y имеет форму элемента x, то x I. y является наименьшим неотрицательным j, так что j {x следует за y в порядке или #x, если y следует за {: x в порядке или если x имеет нет товаров.

Подведение итогов каждого интервала выполняется с использованием клавиши, как выделено во фрагменте 16.

Фрагмент ссылки на tryj.tk демонстрирует центральную предельную теорему с использованием этой гистограммы:

(bins=:(%~>:@i.)10) ( [ (graph=:(,&":"0 1 '#'#"0 1~])) (histogram=:<:@(#/.~)@(i.@#@[,I.)) ) (+/%#) ?5 200 $ 0

Длина 22

=,&(+/)(~:#[)e.&~.~:#]

Fun in J. Это реализует механизм вдохновителя, принимая секретный массив в качестве левого аргумента и предположение в качестве правого. Возвращаемые значения - количество белых и черных колышков. Разобрать:

NB.   ExactMatch: checks where digits correspond:
ExactMatch =: =

NB.   GoodDigitWrongPlace: Copies non-matched numbers from both arguments (left and right
NB.   pairs of parentheses, and checks them for same elements(e.), after eliminating
NB.   doubles in both (&~.)
GoodDigitWrongPlace =: (~: # [) (e.&~.) (~: # ])

NB.   Piecing the conditions together, after summing the booleans:
mm =: ExactMatch ,&(+/) GoodDigitWrongPlace

Быть использованным как

secret (=,&(+/)(~:#[)e.&~.~:#]) guess

Где secretи guessнаходятся любые массивы. Он работает с любым типом данных на самом деле.


17
Ну, или вы получаете нечитаемую кучу странных символов, или вы получаете нечитаемую кучу символов ASCII. Выбрать свой яд.
Джон Дворак

16
@JanDvorak Все языки не читаются, пока вы не изучите их. ;-)
Гарет

5
Я привык думать, что длинные, описательные имена помогают понять код. Тогда я был просветленным .
hoosierEE

@ Гарет Но не все нечитаемы даже после того, как ты их выучил. Не буду называть имен.
flawr

45

RPL (язык программирования Redstone) [и Minecraft]

Это большой вопрос, можем ли мы считать это реальным языком программирования или нет, но мы все равно попробуем. И, поскольку эти два «языка» практически одинаковы, я их объединю, иногда публикую фрагменты на языке «Minecraft» (redstone и т. Д.), А иногда и в RPL. Кроме того, поскольку в Minecraft будет много фрагментов, я буду публиковать ссылки на картинки, а не на сами картинки, чтобы сэкономить место. Кроме того, все фрагменты будут иметь концепцию программирования в Minecraft, а не общий redstone (т.е. двери из красного камня не появятся). Символы будут учитываться в байтах (в RPL) или в соответствии с этим (в Minecraft).

Factoid:

RPL - это язык программирования от изобретателя Тосши, который преобразует код в Redstone и командные блоки Minecraft. Он может выполнять ввод и вывод, циклы, целочисленные манипуляции, триггерные функции, корни и многое другое.

Длина 1:

Кнопка (1 байт) - это самая простая форма ввода в Minecraft. Он также может запускать или останавливать «программу». Аналогично, рычаг (также 1 байт) является другой формой ввода и может также использоваться как для запуска, так и для остановки программы, так как она находится в состоянии «включено» и «выключено». Следует помнить, что Minecraft - это буквально 3D-язык программирования, поэтому расположение кнопки / рычага в программе может иметь огромное значение.

Длина 2:

Кнопка, прикрепленная к лампе из красного камня, в значительной степени является вашей основной программой для кошек. Он принимает входной сигнал (с помощью кнопки или рычага, либо, 0либо 1( offили on)), и выводит его в виде света от лампы, либо либо, 0либо 1( offили on).

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

Длина 3:

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

Длина 4

Этот «фрагмент» на самом деле показывает две концепции: задержка и НЕ Гейт. Задержка выполняется с использованием определенных элементов красного камня, которые имеют метку красного камня . Редстоун-тик равен одной десятой секунды. Разные компоненты красного камня имеют разные задержки: у резака задержка 1 rt (1 тик красного камня), у компаратора задержка 1 rt, у ретранслятора может быть задержка 1, 2, 3 или 4 rt, в зависимости от того, как он настроен. В этом примере для ретранслятора Redstone задана задержка 4RT.

Далее НЕ ворота. Гейт НЕ принимает вход, а инвертирует его. Таким образом, в этой настройке выход будет включен, если вход отключен, и выход будет отключен, если вход включен.

Длина 5

Ворота OR легко реализовать в Minecraft. Два входа подключены к одному выходу. Вот и все. Никакого смешного обмана или чего-то еще, все довольно просто.

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

Длина 6

Вот совет по сжатию вашего «кода». Если вы знаете, что уровень сигнала двух входов достаточно мал, чтобы не мешать работе соответствующих выходов, вы можете подключить красный камень справа друг к другу. В приведенном ниже примере есть простой таймер бункера, который передает элементы туда и обратно примерно через 0,5 с в каждом бункере, соединяясь с компараторами, которые выводят уровень сигнала 1. Это означает, что два выхода не будут мешать друг другу. В этом примере лампы используются только в демонстрационных целях и не учитываются в общем количестве блоков.

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


7
Ты хас 13 upvotes, я могу хаз 10 программ moar?
R '31

4
На самом деле ни одна из ваших программ не написана на RPL, поэтому не выдавайте ее за основу. Это чисто Minecraft "код".
mbomb007

2
У вас дефицит 14 программ м8. Я хотел бы увидеть, что вы имеете в виду;)
Конор О'Брайен

4
Ты хаз 21 голос, я могу хаз 15 программ моара?
wizzwizz4

1
Ты хас 29 возражений, я могу хаз 23 программы моара?
bb010g

42

TI-BASIC

[Язык зависит от того, на каком калькуляторе он используется, но в нем будет использоваться TI-84, если не указано иное.]

Длина 31 фрагмент

Menu("","1",A,"2",B
Lbl A
Lbl B

Это демонстрирует использование меню. Вышеприведенный пример совершенно бесполезен, так как ничего не делает, но их можно использовать для навигации по другой части программы. Первым аргументом является заголовок меню, за которым следуют пары параметров (отображаемая строка, за которой следует 1- или 2-буквенная метка). Вот более понятный пример:

Menu("CHOOSE VALUE","AREA",A,"CIRCUMFERENCE",C
Lbl A
Disp πR²
Stop
Lbl C
2πR

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

Длина 29 фрагмента

Real
√(-16
a+bi
Ans
re^θi
Ans

Real(по умолчанию включено) переводит калькулятор в режим действительных чисел, поэтому вычисления с использованием комплексных чисел приводят к NONREAL ANSошибке. При переводе в a+biрежим калькулятор отображает ответы в виде комплексных чисел, если это применимо, поэтому возвращается второй пример 4i. re^θiРежим использует полярные вместо прямоугольных координат, поэтому он выводит4e^(1.570796327i) .

Длина 23 фрагмента

If A≥9
Then
1→X
7→Y
End

Это просто условное условие, хотя может быть и Elseутверждение. Thenи Endне требуются, если это только одно утверждение.

Длина 21 отрывка

(-B+√(B²-4AC))/(2A)→X

Все любимые, квадратная формула. Сохраняет первое решение квадратного уравнения, так как X, предполагая, что a, b и c сохраняются в соответствующих переменных, как в ax 2 + bx + c .

Длина 20 фрагмента

Shade(|X/2|-3,5-X²,0

Это затеняет пересечение двух функций с несколькими необязательными параметрами: минимальные и максимальные значения x, а также направление и расстояние между линиями затенения.

Длина 18 фрагмента

LinReg(ax+b) L1,L2

Здесь мы вычисляем уравнение линейной регрессии или линейное уравнение, которое наилучшим образом соответствует группе точек, где значения x сохраняются в виде списка в, L1а значения y в L2. Есть много других доступных вариантов регрессии, включая квадратичный, кубический и экспоненциальный.

Длина 17 фрагмента

dbd(1.2711,1.2115

Это вычисляет количество дней между двумя датами, в данном случае 27 января 2011 года, день, когда этот сайт был запущен, и 21 января 2015 года, день, когда это было написано. (Для ленивых это 1455 дней.) Способ кодирования дат немного странный: либо DDMM.YY, либо MM.DDYY, опциональные начальные нули.

Длина 16 фрагмента

For(A,0,5
Disp A

Это показывает две части языка программирования. Первый типичный forцикл, похожий на for(var A=0;a<5;a++)другие языки. (Вы также должны использовать Endкоманду, чтобы выйти из цикла.) Вторая говорит само за себя: она отображаетA , в данном случае 5 раз из-за цикла.

Длина фрагмента 15

Y1=|X³-4|
Y2=3X

Вот два примера известной особенности графических калькуляторов: графические уравнения. Вы можете построить 10 различных уравнений на одной плоскости, и есть много полезных команд для поиска пересечений, максимумов, значений x и т. Д. Эти уравнения выглядят так, когда они отображаются в стандартном окне:

график

Длина фрагмента 14

[[1,2][34,5]]T

Скобки используются для создания матриц, и Tтранспонирует матрицу:

[[1 34]
 [2 5]]

Длина 13 фрагмента

dayOfWk(9,1,6

Это находит день недели 6 января 9 года нашей эры. Выходные данные - это число, где 1 - воскресенье, 2 - понедельник и т. Д. Эта конкретная дата была вторником, поэтому вывод3 .

Длина 12 фрагмента

Circle(1,3,5

Первый из основных инструментов рисования, это рисует круг на графике с центром в (1,3) и радиусом 5.

Длина фрагмента 11

randInt(0,8

Это генерирует (псевдо) случайное целое число от 0 до 8 включительно. Существует необязательный третий аргумент, который сообщает, сколько целых чисел нужно сгенерировать. Существует несколько других случайных функций, в том числе для нормального и биномиального распределения, одна для случайной матрицы и одна для случайно упорядоченного списка без повторений. randIntможет быть высевают путем сохранения ряда , как rand: 2→rand.

Длина фрагмента 10

4>5 or 2≠7

Здесь у нас есть операторы равенства и логики TI-BASIC (in). Операторы неравенства сначала оцениваются 0 or 1и orвозвращают true, если любая из сторон имеет значение true, поэтому это отображается 1.

Длина 9 фрагмента

.656▶F◀▶D

Это может конвертировать из десятичной дроби в дробные и наоборот, что очень полезно. Есть также специальный ▶Fracи ▶Decфункции , которые только идут в одну сторону. Печать 82/125в этом случае.

Длина 8 фрагмента

lcm(14,6

Это печатает наименьшее общее кратное 14 и 6, которое составляет 42.

Длина 7 фрагмента

getDate

Довольно понятен, в данном случае просто печатает текущую системную дату в виде списка {2015 1 19}.

Длина 6 фрагмента

√({4,9

Массивы (или списки) заключены в фигурные скобки и разделены запятыми. Это похоже на mapфункцию многих языков, где она перебирает каждый элемент списка и применяет к нему операцию вне фигурных скобок, в данном случае квадратный корень, поэтому результат таков {2 3}. Обратите внимание, что закрывающие скобки не являются обязательными, поэтому они будут опущены с этого момента.

Длина 5 фрагмента

4iii6

У нас здесь есть пара интересных вещей. Сначала умножаются действительные части 4 и 6, а затем умножаются мнимые части: i^3или -i. Эти умноженные дают -24i. Это демонстрирует наглядное умножение сопоставления и обработку TI-BASIC мнимых чисел.

Длина 4 фрагмента

8°5′

Это 8 градусов, 5 угловых минут, которые преобразуются в градусы как 8.0333...

Длина 3 фрагмента

8→T

Это показывает, как числа могут быть сохранены как переменные, что несколько необычно, потому что сначала идет число, затем стрелка сохранения, затем имя переменной. Как упоминалось в фактоиде, θ(theta) также может использоваться как переменная, а переменные могут быть только одной заглавной буквой.

Длина 2 фрагмента

4M

Как и в Mathematica, вы можете умножать с сопоставлением, в этом нет *необходимости. Все переменные по умолчанию инициализируются равными 0, поэтому будет выводиться 0, если вы не сохранили что-то еще для этой переменной (см. Фрагмент 3).

Длина 1 фрагмента

e

Это константа для числа Эйлера , которая отображается как 2.718281828.

Factoid

Переменные могут хранить только определенные типы данных. Например, A- Zθ) хранят числовые значения, str0- str9хранят строки и [A]- [J]сохраняют матрицы (2-мерные массивы).


Кстати, нижний регистр n(не n) также можно использовать как переменную.
Ypnypn

Интересно. Я никогда не использовал эту переменную.
NinjaBearMonkey

3
Можно спорить о том, str0чтобы быть 1 символом или быть 4. Все инструкции в TI-BASIC имеют длину 1 символ.
Исмаэль Мигель

@IsmaelMiguel Я думал об этом, но они составляют 1 или 2 байта , и я решил нормально считать символы.
NinjaBearMonkey

1
Я уважаю твое решение. Это очень помогает в этом случае. Мне очень понравилось программирование на моем старом TI-83. (Я даже разработал программу рисования в нем!)
Исмаэль Мигель

41

GNU Sed

Я сам навязываю более строгие требования - все фрагменты будут полными sedпрограммами.

Factoid

sed является Тьюринг-полного языка. Вот доказательство.

Длина 0 Фрагмент

Я не думаю, что фрагмент длины 0 строго необходим, но так как он действительно что-то делает в sed, вот он:

Sed является «редактором потока», то есть он читает поток (построчно) из STDIN, редактирует, а затем выводит в STDOUT. Программа sed нулевой длины просто копирует STDIN в STDOUT. Таким образом, catутилита может эмулироваться с помощью sed. Следующее эквивалентно:

cat a.txt b.txt > c.txt

а также

sed '' a.txt b.txt > c.txt

Длина 1 фрагмент

=

Эта программа sed выводит номер строки каждой строки в STDOUT. Это примерно эквивалентно:

nl

или же

cat -n

хотя версия sed помещает номер строки в собственную строку.

Длина 2 Фрагмент

5q

Копирует STDIN в STOUT и qиспользует после строки 5. Это эквивалентно:

head -n5

Возможно, вы начинаете видеть здесь некоторую закономерность - sedее можно использовать для эмуляции многих стандартных инструментов core-utils.

Длина 3 Фрагмент

iHi

intsts "Привет \ n" перед каждой строкой. Мех.

Длина 4 Фрагмент

/a/d

Сила sed в его регулярных выражениях. Эта программа вызывает все строки , соответствующие регулярное выражение , aчтобы быть deleted из потока. Все остальные строки будут по-прежнему выводиться в STDOUT. Это эквивалентно:

grep -v "a"

Длина 5 Фрагмент

:l;bl

Это бесконечный цикл. Мы все любим бесконечные циклы, загружающие процессор. Определяет метку l, затем bранчо (прыгает) к ней. До бесконечности.

Длина 7 Фрагмент

s/a/A/g

По умолчанию sed применяет sкоманды так, что он будет соответствовать только первому вхождению в каждой строке. Если вам нужно, чтобы он соответствовал (и заменял) каждому вхождению в строке, то gфлаг в конце sкоманды сделает это.

Длина 8 Фрагмент

y/01/10/

Мало используемая yкоманда похожа на trутилиту оболочки (хотя и не такая гибкая). Эта программа будет переключать все 0s с 1s и наоборот.

Длина 9 Фрагмент

1!G;$p;h

Этот фрагмент на самом деле занимает 8 байт, но для подавления вывода по умолчанию требуется параметр -n для sed, поэтому согласно стандартным правилам кода-гольфа это считается 9. Эта программа переворачивает строки в потоке. Так:

sed -n '1!G;$p;h'

в точности эквивалентно:

tac

Длина 10 фрагмент

s/[ <TAB>]+$//

Это повторение (неправильного) фрагмента длины 6. Это удаляет конечные пробелы (пробелы и табуляции) из строк.


2
См. Также ПОЛЕЗНЫЕ СЦЕНАРИИ ОДНО-ЛИНИИ ДЛЯ САС , которые, в основном, я и выучилsed
Адам Кац

У вас есть больше голосов. Можем ли мы еще?
Люсер Дрог

2
Ваш факт 404-й.
Wauzl

1
Приятно, но, пожалуйста, обратите внимание, что многие из них используют расширения GNU и не являются стандартными - в частности, длина 3 (стандартная будет i\<newline>Hi<newline>), длина 5 (стандартная будет sed -e :l -e blили :l<newline>bl<newline) и длина 10 (для работы которой необходимо +обратиться к a *). Обратите внимание, что фрагмент длины 9 -n '1!G;$p;h' является стандартным, тогда tacкак нет . :)
Wildcard

1
@Wildcard Да - я ограничил это GNU sed.
Цифровая травма

39

питон

(В сообщении mbomb007 уже есть множество фрагментов Python, но я подумал, что я могу добавить некоторые причудливые факты)

Factoid

Python - это динамически типизированный язык с акцентом на удобочитаемость.

Длина 1 фрагмента

1

В Python 3 вышесказанное эквивалентно Trueв том смысле, что 1 == True(а также 0 == False). Обратите внимание, что это не обязательно относится к Python 2, где вы можете переопределить значениеTrue .

Длина 2 фрагмента

<>

<>является устаревшим оператором сравнения, эквивалентным !=. Он все еще работает в Python 2 (хотя его использование не рекомендуется) и был полностью удален из Python 3.

Длина 3 фрагмента

...

В Python есть ряд функций, которые встроенные функции не используются, но есть только для сторонних библиотек. Этот Ellipsisобъект является одним из них, и он обычно используется для нарезки. Например, если у нас есть следующий трехмерный массив NumPy :

array([[[1, 2, 3], [4, 5, 6]], [[7, 8, 9], [10, 11, 12]]])

тогда a[..., 0](эквивалентно a[:,:,0]) дает все первые элементы:

array([[1, 4], [7, 10]])

В Python 3 ...литерал может использоваться вне синтаксиса среза, что забавно позволяет использовать его в качестве маркера «дел» вместо passили NotImplemented:

def f(x):
    ... # TODO

Длина 4 фрагмента

(1,)

Одноэлементный кортеж в Python.

Python имеет списков (например [1, 2, 3, 4]) , которые являются изменяемыми и кортежи (например (1, 2, 3, 4)) , которые им изменяемым. Одним из распространенных применений для кортежей является использование словарных ключей, поскольку списки не могут быть хэшируемыми.

Распространенная ошибка новичка состоит в том, чтобы пропустить запятую выше, то есть (1), это просто число 1, заключенное в скобки. Одноэлементный кортеж - единственный раз, когда вам нужна запятая перед закрывающими паренами - он поднимает a, SyntaxErrorесли вы пытаетесь поместить один в пустой кортеж (), и является необязательным для кортежей длиной не менее 2.

Длина 5 фрагмента

0or x

В этом фрагменте происходит несколько вещей, так что давайте посмотрим!

orкак ||во многих языках. В Python A or Bкороткое замыкание, возвращающее A(без оценки B), если Aверно, иначе возвращается B. Например, 1 or xвсегда возвращает 1, как 1всегда верно, и даже работает, если xне определено. С другой стороны, 0 or xлибо возвращает xif, если xон определен, либо выдает a, NameErrorесли это не так.

Когда играешь в гольф, мы обычно можем пропустить пробел между числом и or, например, 1 or xставкой 1or x. Это возможно, потому что 1orначинается с цифры, что делает его недопустимым идентификатором Python.

Однако есть одно исключение 0or, которое таинственным образом сбрасывает SyntaxError. Почему? Потому что восьмеричные литералы в Python начинаются с 0o(например 0o20 == 16), и парсер задыхается, когда он достигает r!

Примечание. В Python 2 восьмеричные литералы могут также начинаться с начального нуля, например 020.

Длина 6 фрагмента

*x,y=L

Этот фрагмент демонстрирует специальный тип присваивания в Python, где Lесть список, кортеж или любой другой тип итераций.

В Python вы можете «распаковать» кортежи и списки следующим образом:

a,b = [1,2]

Это присваивает 1 к aи 2 к b. Этот синтаксис также используется для множественного назначения, например

a,b = b,a+b

что полезно при написании программы, которая вычисляет ряд Фибоначчи.

Если длины с обеих сторон не совпадают, то ValueErrorвыбрасывается. Тем не менее, в Python 3 появился новый синтаксис, расширенная итеративная распаковка (или, более разговорно, « помеченное присвоение»), которая позволяет вам делать такие вещи:

*x,y = [1, 2, 3, 4, 5]

Это назначает y на последний элемент, 5, и xк остальной части списка , то есть [1, 2, 3, 4]. Вы даже можете сделать что-то вроде этого:

a,b,*c,d,e = [1, 2, 3, 4, 5, 6, 7]

который присваивает 1 a , 2 к b, [3, 4, 5]к c, 6 к dи 7 к e.

Длина 7 фрагмента

zip(*x)

zip это функция, которая берет несколько списков и, ну, в общем, их упаковывает:

>>> zip([1, 2, 3], [4, 5, 6])
[(1, 4), (2, 5), (3, 6)]

Примечание. В Python 3 zipвместо этого возвращается объект, поэтому, если вам нужен список, подобный приведенному выше, вам нужно заключить вызов вlist()

Это довольно удобная функция, если у вас есть два или более связанных списка, и вы хотите связать их соответствующие записи.

Теперь скажите, что хотите распаковать список - как бы вы это сделали? Мы можем попытаться использовать zipснова, но, к сожалению, это дает:

>>> zip([(1, 4), (2, 5), (3, 6)])
[((1, 4),), ((2, 5),), ((3, 6),)]

Проблема в том, что все находится в одном списке, но zipпринимает отдельные списки в качестве отдельных аргументов функции. Чтобы исправить это, мы вводим *оператор splat, который принимает список / кортеж / etc. и распаковывает их как аргументы функции:

f(*[1,2]) ==> f(1, 2)

И результат:

>>> zip(*[(1, 4), (2, 5), (3, 6)])
[(1, 2, 3), (4, 5, 6)]

Длина 8 фрагмента

x='a''b'

В первый раз, когда я увидел это, меня немного забрало - что значит иметь две строки рядом друг с другом? Ответ был прост:

>>> x
'ab'

Python просто объединяет две строки! Это очень полезно для удобства чтения, поскольку позволяет разбивать длинные строки, например, так (обратите внимание на круглые скобки):

x = ('This is a very long sentence, which would not look very nice '
     'if you tried to fit it all on a single line.')

Длина 9 фрагмента

0!=2 is 2

Вы, возможно, уже знаете, что Python допускает цепочку операторов сравнения, поэтому 5 < x <= 7верно только в том случае, если 5 < xи x <= 7. Если вы этого не знали ... тогда сюрприз!

В любом случае, менее известен тот факт, что, поскольку is/ is not/ in/ not inтакже являются операторами сравнения, они также могут быть связаны. Другими словами, приведенный выше код эквивалентен (0 != 2) and (2 is 2), то есть True.

Примечание: с 2 is 2половиной есть несколько тонкостей , так как isпроверяется, являются ли две вещи одним и тем же объектом , а не имеют ли две вещи одинаковое значение . Python кеширует маленькие целые числа, так 1+1 is 2есть True, но 999+1 is 1000есть False!

Длина фрагмента 10

x=[];x+=x,

Что происходит, когда вы добавляете список к себе? Если мы попробуем распечатать x, мы получим:

[[...]]

К счастью, Python printдостаточно умен, чтобы не пытаться печатать рекурсивные списки. Затем мы можем сделать кучу забавных вещей, таких как:

>>> x[0][0][0][0][0]
[[...]]
>>> x[0] == x
True

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

Длина фрагмента 11

help(slice)

helpФункция очень полезна для отладки в Python. Когда вызывается без аргументов в REPL,help() запускается сеанс справки, в котором вы можете найти документацию по функциям / типам данных / и т. Д. При вызове с конкретным аргументом helpвыдаст информацию о связанном элементе.

Например, help(slice)выдает следующую информацию (усеченную, поскольку она довольно длинная):

Help on class slice in module __builtin__:

class slice(object)
 |  slice(stop)
 |  slice(start, stop[, step])
 |  
 |  Create a slice object.  This is used for extended slicing (e.g. a[0:10:2]).
 |  
 |  Methods defined here:
 |  
 |  __cmp__(...)
 |      x.__cmp__(y) <==> cmp(x,y)
 |  
 |  __getattribute__(...)
 |      x.__getattribute__('name') <==> x.name
 |
 | ...

Что касается slice, как мы видим, мы можем создавать sliceобъекты для индексации. Например:

>>> L = list(range(10))
>>> L[slice(2, 5)]         # L[2:5]
[2, 3, 4]
>>> L[slice(2, None)]      # L[2:]
[2, 3, 4, 5, 6, 7, 8, 9]

Еще одна полезная функция для отладки dir() , которая возвращает все имена в текущей области при вызове без аргумента и возвращает все атрибуты данного объекта при вызове с аргументом.

Длина 12 фрагмента

round(5.0/2)

К чему это относится? Ответ зависит от вашей версии Python!

В Python 2 деление между двумя целыми числами приводит к целочисленному делению (то есть 5/2 == 2), тогда как в Python 3 мы получаем деление с плавающей точкой (то есть 5/2 == 2.5). Тем не менее, это деление между числом с плавающей точкой и целым числом, которое всегда должно приводить к числу с плавающей точкой. Почему мы получили бы другие результаты тогда?

Если мы посмотрим на документацию для roundобеих версий Python, мы найдем ответ:

  • В Python 2 , roundтай - брейков, округляя от 0.
  • В Python 3 , roundтай- брейков округлением в сторону ближайшего четного целого .

Другими словами, округление 5.0/2 = 2.5до 3Python 2, но 2округление до Python 3. Округление до ближайшего четного целого может показаться странным, но на самом деле это называется округлением банкира. , и оно пытается обрабатывать положительные и отрицательные значения аналогичным образом, чтобы уменьшить смещение.

Длина 13 фрагмента

class C:__x=1

Будучи объектно-ориентированным, Python имеет классы. Выше приведен класс, в Cкотором один атрибут имеет __xзначение 1.

Мы можем получить доступ к атрибутам класса, используя точечную запись. Например, если у нас есть класс

class MyClass(): my_attr = 42

тогда печать MyClass.my_attrприведет к 42, как и ожидалось.

Однако, если мы сделаем то же самое и попытаемся получить доступ, C.__xкак определено выше, мы получим:

AttributeError: type object 'C' has no attribute '__x'

В чем дело? Cявно имеет __xатрибут!

Причина в том, что атрибуты, начинающиеся с __эмуляции «приватных» переменных, чего нет у Python . Python меняет имя любого атрибута, начиная с имени __, добавляя имя класса, чтобы избежать конфликтов повторного использования имени. В приведенном выше примере, если бы мы действительно были полны решимости получить доступ к этому 1, мы бы вместо этого должны были сделать

>>> C._C__x
1

Длина фрагмента 14

NotImplemented

В Python есть не только классы, но и перегрузка операторов. Например, вы можете иметь класс

class Tiny():
    def __lt__(self, other):
        return True

где __lt__оператор меньше чем. Теперь, если мы сделаем экземпляр Tiny, мы можем сделать это

>>> t = Tiny()
>>> t < 1
True
>>> t < "abc"
True

так как мы решили __lt__всегда возвращаться True. Обратите внимание, что мы также можем сделать

>>> 42 > t
True

но следующие перерывы:

>>> t > 42
Traceback (most recent call last):
  File "<pyshell#18>", line 1, in <module>
    t > 42
TypeError: unorderable types: Tiny() > int()

Подождите, как это работает? Мы не указали поведение больше-чем с Tiny, поэтому неудивительно, что последний случай обрывается. Но тогда как int(42) знает, что это больше, чем нашTiny объекта?

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

class Unknown():
    def __gt__(self, other):
        # __gt__ for greater-than
        print("Called me first!")
        return NotImplemented

Теперь, если мы сделаем экземпляр нашего нового класса:

>>> u = Unknown()

Мы можем это сделать:

>>> t < u
True
>>> u > t
Called me first!
True

Как мы видим, для u > tэтого произошло то, что Python Unknownсначала попытался вызвать метод «больше» , обнаружил, что он не реализован, и Tinyвместо этого попробовал метод «меньше» для другого класса ( )!

Длина фрагмента 15

x=[],;x[0]+=[1]

Это немного забавно. Сначала мы назначаем xбыть [],что пустой список внутри кортежа, то есть ([],). Затем мы делаем то, x[0]+=[1]что пытается расширить пустой список внутри вторым списком [1].

Теперь, помните , что списки изменяемые и кортежи им изменчивые - что происходит , когда вы пытаетесь изменить изменяемый объект внутри неизменного объекта?

>>> x=[],;x[0]+=[1]
Traceback (most recent call last):
  File "<pyshell#0>", line 1, in <module>
    x=[],;x[0]+=[1]
TypeError: 'tuple' object does not support item assignment

О, так что это дает ошибку, я думаю, это следовало ожидать. Но что если мы попытаемся напечатать x?

>>> x
([1],)

А? Список изменился!

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

Длина 16 фрагмента

@lru_cache(None)

Просто добавьте кеш! Это простой пример декоратора, доступного в Python 3.

Предположим, у нас есть следующая наивная реализация Фибоначчи:

def f(n):
    if n < 2: return 1
    return f(n-1) + f(n-2)

Как может вам рассказать большинство вводных курсов по программированию, это очень плохой способ реализации Фибоначчи, приводящий к экспоненциальной среде выполнения, поскольку мы фактически просто добавляем много единиц в базовом случае. f(10)? Работает в доли секунды. f(32)? Потратьте некоторое время, но это добирается там. f(100)? Нет.

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

from functools import lru_cache

@lru_cache(None)
def f(n):
    if n < 2: return 1
    return f(n-1) + f(n-2)

Как мы видим, все, что я сделал, это импортировал lru_cacheиз functoolsмодуля и добавил @lru_cache(None)перед моей функцией. @обозначает декоратор, который оборачивает функцию, в данном случае для запоминания. lru_cacheПервый аргумент - maxsizeмаксимальный размер кэша - здесь мы установили его, чтобы Noneне указывать максимальный размер.

Теперь, если мы попытаемся использовать это:

>>> f(100)
573147844013817084101

И это даже не заняло ни секунды!

Примечание: f(1000)приводит к ошибке глубины рекурсии, но это история для другого времени


Какой диапазон маленьких целых чисел Python «ловит» для isоператора?
mbomb007

@ mbomb007 От этого вопроса , кажется, от -5 до 256. Вы можете попробовать -5-1 is -6и 255+2 is 257проверить.
Sp3000

37

йота

Фактоид: я могу определить Jot с 2 ответами и доказать, что это Тьюринг с 8 (не используя длины 4, 6 или 7).

Длина 1

1

Это пример двух функций в Jot. Первая - пустая строка, которая оценивает функцию тождества. Второй - 1оператор группировки Йота. 1оценивается как λxy.[F](xy)( лямбда-исчисление нотации), где [F]находится программа перед 1(здесь, пустая строка). Итак, эта программа является функцией, λxy.(λz.z)(xy)которая упрощает до λxy.xy.

Длина 2

10

Теперь мы вводим другой символ в Jot: 0. Опять же, если [F]представляет ценность программы до сих пор, 0оценивает [F]SK, где Sи Kиз комбинаторной логики . Я определил весь язык сейчас.

Длина 5

11100

Теперь я докажу, что Jot завершен по Тьюрингу, определив отображение из комбинаторной логики в Jot. Эта Jot-программа является K-комбинатором .

Длина 8

11111000

Это комбинатор S.

Длина 3

1AB

Здесь Aи Bне являются частью Jot, а скорее заполнителями для произвольного выражения. Выражение ABв комбинаторной логике отображается 1ABв Jot, Aи Bэти три правила рекурсивно преобразуются. QED

Длина N

1
10
11
100
101
110
[...]

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


2
Дано два отзыва. Теперь определите язык.
Джон Дворак

@JanDvorak работает над этим ... я так давно не исследовал эту вещь, что забыл обо всем этом :)
Фил Фрост,

1
Я не понимаю, почему это должно продолжать получать больше голосов. Вы просто собираетесь генерировать случайные двоичные числа увеличивающейся длины: |
Оптимизатор

1
Вы сказали, что для upvote номер 4. Но здесь мы смотрим на «случайное число, которое вы только что сгенерировали»
Оптимизатор

1
Как вы можете решить проблему остановки? Я предполагаю, что это как-то связано с использованием бесконечной (количество бесконечных) программ?
Филип Хаглунд

37

удар

Factoid:

Чрезвычайно серьезная ошибка ShellShock присутствовала в Bash с 1989 года и оставалась неизвестной в течение четверти века. Большая часть радости написания Bash вступает в борьбу со своими многочисленными особенностями и несоответствиями.

Длина 1 фрагмента:

[

Псевдоним для testвстроенного кода, разрешающий код формата if [ a == b ]; then- на самом деле [это отдельная команда, а не синтаксический элемент, и ]он чисто декоративный (хотя требуется [, его требование произвольно, и вы можете покончить с ним, используя alias [=test).

Длина 2 фрагмента:

||

Вроде логично orв большинстве языков, но для процессов. Выполняет команду ||только в том случае, если команда перед ней возвращает ненулевое значение.

Длина 3 фрагмента:

x=y

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

Длина 4 фрагмента:

$IFS

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

Длина 5 фрагмента:

${x^}

Подставьте строку в x, но с первым символом с большой буквы! Такая часто используемая функция, что она имеет свой собственный выделенный фрагмент синтаксиса языка.

Длина 6 фрагмента:

x=($y)

Заполните массив x из строки или списка элементов y, разделив его на все, что в настоящий момент установлено в IFS - по умолчанию, пробел. Очень полезная функция для продвинутого программирования на bash.

Длина 7 фрагмента:

${x[y]}

Массивы! Но подождите, что это ... у - строка, а не числовой индекс? Да, действительно, Bash поддерживает ассоциативные массивы! Многие люди не знают этого. Вам просто нужно declare -A xсначала.

Длина 8 фрагмента:

${x##*,}

Подставьте x, все до последнего ,символа (или что бы вы ни указали). Полезно, чтобы получить последнее поле CSV - это то, что вы не можете так легко сделать cut, который считает поля только слева. % и %% позволяют то же самое вырезать справа; % и # были выбраны для их расположения на клавиатуре США, поэтому было бы понятно, что означает левый, а какой - правый, но это не имеет большого значения для всех, кто не использует клавиатуру США :)

Длина фрагмента 9:

[ a = b ]

В большинстве других языков одиночное равенство в операции сравнения может привести к непреднамеренному поведению в форме присваивания. Хотя не в Баше. Только не пропускайте ни одного пробела, что бы вы ни делали!

Длина фрагмента 10:

if [ a=b ]

Это то, что происходит, если вы забудете об обязательных пробелах. Не скинет ошибку. Всегда будет возвращать true - даже если aи bявляются переменными, которые не установлены, или независимо от того, на что они установлены, не имеет значения - всегда будет возвращаться true. Думайте о коде, как о том, if [ "$password"="$correctpass" ]чтобы увидеть забавный потенциал этой «функции».

Длина фрагмента 11:

x=${y//a/b}

Замена подстроки в стиле Regex! Установите x в значение y, но при каждом замене на b.

Длина фрагмента 12:

[[:upper:]]*

Поиск по шаблону - вы не ограничены только с помощью символа * в оболочке, вы можете использовать любой стандартный матч POSIX , такие как alnum, alpha, и digitт.д.

Длина фрагмента 13:

function x(){

Немного загадочно закрался синтаксис Си! Одно из множества совершенно разных применений фигурных скобок, а также другой пример дополнительных декоративных элементов, чтобы Bash больше походил на другие языки - здесь ()или functionможет быть опущен здесь (но не оба). Также веселее с несовместимыми пробелами - пробел после {является обязательным, но не перед закрытием }, как вfunction x { y;}

Длина фрагмента 14:

echo {Z..A..3}

Еще одно совершенно не связанное использование фигурных скобок. Расширяет диапазон указанным шагом. В этом случае будет выдавать каждую третью букву от Z до A. Полезно для генерации последовательностей без использования seq, но не может использоваться с переменными, поэтому имеет ограниченную функциональность.

Длина фрагмента 15:

echo {a,b,c,d}x

Другое похожее, но не идентичное использование для фигурных скобок в генерации последовательности; печатает ax bx cx dx, и полезно для генерации списка строк из последовательности или списка в одной команде. Опять же, однако, ограничен в полезности, поскольку он не может использоваться с переменными внутри фигурных скобок.


На самом деле, ]это не чисто декоративно. [откажется функционировать, если его последний аргумент не будет ].
FUZxxl

Да, но это не служит никакой другой цели, кроме косметики; и если вы заменяете [его другой формой test, то его ]можно опустить, не изменяя ничего в вызове - я просто подчеркиваю, что это не фактический синтаксис bash, а просто визуальный сахар.
Бунт

Вы правы в том , что это не Баш синтаксис, но тянущийся ]является [синтаксисом , и вы должны предоставить ему так же , как , как вы должны прекратить заявление в C точкой с запятой.
FUZxxl

Это правда, что это обязательно, но совсем не так, как точка с запятой. Требование к нему совершенно произвольно, как видно, если вы просто alias [=testпишете, а затем пишете if [ 1 = 1; thenи т. Д. Но я уточню свою формулировку, чтобы учесть вашу точку зрения :)
Riot

1
Что касается function x(){синтаксиса: вы можете отбросить парены, как вы говорите, но вы также можете просто отбросить functionчасть. Фактически, именно так оболочка POSIX определяет функции, поэтому она более переносима. Вы можете определить полную функцию в 13 символов. Например:x(){ startx;}
Кодзиро

37

APL

Factoid

APL ( Р rogramming л anguage) начал в качестве переводчика для обозначения формулы , разработанной Кен Айверсон . Когда язык был разработан, люди использовали телетайперы для общения с компьютерами. Набор символов для них был ограничен, но из-за их конструкции можно было разместить несколько символов в одной позиции для составления сложных символов. Эта функция активно используется APL, что способствует его печально известной репутации языка только для чтения.

Вы можете попробовать большинство примеров на http://www.tryapl.org .

Длина 1

Персонаж , называемый абажур, и за его форму, и за просветленность, которую вы получаете от его присутствия, вводит комментарий. Исторически сложилось так, что он был создан путем переворота (jot) и (up shoe).

Длина 2

⍳3

Монадическая (с одним аргументом) функция (йота) генерирует вектор из первых нескольких натуральных чисел. Например, вышеупомянутое ⍳3дало бы 1 2 3вектор первых трех натуральных чисел. В некоторых реализациях APL, это дало бы 0 1 2вместо этого, это зависит от значения ⎕IO, тем я ОТ о Rigin.

Длина 3

5\3

В отличие от монадической , двоичная \функция (расширение) копирует аргумент справа так же часто, как аргумент слева; Таким образом, 5\3дает 3 3 3 3 3. Возможно, вы захотите поиграться с векторными аргументами (например 1 2 3\4 5 6), чтобы увидеть, что он тогда делает.

Длина 4

A←⍳3

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

Длина 5

∘.×⍨A

Таблица умножения три на три, то есть

1 2 3
2 4 6
3 6 9

Это немного сложно, поэтому позвольте мне объяснить. ⍺∘.f⍵(следующим образом: альфа - йота точка F омега) является внешнее произведение из и более f. Внешний продукт представляет собой таблицу результатов применения fк каждой возможной паре элементов из и . В этом примере fесть ×(умножение), что приводит к таблице умножения. Оператор (тильда диæрезис) коммутирует свои аргументы, то ⍺f⍨⍵есть равен, ⍺f⍵а f⍨⍵без левого операнда равен ⍵f⍵. Без оператора коммутирования этот фрагмент был бы a∘.×a. Внешний оператор продукта очень универсален; проверить, что произойдет , если вы заменяете =на ×!

Длина 6

{×/⍳⍵}

Факторная функция. Пара фигурных скобок заключает в себе dfn (динамическую функцию), то есть анонимную функцию (ср. Лямбда-выражения). Аргументы для dfn связаны с переменными и, или просто, если dfn вызывается как монадическая (с одним аргументом, в отличие от двоичного, с двумя аргументами) функция. Мы применяем к правильному аргументу, получая целые числа от 1до . Оператор /(косая черта) уменьшает, то есть f/⍵вставляет fмежду элементами . Например, +/⍳5это просто 1+2+3+4+5. В этом случае мы уменьшаем ×, получая произведение предметов ⍳⍵, которое является просто факториалом .

Длина 7

2×3*4+5

Урожайность 39366. ⍺*⍵(альфа-звезда омега) возводится в силу . У APL очень простое правило приоритета: все оценивается справа налево, все функции ассоциативны справа. Операторы связываются сильнее, чем функции, и оцениваются слева направо. Таким образом, вышеприведенное выражение с явными скобками будет записано 2×(3*(4+5))в отличие от обычного (2×(3*4))+5.

Длина 8

¯1+3 3⍴A

Этот фрагмент дает

0 1 2
3 4 5
6 7 8

и демонстрирует два важных понятия: первое понятие - это функция (rho), которая преобразует свой правый аргумент в форму, указанную в его левом аргументе. Форма массива - это вектор длин каждой оси в массиве. Форма скаляра - пустой вектор. Таким образом, 3 3⍴Aпреобразуется Aв три на три матрицы. Второе понятие заключается в том, как здесь используется сложение: мы добавляем ¯1(перекладину один), что означает отрицательный ( ¯префикс для указания отрицательных чисел, а -оператор) в массив. Два операнда имеют разные формы, поэтому операнд с меньшей формой распределяется на другой операнд, вычитая один из каждого элемента в сгенерированной матрице.

Длина 9

+.×⍨3 3⍴A

A, преобразованный в матрицу 3 на 3, умноженный на себя. Оператор .(точка) принимает две функции и создает внутреннее произведение , где первая функция представляет сложение, а вторая - умножение функции . Простое, старое, умножение матриц: +.×общий вариант ≠.∧(где не равно и (вверх по каретке) логично и) для булевых матриц; многие интересные вещи можно смоделировать как внутренний продукт с определенными операторами вместо +и ×.

Длина 10

(.5×⊢+÷)⍣≡

(читай: левая скобка, точка пять, умножить правую галочку и разделить правую скобку звездочка-диреза же). Вычислить квадратный корень из действительного числа, используя вавилонский метод . Левый аргумент - это число, для которого вы хотите вычислить квадратный корень, правый аргумент - это исходное предположение для квадратного корня. Первоначально я хотел предоставить значимое начальное предположение, но у меня закончились символы (добавьте, чтобы использовать само число в качестве начального предположения).

Так как же это работает? Давайте начнем с левой части (.5×⊢+÷), во-первых. Это выражение использует молчаливую нотацию, происходящую из J, которая позже была перенесена обратно в Dyalog APL. Молчаливая запись немного сложна для начинающих, поэтому, пожалуйста, внимательно прочитайте этот раздел. Изолированная последовательность, такая как +/÷≢, которую «нормальные» правила синтаксического анализа не разрешают в одной части речи, называется поездом. Последовательность из двух или трех функций создает функцию, и (путем многократного разрешения) последовательность функций любой длины также создает функцию. Последовательность из трех функций fghведет себя как {(⍺f⍵)g⍺h⍵}, то есть fи hприменяется к аргументам результирующей функции, а результат к ним применяется g. Поезд массива и две функции, такие какAfgведет себя как {Af⍺g⍵}, это,gприменяется к аргументам результирующей функции Aи этот результат применяется к f. У последовательности двух функций также есть семантика, которая объяснена в документации, но не используется в этом примере.

В этом конкретном поезде используется одна новая функция (правый ход). Он ведет себя как {⍵}, давая свой правильный аргумент. Таким образом, все выражение равно {.5×⍵+⍺÷⍵}, что является просто шагом итерации вавилонской формулы. Легко увидеть, как молчаливая нотация приносит пользу гольфисту; это позволяет вам брить довольно много драгоценных символов, где это применимо.

Последний кусочек головоломки - (звездный диæрез), энергетический оператор. Если правый аргумент является массивом, f⍣A⍵относится fк общей сложности Aраз. Например, f⍣3⍵равно fff⍵. Счет может быть отрицательным, и в этом случае APL пытается вывести обратную функцию fи применяет ее. Если правый аргумент является функцией, тоже f⍣g⍵относится fк до тех пор , (fY)gYкогда Yне является результатом многократного применения fв . Следует отметить, что, если gэто =(равно) или ( то же самое), f⍣≡вычисляет точку исправления изf, Это именно то, что нам нужно для вавилонского метода! Мы хотим повторить, пока результат не сходится. Наконец, если применяется к паре вещей, вызывается как двоичная функция, левый аргумент привязывается к fлевому, т. ⍺f⍣g⍵Е. Равен тому, (⍺∘f)⍣g⍵где A∘fведет себя как {Af⍵}.


У тебя больше голосов! Можем ли мы еще?
Люсер Дрог

@luserdroog Конечно, дай мне подумать еще.
FUZxxl

Могу ли я изменить и расширить это?
Адам

@ Adám Да, пожалуйста.
FUZxxl

∘.×⍨a дает мне ошибку значения . Я правильно его использую?
Cyoce

37

Matlab

Фрагмент 26 - перебрать матрицы

Это то, что я только недавно обнаружил. Обычно вы перебираете заданный вектор для циклов for. Но вместо векторов вы также можете использовать матрицы ( rand(10)создает матрицу 10x10 с равномерно распределенными числами от 0 до 1).

for k=rand(10);disp(k);end

Это тогда отображает один вектор столбца случайной матрицы за итерацию.

Фрагмент 25 - простое построение

Мы знаем, что в matlab рисовать легко, но есть супер простая функция ezplot( E-Zпонимаете? Понадобилось довольно много времени, пока я, наконец, не понял, как я писал Zвсегда так, sedа не как cугодно ...) Всем нравятся эллиптические кривые:

ezplot('y^2-x^3+9*x-10.3')

эллиптическая кривая

Фрагмент 24 - интеграция

Старомодное слово (но все еще используемое в числовых вычислениях) для интеграции - «квадратура». Можете ли вы догадаться, каков результат следующего?

quad(@(x)4./(1+x.^2),0,1)

Фрагмент 23 - изображения

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

imrotate(rand(99),9,'c')

Вот

Фрагмент 22 - музыка

load handel;sound(y,Fs)

Это будет звучать примерно так (ссылка на YouTube)

Фрагмент 21 - дифференцировать и интегрировать

polyint(polyder(p),c)

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

Фрагмент 20 - назад к полиномам

p=poly(r);cp=poly(A)

Хотите многочлен с корнями в r? Легко: p=poly(r). Хотите характеристический полином матрицы A? Легко: cp=poly(A). Так roots(p)точно r(или перестановка r).

Фрагмент 19 - еще один волшебный трюк

fminsearch(fun,x0);

Есть люди, которые абсолютно любят эту функцию. В основном это просто поиск минимума funс начальным значением x0(может быть вектором) без каких-либо условий на fun. Это отлично подходит для подгонки маленьких моделей, где вы не можете (или вам лень) различать функцию ошибки / штрафа / цели. Он использует симплексный алгоритм Nelder-Mead, который довольно быстр для функций, в которых вы не можете делать никаких предположений.

Фрагмент 18 - введение в полиномы

p=polyfit(x,y,deg)

Matlab имеет отличное решение для работы с полиномами. С polyfitвами вы получите наименьших квадратов полином степени, degкоторый аппроксимирует точки в x,y. Вы получаете вектор, в pкотором хранятся коэффициенты полиномов, потому что это единственное, что вам нужно для представления полинома. Если вы вернетесь к фрагменту 15, вы можете сделать то же самое, написав c = polyfit(x,y,2). Так, например, [1,-2,3]представляет полином x^2 - 2*x+3. Конечно, есть также функции для подгонки других элементарных или произвольных функций.

Фрагмент 17 - углы и разрывы

unwrap(angle(c))

Если вы хотите получить аргумент «непрерывного» вектора комплексных чисел, вы часто возвращаете значения, которые, кажется, имеют разрыв. Например, angle([-1-0.2i,-1-0.1i,-1,-1+0.1i,-1+0.2i])вы получите, [-2.94,-3.04,3.14,3.04,2.94]так как angleвозвращает только углы между -piи pi. Функция unwrapпозаботится об этом! Если вы получите разрыв, подобный этому, он просто добавит кратное 2*piдля удаления: '[-2.94, -3.04, -3.14, -3.24, -3.34]' Это работает даже для 2d-матриц! Если вы просто строите аргумент комплексных чисел с отрицательной вещественной частью, вы получаете первую графику, вы получаете первое изображение, а при развертывании вы получаете второе:

без развертки с развёртыванием

[x,y] = meshgrid(-1:0.01:0,-0.5:0.01:0.5);
z = x+i*y;
imagesc(angle(z))
imagesc(unwrap(angle(z)))

Фрагмент 16 - скалярное произведение

[1;2;3]'*[4;5;6]

Конечно, есть встроенные методы (например dot), но с оператором матричного преобразования 'это так просто. Если вы не знаете, есть ли у вас вектор строки или столбца, вы можете просто использовать метод a(:)'*b(:)where, который a(:)всегда возвращает вектор столбца.

Фрагмент 15 - линейный метод наименьших квадратов, уродливый метод с волшебной палочкой

[x.^2,x,x.^0]\y

x- вектор (столбец) со значениями на оси x, yзначения y с шумом. Наберите c=[x.^2,x,x.^0]\yи вы получите коэффициенты полинома 2-й степени. Конечно, вы можете использовать одну из миллиарда встроенных функций подгонки matlab (как скучно), почему бы не использовать волшебную палочку? =)

x = (-1:0.1:2)';
y = 3*x.^2-2*x+1+randn(size(x)); %add some gaussian (normal) noise
A = [x.^2,x,x.^0];
c = A\y              %output: c = ]3.0049; -2.3484; 1.1852]
plot(x,y,'x',x,A*c,'-')

linreg

Фрагмент 14 - графики

gplot(graph,x)

Вот как построить график. graphдолжен содержать квадратную матрицу смежности и xдолжен быть матрицей nx2, содержащей координаты каждого узла. Давайте сделаем случайный граф: graph = triu( rand(8)>.7)(создайте Матрицу, которая содержит 0 и 1, получите только верхний треугольник для интересного графа). x = rand(8,2)затем заговор с некоторыми причудливыми стилямиgplot(graph,x,'k-.d')

график (Я объявляю это современным искусством.)

Фрагмент 13 - сетка

meshgrid(a,b)

Это одна из самых удивительных функций, простая, но полезная. Если вы хотите построить реальную функцию в зависимости от двух переменных, вы можете просто определить вектор значений для оси X и один для оси Y (a и b). Затем с помощью meshgrid вы можете создать две матрицы размером len (a) x len (b), где у одной есть только вектор в aкачестве столбца, а у другой - только столбец, в котором bстроки содержат только векторы . Пример использования: a = -3:0.2:3;[x,y]=meshgrid(a)(если оба вектора одинаковы, достаточно просто передать один.) Затем вы можете просто набратьz=x.^2+-y.^2 и, например,mesh(x,y,z), Это работает для произвольного числа измерений! Так что это отлично подходит не только для построения графиков, но и для получения всех возможных комбинаций различных векторов и т. Д. (Так что, если вы хотите создать новый язык кода для гольфа, это должно быть там, просто убедитесь, что вы используете более короткий имя функции ...)

меш

Фрагмент 12 - построение

plot(x,x.^2)

Возьми вектор x=-3:0.5:3и дай plotостальное сделать. Есть еще много функций для построения графика, это просто очень простая функция, которую вы можете использовать постоянно. Этого уже будет достаточно для записи, plot(v)и данные vбудут построены по индексам массива. Насколько это просто? Если вы хотите стилизовать свой график, просто добавьте строку в качестве третьего аргумента: например, 'r:o'вы получите красную пунктирную линию с кругами вокруг точек данных. Если вам нужно несколько графиков, просто добавьте больше аргументов или используйте матрицы вместо векторов. Защищенное.участок

Фрагмент 11 - функциональные ручки

f=@(x,y)x+y

Это пример дескриптора функции, который хранится в f. Теперь вы можете позвонить f(1,2)и получить 3. Дескрипторы функций в matlab очень полезны для математических функций (например, для построения графиков), и вы можете определить их в одной строке. Но один недостаток в том, что вы не можете иметь условные или кусочные (и, следовательно, никакой рекурсии). Если вы хотите этого, вы должны использовать functionоператор и объявить новую функцию, и каждая из них должна быть сохранена в отдельном файле ... (WHYYYYYY ????)

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

The tall system manager obeyed some engineer.
The programmer suggested it.
It's your karma.
A tall and good and not excessively rich and bald and very smart and good tall and tall and terrified and rich and not very terrified and smart and tall and young hamster insisted on it.

... что очень утешительно, если вы достаточно отчаялись, чтобы спросить у консоли why...

Фрагмент 10 - Как выглядит моя матрица?

spy(eye(9))

Как вы уже знаете, eye(9)создает идентификационную матрицу 9x9. spyпросто создает, который показывает нулевые / ненулевые элементы матрицы. Но вы также можете использовать его для отображения любых двоичных 2d данных. Если вы позвоните spyбез аргументов, вы получите милое маленькое пасхальное яйцо =)

шпионить за личностью шпион восточный

Фрагмент 9

kron(a,b)

kronФункция вычисляет произведение Кронекера двух матриц. Это очень полезно для дискретных многомерных линейных операторов. Я также использовал это время от времени для игры в гольф кода. Вы хотите все возможные продукты записей aи b? kron(a,b), Ну вот.

Фрагмент 8

5*a\b.*b

Хорошо, здесь я перепутал 3 разных оператора. Вы можете умножить любую матрицу на скаляр, просто используя *. (Затем каждая запись матрицы умножается на этот скаляр). Но *также выполняет умножение матриц. Если вы добавляете точку вперед, вы получаете .*оператор, этот умножает две матрицы одинакового размера, но с точки зрения ввода . (Это также можно сделать с помощью операторов деления, таких как /и \.)

Далее, оператор обратной косой черты может использоваться как левое деление (в отличие от того, /которое выполняет правое деление, как вы привыкли), но это также самый мощный и характерный оператор matlab: он выполняет «матричное деление». Допустим, у вас есть система линейных уравнений, A*x=bи вы хотите ее решить x, тогда вы можете просто напечатать x=A\b. И \(вы также можете использовать, /но это не так часто для матриц) сначала быстро анализирует матрицу и использует результаты, чтобы найти самый быстрый алгоритм для выполнения этого умножения инверсии! (См. Например здесь )

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

Фрагмент 7

[a,b;c]

Хорошо, это не выглядит много, но это очень удобный инструмент: конкатенация матриц. Запятая между двумя выражениями означает, что они соединяются горизонтально (это означает, что они должны иметь одинаковую высоту), а точка с запятой означает, что предыдущая «строка» будет выше следующей «строки» (под строкой я имею в виду все, что находится между двумя точками с запятой. Простой пример: a = [1,2;3,4]; b = [5;6]; c =[7,8,9]; d=[a,b;c];приведет к тому же dкак d=[1,2,5; 3,5,6; 7,8,9]. (Получите?)

Снял 6

eye(7)

Эта функция создает полную матрицу идентичности 7x7. Это так просто. Есть и другие подобные функции, nan,inf,ones,zeros,rand,randi,randnкоторые работают точно так же. (Если вы передадите два аргумента, вы можете установить высоту / ширину полученной матрицы.) Как я покажу позже, вы можете легко создавать и (и очень наглядно) объединять матрицы (2d-массивы), что чертовски полезно и легко, если вам нужно численно решить уравнения в частных производных. (Когда вы решаете PDE, общий подход заключается в дискретизации операторов производных, в основном вы получите просто огромную систему линейных уравнений, которую нужно решить. Эти матрицы обычно разрежены (только очень мало ненулевых элементов) и имеют некоторый вид симметрия. Вот почему вы можете легко «составить» матрицу, которая вам нужна.

Фрагмент 5

a(a>0.5)

Я надеюсь, что вы не устали от всех способов доступа к массивам. Это показывает простой способ получить все элементы массива, которые удовлетворяют некоторым условиям. В этом случае вы получите вектор всех элементов a, которые больше 0,5. Выражение a>0.5просто возвращает матрицу того же размера, что и матрица aдля каждого элемента, который удовлетворяет условию, и a 0для каждого элемента, который не соответствует.

Фрагмент 4

a(:)

Это снова просто возвращает содержимое aв виде вектора столбца (матрица nx1). Это хорошо, если вы не знаете, сохранили ли вы свои данные как вектор столбца или строки, или если ваши данные двумерные (например, для 2-мерных методов конечных разностей).

Фрагмент 3

1:9

Вы можете легко получить векторы (в данном случае 1xn матриц) с помощью точки с запятой. В этом случае вы получите вектор [1,2,3,4,5,6,7,8,9]. Это также особенно удобно для доступа к фрагментам других векторов, например, для a(2:4)доступа ко второму, третьему и четвертому элементу вектора a. Вы также можете использовать его с размером шага, как 0:0.5:10или около того.

Фрагмент 2

i;

Точка с запятой подавляет вывод на консоль. Вы можете видеть это как хорошо или плохо, но мне нравится это для отладки. Любая строка расчета и т. Д. Автоматически выводит свой результат на консоль, если вы не подавите вывод точкой с запятой.

Фрагмент 1

i

Комплексное число является основным типом числа. (Жаль, что многие люди используют iв качестве переменной подсчета для циклов for, в этом случае она переопределяется.)

вступление

Для тех, кто не знает, MatLab - это язык программирования (с хорошей IDE, также называемой MatLab?), Который в первую очередь предназначен для численных расчетов * и манипулирования данными. (Существует аналог с открытым исходным кодом, называемый «Octave»). Так как он интерпретируется только **, он не очень быстрый, но его сильная сторона заключается в том, что вы можете легко манипулировать матрицами, а многие алгоритмы реализованы оптимизированным способом, так что они работают довольно быстро. при нанесении на матрицы. Это также очень простой в освоении язык, но я не рекомендую его как начальный язык, так как вы будете придерживаться довольно дурных привычек программирования.

* Поскольку это интерпретируемый язык, он может быть очень медленным для дорогих проектов, но у вас есть встроенные методы распараллеливания, и вы также можете использовать несколько компьютеров вместе для запуска программы. Но если вы действительно хотите быстро, я думаю, что вы все еще зависите от C или Fortran или от таких сумасшедших вещей. Но все же многие реализованные алгоритмы (умножение матриц, решения систем линейных уравнений и т. Д.) Сильно оптимизированы и работают довольно хорошо. Но если вы программируете те же алгоритмы в самом Matlab, вам придется подождать =) (Что-то действительно не интуитивное, когда вы переходите с других языков в том, что если вы векторизуете свои операции вместо использования циклов for, вы можете сэкономить много времени в Matlab .)

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


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

3
Хорошее пасхальное яйцо! Если вы наберете «edit spy», вы найдете пример обфускации кода :-)
Abulafia

1
Я пошел, чтобы сказать это, а потом понял, что у меня уже было. Увы, если бы я только мог повторить это снова. Продолжай, @flawr!
Алекс А.

2
Если у вас кончается вдохновение на то, что нужно показать, я могу порекомендовать блог Mathworks: «Об искусстве MATLAB» от Лорен Вершуре Часто они описывают лучшие практики, которые могут быть показаны в пределах ограничений персонажа. Для любопытства рассмотрите Отказаться от Matlab , а для недокументированных функций и возможностей вы можете перейти к Недокументированному Matlab от Яира Альтмана
Денниса Джаруддина

1
@flawr - Для фактоида было бы также замечательно упомянуть тот факт, что исторически, MATLAB был первоначально создан для студентов в области компьютерных наук в Университете Нью-Мексико (Клив Молер был председателем в то время) в качестве простого интерфейса с LINPACK и EISPACK (теперь их заменяет LAPACK ) без необходимости изучать Фортран .... и из-за простоты использования они очень быстро распространились в другие академические учреждения :)
rayryeng

35

CJam

Попробуйте приведенные ниже фрагменты здесь

Длина 20 фрагмента:

q~{]__~z\z<=\~*0>*}*

Мин-мод калькулятор . Выдержка из вопроса:

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

Функция принимает произвольное количество параметров. Тогда minmod (x 1 , x 2 , ..., x n ) определяется как:

  • min (x 1 , x 2 , ..., x n ) , если все x i строго положительны
  • max (x 1 , x 2 , ..., x n ) , если все x i строго отрицательны
  • 0 , иначе.

Длина фрагмента 18:

l'[,65>Dm>_el+_$er

Энкодер ROT13. Сдвигает только a-zA-Zсимволы из входной строки через STDIN

Длина фрагмента 15:

T1{_2$+}ri2-*]p

Полная программа для печати первых Nчисел из серии Фибоначчи, где Nпредоставляется в качестве ввода через STDIN.

Длина фрагмента 12:

{{_@\%}h;}:G

Простая функция GCD. Это можно использовать как 2706 410 Gдля получения GCD в стеке.

Длина фрагмента 11:

123456 789#

#это энергетический оператор. Этот фрагмент демонстрирует замечательную особенность CJam, которая поддерживает BigInts почти для всех математических операций. Таким образом, вывод приведенного выше кода

1596346205622537943703716803040694151242100030904924074732295184521676912291137885341977590649991707684635184329980991487148618486236239062505001539322685142817506810040361209550544146292158784625519911512640361780862459268161619223326802388689703997604303632605734938879647069477372395799326590488746599202521617640394227957532720581758771344616555153473551874187964029973716015080326283503474062024803237072761129557356772954771383125420283743787215768524095651476398918270831514362626616089349128838080859262141293069421199363839940462244772673481244848208112002212957221705577938865719802035511067875502253218277834350725436729497351901219311577128600087062378434520948898301738545267825952998284599001356281260973911216650526574435975050678439968995805415462116669892745933523276658479456263859786003695570642598885206779863730608803831608206418317758451327165760242416052588688579435998154295782751455020445483571514197850814391880423853968520336337963918534259580183058727377932419280412466915889059399591196961188841001024998633317094826403760131868252088477018937989608302521450181593409274231460335072324865982559395114735391976545471553525054490202974741119144469523879456646833238659929705233941114530149037245274032070536718197592615630616792756562341411027203615235147973615347081993563361626845258162606172599728677944001956482301240050182368840648532697569098833480384074404562991348377266778603059081932412368912313845464302833428950934701568958836851009236647605585910687215977468114323293396641238344799575626940766355697576957869656153567798618227770961980620119004224798449940378878601283741944503399682599666873704888519152796472231721010884561046439019823540214190109829183178504573391524533915085342799888899681052113605127068137552531204917650779012455136663716975904242872042805633443567570913936237754642040107392687168596924804730637819953463737212774674563401663682370631910559669378413063684132477269578881395521544729393136204246705936061735379354437327940116154383441927197123218522827575163913310005036963663583344508839784971260123709283218409462028161021477446586507813599051643059982983426688872855309396405653159417356549291603532443699350168178837164682957610433456205211423600319694496115159970718912091395232327389520091646132878609779171226748990343349416763319432268713023302555895744813731889452605219001900815755497209921418814092923394321459962373890912709775151652200071533644718727513889263907829300496554849544461628702471995210369421320165755673222520834013956492183306187393652197405863508709529644837118590847002900783148394313160749018413291215958936871830666201928218294362550829287373305552379418641499562597137520153409556227576809855521876196531587454478159211299517511047868125975115347272184123454929507976958328038242400918390689757262398695703472270927183494613959476164389143107240083171566284628032072645081703351075328092783401422849512230275075331561337345714881104575020436358133210849231625973013523497330004645467493618279226202227586584610761439335895760888873155403816627190368675397978355381544497413492223577022267403347927237298551052219150516984577176643706356698282552857754120841266435149587248192704898338826251727748499150285409036076919533685800933215325289882260771526293167171975367192287689881199864600661035143522211647660445960687046757311913589429739868592726372013684511683081229044622752191694278221303073075505531920922815724661725685493922212700535444400760813940151761980008355835574184921854364539924999643954874549857103642483664109073938527328920827803218865362851320233433429604394590974694396314165313743853607609394553133883545319222169958204731303672940856293527174545435349105954532301106962634516087237739490953930886293289854731305112253177512851251930821765454042415085420000484369355605183062368648992392499663861508991984554431113080399485470268940148600970493633737364443822752829774334511729579419931500217970224646496435527826186627011323464848141074486509849545954714213290443775688291020289759390171236344528896

Длина фрагмента 10:

"`%W_"_W%`

Мы уже сделали Quine, давайте изменим его! Это одна из самых коротких обратных квин в CJam. Обратная квинна - это квин, которая печатает свой исходный код в обратном порядке.

Длина фрагмента 9:

5,K,+_&S*

Этот фрагмент демонстрирует множество особенностей CJam,

5, "create an array of numbers 0 to 4"
K, "create an array of numbers 0 to 19"
+  "List concatination"
_  "Duplicate top stack element"
&  "Set distinct operator in this case"
S* "Join array elements with space character"

Длина 8 фрагмента:

"`_~"`_~

Один из наименьших возможных квинов в CJam. Это настоящий quine в том смысле, что он фактически не читает исходный код каким-либо образом. (Чтение исходного кода даже невозможно в CJam)

Длина 7 фрагмента:

"AB"_m*

m*создает все декартовы произведения двух верхних элементов стека. Например, приведенный выше код поместит ["AA" "AB" "BA" "BB"]в стек, который является декартовым произведением "AB"и "AB".

Длина 6 фрагмента:

"_~"_~

Приятный повторяющийся код. НЕ запускайте это :). Это представление кода является основой для простейшего quine в CJam. Вы кладете строку "_~"в стек, делаете copy ( _) и оцениваете ее. Который, в свою очередь, делает то же самое снова (и снова ..), пока не достигнет максимального исключения рекурсии.

Длина 5 фрагмента:

{A}:F

Вот как работает базовая функция в CJam. Вышеприведенное выражение присваивает блок кода {A}переменной F. Теперь в вашем коде вы можете поместить Fкуда угодно для запуска блока кода (и получите 10в этом случае)

Длина 4 фрагмента:

"A"~

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

Длина 3 фрагмента:

Kmr

Типичный генератор случайных чисел от 0 до K20.

Длина 2 фрагмента:

es

Это дает текущую метку времени (миллисекунды от эпохи). CJam также имеет etместное время в более удобном формате, который возвращает массив, состоящий из различных частей текущего времени (день, час и т. Д.).

Длина 1 фрагмента:

A

CJam имеет почти все прописные алфавиты в качестве предопределенных переменных. A10, Bсоставляет 11 и до K20. Pэто pi (3.141592653589793), Nявляется новая линия и многие другие . Они могут быть очень полезны, когда вам нужны начальные значения в переменных или даже когда вам нужно двузначное число в 1 байте.

Factoid

CJam вдохновлен GolfScript, но создает на нем множество функций, включая поддержку сетевого вызова GET: D

PS: я постараюсь обновлять ответ каждые 5 голосов или каждые 2 часа (что раньше)


Есть некоторые проблемы с вашим примером ROT13: p Но я нахожусь под впечатлением от quine, думаю, я позаимствую его :)
aditsu

@aditsu в чем проблема?
Оптимизатор

Это меняет регистр букв NZ. Кроме того, у него есть @ без причины, вместо него можно поставить D.
aditsu

@aditsu Довольно уверен, что это ROT 13 в диапазоне a-zA-Z, и это является причиной изменения дела. Вы не можете прочитать это? это только ваш собственный язык: P @ там на 18 символов, я думаю: D
Оптимизатор

Это не то, что обычно делает ROT13. Я не понимаю, почему вы спрашиваете, могу ли я читать на своем родном языке, проблема не в понимании того, что делает программа, а в том, что она не выполняет ожидаемого.
aditsu

34

Common Lisp

Lisp (от LISt Processing) - один из старейших языков, используемых до сих пор (только FORTRAN старше). Он известен как первый язык, где код - это данные, а данные - это код; называется гомоиконичность. Это был также первый язык для сборки мусора. Первоначально разработанный Джоном Маккарти в статье 1958 года как полностью теоретический, он стал настоящим языком, когда Стив Рассел понял, что функция eval может быть реализована на компьютере. Он наиболее распространен в искусственном интеллекте и мгновенно распознается по преобладанию скобок. Common Lisp был разработан для объединения многих старых диалектов Lisp в более стандартизированную форму.

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

Длина 1

*

Из-за акцента на использовании S-выражений и списков для кодирования в Lisp очень мало допустимых выражений, которые не содержат скобок, называемых атомами. Все, что введено непосредственно в REPL (цикл read-eval-print), обрабатывается как переменная и оценивается как таковое. *содержит предыдущее значение, которое было напечатано REPL.

Длина 2

()

Это пустой список, один из самых важных символов в Лиспе. Каждый правильный список в Лиспе заканчивается пустым списком, подобно тому, как каждая правильная строка в Си заканчивается \0.

Длина 3

(*)

Это основной вызов функции, который состоит из символа, заключенного в скобки. Лисп не содержит операторов, они тоже просто функции. Я выбрал умножение специально, потому что это не бинарная функция; Оператор умножения в Лиспе принимает неопределенное количество аргументов. Если ему не дано никаких аргументов, он возвращает 1тождественный оператор для умножения.

Длина 4

`(1)

Это «против», это просто еще один способ сказать, что это пара элементов. В Лиспе каждый список состоит из cons-ячеек, связанных с cons-ячейками, где первый элемент (the car) является значением, а второй элемент (the cdr) указывает на следующую cons-ячейку. Это составляет основу Lisp, основанного на связанных списках. Эта конкретная ячейка "против" имеет 1в качестве автомобиля и пустой список в качестве своего CDR.

Длина 7

(not t)

Я хочу коснуться истинностных ценностей в Лиспе. Это вернется nil. В Common Lisp, tэто символ для true while nilи ()представляет false и равен друг другу, но обратите внимание, что это определение не является стандартным для всех диалектов Lisp; Схема, например, различает #fложные и '()пустые списки.

Длина 9

(cdr ())

Как я уже говорил, cdr - это хвостовой элемент списка, который вы можете получить с помощью функции cdr. Кроме того, вы можете получить элемент головы, автомобиль, с функцией car. Довольно просто, правда? Автомобиль и CDR пустого списка оба nil.

Длина 10

(cons 1 2)

Наконец, достаточно длины, чтобы начать работу со списками. consсоздает cons-ячейку с первым параметром как автомобиль и вторым как cdr. Но вместо распечатки (1 2)это дает (1 . 2). Возвращаясь к фрагменту длины 2, надлежащий список должен заканчиваться пустым списком, поэтому cdr последней cons-ячейки должен указывать на пустой список. В этом случае на последнюю ячейку cons указывает 2, поэтому Lisp сообщает нам, что у нас неправильный список, но все же позволяет нам это делать, например, как вы можете создать C-строку без a \0.

Длина 11

(cons 1 ())

Теперь мы создали наш первый правильно сформированный список. Это единственная клетка с автомобилем 1и CDR (). Вы заметите, что для каждого другого списка я привожу его с обратной кавычкой / галочкой; любой другой правильный список будет пытаться оценить свой первый аргумент как функцию с оставшимися элементами в качестве параметров. Строго говоря, ()это не список, хотя; это символ, состоящий из а (и а, )который представляет пустой список. Lisp позволяет вам использовать практически любой печатный символ в имени символа и позволит вам переопределить любой символ, как вы хотите.

Длина 12

(cdr `(1 2))

Это приведет к выводу (2), 2а не так, как некоторые люди догадаются. Помните, что каждый cdr должен указывать либо на другую cons-ячейку, либо на пустой список; очевидно, 2это не пустой список, так что это, должно быть, еще одна ячейка "против" автомобиля 2и CDR ().

Длина 13

'#1=(1 . #1#)

Это создаст круговой список с одним значением 1. При печати будет напечатано «(1 1 1 1 ...» навсегда, так что на практике его можно считать бесконечным списком (с которым вы можете работать cdrбесконечно много раз). чтобы получить всегда один и тот же результат, сам!). Если не назначить Tглобальную переменную *print-circle*, в этом случае она будет напечатана как #1=(1 . #1#).


Это последнее редактирование! Скорее, кто-то сделает esolang на тему Битлз: D
fede s.

1
@fedes. Джон Маккарти, Пол Маккартни ... этот язык должен называться Карти Картри.
кот

33

GNU Make

Я выйду на конечности на этом. Я думаю, что это может быть впервые, makeкоторый был показан в PPCG.

Factoid

Марку можно считать функциональным языком.

Фрагмент длины 0

Я не думаю, что фрагменты длины 0 требуются, но в любом случае это один. Я думаю, что это может быть самой полезной из всех программ длины 0. С пустым Makefile (или вообще без make-файла), make все еще имеет кучу встроенных правил. Например, есть встроенные правила по умолчанию для компиляции файла .c в .o или двоичный файл, учитывая, что файл .c существует в текущем каталоге. Итак, если мы сделаем:

make hello.o

make найдет правило .c to .o и скомпилирует hello.c, чтобы дать hello.o

Точно так же, если мы делаем:

make goodbye

Если в текущем каталоге есть файл goodbye.c, он будет скомпилирован в двоичный файл до свидания.

Длина 1 фрагмент

TAB

Да, символ табуляции. Хотя это само по себе мало что значит, в Make это имеет большое значение. В частности, все строки рецептов, следующие за определением цели в правиле, ДОЛЖНЫ начинаться с TAB. Это вызывает всевозможные разочарования при отладке make-файлов, когда смешиваются TAB и пробелы.

Длина 2 Фрагмент

$@

Это автоматическая переменная для использования в рецептах. Это расширится до имени файла цели правила. Есть и другие полезные автоматические переменные .

Длина 3 Фрагмент

a:=

Кратчайший просто расширенное назначение переменных. Переменная a устанавливается в "" сразу после первого разбора файла Makefile. Если вместо этого мы сделаем это a=, то присвоение будет рекурсивно расширено, то есть расширение будет отложено до момента фактической ссылки на переменную.

Длина 4 Фрагмент

W:;w

Кратчайшая полезная полная спецификация правил. Это определяет цель Wс правилом, которое просто запускает команду wоболочки. таким образом

make W

эквивалентно:

w

Это альтернативный синтаксис правила в том, что рецепт следует за целью в той же строке, разделенной новой строкой. Чаще всего строки рецепта следуют сразу за отдельной целевой строкой, TABсимволы начинаются с каждой строки рецепта.

Длина 5 Фрагмент

$(@D)

Еще одна автоматическая переменная. Аналогично $@, но это распространяется на часть пути каталога с именем файла и завершающим / удаленным.


Может быть, некоторые строковые функции, такие как $(basename )или $(patsubst )? ( напр. )
luser droog 11.09.16

32

Marbelous

Длина фрагмента 14

}0}1
Mulx
HxHx

Этот фрагмент демонстрирует еще несколько библиотек Marbelous и представляет новую концепцию, а именно: многосотовые платы. MulxПлата принимает два мрамора в качестве входных данных и выводит 2 шариков. Мраморы, которые входят в крайнюю левую ячейку, Mulxбудут соответствовать }0устройствам на этой плате и самой правой ячейке }1. Аналогично, выходы будут выходить из разных ячеек. Ширина доски может быть рассчитана так, MAX(1, highest output device + 1, highest input device + 1)что ячейки, которые не соответствуют устройству ввода, будут выбрасывать любой мрамор, который падает на них.

Длина 13 фрагмента

7E
??
>Y!!
{0

Это доска, которая будет выплевывать случайный печатный символ ascii на каждом тике. У Marbelous есть два способа генерирования случайных значений. Существует, ??который возвращает случайное значение между 0 и входным мрамором, который он получает, включительно и ?n: ?0до ?Zсоответственно. Который действует очень похоже на ??. У нас также есть то, !!что завершает плату, даже если не все выходы заполнены. Можете ли вы выяснить, как ?nустройства могут быть реализованы в виде плат в Marbelous с использованием ???

Длина 12 фрагмента

}0}1
Fb//
Dp

Здесь мы видим несколько библиотечных функций Marbelous в действии. Fbвыводит n-е число Фибоначчи, где n - входной мрамор. Dpпечатает входной мрамор в STDOUT как десятичное число. Они оба реализованы в Marbelous и могут быть вызваны при проверке включения библиотек в онлайн-интерпретаторе , для интерпретатора python вы должны явно включать каждый файл. Реализацию этих досок можно найти на github . Обратите внимание, что эта конкретная программа принимает 2 входа и будет вызывать плату Фибоначчи два раза. Доски, которые вызываются, возвращаются в пределах одного тика доски, которая их вызвала.

Длина фрагмента 11

}0}0
{<{0{>

Это требует некоторого объяснения. Эти }0устройства imputs, так как они имеют одинаковое число (0), они будут содержать то же значение , когда эта плата не вызывается. Три устройства в нижнем ряду являются выходами. {<выходы слева от платы, {0выходы под первой ячейкой платы и {>выходы справа. Выход выводится только тогда, когда все отдельные устройства вывода заполнены. В этом случае, однако, правильное устройство вывода никогда не достигается. Доска выйдет из-за отсутствия активности и выдаст два значения, которые она имеет в любом случае. Можете ли вы представить, как это можно реализовать /\в качестве доски Marbelous?

Длина фрагмента 10

..40
FF
\\

Здесь есть несколько вещей, которые играют важную роль в Marbelous. Во-первых, есть дополнение. Если вы проследите путь двух шариков на доске, вы заметите, что они окажутся в одной ячейке одновременно. Когда это произойдет, они будут добавлены вместе. (забавный факт: в какой-то момент считалось, что вместо сложения вместе шарики должны образовывать стопку) Однако Marbelous - это 8-битный язык, поэтому добавление мрамора к FFэквивалентно вычитанию 1 из него.

Длина 9 фрагмента

00
\\/\]]

Это самый короткий способ реализовать элементарную версию cat в Marbelous. 00 \ / \ Это цикл, который помещает 00значение мрамора на ]]устройство каждую секунду. Это устройство STDIN. Когда мрамор приземляется на это устройство, он пытается прочитать первый символ из STDIN, если он есть, он отталкивается (и в этом случае печатается снова). Если его нет, оригинальный amrble сдвигается вправо. (и в этом случае разгромили)

Длина 8 фрагмента

}0
~~
{0

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

Длина 7 фрагмента

00
\\/\

Это самый компактный бесконечный цикл, который вы можете создать в Marbelous. \\Устройство толкает любой мрамор справа, /\копирует мрамор и толкает одну копию влево , а другой вправо. Так как доска имеет ширину всего в две ячейки, мрамор справа будет разбит.

Длина 6 фрагмента

46MB75

Вот пример рекурсии MB(главная плата с неявным именем Fuвызывается при каждом тике, но не перед печатью в STDOUT при каждом вызове. (В результате следующее: FuFuFuFuFuFu...это, очевидно, переполняет стек вызовов.

Длина 5 фрагмента

2A
++

Немного арифметики. Мрамор с ценностью 2Aпадает на первый тик и попадает в ++клетку. Это оператор. Этот конкретный оператор увеличивает любой мрамор, который падает на него, и позволяет ему упасть. Мрамор теперь имеет ценность 2Bи падает с доски. Это печатает +на STDOUT.

Длина 4 фрагмента

:
24

Два интерпретатора здесь не согласны, я дал первой доске файла имя в этом примере (имя - пустая строка). Интерпретатор python предполагает, что это основная плата, и вызывает эту плату при запуске программы (которая печатает $). Интерпретатор javascript не находит основной платы и, следовательно, не является точкой входа. Это может быть полезно при написании файла библиотеки для Marbelous.

Длина 3 фрагмента

:Bo

Это именованная доска, без тела, мы можем вызвать эту доску, написав Boв ячейке любой доски (включая Boсебя)

Длина 2 фрагмента

3A

Этот код является телом ячейки размером 1x1 (каждая ячейка имеет ширину два символа) с неявным именем MB(для главной платы). Он печатает значение ascii шестнадцатеричного значения, 3Aкогда мрамор падает с доски. Выходные данные этой программы просто являются исходным кодом:

Длина 1 фрагмента

:

Наряду с #этим, это одна из двух единственных допустимых 1-символьных программ в marbelous. #является индикатором комментария, поэтому не очень интересным. :Marbelous говорит, что вы собираетесь объявить доску. Ни один из двух компиляторов не заботится о том, чтобы вы на самом деле не называли и не определяли плату. Программа ничего не делает.

Factoid:

Marbelous был разработан людьми на этом сайте, некоторые имена, которые использовались для этого языка, были Rube и просто Marbles .


2
бей меня к этому. хорошие фрагменты!
Спарр

Ваш фрагмент длины 12, кажется, принимает два входа и распечатывает два разных числа Фибоначчи. это было намеренно?
Спарр

@Sparr, да, это было для демонстрации того, как функции работают в Marbelous.
переиздание

может добавить это к объяснению? из того, что вы написали, я бы ожидал, что фрагмент будет принимать один вход и выводить одно число Фибоначчи.
Спарр

Я действительно надеюсь, что вы получите 40 баллов, так что моя функция Фибоначчи будет соответствовать ...
Спарр

31

вперед

Forth имеет только два типа, int и float (и float не обязательны!), Но ему все еще удается иметь символы, строки, длинные long int, указатели, указатели функций, структуры и многое другое; все в том, как вы используете это!

Длина 1

.

Команда .(или «слово», как мы ее называем) печатает целочисленное значение поверх стека данных; если стек пуст, вы получите ошибку во время выполнения. Он также удаляет значение из стека - upvote, чтобы посмотреть, как мы можем его сохранить!

Длина 2

.s

.sСлово отображает значения в данный момент в стеке, без удаления какого - либо из них. Он также отображает общее количество значений. В Gforth .sпо умолчанию ограничено показом только первых 9 значений; может быть, мы узнаем, как показать больше?

Длина 3

see

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

Длина 4

1 0=

Я упоминал, что Forth - это основанный на стеке язык с постфиксными операторами? Нажатие 1 0=вводит 1в стек, а затем выполняет 0=слово, которое выталкивает верхнее значение из стека и выталкивает, trueесли оно равно 0, falseесли нет. 0=удобное слово для 0 =; Есть несколько сокращенных слов, как это для общих значений + словосочетаний, как 1+и 0<>. Более того, в то время как falseв Forth 0 и любое ненулевое значение true, встроенные тестовые слова возвращают trueистинные результаты и trueпроходят весь путь - это значение со всеми установленными битами, то есть -1!

Длина 5

-1 u.

Нажмите -1на стек, затем вытолкните его и напечатайте как целое число без знака. Это может быть использовано для быстрого просмотра максимального значения для unsigned int в вашей версии Forth (но не максимального интегрального значения, которое оно изначально поддерживает!). Вы можете спросить: «Как мы узнаем, когда следует печатать int, .а когда - u.?» Ответ: .когда подписано, u.когда подписано. «Я не это имел в виду», - говорите вы. «Как мы узнаем, когда значение на вершине стека подписано, а когда оно не подписано?» Ответ: Вы программист - это ваша работа! Вы должны знать, представляет ли каждое целое число в стеке целое число, целое число без знака int*,char*, указатель на функцию, или другой, или иначе вы получите демонов в нос. Форт не собирается следить за этим для вас; что это, C?

Длина 6

." Hi"

Печать Hi. ."это слово Forth (за которым, как и у всех слов Forth, должен следовать пробел или EOF), которое читает входной поток через следующий "и выводит любые байты между ними. Если вы поставите более одного пробела после .", ."будут напечатаны все, кроме пробела сразу после . Escape-последовательности не поддерживаются (поэтому вы не можете напечатать строку с символом « "в» ."), но Gforth добавляет .\"язык, который поддерживает их.

Длина 7

: + - ;

Вы определяете свои собственные слова в Forth, записывая двоеточие, название слова, слова, которые вы хотите, чтобы ваше слово исполнялось, и точку с запятой. Слово может быть любой последовательностью непробельных символов (пробел - это то, как Forth сообщает, где заканчивается одно слово, а другое начинается, в конце концов), даже знаки препинания и даже операторы (в конце концов, просто слова). Вышеуказанный фрагмент переопределяется +в значение -, поэтому теперь, когда вы пытаетесь добавить, вы вместо этого вычитаете. Любые ранее существующие слова, которые используют +, не затрагиваются, так как они хранят ссылку на оригинальное определение +.

Примечание: некоторые слова в определениях других слов делают разные вещи, чем снаружи, но, кроме структур управления, все они довольно эзотеричны. Большинство слов делают то же самое внутри определения, что и снаружи, но иногда это не очевидно - : show-see see see ;не будет делать то, что вы думаете!

Длина 8

: 42 - ;

Когда я сказал, что слово может быть любой последовательностью пробельных символов, я имел в виду любую последовательность. Нет, у Forth нет слова для каждого отдельного номера; цифры просто немного особенные. Когда Forth встречает непробельную последовательность, он сначала видит, является ли это известным словом; если это не так, он пытается разобрать его как число; если это не удается, только тогда вы получите ошибку. Определение слова, которое пишется так же, как и число, означает, что вы больше не сможете вводить это написание числа напрямую, не получая слово вместо этого, но Gforth и различные другие Forths дают вам несколько способов написания чисел в любом случае .

Длина 9

IF 1 THEN

Наконец- то знакомое! Очевидно, этот код проверяет, 1является ли его аргумент истинным, и, если это так, выполняет все, что следует после THEN, верно? Неправильно. Когда выполнение достигает значения IF, значение в верхней части стека отбрасывается, и если это значение равно true (т. Е. Не равно нулю), выполнение продолжается со всем, что находится внутри, IF ... THENи затем со всем, что следует после THEN; если значение равно нулю, мы просто пропустим сразу после THEN. Обратите внимание, что из-за того, как эти слова реализованы внутри (что в терминах других слов Forth!), IFИ THENмогут использоваться только внутри определения слова, а не в «интерпретировать состояние».

Длина 12

( x y -- y )

Это комментарий. Он идет от одного (к следующему )сразу после него. (В интерпретаторе новая строка также может завершить его.) Это не «встроено» в синтаксис Форта (что-нибудь?); (это просто другое слово, которое отбрасывает все во входном потоке до следующего ). (Это верно - Forth может манипулировать тем, как читается его исходный код. Perl - не единственный язык, который не может быть проанализирован без его выполнения!) Поскольку это слово, вы должны следовать за ним с пробелом, иначе Forth будет жаловаться, что (xне определено Мы также можем пересмотреть определение (в рамках нашей продолжающейся кампании стрельбы себе в ногу.

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

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

Длина 13

1 2 3 4 d+ d.

Как указывалось ранее, тип значения Forth полностью зависит от того, как вы его используете - если вы рассматриваете значение как указатель, это указатель, а если это значение не является хорошим указателем, это ваша вина, что вы рассматриваете его как единое целое. Однако независимо от того, к какому типу вы относитесь как к значению, оно всегда будет занимать одну ячейку в стеке данных; Исключения составляют целые числа с двойной ячейкой или двойной точности . Это целые числа, которые представлены двумя значениями в стеке, что позволяет выполнять арифметику с вдвое большим количеством битов, чем обычно. Ячейка с более значимой или более высокой разрядностью размещается поверх ячейки с менее значимой или младшей битой, так что 1 0это представление двойной ячейки 1, и0 1либо 2 ^ 32, либо 2 ^ 64, в зависимости от того, насколько велики обычные ячейки вашего Форта. Естественно, чтобы рассматривать значение двойной ячейки как таковое, нам нужно использовать слова, которые явно оперируют значениями двойной ячейки; обычно это просто d(или udдля беззнакового), за которым следует имя соответствующего одноклеточного слова: d+для добавления, d<для сравнения, d.для печати и т. д.


+1 за форт. Я начал искать языки, которые еще не были сделаны. Рад видеть это уже здесь.
mbomb007

2
Кроме того, если вы когда-нибудь доберетесь до +1675, у меня будет хорошее ASCII-изображение для вывода. : D
mbomb007

31

Pyth

Для дальнейших фрагментов, я буду публиковать решения проблем в гольф и ссылку на проблему.

Длина 17:

<ussC,cG\_GUQ*zQQ

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

Заполнить бланки

Длина 14:

#QX=Qhf>FT.:Q2

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

Перестановка набора чисел в порядок

Длина 13:

?hu]+HG_UQYQY

Создайте следующую структуру: [0, [1, [2, [3]]]].

Дом на диапазоне списков

Длина 12:

uxyG*HQjvz2Z

XOR умножение.

Умножение XOR

Длина 11:

lfqSzST.:wz

Посчитайте, сколько подстрок первого слова являются анаграммами второго слова.

Обнаружение анаграмм в родительской строке

Длина 9:

fqJjQT_J2

Найдите самую низкую базу, на которой вводится палиндром.

Самая низкая база палиндрома

Длина 5:

!%lQ1

Проверьте, является ли вход степенью 2. Возьмите логарифмическую базу 2, возьмите мод результата 1 и возьмите логическое нет.

Проверьте, является ли целое число степенью 2 без использования +, - операций

Длина 4:

sjQ2

Вычисляет вес Хэмминга ввода, складывая представление базы 2 входа.

Подсчитайте количество единиц в 16-битном целом без знака

Длина 3:

^G2

^ в последовательности int дает декартово произведение первого аргумента с собой n раз, где n - второй аргумент.

В этом случае, так как Gявляется Alphabet ( abcdefghijklmnopqrstuvwxyz), ^G2дает все 2 буквенные строки, aaчерез zz.

Длина 2:

lT

lв то время как обычно выступает в качестве len(), также может использоваться в качестве базы журналов 2. Так Tкак переменная инициализируется 10, это печатает 3.3219280948873626, база журналов 2 из 10.

Длина 1:

H

Hявляется пустым словарем (хеш-таблицей) в Pyth и является единственным способом получить словарь в Pyth, если не использовать v(eval) или $(литерал Python).

Factoid:

Pyth не имеет многосимвольных конструкций, кроме литералов. Кроме того, Pyth компилирует по существу один в один в Python.


Был ли ваш фактоид добавлен до того, как у вас есть команды, которые начинаются с .?
Утренняя монахиня

@LeakyNun Да ..
Исаак
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.