というわけで

勉強再開。
こないだ買ったこの本読んでみた。

Rubyによる情報科学入門

Rubyによる情報科学入門

情報科学ってそういえば一度も勉強したことなかったのでやってみようかなと。
なんか評判は内容が浅いとかRubyの良さが..とかあるみたいですが、アルゴリズム超初心者な自分には分かりやすかったのでいい本だと思いました。

8章ではコマンドラインエディタを例に動的データ構造について説明されているのですが、クラスなのにポインタチックで(あたりまえか)ちょっと新鮮でした。
そのまま読んでも何か丸写しになっちゃいそうだったのでPythonに置き換えて試してます。

こんな感じになるんだろか。

# -*- coding: utf-8 -*-

class Buffer(object):
    def __init__(self):
        self.tail = self.cur = Cell("EOF", None)
        self.head = self.prev = Cell("", self.cur)
        self.lineno = 1

    def getlineno(self):
        return self.lineno

    def goto(self, n):
        self.top()
        for i in range(n - 1):
            self.forward()

    def attend(self):
        return self.cur == self.tail

    def top(self):
        self.prev = self.head
        self.cur = self.head.next

    def forward(self):
        if self.attend():
            return
        self.prev = self.cur
        self.cur = self.cur.next

    def insert(self, s):
        self.prev.next = Cell(s, self.cur)
        self.prev = self.prev.next

    def show(self):
        print("  " + self.cur.data.strip())

    def delete(self):
        if self.attend():
            return
        self.cur = self.prev.next = self.next

    def exchange(self):
        if self.attend() or self.cur.next == self.tail:
            return
        a = self.prev
        b = self.cur.next
        c = self.cur
        d = self.cur.next.next
        a.next = b
        b.next = c
        c.next = d
        d.next = b

    def backward(self):
        if self.prev == self.head:
            return
        a = self.prev
        self.top()
        while self.cur != a:
            self.forward()

    def invert(self):
        self.top()
        if self.attend():
            return
        a = self.cur
        b = self.cur.next
        a.next = self.tail
        while b != self.tail:
            c = b.next
            b.next = a
            a = b
            b = c
        self.head.next = a
        self.top()

    def subst(self, str):
        if self.attend():
            return
        a = str.split('/')
        import re
        self.cur.data = re.sub(a[0], a[1], self.cur.data)

    def read(self, file):
        for line in open(file, 'r'):
            self.insert(line)

    def save(self, file):
        self.top()
        f = open(file, 'w')
        while not self.attend():
            f.write(self.cur.data)
            self.forward()

class Cell(object):
    def __init__(self, data, next):
        self.data = data
        self.next = next

#editor driver
def edit():
    import sys
    e = Buffer()
    print '>'
    for line in iter(sys.stdin.readline, ''):
        c = line[0]
        s = line[1:].strip()
        if c == 'q':
            return
        elif c == 't':
            e.top()
            e.show()
        elif c == 'p':
            e.show()
            l = e.getlineno()
            for i in range(int(s)):
                e.forward()
                e.show()
            e.goto(l)
        elif c == 'i':
            e.insert(s)
        elif c == 'r':
            e.read(s)
        elif c == 'w':
            e.save(s)
        elif c == 's':
            e.subst(s)
            e.show()
        elif c == 'd':
            e.delete()
        elif c == 'x':
            e.exchange()
        elif c == 'b':
            e.backward()
        elif c == 'v':
            e.invert()
        elif c == 'a':
            e.forward()
            e.insert(s)
            e.backward()
        elif c == 'c':
            e.delete()
            e.insert(s)
            e.backward()
        elif c == 'g':
            e.goto(int(s))
        else:
            e.forward()
            e.show()

分岐の多さが。Pythonにswitch文あるといいのにな。
C言語で書くとげんなりしそうだけど、やっぱLLだと書きやすいな。。。