суббота, 28 декабря 2013 г.

iptables ssh only.

Простейший скрипт настройки файрволла, позволяющий залезть на сервер по ssh и при этом блокировать все остальное.

#!/bin/sh

# Стираем все старые правила и удаляем все пользовательские сhains.
iptables -F
iptables -X

# Установим все дефолтные политики в DROP
iptables -P INPUT DROP
iptables -P OUTPUT DROP
iptables -P FORWARD DROP

# Разрешим все без ограничений на интерфейсе loopback
iptables -A INPUT -i lo -j ACCEPT
iptables -A OUTPUT -o lo -j ACCEPT
 
# Разрешим ssh траффик
iptables -A INPUT -p tcp --dport 22 -j ACCEPT
iptables -A OUTPUT -p tcp --sport 22 -j ACCEPT

чуть более подробно: источник

вторник, 5 ноября 2013 г.

Повседневные программы CLI

Установил Xmonad window manager и теперь стало очень актуально, как запускать всякие повседневные пользовательские задачи из коммандной строки (And how to configure f*kin russian keyboard layout and pretty fonts =)))
Тут я буду выкладывать то, что использую таким образом.
  1. eog
    просмотр изображений
  2. mplayer
    простейший медиаплеер. забавно писать скрипты с пользовательской оболочкой вокруг него.
  3. amixer and alsamixer
    аудио микшеры. первый - строго cli. Второй работает в терминале, но имеет userfriendly интерфейс.

pymongo getting started

  1. установка mongodb и pymongo MongoDB пока пропустим, см. их мануал.
    Pymongo:
    sudo apt-get install python-setuptools # если еще нет йих
    sudo easy_install pymongo
       
  2. Готовим котов
    import mongodb
    from mongodb import MongoClient
    client = MongoClient()                    # если монга крутится на локальной машине и стандартном порту
    client = MongoClient('hostname', 27017)   # если нужно эти параметры специфицировать
                                              # и юзать БД с удаленного хоста
    client.database_names()                   # посмотрим, что за базы есть в этой вашей монге
    db = client.db_chosen_name                # выбираем базу для работы
    db.collection_names()                     # смотрим, какие коллекции в энтой вашей базе есть
    collection = db.test_collection           # выбрали одну
    collection = db.['my.col-test']           # то же самое, но работает и с именами, в которых есть точки          
      
  3. Добавим документ в базу
    db = client.mydb                          # выбрали базу, если такой не было, она создается
    users = db["users"]                       # коллекция users. если не было - создается
    user = {"name": "Vasia",
            "age": 43,
            "interests": ["vodka", "balalayka"],
            "pets": {"dog": "Tuzik",
                     "cat": "Mashka"}
           }
    _id = users.insert(user)                  # добавляем в базу, функция возвращает uuid
      
  4. Поиск в базе
    vasias = users.find({"name": "Vasia"})          # возвращает итератороподобный объект
    old_peaple = users.find({"age": {"$gt": 60}})   # все документы с полем "age" > 60
    tuzik_owner = users.find({"pets.dog": "Tuzik"}  # поиск по вложенным полям
    old_people.count()                              # сколько же их нашлось?
    tuzik_owners.sort("age")                        # отсортировать по возрасту всех владельцев Тузиков
     
Полная документация по pymongo(eng)

понедельник, 21 октября 2013 г.

Не знаю куда сунуть эти ссылки, но они мне нужны под рукой.

askubuntu.com
ubuntu help

RHCSA Objectives
стредства мониторинга системы

Заметки по работе с сетью в ubuntu

получить свой видимый внешний ip адрес: wget -O - -q icanhazip.com

получение доступа по ssh к хосту с public ip:

  устанавливаем: sudo apt-get install ssh-client
                                         -server

  посмотрим, что в iptables (любопытства ради):
  # sudo iptables -L

  и пропишем принятие пакетов по порту ssh (22 port):
  # sudo iptables -A INPUT -p tcp --dport ssh -j ACCEPT

  сохраним наши правила файрволла:
  # sudo sh -c "iptables-save > /etc/iptables.rules"

  все, можно подключаться к хосту по ssh



для создания обратного SSH-туннеля можно:
  На клиентской машине:
  # ssh -R remoteport:localhost:22 username@servername
  На стороне сервера:
  # ssh -p remoteport username@localhost


пятница, 27 сентября 2013 г.

Основные команды shell

Еще пока сырой документ, но т.к. сам часто пользуюсь, выложу. Оригинал, от которого постепенно буду отходить в сторону лучшей структурированности и полезности: Basic shell commands by Jeremy Sanders Вообще, посмотрите на сайте, что там Джереми наваял, есть еще интересное :)

Все, что написано на русском языке, было проверено мной лично в терминале на Ubuntu 12.04LTS

  1. cat - Распечатать содержимое на экране. Можно использовать в связке с другими утилитами.
    cat helloworld.py                           # Отобразить любопытный листинг в терминале 
    cat file1 file2 file3 > outfile             # собрать файлы в один
    cat *.txt > outfile                         # собрать все .txt файлы вместе
    cat egg.py spam.py | grep '\bdef\b'         # найти в указанных файлах 
                                                # все вхождения def - определения функции
    
    cat foo.py bar.py | sed -e 's/шило/мыло/g' > out.py 
                                  # заменить в файлах шило на мыло и сохранить это в out.py
    

  2. cd - Сменить текущую директорию
    cd                     # в домашнюю папку
    cd ~/books             # /home/user/books
    cd ~dima               # /home/dima
    cd somedir             # в директорию относительно текущей
    cd /dir1/dir2/dir3...  # в указанную абсолютно директорию
    cd -                   # в предыдущую директорию (аналог backspace в оконном менеджере)
    cd ..                  # в директорию уровнем выше
    

  3. mkdir - Создать директорию
    mkdir testdir                  # в текущей папке появится testdir
    

  4. cp - Копировать файл(ы)
    cp file1 file2                      # копировать file1 в file2
    cp file1 directory                  # копировать file1 в папку directory
    cp file1 file2 file3 ... directory  # копировать несколько файлов в директорию
    cp *.txt myTextsDir                 # копировать все .txt файлы в директорию myTextsDir 
    cp -R dir1 dir2/  # copy dir1 into dir2 including subdirectries
    cp -pR dir1 dir2/ # copy directory, preserving permissions
    

  5. date - Текущая дата и время
    > date
    Вт. Сент. 24 16:14:46 MSK 2013
    

  6. chmod - Управление доступом
    chmod +x script.py             # делает script.py исполняемым файлом
    chmod -x script.py             # script.py перестает быть исполняемым
    

  7. vim - Текстовый редактор, требует установки и изучения(!)
    vim foo.txt               # открывает файл для работы в терминале
    gvim foo.txt              # открывает файл в отдельном окне 
                              # M-x start server first)
    

  8. file - Выводит информацию о типе файла
    > file temp_70.jpg 
    temp_70.jpg: JPEG image data, JFIF standard 1.01,
    resolution (DPI), 72 x 72
    

  9. gedit - Текстовый редактор gedit
    gedit file.txt # открыть файл в gedit
    

  10. gnuplot - Пакет для построения графиков, требует дополнительной установки.

  11. grep - Ищет текст в файлах. Показывает список строк с найденным текстом (с указанием имени файла, если ищем больше чем в одном файле).
    grep "привет" file1 file2 ...   # ищет текст 'привет' в указанных файлах
    grep -i "ПрИвЕТ" filename       # регистронезависимый поиск
    cat filename | grep "hi there"  # связать команды
    grep -v "ложь" filename         # вывести строки, НЕ содержащие 'ложь'
                                    # кавычки могут быть одинарными
    

  12. sed - Потоковый текстовый редактор
    sed -e 's/oldstuff/newstuff/g' inputFileName > outputFileName 
                  # типичное использование sed:
                  # s - заменить
                  # oldstaff - старое
                  # newstaff - на новое
                  # g - глобально, во всем документе inputFileNama
                  # и затем это все дело сохранить в outputFileName
    
    sed на википедии

  13. cc или gcc - Компиляция программы на C
    cc test1.c                     # компилирует test1.c в a.out
    cc -o test2.prog test2.c       # компилирует test2.c в test2.prog, выходной файл после ключа -o
                                   # запуск программы ./a.out или соответственное название
    

  14. gtar - GNU version of the tar utility (also called tar on Linux). Store directories and files together into a single archive file. Use the normal tar program to backup files to a tape. See info tar for documentation.
    gtar cf out.tar dir1    # put contents of directory into out.tar
    gtar czf out.tar.gz dir1 # write compressed tar, out.tar.gz
    gtar tf in.tar          # list contents of in.tar
    gtar tzf in.tar.gz      # list contents of compressed in.tar.gz
    gtar xf in.tar          # extract contents of in.tar here
    gtar xzf in.tar.gz      # extract compressed in.tar.gz
    gtar xf in.tar file.txt ... # extract file.txt from in.tar
    

  15. gzip / gunzip - GNU Compress files into a smaller space, or decompress .Z or .gz files.
    gzip file.fits          # compresses file.fits into file.fits.gz
    gunzip file.fits.gz     # recovers original file.fits
    gzip *.dat              # compresses all .dat files into .dat.gz
    gunzip *.dat.gz         # decompresses all .dat.gz files into .dat
    program | gzip > out.gz # compresses program output into out.gz
    program | gunzip > out  # decompresses compressed program output
    

  16. info - A documentation system designed to replace man for GNU programs (e.g. gtar, gcc). Use cursor keys and return to go to sections. Press b to go back to previous section. A little hard to use.
    info gtar               # documentation for gtar
    

  17. kill - Kill, pause or continue a process. Can also be used for killing daemons.
    > ps -u jss
    ...
     666  pts/1        06:06:06  badprocess 
    > kill 666        # this sends a ``nice'' kill to the
                      # process. If that doesn't work do
    > kill -KILL 666   # (or equivalently)
    > kill -9 666     # which should really kill it!
    
    > kill -STOP 667  # pause (stop) process 
    > kill -CONT 667  # unpause process
    

  18. logout - Closes the current shell. Also try ``exit''.

  19. lp - Sends files to a printer
    lp file.ps  # sends postscript file to the default printer
    lp -dlp2 file.ps           # sends file to the printer lp2
    lp -c file.ps    # copies file first, so you can delete it
    lpstat -p lp2         # get status and list of jobs on lp2
    cancel lp2-258                  # cancel print job lp2-258 
    
    lpr -Plp2 file.ps                    # send file.ps to lp2
    lpq -Plp2                        # get list of jobs on lp2
    lprm -Plp2 1234                   # delete job 1234 on lp2
    

  20. ls - Показать список файлов или информацию о них
    ls file     # проверить, существует ли 
    ls -l file  # показать информацию о файле
    ls *.txt    # показать все файлы с расширением .txt
    ls -lt      # показать информацию о всех файлах в директории в порядке создания
    ls -lrt     # above reversed in order
    ls -a       # показать все файлы, влючая скрытые
    ls dir1     # показать содержимое папки dir1
    ls -d dir1  # существует ли папка dir1?
    ls -p       # добавляет значащие символы к концам файлов
    ls -R       # показывает файлы и в поддиректориях
    ls -1       # показывать 1 файл в каждой строке
    

  21. man - Справочная информация о командах
    man man      # справка о самом man
    man grep     # справка о grep
    

  22. more - Показать файл последовательно по одному экрану
    more file                # показать file, следующий экран - пробел
    grep 'frog' file | more  # сделать то же с выходом другой команды
    

  23. mv - Перемещает или переименовывает файлы
    mv file1 file2                     # переименовать file1 в file2
    mv dir1 dir2                       # переименовать папку dir1 в dir2
    mv file1 file2 file3 ... directory # переместить файлы в папку directory
    

  24. nano - Очень простой текстовый редактор. Поддерживает подсветку кода и запускается прямо в терминале. Бывает удобно.

  25. nice - Start a process in a nice way. Nice levels run from -19 (high priority) to 19 (low priority). Jobs with a higher priority get more CPU time. See renice for more detail. You should probably be using the grid-engine to run long jobs.
    nice +19 myjob1   # run at lowest priority
    nice +8 myjob2    # run at lowish priority
    

  26. openoffice.org - a free office suite available for Linux/Unix, Windows and Mac OS X.

  27. passwd - change your password

  28. pine - A commonly used text-based mail client. It is now called alpine. Allows you to send and receive emails. Configuration options allow it to become quite powerful. Other alternatives for mail are mozilla mail and mutt, however I suggest you stick to alpine or thunderbird.

  29. printenv - Print an environment variable in tcsh
    setenv MYVARIABLE Fred
    printenv MYVARIABLE
    printenv # print all variables
    

  30. ps - List processes on system
    > ps -u jss          # list jss's processes
      934 pts/0    00:00:00 bash
    ^^^^^ ^^^^^    ^^^^^^^^ ^^^^^^^
    PID   output   CPU time name
    > ps -f      # list processes started here in full format
    > ps -AF     # list all processes in extra full format
    > ps -A -l            # list all processes in long format
    > ps -A | grep tcsh   # list all tcsh processes
    

  31. pwd - Текущая рабочая директория
    > pwd
    /home/jss/writing/lecture
    

  32. renice - Renice a running process. Make a process interact better with other processes on the system (see top to see how it is doing). Nice levels run from -19 (high priority) to 19 (low priority). Only your own processes can be niced and they can only be niced in the positive direction (unless you are root). Normal processes start at nice 0.
    > ps -u jss | grep bigprocess      # look for bigprocess
     1234 pts/0    99:00:00 bigprocess
    > renice 19 1234                   # renice PID 1234 to 19
    

  33. rm - Удалить файлы
    rm file1     # молча удаляет файл
    rm -i file   # удалить файл, спросив перед этим y/n
    rm -r dir1   # удаляет папку и все в ней (осторожно с этим, детки!)
    rm -rf dir1  # то же самое, но не спрашивает, даже если поставить флаг -i
    

  34. rmdir - Удаляет директорию, если она пуста (rm -r dirname удалит с содержимым)
    rmdir dirname
    

  35. staroffice - An office suite providing word processor, spreadsheet, drawing package. See Users' Guide on how to install this. This is a commercial version of the openoffice office package - use openoffice.org on linux.

  36. setenv - Set an environment variable in tcsh.
    setenv MYVARIABLE Fred
    echo Hi there $MYVARIABLE
    

  37. tar - Combine files into one larger archive file, or extract files from that archive (same as gtar on Linux).
    tar cvf /dev/rmt/0 ./      # backup cwd into tape
    tar tvf /dev/rmt/0         # list contents of tape
    tar xvf /dev/rmt/0         # extract contents of tape
    

  38. thunderbird - Почтовая программа mozilla thunderbird.

  39. top - Interactively show you the ``top'' processes on a system - the ones consuming the most computing (CPU) time. Press the ``q'' key in top to exit. Press the ``k'' key to kill a particular process. Press ``r'' to renice a process.

  40. sudo apt-get remove program - Удалить программу program из системы

воскресенье, 22 сентября 2013 г.

Шаблоны документов в Ubuntu

Руки не доходили узнать, как же в диалоговое окно создания документов засунуть свои шаблоны. Оказалось, все гораздо проще, чем можно себе представить. Нужно всего лишь кинуть в папку Шаблоны в директории своего юзера нужный полупустой файл, оформленный должным образом. Например, положим туда файл с названием python_empty.py:
#!/usr/bin/python

if __name__ == '__main__':
    print 'Hello, World!!'
и в списке шаблонов появится python_empty. Мелочь, а приятно.

суббота, 21 сентября 2013 г.

Hotkeys - горячие клавиши ubuntu shell



То, что в таблице не переведено - либо не заработало, либо мне было лень разбираться что происходит.

Ctrl + A Курсор в начало текущей строки
Ctrl + E Курсор в конец текущей строки
Ctrl + L               Очищает экран, то же, что и команда clear
Ctrl + U Удаляет в текущей строке символы ДО курсора, если курсор в конце строки - удаляет ее всю.
Ctrl + H То же, что и backspace
Ctrl + R Let’s you search through previously used commands. Пока не понял, как это работает =))
Ctrl + C Kill все, что запущено
Ctrl + D Перезапускает шелл
Ctrl + Z Запущенный процесс приостанавливается, затем командой fg его можно активизировать
Ctrl + W Удаляет часть слова ДО курсора
Ctrl + K Очищает текущую строку ПОСЛЕ курсора
Ctrl + T Меняет местами два символа, находящихся перед курсором
Esc + T Меняет местами два слова, находящихся перед курсором и устанавливает его в конец второго слова
Alt + F Move cursor forward one word on the current line. Не заработало.
Alt + B Move cursor backward one word on the current line. Не работает.
Tab Auto-complete files and folder names. Бибикает, но не автокомплитит.
Shift-Ctrl-V Вставить из буфера, вместо привычного Ctrl-V
И еще пара используемых мной хоткеев в ubuntu
Ctrl-Alt-стрелки  Переключение между рабочими столами
Ctrl-Alt-T Вызов терминала, дальше F11 и мы в нирване
Alt-Tab Зачем я сюда это-то пишу? =)
Ctrl-Win-D Свернуть все окна. Win - это такая кнопочка с логотипом мелкомягких, не знаю как она называется

среда, 18 сентября 2013 г.

Основы bash. Детский справочник.

1. Хэллоу ворлд.

Куда уж без него.
 #!/bin/bash
 echo "Hello World!!"
Запускаем командой
 bash _filename_
Перед запуском нужно его установить как исполняемый скрипт. Следующая команда устанавливает скрипт исполняемым и позволяет его запускать любому пользователю:
 chmod +rx _filename_
А затем его можно запускать просто по имени файла с указанием директории:
 ./_filename_

2. Переменные окружения

Пример еще одной простой программы с переменными окружения (environment)
 #!/bin/bash
 echo "Версия bash -> $BASH_VERSION"
 parameter=$1   #в $1 находится первый параметр скрипта при запуске в командной строке
 name=$0        #в $0 соответственно само имя скрипта
                #пробелов вокруг оператора = быть не должно 
 echo "В двойных кавычках переменные подставляются: параметр -> $parameter имя -> $name"
 echo 'В одинарных, соответственно, идет plaintext: параметр -> $parameter имя -> $name'

3. UNIX утилиты.

Сам по себе bash не очень мощная вещь. Но через него удобно использовать многочисленные стандартные утилиты.
cp foo.txt bar.txt #копирует файл из 1 в 2
du -sh *           #выводит занимаемое место всеми файлами директории(* это типа регэксп =))
date               #дата и время
ну и так далее, полный список приводить не стоит. Все это можно использовать в bash скриптах.

понедельник, 29 июля 2013 г.

понедельник, 22 июля 2013 г.

Элементарные сведения о транзисторах


Опять, по дурацкой своей лентяйской традиции я соберу немного ссылок на простые статьи о транзисторах.
  1. Устройство полевых транзисторов
  2. Схемы включения биполярных транзисторов и температурная стабилизация
  3. Еще о включении и стабилизации
  4. Раздел о транзисторах очень любопытного англоязычного сайта с анимацией и картинками

О возможностях усилительных микросхем


Статейка о возможностях TDA2030. Различные включения усилителей и источники питания с рассчетом.

Краткое описание применения менее мощной микросхемы TDA1517. Судя по всему, годится для "компьютерной" стереосистемки.

А также можно скачать datasheet к TDA2050 , TDA2030 и TDA1517

среда, 17 июля 2013 г.

Блок питания


Несколько ссылок на тему блока питания
  1. Мастеркит 1
  2. Мастеркит 2
  3. Простой транзисторный БП
  4. Простой БП на интегральном стабилизаторе
  5. Видео: как увеличить мощность микросхемы стабилизатора
  6. Видео: включение стабилизатора напряжения
  7. Немного об ИС LM317
  8. Простые стабилизаторы напряжения и их рассчет
  9. О микросхеме стабилизатора напряжения серии КР142ЕН. Импортный аналог - серия 7800
  10. Продолжение статьи о ИМС стабилизаторах, умощнение с помощью транзисторов.
Также в этом блоге выше есть ссылка на интереснейшую статью о микросхеме TDA2030, в которой ее используют для построения лабораторного БП, что является весьма интересным вариантом - применять TDA2030 также просто как и операционный усилитель, а выходной ток у нее до примерно 3,5 А.

http://pro-radio.ru/

вторник, 23 апреля 2013 г.

Вечерний Numpy

Тут я буду собирать совершенно разрозненные сведения о функциях пакета numpy для python.

import numpy as np В качестве предварительного замечания.

np.std(x) стандартное отклонение заданного вектора

np.fft.fft(x) быстрое преобразование фурье, результат - комплексная амплитуда гармоник

np.random.randn() одно число, нормально распределенное с сигма 1, матожидание 0.

np.polyfit(x,y,deg) возвращает МНК коэффициенты полинома y(x) степени deg.

np.polyval(p,x) вычисляет полином p в точке x: p[0]*x**(N-1) + p[1]*x**(N-2) + ... + p[N-2]*x + p[N-1]

пятница, 15 марта 2013 г.

Подсветка синтаксиса haskell на blogspot

Однажды я согрешил. Честолюбие сыграло во мне, жадность и святая злость вскипели полным ходом. Тысячу раз приходя на сайт восхитительной книги Learn You A Haskell мне захотелось стырить замечательную подсветку синтаксиса Haskell вместе с элементами дизайна. Покопался в исходниках сайта, накачал css и js файлов, потом порылся в google на эту тему и задача решилась. На blogspot это заработало, хотя и с гораздо большим количеством костылей и элементов культа карго, чем это желательно.

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

<link href='http://patamushta-ff.narod2.ru/styleHs.css' rel='stylesheet' type='text/css'/>
<link href='http://patamushta-ff.narod2.ru/SyntaxHighlighter.css' rel='stylesheet' type='text/css'/>
<script src='http://patamushta-ff.narod2.ru/shCore.js' type='text/javascript'/>
<script src='http://patamushta-ff.narod2.ru/shBrushPlain.js' type='text/javascript'/>
<script src='http://patamushta-ff.narod2.ru/shBrushHaskell.js' type='text/javascript'/>

При этом текст в редакторе блоггера должен быть обрамлен в два div'a:

<div class="bgwrapper">
<div id="content"<

В конце (я не понял почему именно в конце, но лучшего решения пока не нашел) шаблона, перед закрытием тега html я прилепил еще эту строку:

<script type="text/javascript" src="http://patamushta-ff.narod2.ru/shAdd.js"></script>

После данных телесных манипуляций открылись новые кармические уровни для блоггинга в этом вашем blogspot. Первое, и самое главное, если к блоку pre, в который мы обычно помещаем листинг добавить атрибуты <pre name="code" class="haskell: ghci">, то будет получаться моднейший блок кода на хаскеле, абсолютно подсвеченный крутейшими цветами:

bmiTell :: (RealFloat a) => a -> a -> String  
bmiTell weight height  
    | bmi <= skinny = "You're underweight, you emo, you!"  
    | bmi <= normal = "You're supposedly normal. Pffft, I bet you're ugly!"  
    | bmi <= fat    = "You're fat! Lose some weight, fatty!"  
    | otherwise     = "You're a whale, congratulations!"  
    where bmi = weight / height ^ 2  
          skinny = 18.5  
          normal = 25.0  
          fat = 30.0  

И вторая фича. Текст в тэге <span class="fixed">foo</span> становится foo.

И последнее. Да, согласен, все это - дикий костыль и вообще невозможно использовать. Но мне это помогло.

четверг, 7 марта 2013 г.

MathJax в blogspot

Мы все постоянно хотим одного. Мы хотим красивых математических формул в браузере. Да еще чтобы набирать их можно было как в LaTeX'e. Осуществить эту мечту поможет замечательная штука MathJax, но при попытке подключить ее к blogspot можно испытать много боли. Google и небольшое знание английского языка помогли найти решение.

Сначала нужно подключить скрипт MathJax к посту. Для этого в одну строчку пишем (удалите лишние переводы строки!):

<script type="text/javascript"
src="http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML">
</script>

Затем пишем что-то в духе:

Если \(a \ne 0\), тогда существует два решения уравнения \(ax^2 + bx + c = 0\), которые можно представить в виде $$x = {-b \pm \sqrt{b^2-4ac} \over 2a}.$$

И получаем на выходе красивый математический текст:

Если \(a \ne 0\), то существуют два решения уравнения \(ax^2 + bx + c = 0\), которые представляются в виде $$x = {-b \pm \sqrt{b^2-4ac} \over 2a}.$$

Eще пример:

\begin{pmatrix} 1 & 2 & 3 \\ 4 & 5 & 6 \end{pmatrix} становится симпатичной матрицей:

\begin{pmatrix} 1 & 2 & 3 \\ 4 & 5 & 6 \end{pmatrix}

Всем добра!

Простые бинарные деревья на Haskell


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

data Tree a = EmptyTree | Node a (Tree a) (Tree a) deriving (Show, Read, Eq)

2. Теперь создадим функцию, которая добавляет элемент в дерево. Она должна делать так:

  • Если дерево пусто, то мы создаем вместо него синглетон, т.е. дерево с элементом и двумя пустыми поддеревьями.
  • Если не пусто, то если элемент меньше текущего, мы добавляем его в левое поддерево, если больше, то в правое. Если элемент совпадает, нужно оставить все как есть.
Как всегда, алгоритм на Haskell реализуется легкой формализацией словесного описания:
singleton :: a -> Tree a  
singleton x = Node x EmptyTree EmptyTree  
  
treeInsert :: (Ord a) => a -> Tree a -> Tree a  
treeInsert x EmptyTree = singleton x  
treeInsert x (Node a left right)   
    | x == a = Node x left right  
    | x < a  = Node a (treeInsert x left) right  
    | x > a  = Node a left (treeInsert x right)  

3. Поиск элемента в дереве тоже более чем прост благодаря его упорядоченной организации:

  • Если дерево пусто, то, очевидно, в нем нет искомого элемента
  • Если не пусто, то либо мы нашли, что искали, либо если искомое меньше текущего, то ищем в левом поддереве, иначе - в правом.
treeElem :: (Ord a) => a -> Tree a -> Bool
treeElem x EmptyTree = False
treeElem x (Node a left right) 
    | x == a = True
    | x < a  = treeElem x left
    | x > a  = treeElem x right  

4. Преобразование списка в дерево. Можно просто добавить список к пустому дереву, а перед этим реализовать функцию добавления к дереву списка объектов того же типа, что и в вершинах дерева.

makeTree :: Ord a => [a] -> Tree a
makeTree xs = treeListInsert xs EmptyTree

treeListInsert :: Ord a => [a] -> Tree a -> Tree a
treeListInsert [] tree = tree
treeListInsert (x:xs) tree = treeListInsert xs (treeInsert x tree)

5. Преобразование дерева в список также очевидно, причем список получается упорядоченным:

treeToList :: Ord a => Tree a -> [a]
treeToList EmptyTree = []
treeToList (Node a left right) = treeToList left ++ [a] ++ treeToList                            С                                                               right

6. Осталось реализовать: delete element; проверка балансировки... кроме этого, нужно реализовать сбалансированные деревья. так же интересно это сделать параллельно с модулем на языке С