言語処理100本ノックのUNIXコマンド章を解きました。
Pythonでも解くことを想定されているのかもしれないけど、シェルスクリプトでだけ解きました。
シェルスクリプトで出来るから良いかなって思って。
githubに置いておきます。
言語処理100本ノックを解いていきます。
言語処理100本ノック 2020 (Rev 2) - NLP100 2020
なるべく関数型言語チックに書いているつもりです。再代入はなるたけ避ける。
解答はgithubにも載せておきます。
GitHub - nanjakkun/nlp_100_ans: 言語処理100本ノックの解答
1章 準備運動
このエントリです。
2章 UNIXコマンド
文字列”stressed”の文字を逆に(末尾から先頭に向かって)並べた文字列を得よ.
str = "stressed"[::-1] print(str)
sliceの使い方を知っていれば一瞬。[start:stop:step]。
他言語から来るとstrにreverseってメソッドが欲しくなるかも。
「パタトクカシーー」という文字列の1,3,5,7文字目を取り出して連結した文字列を得よ.
str = "パタトクカシーー"[::2] print(str)
これも前問と同様sliceの使い方知ってれば。
「パトカー」+「タクシー」の文字を先頭から交互に連結して文字列「パタトクカシーー」を得よ.
itr = map(lambda x: x[0] + x[1], zip("パトカー", "タクシー")) print("".join(itr))
zip使いましょう。
“Now I need a drink, alcoholic of course, after the heavy lectures involving quantum mechanics.”という文を単語に分解し, 各単語の(アルファベットの)文字数を先頭から出現順に並べたリストを作成せよ.
import re str1 = "Now I need a drink, alcoholic of course, after the heavy lectures involving quantum mechanics." itr1 = map(lambda str: len(str), re.split(r'[\s,\.]+', str1)) itr2 = filter(lambda x: x > 0, itr1) print(list(itr2))
"Hi He Lied Because Boron Could Not Oxidize Fluorine. New Nations Might Also Sign Peace Security Clause. Arthur King Can.” という文を単語に分解し,1, 5, 6, 7, 8, 9, 15, 16, 19番目の単語は先頭の1文字, それ以外の単語は先頭の2文字を取り出し, 取り出した文字列から単語の位置(先頭から何番目の単語か)への連想配列(辞書型もしくはマップ型)を作成せよ.
import re str1 = "Hi He Lied Because Boron Could Not Oxidize Fluorine. New Nations Might Also Sign Peace Security Clause. Arthur King Can." def to_elemnt_symbol(itr) -> str: idx = itr[0] if (idx in [1, 5, 6, 7, 8, 9, 15, 16, 19]): return itr[1][0], idx else: return itr[1][0:2], idx itr1 = filter(lambda x: len(x) > 0, re.split(r'[\s,\.]+', str1)) itr2 = map(to_elemnt_symbol, enumerate(itr1, 1)) print(dict(itr2))
他言語だとmapWithIndexみたいなのを使うところはPythonではenumerate。
与えられたシーケンス(文字列やリストなど)からn-gramを作る関数を作成せよ. この関数を用い,”I am an NLPer”という文から単語bi-gram,文字bi-gramを得よ.
def word_n_gram(text, num=2): words = text.split(" ") return list(map(lambda i: words[i:i+num], range(len(words)))) def char_n_gram(text, num=2): words = text.replace(" ", "") return list(map(lambda i: words[i:i+num], range(len(words)))) text1 = "I am an NLPer" print(word_n_gram(text1, 2)) print(char_n_gram(text1, 2))
“paraparaparadise”と”paragraph”に含まれる文字bi-gramの集合を, それぞれ, XとYとして求め,XとYの和集合,積集合,差集合を求めよ. さらに,’se’というbi-gramがXおよびYに含まれるかどうかを調べよ.
# 前回の問題で使ったのと同じ関数 def char_n_gram(text, num=2): words = text.replace(" ", "") return list(map(lambda i: words[i:i+num], range(len(words)))) text1 = "paraparaparadise" text2 = "paragraph" X = set(char_n_gram(text1)) Y = set(char_n_gram(text2)) print("union: ", X | Y) print("intersect: ", X & Y) print("diff: ", X - Y) if "se" in X: print("X contains se") if "se" in Y: print("Y contains se")
Set使いましょう。
引数x, y, zを受け取り「x時のyはz」という文字列を返す関数を実装せよ. さらに,x=12, y=”気温”, z=22.4として,実行結果を確認せよ.
def weather(x: int, y: str, z: float) -> str: return f'{x}時の{y}は{z}' print(weather(12, "気温", 22.4))
文字列に変数展開する方法はいくつかあるけどその1つ。
与えられた文字列の各文字を,以下の仕様で変換する関数cipherを実装せよ. - 英小文字ならば(219 - 文字コード)の文字に置換 - その他の文字はそのまま出力 この関数を用い,英語のメッセージを暗号化・復号化せよ.
def cipher(text: str) -> str: def transform_char(ch): if (97 < ord(ch) & ord(ch) < 122): return chr(219 - ord(ch)) else: return ch return "".join(list(map(transform_char, text))) text1 = "lorem ipsum" print(cipher(text1)) print(cipher(cipher(text1)))
decodeとencodeが同じ関数なんですねえ。2回同じのを作用させると元に戻る。
スペースで区切られた単語列に対して,各単語の先頭と末尾の文字は残し, それ以外の文字の順序をランダムに並び替えるプログラムを作成せよ. ただし,長さが4以下の単語は並び替えないこととする. 適当な英語の文(例えば”I couldn’t believe that I could actually understand what I was reading : the phenomenal power of the human mind .”)を与え, その実行結果を確認せよ.
import random def typoglycemia(text) -> str: def shuffle(word) -> str: if (len(word) <= 4): return word else: substr = word[1:-1:] return word[0] + "".join(random.sample(substr, len(substr))) + word[-1] words = text.split(" ") return " ".join(map(shuffle, words)) text1 = "I couldn’t believe that I could actually understand what I was reading : the phenomenal power of the human mind ." print(typoglycemia(text1))
以前流行ったアレですね。
この ぶんょしう は イリギス の ケブンッリジ だがいく の けゅきんう の けっか 、 にんんげ は もじ を にしんき する とき その さしいょ と さいご の もさじえ あいてっれば じばんゅん は めくちちゃゃ でも ちんゃと よめる という けゅきんう に もづいとて わざと もじの じんばゅん を いかれえて あまりす。
ChatGPT(3.5)に解けるのかと思って問題を与えてみたら、大体解けますね。ちょっと間違ってたりするけど。
と言ってもこれは解答をネットにアップしている人は他にもいるので、まあ、って感じではありますが。
速度的には自分で書くより向こうのほうがずっと速いのでこちらの完敗でございます。
題意のとおりreCAPTCHAや画像認証をやめてほしい。
Webサービスで何かのステップの先に進もうとすると人力で画像を読み取って入力しないといけないやつね。
読みづらくした文字を読み取って入力させたり、この◎◎枚の絵の中から●が描かれたものを選べ、みたいなやつ。
正直あの手のものが苦手で、何度も失敗することがよくある。
セキュリティを担保するんだったら他段階認証とかにしてほしい。ログインが必要なサービスだったらそっちのほうが安全だし利用者に負担がかからないと思う。
画像認証なんて攻撃者がちょっと本気を出せば突破できるものだし。
ログイン不要でコメントできるサービスでbotを防ぐのには多少効果があるのかはしれない。
VSCodeのRuby用ExtentionとしてはVSCode Ruby を使っていたんですが、Ruby LSPへの乗り換えを勧められるので乗り換えました。
VSCode Ruby - Visual Studio Marketplace
Ruby LSP - Visual Studio Marketplace
VSCodeのextention画面からRuby LSPインストールします。
Ruby LSPをインストールしてもそのままでは動きません。
なんか”Lockfileがプロジェクト直下に見当たらないよ”的なエラーメッセージが出ます。
VSCodeのMulti-root workspacesを有効にしろと言ってきます。
(なお、1 Workspaceに1 root = 1 projectの場合にはそのまま動くと思います)
workspacesをMulti-rootにするには、workspace直下の.code-workspaceを編集します。
{ "folders": [ { "path": "." } ], }
上記のようにrootが直下1つになっているのを
{ "folders": [ { "path": "project_a" }, { "path": "project_b" }, ], }
のようにします。
Ruby 3.0以降でないと使えないです。
Ruby 2.7以前のプロジェクトを触らないときは効いてくれません・・
また当然ですがプロジェクトの.ruby-versionで指定されたバージョンと同じバージョンのRubyがローカルに必要です。
dockerで開発しているといなかったりするんですよねえ。
なーんかRubyのREPLの色が見づらくて変えられないかなーと思っていたら変えられるとのこと。
reline/doc/reline/face.md at master · ruby/reline · GitHub
$HOME/.irbrc に
if defined? Reline::Face Reline::Face.config(:completion_dialog) do |conf| conf.define :default, foreground: :white, background: :blue conf.define :enhanced, foreground: :white, background: :magenta conf.define :scrollbar, foreground: :white, background: :blue end end
relineがない環境でirbが落ちないようにinstallされているか調べています
Switchの「両手いっぱいに芋の花を」というゲーム、どんな職の組み合わせでもクリアできるらしい、ということで
何なら無職オンリーのPTでもクリアできるんじゃね?
と思い立ってやってみました。
注:無職なんて職業はこのゲームにありません。技能を取得しなければ全職ステータスが同じ上に装備できるものも同じです。
要は技能取得なしの縛りプレイです。
技能を取得しないのでポイントの割り振りに悩まされることはありません。
戦闘中にできることは通常攻撃、通常ガード、構え直し、の3つのみです。
装備をどうするかが攻略の鍵です。
戦闘中にできることは3つ、と言いましたが装備品によっては装備している間だけ技能が使えるようになるものがあります。
このうち複数攻撃できるものは
回復手段も限られていて
になりますが後ろ2つは終盤まで手に入りません。
とはいえ、このゲームは回復よりガードが重要で、回復がないと勝てなかったと思われる戦いは3つだけでした。
初めての小ボス。流石に余裕です。
ウィザードがいると戦利品の凍てつくワンドがとても役立ちますが技能を使えないので無駄です。分解しましょう。
ここまで同じ敵と複数回戦う稼ぎなし、隠しアイテムなしでやってきましたが早々に負けました。
ちょっとずるして「不敗のカトラス」を回収してきてから再戦します。
初めての中ボス。意外と初見で楽勝でした。
事前に雷雨の矛を取っておいたのが良かったです。
とてもつらいです。ガードをしてもスタミナが切れて崩されたりちょっとずつ削られて負けたりします。
ここでポーションベルトを使えばよいということに気づきました。崖下の窪地でどう猛無比の一角獣を狩って素材を集めます。 素材をなかなか落としてくれないのでついでにレベルも上がります。
また、スタミナ切れに対処するために赤いスクトゥムでスタミナを増やします。
ポーションを使う精神力もなくなったところでギリギリ撃破。
前衛
中衛
後衛
小ボスですが地味につらいです。
野生のクラブ、一撃離脱のウォーハンマー、大陸製の杖 + 杖使いのケープを集めてきてちょっとずつ強化して殴り倒しました。
ここから鉄を使って強化していっているので慢性的に鉄不足です。
要らないアイテムはどんどん分解。
3体目の中ボス。
遠距離攻撃しか当たらないので事前に大陸製の弓を2本集めてきて中衛と後衛から攻撃します。
あっさり撃破。
この攻略では必須アイテムの勇壮の革鎧の材料をたまに落とすので落とすまで何度か通いましょう。
倒すのが楽で良かった。
広葉樹林の奥地 B3Fにいます。
召喚が厄介・・なんですが数が増えると連鎖する稲妻の威力が上がるので一網打尽。
広葉樹林の奥地 B2Fにいます。
5体で出てくるのでコイツラも連鎖する稲妻の威力が上がるので一網打尽。
LVが低くて魔力が足りないと生き残ってしまうかもしれません。
この時点でだいぶ防御力の高い寵臣の甲殻鎧の材料を落とします。
こいつもB2Fにいます。
正攻法で倒せました。
こいつよりお供の落とす錨ハンマーが大事。
また近くに悲哀の衣があるので回収しておきましょう。
小ボス。
この時点でもなんとか倒せますが、こいつの落とすものはまだ要らないのでスルーでOK。
召喚してくる骸骨は前衛と中衛の打撃で一撃で処理していきましょう。
ガード不能の攻撃をしてくるので躱さないと死人が出ます。
寵臣の甲殻鎧の回避攻撃で避けるのを祈るしかありません。
それでも当たってしまったらやり直しの運ゲー。
前衛
中衛
後衛
B5Fで腕力の杖が手に入り、腕力の杖 + 杖使いのケープを装備したキャラに勇壮の革鎧が胆勇をかけると火力が跳ね上がります。
さっそく餌食になるのがこのイフリート。
前衛
中衛
後衛
腕力の杖はこの後も大半の戦いにおいて主ダメージソースとなるので優先して強化します。
最深層まで一度たどり着けると悲哀の衣を買うことができるので3人分揃えましょう。
生物にしか効かない攻撃をしてきたら無駄行動になり大幅にアドバンテージを取れます。
LVがある程度あればハームタッチも1回は耐えられるので楽です。
ドロップ率が上がるアイテムを落とすので早めに倒しておきたい敵。
こいつも生物にしか効かない攻撃をしてきます。
前衛
中衛
後衛
火力がほしいので1人は悲哀の衣は装備させずに火力要因にしました。狙われないように祈りましょう。
ここに何度も通って装備を集めましょう。
優先度の高いのは霊峰の槌です。しかも2つ欲しい。献身的なアコライトを狩りまくりましょう。
2つ出るまでにはLVも上がって他の装備もだいたい1個ずつ集まるでしょう。
前衛
中衛
後衛
高い威力の弓なら一撃で1体倒せます(ただしLVと武器の強化が足りないと仕留めきれない)。
但し遠距離攻撃半減の技能を使われると落とせないので使わないときまで逃げてやり直す。
これで2ターンで終わります。
なお、こいつらの落とす円鱗の盾を2つ集めると火炎2発で1ターンで終わります。
こいつら全部、火炎で1ターンキルです。
石化がボーナス行動なので余裕でしょう。
適当に腕力の杖で殴り倒しましょう。
大樹の大盾は2つ集めましょう。
LV40ボスで一番弱いかもしれない。
火吐きを連発で余裕です。
ただし遠距離攻撃大幅カット技は困るので使われそうになったら霊峰の槌の氷結で妨害しましょう。
火吐きできるようになれば余裕です。
不凍マントを人数分作るまで通いましょう。
側面からぶつかって先制攻撃しましょう。
で2ターン目で敵は半壊です。
前衛
中衛
後衛
こいつらは2ターン氷結させればその間に腕力の杖で殴り倒せます。
後衛は1ターン目に中衛に胆勇、2ターン目に敵前衛に氷結。
中衛は1ターン目2ターン目は狙われていればガード、そうでなければ攻撃。
敵が1体になって構え直しのターンで前衛が氷結、後衛が中衛に胆勇。
これでだいたい倒せます。中衛が狙われすぎるとたまに失敗します。
前衛
中衛
後衛
四天王最弱。
命中は低いわ、硬そうに見えて打撃に弱いわ、HP自体も低い。
胆勇かけて3回殴れば終わり。凍結も絡めると2回で終わり。
前衛
中衛
後衛
お供を3体召喚しますが打撃武器ばかりのPTの敵ではありませんでした。
四天王弱い方から2番目。
不凍マントさえ揃っていれば楽。
前衛、中衛
後衛
お供の庇うが厄介だが、氷結で凍らせれば次のターンは動けないのでそこを殴り倒す。
HPが多く、氷結 + 胆勇殴りコンボで倒しきれない。
ということで大樹の大盾で回復しながら持久戦に持ち込みました。
後衛まであまり攻撃が飛んでこないことを良いことに、後衛は回復を捨てて弓で攻撃してます。
相手のHPが減ると攻撃が激化して隙がなかなかないですが、3巡くらいパターンを回ると精神力が切れて通常攻撃しかしなくなるので後はお好きに。
前衛
中衛
後衛
隔世のデーモンと同じ対策で。
HPが1/4減るごとに攻撃パターンが変化しますが、最後の1/4まで減ったところで後衛がやられてしまいました。
しばらく耐えていたらまたも相手の精神力が切れてしまったので後は楽勝。
裏ボス? お供が3体いるのがつらいです。
行動がある程度ランダムなので無駄行動が出るまでやり直せばなんとか。
重装センチネルが1ターン目から庇うとつらく、そうでないときに献身的なアコライト、狼の森の狙撃手を速攻撃破できると勝機が。
前衛
中衛
後衛
前回の続き
ちょっとCSSいじりました。
#entrylist-ad-right-top { position: absolute; right: 0; z-index: 1; top: 32px; } .entrylist-wrapper { width: 100%; } .entrylist-contents-title { min-height: 0px; width: 400px; order: 2; padding: 0; margin: 0; } .entrylist-header-main .entrylist-image-entry .entrylist-contents-title { padding-right: 0; } .entrylist-contents-title a { overflow: hidden; display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; font-size: small; } .entrylist-item { width: 100%; } .entrylist-header-main, .entrylist-item>li { flex-basis: auto; max-width: 100%; width: 100%; } .entrylist-contents-body { max-width: 60%; } .entrylist-item .entrylist-image-entry .entrylist-contents-description, .entrylist-contents-description { text-align: left; overflow: hidden; display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; margin-bottom: 0; } .entrylist-contents-thumb{ display:none; } .entrylist-contents-main { padding: 4px; flex-direction: row; } .entrylist-contents-users { display: inline; text-transform: none; font-size: medium; right: auto; } .entrylist-contents-users a { display: inline; } .entrylist-contents-users span { font-size: 14px; } .entrylist-contents-domain, .river-placement .entrylist-contents-domain { width: 130px; padding: 0.8rem 0 0 0.2rem; order: 1; } .entrylist-contents-meta { padding: 0; order: 0; width: 100px; } .entrylist-contents-meta li { margin-top: 20px; } .entrylist-contents-date { display: none; } .entrylist-contents-tags { display: none; }
特定のドメインの記事は見えなくしたい場合。
例として匿名ダイアリーを非表示にしたい場合。
li.js-keyboard-selectable-item:has(a[href="/site/anond.hatelabo.jp/"]) { display:none; }
はてなブックマークをPCのブラウザで見ると、1行に4つの記事が表示されていて、見るときに視線を左右に移動させないといけないのがちょっとつらい。
1行1記事で基本上から下にだけ視線を移動させれば良いようにしたい。
ということでCSSを無理やり当てて表示を変更してみました。
ちょっとまだガタガタしている部分もありますが、気が向いたら直します。
StylusっていうChrome Extentionを使用しました。(Firefoxにもあります)
特定のサイトのCSSを上書きできるブラウザ拡張は他にもあるのでお好みのものをどうぞ。
.entrylist-wrapper { width: 100%; } .entrylist-contents-title { min-height: 0px; width: 400px; } .entrylist-contents-title a { overflow: hidden; display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; font-size: small; } .entrylist-item { width: 100%; } .entrylist-header-main, .entrylist-item>li { flex-basis: auto; max-width: 100%; width: 100%; } .entrylist-contents-body { width: 50%; } .entrylist-item .entrylist-image-entry .entrylist-contents-description, .entrylist-contents-description { text-align: left; overflow: hidden; display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 3; margin-bottom: 0; } .entrylist-contents-thumb{ display:none; } .entrylist-contents-main { padding: 4px; flex-direction: row; } .entrylist-contents-users { text-transform: none; } .entrylist-contents-users span { font-size: 10.5px; } .entrylist-contents-domain { padding: 0; } .entrylist-contents-meta { padding: 0; } .entrylist-contents-tags { max-width: 200px; padding: 0; }
昔々は本家はてなブックマークも1行に1記事でした。
で。それが今の表示に変わってから元の行表示がほしいユーザーがいて、その人たちに嫁のはてぶっていうサイトが人気だったんですが、そこも閉鎖してしまってました。
既存のPDFにテキストを追加したい・・と思ったことありませんか?
今の時期なら国税庁が配布している確定申告書等のPDFに印字したい、とかでしょうか。
確定申告書等の様式・手引き等(令和5年分の所得税及び復興特別所得税の確定申告分)|国税庁
※なお、私はe-Taxで済ませたので実際のところは確定申告書を印刷したいわけではありません
PDFをjpgなりpngなりのラスター画像にして編集する方法。
画像にしてしまえばいくらでも文字を載せたりすることはできます。
が、欠点としては以下の点が挙げられます
GitHub - mozilla/pdf.js: PDF Reader in JavaScript
pdf.jsはJavaScriptでHTML5のcanvasにPDFを描画するためのライブラリ。
描画してからcanvasのtoDataURLを使うとPNGを出力できるが、当然テキストの情報は失われます。
無理やりpdf.jsが内部で持っているoperationのdataをいじれば内容は編集できるが、素のPDFの情報に近く、編集するのはかなり大変。
https://github.com/Hopding/pdf-lib
jsのコードからテキストを追加できます。
ただしGUIはなく、位置を指定する必要がある(単位はポイント=1/72インチ?)。また文字ごとの間隔を調整したい場合は1文字ずつ印字、になりそう。
既存テキストの編集はできません(対応したいと言っているが3年位開発止まってる)。
https://github.com/julianhille/MuhammaraJS
HummusJSが開発終了してMuhammaraJSに引き継がれた。
C++製ライブラリとそのjsラッパーなのでブラウザでは動作しない(だれかWebAssembly化して・・)
Java製ライブラリ。
テキストの追加は出来る。
コードからPDFにテキスト追加できるライブラリはいくつかありましたが、既存テキストの編集は見つけられませんでした。
タイトルの通り、Chromeのページ内検索で正規表現を使いたい、んですが、今までずっとむず痒さを覚えつつも放置してました。
使いたいケースは主にgithub上でコード読むとき。今まで正規表現で検索したいときはローカルにチェックアウトする、っていう無駄なことしてました。 (リポジトリからコードを探すときはgithubの機能で正規表現で検索できますが、今見てるファイル内を検索したいときに困っていました)
あと、Chromeの検索は大文字小文字区別しないので困ります。
そんなんextention作ってくれてる人いるだろう、と思ったら案の定ありました。ありがとうございます。
https://chromewebstore.google.com/detail/chrome-regex-search/bpelaihoicobbkgmhcbikncnpacdbknn
Firefoxは昔ブラウザ標準の機能で正規表現検索機能あったと思うんだけど少なくとも今はなさそう。大文字小文字の区別はできます。