Language detail: Python

Coverage: 96.95%
number of '+' ratings
contribution for coverage

Unsolved challenges

codes

Feed

Used modules

next >>

文字列で+を表示する (Nested Flatten)

方向指示を三角関数で求めるように改造。それにしても何て冗長な数式だい。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
import math

class Canvas:

    __canvas = []

    def __init__(self, width, length):
        for y in range(0, length):
            self.__canvas.append([' '] * width)
        
    __x = 0
    __y = 0
    def point(self, x, y):
        self.__x = x
        self.__y = y

    def draw(self, string, direction):
        for char in string:
            self.__canvas[self.__y][self.__x] = char
            self.__x += direction[0]
            self.__y += direction[1]

    def get(self):
        return self.__canvas

    def p(self):
        for row in self.__canvas:
            print ''.join(row)

def direction(i):
    return (int(2 * (0.25 + 0.25 * math.sin(math.pi * (2 * i + 5) / 2)) * math.copysign(1, (math.sin(math.pi * (2 * i + 5) / 2 / 6)))),
    int(2 * (0.25 + 0.25 * math.sin(math.pi * (2 * i - 1) / 2)) * math.copysign(1, (math.sin(math.pi * (2 * i - 1) / 2 / 6)))))

def drawCross(string):
    canvas = Canvas(len(string)*3+1, len(string)*3+1)
    canvas.point(len(string), 0)
    for i in range(0, 12):
        canvas.draw(string, direction(i))
    canvas.p()
    
drawCross('doukaku')
Python の勉強の一環として取り組んでみました。
□や◇その他の形状にも柔軟に対応できる(無駄な)汎用性がウリです。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
class Canvas:

    __canvas = []

    def __init__(self, width, length):
        for y in range(0, length):
            self.__canvas.append([' '] * width)
        
    __x = 0
    __y = 0
    def point(self, x, y):
        self.__x = x
        self.__y = y

    def draw(self, string, direction):
        for char in string:
            self.__canvas[self.__y][self.__x] = char
            self.__x += direction[0]
            self.__y += direction[1]

    def p(self):
        for row in self.__canvas:
            print ''.join(row)
            
class Direction:
    north = [0, -1]
    northEast = [1, -1]
    east = [1, 0]
    southEast = [1, 1]
    south = [0, 1]
    southWest = [-1, 1]
    west = [-1, 0]
    northWest = [-1, -1]

def drawCross(string):
    canvas = Canvas(len(string)*3+1, len(string)*3+1)
    canvas.point(len(string), 0)

    directions = (
        Direction.east,
        Direction.south,
        Direction.east,
        Direction.south,
        Direction.west,
        Direction.south,
        Direction.west,
        Direction.north,
        Direction.west,
        Direction.north,
        Direction.east,
        Direction.north)

    for d in directions:
        canvas.draw(string, d)
    canvas.p()
    
drawCross('doukaku')

pythonがまだだったので投稿。

最初に、board = [" " * max] * max とやったらshalow copyだったためにはまったのは良い思い出・・・。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import sys

if len(sys.argv) < 2 or len(sys.argv[1]) < 2:
    print "Usage:doukaku291 word(more than 2-chars)"
    exit(0)

w = sys.argv[1]
l = len(w)
max = l * 3 + 1
board = [[" " for i in xrange(max)] for j in xrange(max)]

ds = [
    (1, 0), (0, 1), (1, 0), (0, 1),
    (-1, 0), (0, 1), (-1, 0), (0, -1),
    (-1, 0), (0, -1), (1, 0), (0, -1),
]

(x, y) = (l, 0)
for d in ds:
    for s in w:
        board[y][x] = s
        (x, y) = (x + d[0], y + d[1])

for line in board:
    print "".join(line)
コラッツ・角谷の問題 (Nested Flatten)
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#!/usr/bin/env python

import sys

memo = {}

def collatz(n):
    if n == 1:
        return 0
    elif memo.has_key(n):
        return memo[n]
    else:
        if n % 2 == 0:
            memo[n] = 1 + collatz(n/2)
        else:
            memo[n] = 1 + collatz(3*n+1)
        return memo[n]

def test(num):
    return reduce(max, [collatz(i) for i in range(1, num+1)])

if __name__ == '__main__':
    print test(int(sys.argv[1]))
漢数字で九九の表 (Nested Flatten)

コメントには数字を使ってるけど...

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#!/usr/bin/env python
# -*- coding: utf-8 -*-

numbers = ["〇", "一", "二", "三","四", "五", "六", "七", "八", "九"]

def ninenine():
    for i, n in enumerate(numbers):
        for j, m in enumerate(numbers):
            if n == "〇" or m == "〇":
                continue

            d1 = numbers[i*j/len(numbers)]
            if d1 == "〇": d1 = " "

            d0 = numbers[i*j%len(numbers)]
                
            if m == "九":
                print d1+d0
            else:
                print d1+d0,

if __name__ == "__main__":                
    ninenine()
箱詰めパズルの判定 (Nested Flatten)
二次元配列とか使ってないです。
整数とビット演算だけでゴリゴリ処理してます。
Cに移植しようかどうしようか考え中。
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
#coding:utf-8

import copy


class packField:
    @staticmethod
    def strToBitpattern(patternString):
        n = 0
        for s in patternString:
            if s == 'x':
                n |= 1
                n <<= 1
            elif s == '_':
                n <<= 1
            else:
                pass

        while n & 1 == 0:
            n >>= 1
        return n

    def __init__ (self):
        self.field = packField.strToBitpattern(
                '''
                xxxxxx
                x____x
                x____x
                x____x
                x____x
                xxxxxx
                ''')

        self.block = {}
        self.block['I'] = []
        self.block['O'] = []
        self.block['T'] = []
        self.block['L'] = []
        self.block['Z'] = []

        self.block['I'].append(
            packField.strToBitpattern(
            '''xxxx'''
            )
        )
        self.block['I'].append(
            packField.strToBitpattern(
                '''
                x_____
                x_____
                x_____
                x_____
                ''')
        )
        self.block['O'].append(
            packField.strToBitpattern(
                '''
                xx____
                xx____
                ''')
        )

        self.block['T'].append(
            packField.strToBitpattern(
                '''
                _x____
                xxx___
                ''')
        )
        self.block['T'].append(
            packField.strToBitpattern(
                '''
                xxx___
                _x____
                ''')
        )
        self.block['T'].append(
            packField.strToBitpattern(
                '''
                x_____
                xx____
                x_____
                ''')
        )
        self.block['T'].append(
            packField.strToBitpattern(
                '''
                _x____
                xx____
                _x____
                ''')
        )

        self.block['L'].append(
            packField.strToBitpattern(
                '''
                x_____
                x_____
                xx____
                ''')
        )

        self.block['L'].append(
            packField.strToBitpattern(
                '''
                _x____
                _x____
                xx____
                ''')
        )
        self.block['L'].append(
            packField.strToBitpattern(
                '''
                xx____
                _x____
                _x____
                ''')
        )
        self.block['L'].append(
            packField.strToBitpattern(
                '''
                xx____
                x_____
                x_____
                ''')
        )
        self.block['L'].append(
            packField.strToBitpattern(
                '''
                xxx___
                x_____
                ''')
        )
        self.block['L'].append(
            packField.strToBitpattern(
                '''
                xxx___
                __x___
                ''')
        )
        self.block['L'].append(
            packField.strToBitpattern(
                '''
                x_____
                xxx___
                ''')
        )
        self.block['L'].append(
            packField.strToBitpattern(
                '''
                __x___
                xxx___
                ''')

        )
        self.block['Z'].append(
            packField.strToBitpattern(
                '''
                xx____
                _xx___
                ''')
        )
        self.block['Z'].append(
            packField.strToBitpattern(
                '''
                _xx___
                xx____
                ''')
        )
        self.block['Z'].append(
            packField.strToBitpattern(
                '''
                x_____
                xx____
                _x____
                ''')
        )
        self.block['Z'].append(
            packField.strToBitpattern(
                '''
                _x____
                xx____
                x_____
                ''')
        )

        print self.field
        print self.block

    def solve(self, blocks, field = None):
        if blocks == []:
            return True

        if field == None:
            field = self.field

        for pattern in self.block[blocks[0]]:
            while pattern < field:
                if field & pattern == 0:
                    field ^= pattern
                    result = self.solve(blocks[1:], field)
                    if result == True:
                        return True
                    field ^= pattern
                pattern <<= 1
        return False




if __name__ == "__main__":
    p = packField()
    print 'IIII', p.solve(['I','I','I','I',])
    print 'OOOO', p.solve(['O','O','O','O',])
    print 'IOOT', p.solve(['I','O','O','T',])
    print 'LZLZ', p.solve(['L','Z','L','Z',])
    print 'IZZZ', p.solve(['I','Z','Z','Z',])
IPv6アドレスの短縮 (Nested Flatten)
socketモジュールで
1
2
3
4
5
6
7
8
from socket import *
from struct import *

def ipv6_compress(addr):
    return inet_ntop(AF_INET6, inet_pton(AF_INET6, addr))

def ipv6_decompress(addr):
    return ":".join(format(x, "04x") for x in unpack("!8H", inet_pton(AF_INET6, addr)))
居眠り床屋問題 (Nested Flatten)

Python 2.6 , 3.0 から加わった multiprocessing をつかってみました。 Python 2.6 で動作確認しています。

はじめは席を multiprocessing.Queue(maxsize=3) としていたのですが、これには中身を取り出さずにのぞき見る術がないのに気づきました。これでは「散髪用兼順番待ち用椅子」ではなくただの「順番待ち用椅子」であり、店に散髪中 1 人、待機 3 人の計 4 人の状態もありえる作りでした。

このため、席は Seats クラスとして作り直しています。客がいるかどうかは check メソッドで見ます。客の着席退席は sit, stand メソッドです。

1回目

[barber 1332] 床屋、眠る
[shop 1052] 来店 0
[shop 1052] 床屋を起こす 0
[barber 1332] 床屋、目覚める
[barber 1332] 散発開始 0
[shop 1052] 来店 1
[barber 1332] 散発終了 0
[barber 1332] 散発開始 1
[shop 1052] 来店 2
[shop 1052] 来店 3
[shop 1052] 来店 4
[shop 1052] 満席で立ち去る 4
[barber 1332] 散発終了 1
[barber 1332] 散発開始 2
[shop 1052] 来店 5
[shop 1052] 来店 6
[shop 1052] 満席で立ち去る 6
[barber 1332] 散発終了 2
[barber 1332] 散発開始 5
[shop 1052] 来店 7
[barber 1332] 散発終了 5
[barber 1332] 散発開始 7
[barber 1332] 散発終了 7
[barber 1332] 散発開始 3
[barber 1332] 散発終了 3
[barber 1332] 床屋、眠る
[shop 1052] 来店 8
[shop 1052] 床屋を起こす 8
[barber 1332] 床屋、目覚める
[barber 1332] 散発開始 8
[shop 1052] 来店 9
[shop 1052] 来店 10
[shop 1052] 来店 11
[shop 1052] 満席で立ち去る 11
[barber 1332] 散発終了 8
[barber 1332] 散発開始 9
[shop 1052] 来店 12
[shop 1052] 来店 13
[shop 1052] 満席で立ち去る 13
[shop 1052] 来店 14
[shop 1052] 満席で立ち去る 14
[shop 1052] 来店 15
[shop 1052] 満席で立ち去る 15
[barber 1332] 散発終了 9
[barber 1332] 散発開始 12
[barber 1332] 散発終了 12
[barber 1332] 散発開始 10
[barber 1332] 散発終了 10
[barber 1332] 床屋、眠る

2回目

[barber 2356] 床屋、眠る
[shop 2180] 来店 0
[shop 2180] 床屋を起こす 0
[barber 2356] 床屋、目覚める
[barber 2356] 散発開始 0
[shop 2180] 来店 1
[barber 2356] 散発終了 0
[barber 2356] 散発開始 1
[shop 2180] 来店 2
[shop 2180] 来店 3
[shop 2180] 来店 4
[shop 2180] 満席で立ち去る 4
[shop 2180] 来店 5
[shop 2180] 満席で立ち去る 5
[shop 2180] 来店 6
[shop 2180] 満席で立ち去る 6
[shop 2180] 来店 7
[shop 2180] 満席で立ち去る 7
[barber 2356] 散発終了 1
[barber 2356] 散発開始 2
[barber 2356] 散発終了 2
[barber 2356] 散発開始 3
[barber 2356] 散発終了 3
[barber 2356] 床屋、眠る
[shop 2180] 来店 8
[shop 2180] 床屋を起こす 8
[barber 2356] 床屋、目覚める
[barber 2356] 散発開始 8
[barber 2356] 散発終了 8
[barber 2356] 床屋、眠る
[shop 2180] 来店 9
[shop 2180] 床屋を起こす 9
[barber 2356] 床屋、目覚める
[barber 2356] 散発開始 9
[shop 2180] 来店 10
[shop 2180] 来店 11
[shop 2180] 来店 12
[shop 2180] 満席で立ち去る 12
[shop 2180] 来店 13
[shop 2180] 満席で立ち去る 13
[shop 2180] 来店 14
[barber 2356] 散発終了 9
[barber 2356] 散発開始 10
[shop 2180] 来店 15
[shop 2180] 満席で立ち去る 15
[barber 2356] 散発終了 10
[barber 2356] 散発開始 14
[barber 2356] 散発終了 14
[barber 2356] 散発開始 11
[barber 2356] 散発終了 11
[barber 2356] 床屋、眠る
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
# coding: utf-8

from multiprocessing import \
        Process, Queue, Lock, Event, Array, current_process
from Queue import Empty
import time
import random

def barber(seats, output_data, barber_waking):
    pid = current_process().pid

    while True:
        try:
            seat_num, customer = seats.check()
        except SeatsEmpty:
            seat_num, customer = None, None
        if customer is not None:
            output_data.put(u"[barber %d] 散発開始 %d" % (pid, customer))
            time.sleep(random.randint(100, 400) / 1000.0)
            output_data.put(u"[barber %d] 散発終了 %d" % (pid, customer))
            seats.stand(seat_num)
        else:
            # 客がいないので寝る
            barber_waking.clear()
            output_data.put(u"[barber %d] 床屋、眠る" % pid)
            barber_waking.wait() # 寝た
            # 起こされた
            output_data.put(u"[barber %d] 床屋、目覚める" % pid)

def shop(seats, output_data, barber_waking):
    pid = current_process().pid

    for customer in  xrange(0, 16):
        try:
            output_data.put(u"[shop %d] 来店 %d" % (pid, customer))
            seats.sit(customer)
        except SeatsFull:
            output_data.put(u"[shop %d] 満席で立ち去る %d" % (
                pid, customer))
        else:
            if not barber_waking.is_set():
                output_data.put(u"[shop %d] 床屋を起こす %d" % (
                    pid, customer))
            barber_waking.set()
        if customer != 7:
            time.sleep(random.randint(0, 200) / 1000.0)
        else:
            time.sleep(random.randint(1200, 1400) / 1000.0)

class SeatsEmpty(Exception):
    pass

class SeatsFull(Exception):
    pass

class Seats(object):
    def __init__(self, num):
        # seats には客の id  (>= 0) が入る。負の値は空席を意味する
        self.seats = Array('b', num, lock=False)
        self.lock = Lock()
        with self.lock:
            for i in xrange(num):
                self.seats[i] = -1

    def check(self):
        u"""客がいるかどうか見る
        
        客がいなければ SeatsEmpty 例外を送出する。"""
        with self.lock:
            for seat_num, customer in enumerate(self.seats):
                if customer >= 0:
                    return seat_num, customer
            else:
                raise SeatsEmpty()

    def sit(self, customer):
        u"""客を空席に座らせる
        
        空席がない場合 SeatsFull 例外を送出する。"""
        with self.lock:
            for seat_num, seat in enumerate(self.seats):
                if seat < 0:
                    self.seats[seat_num] = customer
                    break
            else:
                raise SeatsFull()

    def stand(self, seat_num):
        u"""seat_num 番目の席に座っている客に席を立たせる"""
        with self.lock:
            assert self.seats[seat_num] >= 0
            self.seats[seat_num] = -1

def main():
    seats = Seats(3) # 席
    output_data = Queue() # 出力バッファ
    # 出力を別プロセスもしくは親プロセスで
    barber_waking = Event() # 床屋が起きているか
    barber_waking.set()

    process_shop = Process(
            target=shop,
            args=(seats, output_data, barber_waking))
    process_barber = Process(
            target=barber,
            args=(seats, output_data, barber_waking))

    process_barber.start()
    process_shop.start()

    while (process_shop.is_alive() or
           barber_waking.is_set() or
           not output_data.empty()):
        try:
            print output_data.get(timeout=1)
        except Empty:
            pass

    process_barber.terminate()
    process_barber.join()

if __name__ == '__main__':
    main()
ストレンジアトラクタの描画 (Nested Flatten)

sprottのアトラクタ。a.pngに出力。

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
# sprott attractor
# output to a.png
# identify attractor as 12 charactor string
# as FIRCDERRPVLD
#
# for more detail , see :
#   http://sprott.physics.wisc.edu/pubs/paper203.htm

import java
import math
from java.awt       import *
from java.awt.image import *
from javax.imageio  import *
from java.io        import *
from java.util      import *

def createPictureFile(imgWidth , imgHeight , imgType , fileName , op):
    bi = BufferedImage(imgWidth,imgHeight,BufferedImage.TYPE_BYTE_GRAY)
    g  = bi.createGraphics()
    g.setPaint(Color.WHITE)
    g.fillRect(0,0,imgWidth,imgHeight)
    g.setColor(Color.BLACK)
    op(g)
    outFile = File(fileName)
    ImageIO.write(bi,imgType,outFile)

# coefficients named A through Y (25 possible values)
coef ={    'A':-1.2,
        'B':-1.1,
        'C':-1.0,
        'D':-0.9,
        'E':-0.8,
        'F':-0.7,
        'G':-0.6,
        'H':-0.5,
        'I':-0.4,
        'J':-0.3,
        'K':-0.2,
        'L':-0.1,
        'M': 0.0, # <---- Zero
        'N':+0.1,
        'O':+0.2,
        'P':+0.3,
        'Q':+0.4,
        'R':+0.5,
        'S':+0.6,
        'T':+0.7,
        'U':+0.8,
        'V':+0.9,
        'W':+1.0,
        'X':+1.1,
        'Y':+1.2}

#        123456123456
sign = "FIRCDERRPVLD" # 12charactors signature of system 
#"AMTMNQQXUYGA"
#"CVQKGHQTPNTE"

a = map(lambda x:coef[x],sign)
print a

num_trajectory           = 100
num_point_per_trajectory = 1000

ratio     = 200.0
imgWidth  = 500
imgHeight = 500
offsetx   = imgWidth /2
offsety   = imgHeight/2
imgType   = "png"
fileName  = "a.png"

oval_r    = 0.1
num_ring  = 1

limitPositive = 10e6
limitNegative =-limitPositive

def drawProc(g) :
    rand = java.util.Random()
    for j in range(num_trajectory) :
        iring = (j % num_ring) + 1 
        r     = (oval_r * iring)/num_ring
        theta = rand.nextDouble() * math.pi * 2
        #
        (x,y) = ( r*math.cos( theta ) , r*math.sin( theta ) )
        #
        for i in range(num_point_per_trajectory) :
            if limitNegative > x or limitPositive < x  or limitNegative > y or limitPositive < y :
                break
            
            ix = int(               ratio*x + offsetx   )
            iy = int( imgHeight - ( ratio*y + offsety ) )
            if imgWidth > ix >= 0 and imgHeight > iy >= 0 :
                g.drawLine(ix,iy,ix,iy)
            
            x_x  = x*x
            y_y  = y*y
            x_y  = x*y
            (x,y) = (    a[0] + a[1]*x + a[2]*x_x + a[3]*x_y + a[ 4]*y + a[ 5]*y_y ,
                        a[6] + a[7]*x + a[8]*x_x + a[9]*x_y + a[10]*y + a[11]*y_y )

createPictureFile(imgWidth , imgHeight , imgType , fileName , drawProc )

グモウスキ-ミラ アトラクタ。a.pngに出力。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
# Gumowski-Mira attractor
# output to a.png

import java
import math
from java.awt       import *
from java.awt.image import *
from javax.imageio  import *
from java.io        import *
from java.util      import *

def createPictureFile(imgWidth , imgHeight , imgType , fileName , op):
    bi = BufferedImage(imgWidth,imgHeight,BufferedImage.TYPE_BYTE_GRAY)
    g  = bi.createGraphics()
    g.setPaint(Color.WHITE)
    g.fillRect(0,0,imgWidth,imgHeight)
    g.setColor(Color.BLACK)
    op(g)
    outFile = File(fileName)
    ImageIO.write(bi,imgType,outFile)


xa   =  0.0005
xb   =  1.0
a    = -0.48
b    =  0.9924

def f_0(x) : 
    x_x = x*x
    return a * x + ( 2*(1-a)*x_x / (1+x_x) )

def f_1(x) : 
    x_x = x*x
    return a * x + ( 2*(1-a)*x_x / ((1+x_x)*(1+x_x)) )

# from http://codezine.jp/article/detail/327?p=2
def f_2(x) :
    x_x = x*x
    return a * x + ( 2*(1-a)*x / (1+x_x) )

# from http://codezine.jp/article/detail/327?p=2
def f_3(x) :
    x_x = x*x
    return a * x + ( 2*(1-a) / (1+x_x) )

def g_0(y) :
    return b *y + xa * (1- xb*y*y)*y

gm_g = g_0
gm_f = f_0

num_trajectory           = 100
num_point_per_trajectory = 1000

ratio     = 20.0
imgWidth  = 500
imgHeight = 500
offsetx   = imgWidth /2
offsety   = imgHeight/2
imgType   = "png"
fileName  = "a.png"

oval_r    = 0.5
num_ring  = 10

limitPositive = 10e6
limitNegative =-limitPositive

def drawProc(g) :
    rand = java.util.Random()
    for j in range(num_trajectory) :
        iring = (j % num_ring) + 1 
        r     = (oval_r * iring)/num_ring
        theta = rand.nextDouble() * math.pi * 2
        #
        (x,y) = ( r*math.cos( theta ) , r*math.sin( theta ) )
        #
        u = gm_f(x)
        for i in range(num_point_per_trajectory) :
            if limitNegative > x or limitPositive < x  or limitNegative > y or limitPositive < y :
                break
            
            ix = int(               ratio*x + offsetx   )
            iy = int( imgHeight - ( ratio*y + offsety ) )
            if imgWidth > ix >= 0 and imgHeight > iy >= 0 :
                g.drawLine(ix,iy,ix,iy)
            
            xx = gm_g(y) + u
            u  = gm_f(xx)
            yy = u - x
            
            (x,y) = (xx,yy)

createPictureFile(imgWidth , imgHeight , imgType , fileName , drawProc )

エノンアトラクタ。a.pngに出力。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
# henon attractor
# output to a.png

import java
import math
from java.awt       import *
from java.awt.image import *
from javax.imageio  import *
from java.io        import *
from java.util      import *

def createPictureFile(imgWidth , imgHeight , imgType , fileName , op):
    bi = BufferedImage(imgWidth,imgHeight,BufferedImage.TYPE_BYTE_GRAY)
    g  = bi.createGraphics()
    g.setPaint(Color.WHITE)
    g.fillRect(0,0,imgWidth,imgHeight)
    g.setColor(Color.BLACK)
    op(g)
    outFile = File(fileName)
    ImageIO.write(bi,imgType,outFile)

# from : http://codezine.jp/article/detail/327?p=2

h_sq =lambda it:it*it
h_cu =lambda it:it*it*it
h_si =lambda it:0.8*math.sin(it)
h_in =lambda it:0.1 / it

henon = h_sq
alpha = 0.47 * math.pi
# 0.07
# 0.30
# 0.39
# 0.47
# 0.61
# 0.84
sin_alpha = math.sin(alpha)
cos_alpha = math.cos(alpha)

num_trajectory           = 100
num_point_per_trajectory = 1000

ratio     = 300.0
imgWidth  = 500
imgHeight = 500
offsetx   = imgWidth /2
offsety   = imgHeight/2
imgType   = "png"
fileName  = "a.png"

oval_r    = 1.0
num_ring  = 15

limitPositive = 10e6
limitNegative =-limitPositive

def drawProc(g) :
    rand = java.util.Random()
    for j in range(num_trajectory) :
        iring = (j % num_ring) + 1 
        r     = (oval_r * iring)/num_ring
        theta = rand.nextDouble() * math.pi * 2
        #
        (x,y) = ( r*math.cos( theta ) , r*math.sin( theta ) )
        #
        for i in range(num_point_per_trajectory) :
            if limitNegative > x or limitPositive < x  or limitNegative > y or limitPositive < y :
                break
            
            ix = int(               ratio*x + offsetx   )
            iy = int( imgHeight - ( ratio*y + offsety ) )
            if imgWidth > ix >= 0 and imgHeight > iy >= 0 :
                g.drawLine(ix,iy,ix,iy)
            
            temp  = y - henon(x)
            (x,y) = (x*cos_alpha - temp*sin_alpha,  
                     x*sin_alpha + temp*cos_alpha) 

createPictureFile(imgWidth , imgHeight , imgType , fileName , drawProc )

池田写像。a.pngに出力

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
# ikeda attractor
# output to a.png

import java
import math
from java.awt       import *
from java.awt.image import *
from javax.imageio  import *
from java.io        import *
from java.util      import *

def createPictureFile(imgWidth , imgHeight , imgType , fileName , op):
    bi = BufferedImage(imgWidth,imgHeight,BufferedImage.TYPE_BYTE_GRAY)
    g  = bi.createGraphics()
    g.setPaint(Color.WHITE)
    g.fillRect(0,0,imgWidth,imgHeight)
    g.setColor(Color.BLACK)
    op(g)
    outFile = File(fileName)
    ImageIO.write(bi,imgType,outFile)

a = 1.0
b = 0.9
k = 0.4
p = 6.0

num_trajectory           = 100
num_point_per_trajectory = 1000

ratio     = 100.0
imgWidth  = 500
imgHeight = 500
offsetx   = imgWidth /2
offsety   = imgHeight/2
imgType   = "png"
fileName  = "a.png"

def drawProc(g) :
    rand = java.util.Random()
    for j in range(num_trajectory) :
        theta= rand.nextDouble() * math.pi * 2.0
        (x,y) = ( math.cos( theta ) , math.sin( theta ) )
        #
        for i in range(num_point_per_trajectory) :
            ix = int(              ratio*x + offsetx    )
            iy = int( imgHeight - ( ratio*y + offsety ) )
            g.drawLine(ix,iy,ix,iy)
            
            tn = k - p/(1.0 + (x*x + y*y) )
            
            sinTn = math.sin(tn)
            cosTn = math.cos(tn)
            
            (x,y) =( b * ( x*cosTn - y*sinTn ) + a , 
                     b * ( x*sinTn + y*cosTn )     ) 

createPictureFile(imgWidth , imgHeight , imgType , fileName , drawProc )

池田写像。a.pngに出力

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
# ikeda attractor
# output to a.png

import java
import math
from java.awt       import *
from java.awt.image import *
from javax.imageio  import *
from java.io        import *
from java.util      import *

def createPictureFile(imgWidth , imgHeight , imgType , fileName , op):
    bi = BufferedImage(imgWidth,imgHeight,BufferedImage.TYPE_BYTE_GRAY)
    g  = bi.createGraphics()
    g.setPaint(Color.WHITE)
    g.fillRect(0,0,imgWidth,imgHeight)
    g.setColor(Color.BLACK)
    op(g)
    outFile = File(fileName)
    ImageIO.write(bi,imgType,outFile)

a = 1.0
b = 0.9
k = 0.4
p = 6.0

num_trajectory           = 100
num_point_per_trajectory = 1000

ratio     = 100.0
imgWidth  = 500
imgHeight = 500
offsetx   = imgWidth /2
offsety   = imgHeight/2
imgType   = "png"
fileName  = "a.png"

def drawProc(g) :
    rand = java.util.Random()
    for j in range(num_trajectory) :
        theta= rand.nextDouble() * math.pi * 2.0
        (x,y) = ( math.cos( theta ) , math.sin( theta ) )
        #
        for i in range(num_point_per_trajectory) :
            ix = int(              ratio*x + offsetx    )
            iy = int( imgHeight - ( ratio*y + offsety ) )
            g.drawLine(ix,iy,ix,iy)
            
            tn = k - p/(1.0 + (x*x + y*y) )
            
            sinTn = math.sin(tn)
            cosTn = math.cos(tn)
            
            (x,y) =( b * ( x*cosTn - y*sinTn ) + a , 
                     b * ( x*sinTn + y*cosTn )     ) 

createPictureFile(imgWidth , imgHeight , imgType , fileName , drawProc )
Twitterへの投稿 (Nested Flatten)
1
2
3
import twitter
t = twitter.Api("user", "pass")
s = t.PostUpdate("test")
UTF-16をUTF-8に変換 (Nested Flatten)

投稿してから気づきましたが、こうすればcodecsモジュールは必要ありませんね(汗)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
def solve(*a):
    s = "".join(map(chr, a)).decode("utf-16be")
    def format(c):
        s = bin(ord(c))
        assert s[:2] == '0b'
        return s[2:].rjust(8, '0')
    print " ".join(map(format, s.encode("utf-8")))

def main():
    solve(0x00, 0x41, 0x00, 0x42, 0x00, 0x43)
    solve(0x30, 0x42, 0x30, 0x44, 0x30, 0x46)

if __name__ == '__main__':
    main()

codecsモジュールを使ってみました。サロゲートペアについては確認してません。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
import codecs

def solve(*a):
    s = codecs.getdecoder("utf-16be")("".join(map(chr, a)))[0]
    def format(c):
        s = bin(ord(c))
        assert s[:2] == '0b'
        return s[2:].rjust(8, '0')
    print " ".join(map(format, s.encode("utf-8")))

def main():
    solve(0x00, 0x41, 0x00, 0x42, 0x00, 0x43)
    solve(0x30, 0x42, 0x30, 0x44, 0x30, 0x46)

if __name__ == '__main__':
    main()
作業予定表から週単位で作業量を積み上げる (Nested Flatten)

それなりに汎用的にできたとは思うのですが。サンプル入力でしか動作確認してないんで、あまり自信なし。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
# coding: shift_jis

import collections
import datetime
import bisect
import codecs
import sys
import re

Job = collections.namedtuple('Job', 'start count mark')

def read_jobs():
    jobs = []
    io = codecs.open("p227.txt", "r", "shift_jis")
    io.next() # skip first line
    for line in io:
        m = re.search('(\d+)/(\d+)/(\d+)', line)
        start = datetime.date(*map(int, m.groups()))
        m = re.search(u'(\d+)日間', line)
        count = int(m.group(1))
        m = re.search(u'\((.)\)', line)
        mark = m.group(1)
        jobs.append(Job(start, count, mark))
    return jobs

def solve(year, month, jobs):
    def iter_dates():
        date = datetime.date(year, month, 1)
        while date.month == month:
            yield date
            date += datetime.timedelta(days=1)
    # store start days of each week
    days = [date.day for date in iter_dates() if date.day == 1 or date.weekday() == 0]
    # initialize marks
    marks = [None]
    for date in iter_dates():
        if date.day in days:
            marks.append([])
        else:
            marks.append(marks[-1])
    # store marks
    for job in jobs:
        date = job.start
        for _ in xrange(job.count):
            if date.year == year and date.month == month:
                marks[date.day].append(job.mark)
            date += datetime.timedelta(days=1)
    # select marks on days
    marks = [marks[day] for day in days]
    # output
    col_headers = ["%d/%d" % (month, day) for day in days]
    col_size = max(len(s) for s in col_headers) + 1
    max_mark_len = max(len(a) for a in marks)
    def fix_col(s):
        return s.encode(sys.stdout.encoding).ljust(col_size)
    for row in xrange(max_mark_len):
        buf = []
        for a in marks:
            i = max_mark_len - 1 - row
            buf.append(fix_col(a[i] if i < len(a) else u" "))
        print "".join(buf)
    print "".join(fix_col(s) for s in col_headers)

def main():
    solve(2009, 1, read_jobs())

if __name__ == '__main__':
    main()
ストレンジアトラクタの描画 (Nested Flatten)

C言語によるアルゴリズム事典(奥村晴彦)のローレンツアトラクタです。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
import Tkinter as Tk

class PlotterCanvas(Tk.Canvas):
    def __init__(self, master, xmin, ymin, xmax, ymax):
        Tk.Canvas.__init__(self, master)
        self._xmin = xmin
        self._ymin = ymin
        self._xmax = xmax
        self._ymax = ymax
    def _convert_x(self, x):
        w = float(self.cget("width"))
        ratio = (x - self._xmin) / (self._xmax - self._xmin)
        return w * ratio
    def _convert_y(self, y):
        h = float(self.cget("height"))
        ratio = (y - self._ymin) / (self._ymax - self._ymin)
        return h - h * ratio
    def move(self, x, y):
        self._x = x
        self._y = y
    def draw(self, x, y):
        self.create_line(
            self._convert_x(self._x),
            self._convert_y(self._y),
            self._convert_x(x),
            self._convert_y(y))
        self.move(x, y)

def draw_lorenz(canvas):
    A = 10.0
    B = 28.0
    C = 8.0 / 3.0
    D = 0.01
    x = y = z = 1
    for k in xrange(3000):
        dx = A * (y - x)
        dy = x * (B - z) - y
        dz = x * y - C * z
        x += D * dx; y += D * dy; z += D * dz
        if k > 100:
            canvas.draw(x, z)
        else:
            canvas.move(x, z)

def main():
    root = Tk.Tk()
    canvas = PlotterCanvas(root, -30, 0, 30, 60)
    canvas.pack()
    draw_lorenz(canvas)
    root.mainloop()

if __name__ == '__main__':
    main()
化学反応式の完成 (Nested Flatten)

連立一次方程式で解くようにしました。単純な掃き出し法です。各化合物に係数を振って、答えを出すために最初の係数だけは1に固定しました。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
from fractions import Fraction as F
from fractions import gcd
import collections
import itertools
import re

def lcm(a, b):
    return a // gcd(a, b) * b

def solve(prev_list, next_list):
    # create unique list of elements
    elements = []
    for s in itertools.chain(prev_list, next_list):
        for element in re.findall('[A-Z][a-z]*', s):
            if element not in elements:
                elements.append(element)
    # count the number of elements in each terms
    coefs = []
    for the_list, sign in ((prev_list, +1), (next_list, -1)):
        for s in the_list:
            coef = collections.defaultdict(int)
            for m in re.finditer('([A-Z][a-z]*)(\d*)', s):
                coef[m.group(1)] += sign * F(int(m.group(2)) if m.group(2) else 1)
            coefs.append(coef)
    # create a system of linar equation
    matrix = []
    for element in elements:
        matrix.append([coef.get(element, F(0)) for coef in coefs] + [F(0)])
    matrix.append([F(1)] + [F(0)] * (len(coefs) - 1) + [F(1)])
    # solve a system of linar equation
    n = len(matrix)
    assert all(len(a) == n + 1 for a in matrix)
    for col in xrange(n):
        for row in xrange(col, n):
            if matrix[row][col]:
                matrix[col], matrix[row] = matrix[row], matrix[col]
                break
        else:
            raise ValueError("non-zero element cannot be found")
        value = matrix[col][col]
        for col2 in xrange(n + 1):
            matrix[col][col2] /= value
        for row in xrange(n):
            if row == col:
                continue
            value = matrix[row][col]
            for col2 in xrange(n + 1):
                matrix[row][col2] -= matrix[col][col2] * value
    ans = [matrix[row][-1] for row in xrange(n)]
    # normalize answer (erase denominator)
    n = 1
    for f in ans:
        n = lcm(n, f.denominator)
    ans = [(f * n).numerator for f in ans]
    ans = ["" if m == 1 else str(m) for m in ans]
    # output
    print \
        " + ".join(ans[i] + s for (i, s) in enumerate(prev_list)) + \
        " -> " + \
        " + ".join(ans[i + len(prev_list)] + s for (i, s) in enumerate(next_list))

def main():
    solve(("Mg", "O2"), ("MgO",))
    solve(("C2H2", "O2"), ("CO2", "H2O"))

if __name__ == '__main__':
    main()
シードを固定した乱数 (Nested Flatten)
1
2
3
import random
random.seed(42)
print random.random()
next >>

Index

Feed

Other

Link

Pathtraq

loading...