2 декабря 2012 в 18:20

10 PRINT CHR$(205.5+RND(1));: GOTO 10

10 PRINT CHR$(205.5+RND(1)); : GOTO 10 — это название книги, выпущенной издательством MIT press, авторы которой исследуют историю, эстетику и философию программирования, основываясь на одной-единственной крошечной однострочной программе на Бейсике для компьютера Commodore 64, которая генерирует похожий на лабиринт бесконечный узор. Собственно, заголовок книги — её полный листинг. Эта коротенькая демка была популярна тридцать лет назад и портировалась на множество языков и платформ.



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

Все доходы от продажи книги авторы отдают благотворительной организации Playpower, которая занимается созданием бесплатных обучающих игр для развивающихся стран на открытой и крайне дешёвой 8-битной аппаратной платформе. Кроме того, книга в формате PDF доступна для свободного скачивания под лицензией Creative Commons BY-NC-SA 3.0 на официальном сайте.

Илья Сименко @ilya42
карма
469,7
рейтинг 0,0
full stack javascript developer
Самое читаемое

Комментарии (73)

  • НЛО прилетело и опубликовало эту надпись здесь
  • +10
    10 PRINT CHR$(205.5+RND(1));: GOTO 10
    Сегодня же видел такую реинкарнацию:

    yes 'c=(╱ ╲);printf ${c[RANDOM%2]}'|bash

    Еще куча немного версий на bash :)
    • 0
      Извиняюсь за оффтоп. Никто не знает, почему
      yes 'c=(╱ ╲);printf ${c[RANDOM%2]}'|bash
      
      нормально работает, а
      yes 'c=(1 2);printf ${c[RANDOM%2]}'|bash
      
      Вешает GNOME Terminal намертво(версия 2.30.2)?
      • +1
        У меня всё нормально и в guake, и в gnome-terminal 3.6
        • 0
          Гм…
          1) только при скроле мышью, при простой прокрутке такого не возникает. И в фулскрине заметнее.
          2) несколько преувеличил. Он «отвисает» через некоторое время. И в более новых версиях(только 3.4 смотрел), проблема менее заметна.
  • 0
    Что-то не могу подобрать подходящего шрифта под windows — без слешей повёрнутых на 45 градусов получается некрасиво :)
  • 0
    А в fb2/epub где-нибудь есть? PDF всё же не самый удобоваримый формат.
    • –2
      А конвертеры ныне не модны или под запретом? Сам пользуюсь одним «комбайном» для конвертации в epub. Писать название не буду (не сочли бы за рекламу), но напоминает оно птичку маленькую.
      • +4
        Сконвертированное из PDF и изначально бывшее в правильном формате — всё же несколько разные вещи, не находите?
        • 0
          Согласен. Но опять таки, если PDF правильно подготовлен, то с конвертацией особых проблем не возникнет.
      • +15
        Что плохого в том, чтобы посоветовать другим бесплатную кросплатформенную программу, которая вам понравилась?
        Я тоже пользовался Calibre и считаю, что об этом можно и нужно говорить открыто.
  • –17
    X… У…
    Хорошо, что третью букву не может нарисовать.
  • +5
    Для тех, у кого только cmd под рукой:
    @echo off
    :1
    set /a a=%random% %% 2
    if %a%==0 set /p "t=/"<nul & goto 1
    if %a%==1 set /p "t=\"<nul & goto 1
    
    • 0
      Только тут генератор псевдослучайных чисел какой-то неинтересный: очень много квадратиков, и вообще повторяющихся последовательностей.
      • +1
        Да, косяк. Вот получше:
        @echo off
        set /a x=123456789+%random%
        set /a y=362436069+%random%
        set /a z=521288629+%random%
        :1
        set /a "x ^= x << 16"
        set /a "x ^= x >> 5"
        set /a "x ^= x << 1"
        set /a "t = x"
        set /a "x = y"
        set /a "y = z"
        set /a "z = t ^ x ^ y"
        set /a "a = z & 1"
        if %a%==0 set /p "t=/"<nul & goto 1
        if %a%==1 set /p "t=\"<nul & goto 1
        

        хороший генератор с периодом 2^96-1
      • 0
        А все потому что нужно брать не младший бит случайного числа, а старший.
    • +1
      Меряемся, у кого короче )

      @echo off & setlocal enabledelayedexpansion 
      :a
      set c=/\ &for /f %%i in ('set /a %random% %% 2') do echo|set /p=!c:~%%i,1!&goto a
      

      • +7
        добился однострочника, запускаемого из командной строки (без bat-файла):

        cmd /v:on/q/c for /l %j in (0,0,1)do if !random! LSS 16384 (<nul set/p=/)else (<nul set/p=\)
        
        • +19
          Как вспомню историю про
          $??s:;s:s;;$?::s;;=]=>%-{<-|}<&|`{;;y; -/:-@[-`{-};`-{/" -;;s;;$_;see
          
          сразу отпадает охотя что-то куда-то копировать и запускать…
  • –13
    У Васика операторы не заканчивались ";" Двоеточия достаточно.
    • +18
      это чтобы перевода строки не было
  • 0
    А на js нет подобного?
    • 0
      Моя скромная поделка jsfiddle.net/SyfMU/
      Ткните носом, как можно сделать код красивее, т.к. на js пишу крайне редко.
      • +3
        В одну строчку:
        for (var i=1; i<=640; i++) document.write((parseInt(0.5+Math.random())?"/":"\\")+(i%40?"":"\n"));
        • 0
          for(var i=640,m=Math; i-->0;) document.write((m.floor(0.5+m.random())?"/":"\\")+(i%40?"":"\n"));
          • 0
            нет все же это короче
            for(var i=640; i-->0;) document.write((parseInt(0.5+Math.random())?"/":"\\")+(i%40?"":"\n"));
            • 0
              Так еще короче работает из консоли хрома
              for(var i=640; i-->0;) document.write("╱╲"[parseInt(0.5+Math.random())]+(i%40?"":"<br>"));
              • 0
                Тяжело остановиться
                for(var i=640; i-->0;) document.write("╱╲"[(0.5+Math.random())^1]+(i%40?"":"<br>"));

                Пока не понял почему, но работает.
                • +4
                  Понял — битовые операции округляют операнды.
                  for(var i=640; i-->0;) document.write("╱╲"[(Math.random()*2)^0]+(i%40?"":"<br>"));
      • +2
        Я тоже пробовал делать просто текстом, но из-за шрифтов оно выглядит некрасиво. Пришлось делать в виде изображения.

        Исходник (PHP + Gd)
        Скриншот
      • +10
        Да, кстати, вместо слешей лучше использовать символы диагоналей U+2571 и U+2572, как тут.

        Сравните:
        /\/\/\/\
        \/\/\/\/
        vs
        ╱╲╱╲╱╲╱╲
        ╲╱╲╱╲╱╲╱
        • 0
          Действительно, разница разительная. Спасибо.
      • +4
        Можно использовать другие символы:
        ╱╲
  • +12
    ностальгия: только сейчас, глядя на видео, вспомнил как успокаивает мигающий курсор — прям как собачка, виляющая хвостом… нынешние компы какие-то высокомерные — а этот ждет команды, тут же исполняет, виляет хвостиком в ожидании следующей команды… эх, старею… :-)
    • +6
      Знаете, у меня по-прежнему курсор мигает каждый день. Постоянно.
      • +3
        цените это… возможно, в этом есть свой элемент счастья )
      • НЛО прилетело и опубликовало эту надпись здесь
  • 0
    На Commodore конечно более таинственно выглядит, даже не сразу понял, как это получается :)
  • +5
    Почему исходники не на github?
    • +7
      Какой github, только тетрадка книжка, только хардкор!!!
  • +4

    Вот что странно — операторы уже не все помню (пришлось воспользоваться мануалом), а где какой символ на клавиатуре расположен — пальцы помнят.
    А результат совсем не такой впечатляющий, как на C64.
    • 0
      На какой клавиатуре, JCUKEN — как на MSX?
      • 0
        Нет, «обычная» QWERTY, а под символами я имел в виду * ( ) +:; и т.д., набираемые с модификатором Symbol Shift.
    • +1
      Лучше заменить PRINT на RANDOMIZE USR, так будет прикольнее :-)
    • 0
      Я когда недавно решил побаловаться спектрумовским бейсиком удивился, что пальцы помнят не только символы, но вообще все операторы. Стоит подумать про оператор и я уже знаю на какой клавише и в каком регистре он находится…
  • +5
    Басик… Почти 20 лет прошло с тех пор, как я впервые набрал GOTO:))
    • +1
      15 лет прошло с тех пор, как я впервые отказался от оператора goto :)
      • +2
        Cколько лет пройдет до того момента, когда от goto откажутся компиляторы? :)
        • +2
          Поглядите код ядра Линукс, вы очень сильно удивитесь…
          • 0
            Я про ассемблерные jump-ы, безусловные переходы, что есть тот же самый goto по сути. Неужто в линуксе обошлись без него? Тогда очень сильно удивлюсь.
            • +3
              Простите, вы написали именно про goto, в ядре линукса именно этот оператор используется невероятно часто. А тут вы внезапно ассемблер вспомнили.

              В ассемблере таки да, одни джампы. При чём условные, безусловные. Но при чём здесь ассемблер?
              • +1
                Извиняюсь, не так понял. Значит таки есть там goto. Как я ответил ниже habrahabr.ru/post/161035/#comment_5529703 это всего лишь подколка в сторону ненавистников goto.
                • +1
                  Хорошо: мир, дружба, жвачка!
            • +2
              В DCPU-16, насколько я помню, без него обошлись, оставили MOV IP, адрес. Но вообще, от IP пора отказываться. Слишком неэффективная штука.
              • 0
                В пользу чего можно отказаться от IP?
                • –2
                  Чего-нибудь вроде FPGA. Или нейронных сетей. У нас в мозгах никакого IP нет.
        • 0
          Фундаментальный вопрос — без бутылки не разобраться
        • НЛО прилетело и опубликовало эту надпись здесь
          • +2
            Это я так хитро поддел ненавистников goto. Как не абстрагируйся, все равно код сведется к простым машинным командам, где без него никак.
            • НЛО прилетело и опубликовало эту надпись здесь
              • +1
                Поиск скрытого смысла и скрытых аналогий — важнейшая часть обработки информации. Без неё не только ничего нового не создашь, но и ничего полезного не извлечешь.
          • +1
            Не «if else», а «if goto»! Иногда даже goto не пишут, просто if условие метка (или if число три метки, как в Фортране).
        • +2
          Достаточно запретить все языки, кроме Brainfuck — в нём goto не предусмотрен. Для особо сопротивляющихся можно оставить интерпретаторы алгоритмов Маркова.
  • +2
    Very short C programs and Javascript expressions generating musical output.

    www.youtube.com/watch?v=tCRPUv8V22o
    • 0
      «Дайте гимн Советского Союза на Си++!» ©
  • +1
    Мне больше пример на руби понравился:

    ruby -e 'print ["\u2571","\u2572"].sample while sleep 0.001'
  • +1
    Раз пошла такая пьянка, то вот вам код на Пайтоне:
    import random; while 1: print random.choice(u'╱╲'),
    
    • 0
      Тогда уж
      import random; while 1: print(random.choice('╱╲'), end='')
      
      • 0
        Да кому он нужен ваш третий Пайтон? :)
        • 0
          Мне почему-то третий питон больше нравится. print как функция больше привлекают. Ну и еще нормальная поддержка unicode )). Так что готов поспорить, что третий заменит второго.
          • 0
            danial72, вы приняли шутку слишком всерьез
            • 0
              Просто я не умею смешно шутить в ответ на шутку
  • +1
    Пару месяцев назад делал штуку по похожему алгоритму: explored.tk/experiments/swoop/

    В каждом тайле 2 диагональных линии, "//" либо "\\". Получается красивее.

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