Python Challenge は、出題ページの情報(含む、ソース)をヒントにして、続く次の出題ページの URL を導き出すクイズ集。もちろん Python を駆使することが前提ですが、ふだん使い慣れた別の言語処理系でチャレンジしておられるかたも多いようです。そこで、解答を得るためのスクリプトに Squeak の Smalltalk を用いてみました。とりあえずレベル 10 まで。以下、ネタバレ要注意。
レベル 1
'koe' collect: [: each |
each isLetter
ifTrue: [Character alphabet atWrap: (Character alphabet indexOf: each) + 2]
ifFalse: [each]]
レベル 2
contents comment bag rares |
contents _ (HTTPSocket httpGet: '
http://www.pythonchallenge.com/pc/def/xyz.html') contents.
comment _ (contents findBetweenSubStrs: #('<!--' '-->'))
inject: ''
into: [: result : each | result size < each size ifTrue: [each] ifFalse: [result]].
bag _ comment asBag.
rares _ bag select: [: each | (bag occurrencesOf: each) = 1].
^ comment select: [: each | rares includes: each]
手抜き版
contents _ (HTTPSocket httpGet: '
http://www.pythonchallenge.com/pc/def/xyz.html') contents.
comment _ (contents findBetweenSubStrs: #('<!--' '-->'))
inject: ''
into: [: result : each | result size < each size ifTrue: [each] ifFalse: [result]].
^ comment select: [: each | each isLetter]
レベル 3
contents _ (HTTPSocket httpGet: '
http://www.pythonchallenge.com/pc/def/xyz.html') contents.
comment _ (contents findBetweenSubStrs: #('<!--' '-->'))
inject: ''
into: [: result : each | result size < each size ifTrue: [each] ifFalse: [result]].
(((1 to: comment size - 8)
collect: [: idx |
| subCollection |
{ subCollection _ (comment copyFrom: idx to: idx + 8) asOrderedCollection.
#(1 4 7) collect: [: nn | subCollection removeAt: nn]}]
thenSelect: [: each |
(each first allSatisfy: [: char | char isUppercase])
and: [each last allSatisfy: [: char | char isLowercase]]]) collect: [: each |
each last middle]) as: String
レベル 4
nString prevString contents |
nString _ '12345'.
World findATranscript:
nil.
[ contents _ (HTTPSocket
httpGet: '
http://www.pythonchallenge.com/pc/def/xyz.php?nothing=', nString) contents.
contents _ contents asUnHtml withoutTrailingBlanks.
Transcript cr; show: contents.
prevString _ nString.
nString _ contents subStrings last.
(contents findString: 'Divide by two') isZero
ifFalse: [nString _ (prevString asNumber // 2) asString].
nString asInteger isNil ifTrue: [^ contents]] repeat
レベル 5
Python のライブラリを使わなければならないのでここでギブアップか…と思ったのですが、この問題を解くために、もとのモジュールのサブセットに相当するスクリプトを Ruby で書いてくださったかたがおられましたので、これを参考に同様のことを Squeak の Smalltalk で記述しました。オリジナルの Python モジュールや Ruby のコードではクラスを定義しているのですが、その必要もなさそうなので解答の出力を含めた手続き的なものにしました。
参考:
http://d.hatena.ne.jp/teamikl/20050508#p1
/lib/pickle.py
stream mark buffer result char bracketing |
stream _ CrLfFileStream fileNamed: 'xyz.p'.
mark _ OrderedCollection new.
buffer _ Dictionary new.
result _ OrderedCollection new.
bracketing _ [| lastMark |
lastMark _ result at: (result lastIndexOf: mark).
[result last = lastMark] whileFalse: [lastMark addFirst: result removeLast]].
[char _ stream next. stream atEnd] whileFalse: [
char caseOf: {
[$I] -> [result add: stream nextLine asInteger].
[$S] -> [result add: (Compiler evaluate: stream nextLine)].
[$(] -> [result add: mark copy].
[$t] -> [bracketing
value].
[$l] -> [bracketing
value].
[$a] -> [|
value |
value _ result removeLast. result last add:
value].
[$p] -> [buffer at: stream nextLine asInteger put: result last].
[$g] -> [result add: (buffer at: stream nextLine asInteger)].
[$.] -> [stream upToEnd]}].
World findATranscript:
nil.
result first
do: [: lines | lines do: [: line | line last timesRepeat: [Transcript show: line first]]]
separatedBy: [Transcript cr].
((SystemWindow windowsIn: World satisfying: [: window | window isActive]) anyOne
submorphs select: [: morph | morph isKindOf: PluggableTextMorph]) anyOne
font: (TextStyle named: 'Atlanta') defaultFont
レベル 6
nString members repeat contents archive |
nString _ '90052'.
archive _ ZipArchive new readFrom: (FileStream fileNamed: 'xyz.zip').
members _ archive members.
World findATranscript:
nil.
repeat _ true.
[repeat] whileTrue: [
| fileName member |
fileName _ nString, '.txt'.
contents _ ((FileDirectory default directoryNamed: 'xyz') fileNamed: fileName) contents.
contents _ contents asUnHtml withoutTrailingBlanks.
member _ (members select: [: mm | mm fileName = fileName]) anyOne.
Transcript show: member fileComment withSqueakLineEndings.
nString _ contents subStrings last.
nString asInteger isNil ifTrue: [repeat _ false]].
archive close.
((SystemWindow windowsIn: World satisfying: [: window | window isActive]) anyOne
submorphs select: [: morph | morph isKindOf: PluggableTextMorph]) anyOne
font: (TextStyle named: 'Atlanta') defaultFont
レベル 7
form xx gray firstLevelCode firstLevel secondLevelCode secondLevel codeToString |
form _ PNGReadWriter formFromStream: (
HTTPSocket
httpGet: '
http://www.pythonchallenge.com/pc/def/xyz.png'
accept: 'image/
png').
form asMorph openInWorld.
firstLevelCode _ OrderedCollection new.
xx _ 0.
[(gray _ form colorAt: xx @ 50) isGray] whileTrue: [
firstLevelCode add: (gray red * 255) rounded.
xx _ xx + 7].
codeToString _ [: grys | String withAll: (grys collect: [: each | each asCharacter])].
firstLevel _ codeToString
value: firstLevelCode.
secondLevelCode _ ((firstLevel findBetweenSubStrs: #('[' ']')) last subStrings: #($,))
collect: [: each | each asInteger].
secondLevel _ codeToString
value: secondLevelCode.
^ {firstLevel. secondLevel}
レベル 8
残念ながら Squeak システムには bzip2 の移植がまだないのでパス。
レベル 9
first _ #(100 100 100 200 200 200 200 100 100 100).
second _ #(150 150 150 250 250 250 250 150 150 150).
pen _ Pen new defaultNib: 2.
Display fillWhite; restoreAfter: [
pen color: Color brown ; place: first first @ first second.
first pairsDo: [: xx : yy | pen goto: xx @ yy].
pen color: Color darkGray; place: second first @ second second.
second pairsDo: [: xx : yy | pen goto: xx @ yy]]
レベル 10
aa _ [: nn |
|
value rule |
value _ '1'.
rule _ [: curr |
| next |
next _ OrderedCollection new: curr size + 1.
(RunArray newFrom: curr) runsAndValuesDo: [: run : val |
next add: run asString asCharacter; add: val].
next as: String].
nn timesRepeat: [
value _ rule
value:
value].
value].
^ (aa
value: 30) size