数を並び替えた最大値(Go言語)
正の整数のリストを与えられたとき、数を並び替えて可能な最大数を返す関数を記述せよ。例えば、[50, 2, 1, 9]が与えられた時、95021が答えとなる。
1時間以内に解けなければプログラマ失格となってしまう5つの問題が話題に | ソフトアンテナブログ
ここで Ruby で解いたものを、Go でもやってみました。
problem1.go
package main import "fmt" import "strconv" func remove(ar []int, i int) []int { tmp := make([]int, len(ar)) copy(tmp, ar) return append(tmp[0:i], tmp[i + 1:]...) } func permutation(ar []int) [][]int { var result [][]int if len(ar) == 1 {return append(result, ar)} for i, a := range ar { for _, b := range permutation(remove(ar, i)) { result = append(result, append([]int{a}, b...)) } } return result } func join(ar []int) (st string) { for _, n := range ar { st += strconv.Itoa(n) } return } func solve(ar []int) int { max := 0 for _, a := range permutation(ar) { n, _ := strconv.Atoi(join(a)) if n > max {max = n} } return max } func main() { fmt.Println(solve([]int{50, 2, 1, 9})) //=>95021 }
Ruby の Module 覚え書き
module Example def a output "inner" end def output(st) puts st end end include Example output "outer" #=>"outer" a #=>"inner"
include
すればモジュール内のメソッドがふつうに使える。
module Example def a output "inner" end def output(st) puts st end module_function :a, :output end Example.a #=>"inner" output "outer" #=>NoMethodError
include
しないなら、module_function
の指定をするなどしないと呼べない。その際、メソッド内部で呼ばれているメソッドも、module_function
の指定をしないと呼べない。なお、module_function
の指定をしても、include
すれば上と同じように呼べる。
自分でこんな解決策も考えた。
obelisk.hatenablog.com
定数と Proc を使うという手もある。
module Example def a Output.("inner") end module_function :a Output = ->(st) {puts st} end Example.a #=>"inner" Example::Output.("outer") #=>"outer" Output.("outer") #=>NameError
Output.()
は外から呼び出そうと思えば呼び出せるが、名前空間を作る目的なら充分に感じる。
Linux Mint 19 へのアップグレード
まず、ディスプレイマネージャが LightDM になっているかの確認が必要なようです。わたしの場合は
$ cat /etc/X11/default-display-manager
で /usr/sbin/mdm
だったので、変更が必要でした。
$ apt install lightdm lightdm-settings slick-greeter
$ apt remove --purge mdm mint-mdm-themes*
$ sudo dpkg-reconfigure lightdm
で、PC を再起動します。すると、ディスプレイマネージャが LightDM に切り替わっています。
そして
$ apt install mintupgrade $ mintupgrade check
でエラーが出なければ、Mint 19 へアップグレード可能ということらしいです。
あとは
$ mintupgrade upgrade
でアップグレードが始まります。
ありゃ、エラー出まくり。
dpkg: error processing package gconf2 (--configure): dependency problems - leaving triggers unprocessed dpkg: dependency problems prevent processing triggers for gconf2: gconf2 depends on dbus-x11; however: Package dbus-x11 is not configured yet. Processing was halted because there were too many errors. E: Sub-process /usr/bin/dpkg returned an error code (1)
とか。さて、ここに従って
$ sudo dpkg --configure -a $ sudo apt-get install -f
してみる。しかし下のコマンドで何も起きない。なのでエイヤッと
$ apt upgrade $ apt dist-upgrade
する。どうやらうまくいったみたいだ。
再起動で Linux Mint 19 を立ち上げる。スタート時のログインを省略。キーリングのパスワードを無効にする。
ログアウトからの自動ログインは簡単にできる方法がまだ見つかっていない。
third-party PPA が消えてしまったので、インストール前に選択して保存していた Upgrade-Backup ディレクトリから PPA を復元する(いや、迂闊だった。あぶないところだったな)。インストール時にエラーが出なければ、自動で更新されていたのかも知れない。
Mint 18 のときの不具合である、新しいカーネルでの画面のちらつきと日本語入力(Mozc)の起動の問題は、Mint 19 では出なくなった。画面のちらつきがなくなったのは、ディスプレイマネージャの変更によるのかも知れない。(結局サスペンド復帰のトラブルがあって、最新のカーネルは使えないことがわかった。)
このブログのデザイン
ベースはオフィシャルテーマの Life。
CSS。
body { background-color: lightyellow; font-family: "メイリオ", serif; } .entry-content p { margin: 9px 0; } .page-index #blog-title { margin: 0px; padding-bottom: 0; } div#blog-title-inner { text-align: left; border-bottom: 1px dashed #BDC4CB; line-height: 1em; } h1#title a { color: peru; font-style: italic; font-size: 26pt; text-shadow: darkgray 3px 3px 4px; margin-left: 30px; } div#container { background-color: lightyellow; width: 100%; } div#content { background-color: lightyellow; } div#content-inner {} article.entry { border: 1px solid lightgreen; padding: 10px; background-color: #FFFBE0; } div.date { text-align: left; } div.date a { color: black; font-size: 13pt; font-weight: bold; color: black; margin-left: 28px; } h1.entry-title { background-color: lightyellow; text-shadow: silver 2px 2px 3px; border: 1px solid peru; border-left: 9px solid peru; text-align: left; margin-left: 20px; margin-right: 20px; padding-left: 20px; font-size: 1.6em; line-height: 1.6em; } header.entry-header { margin-bottom: 15px; } div.entry-content { background-color: white; border: 1px solid lightgreen; margin: 0 20px; max-width: none; padding: 10px; line-height: 1.4em; font-size: 0.95em; } div.categories { text-align: left; margin-bottom: 1px; padding: 2px; padding-left: 28px; } article.entry { margin-bottom: 40px; } .entry-content a.keyword { border-bottom: 1px dotted transparent; } a.keyword:hover { border-bottom-color: lightgreen; } @media (min-width:1020px) {.entry-content pre { margin: 0 0; font-family: "Ubuntu Mono", "Courier New", Consolas, monospace, sans-serif; font-size: 1em; }} .entry-content code { font-family: "Ubuntu Mono", "Courier New", Consolas, monospace, sans-serif; } h3 { border: solid lightgreen; border-width: 0px 0px 1px 7px; padding-left: 10px; } blockquote { background-color: #F7F8F9; margin: 0; } @media (min-width: 1020px) { .entry-content blockquote { margin: 0; }} @media (min-width:1020px) { .page-entry .entry-title { font-size: 1.6em; line-height: 1.6em; }} @media (min-width: 1020px) { .entry-content h3 { font-size: 115%; }} footer.entry-footer { max-width: none; margin: 0 20px; } .hatena-urllist li { padding: 0.2em 0; } div.hatena-module a { color: #5f9a41; } img.large { width: 100%; } img.half { width: 50%; } img.golden { width: 62%; } img.height-golden { width: 46%; }
フッタ HTML。
<script type="text/javascript"> var ndlist = document.querySelectorAll("div.entry-content a"); for (var i = 0; i < ndlist.length; i++) { if (ndlist[i].innerText != "続きを読む") { ndlist[i].setAttribute("target", "_blank"); ndlist[i].setAttribute("style", "color: #5f9a41;"); } } </script> <script type="text/javascript"> var nodes = document.querySelectorAll('a.entry-title-link'); for (var j = 0; j < nodes.length; j++) { var url = nodes[j].getAttribute('href'); var a = document.createElement("a"); a.setAttribute("href", 'http://b.hatena.ne.jp/entry/' + url); a.setAttribute("target", "_blank"); a.innerHTML = '<img src="http://b.hatena.ne.jp/entry/image/' + url + '">'; nodes[j].appendChild(a); } </script>
うんこな電子メール(1)
こんにちは!
おそらくあなたが推測したように、あなたのアカウント*********@yahoo.co.jpは、私があなたからそれをあなたに伝えたように、ハッキングされました。
私は国際的なハッカーグループの一員です。
2018年7月23日から2018年9月17日まで、あなたが訪問した成人のウェブサイトを通じて、作成したウイルスに感染しました。
これまでのところ、あなたのメッセージ、ソーシャルメディアアカウント、メッセンジャーにアクセスできます。
さらに、これらのデータを完全に減衰させました。私たちはあなたの小さな秘密を知っています...ええ、あなたはそれらを持っています。 私たちはあなたの行為を見て、ポルノのウェブサイトに記録しました。 あなたの味はとても変わっています。
しかし、重要なことは、時にはあなたのウェブカメラであなたを録画し、あなたが見たものと録画を同期させることです!
私はあなたの友人、親戚、あなたの親密な人にこのビデオを表示することに興味がないと思う...Bitcoinウォレットに$550を転送する: 19fbzcVjCXSwoCjCfKtjRVHaVrghY7ZmDX
私はそれ以降、あなたの "データ"をすべて消去することを保証します:Dこのメッセージを読むとタイマーが始まります。 あなたは上記の金額を支払うのに48時間を要します。
送金が完了すると、データは消去されます。
そうでない場合は、感染した瞬間に、録画されたすべてのメッセージとビデオが自動的にあなたのデバイス上にあるすべての連絡先に送信されます。常にあなたのセキュリティについて考えるべきです。 このケースでは秘密を守るように教えてくれることを願っています。
自分を大事にして下さい。
下らんヤツらだな。いい加減にしておけ。
UEFI と grub あたりのメモ
nort-wmli.blogspot.comここを参考に…。
$ su パスワード: tomoki-VJF152 tomoki # cd /boot/efi tomoki-VJF152 efi # ls BCD.LOG EFI boot-sav tomoki-VJF152 efi # cd EFI tomoki-VJF152 EFI # ls Boot Microsoft VAIO ubuntu tomoki-VJF152 EFI # ls Boot bootx64.efi tomoki-VJF152 EFI # ls Microsoft Boot tomoki-VJF152 EFI # ls VAIO Boot tomoki-VJF152 EFI # ls ubuntu fw fwupx64.efi grub.cfg grubx64.efi mmx64.efi shimx64.efi tomoki-VJF152 EFI # ls Microsoft/Boot BCD bg-BG el-GR hr-HR memtest.efi ro-RO tr-TR BCD.LOG boot.stl en-GB hu-HU nb-NO ru-RU uk-UA BCD.LOG1 bootmgfw.efi en-US it-IT nl-NL sk-SK zh-CN BCD.LOG2 bootmgr.efi es-ES ja-JP pl-PL sl-SI zh-HK BOOTSTAT.DAT cs-CZ et-EE ko-KR pt-BR sr-Latn-CS zh-TW Fonts da-DK fi-FI lt-LT pt-PT sr-Latn-RS Resources de-DE fr-FR lv-LV qps-ploc sv-SE tomoki-VJF152 EFI # ls VAIO/Boot BCD bootmgr.efi es-ES ja-JP pl-PL sl-SI zh-HK BOOTSTAT.DAT cs-CZ et-EE ko-KR pt-BR sr-Latn-CS zh-TW Fonts da-DK fi-FI lt-LT pt-PT sr-Latn-RS Resources de-DE fr-FR lv-LV qps-ploc sv-SE bg-BG el-GR hr-HR memtest.efi ro-RO tr-TR boot.stl en-GB hu-HU nb-NO ru-RU uk-UA bootmgfw.efi en-US it-IT nl-NL sk-SK zh-CN tomoki-VJF152 EFI # man grub-install | less -X GRUB-INSTALL(8) System Administration Utilities GRUB-INSTALL(8) NAME grub-install - install GRUB to a device SYNOPSIS grub-install [OPTION...] [OPTION] [INSTALL_DEVICE] DESCRIPTION Install GRUB on your drive. --compress[=no,xz,gz,lzo] compress GRUB files [optional] -d, --directory=DIR use images and modules under DIR [default=/usr/lib/grub/<plat‐ form>] --fonts=FONTS install FONTS [default=unicode] --install-modules=MODULES install only MODULES and their dependencies [default=all] -k, --pubkey=FILE embed FILE as public key for signature checking --locale-directory=DIR use translations under DIR [default=/usr/share/locale] --locales=LOCALES install only LOCALES [default=all] --modules=MODULES pre-load specified modules MODULES --themes=THEMES install THEMES [default=starfield] -v, --verbose print verbose messages. --allow-floppy make the drive also bootable as floppy (default for fdX devices). May break on some BIOSes. --boot-directory=DIR install GRUB images under the directory DIR/grub instead of the boot/grub directory --bootloader-id=ID the ID of bootloader. This option is only available on EFI and Macs. --core-compress=xz|none|auto choose the compression to use for core image --disk-module=MODULE disk module to use (biosdisk or native). This option is only available on BIOS target. --efi-directory=DIR use DIR as the EFI System Partition root. --force install even if problems are detected --force-extra-removable force installation to the removable media path also. This option is only available on EFI. --force-file-id use identifier file even if UUID is available --label-bgcolor=COLOR use COLOR for label background --label-color=COLOR use COLOR for label --label-font=FILE use FILE as font for label --macppc-directory=DIR use DIR for PPC MAC install. --no-bootsector do not install bootsector --no-nvram don't update the `boot-device'/`Boot*' NVRAM variables. This option is only available on EFI and IEEE1275 targets. --no-rs-codes Do not apply any reed-solomon codes when embedding core.img. This option is only available on x86 BIOS targets. --no-uefi-secure-boot do not install an image usable with UEFI Secure Boot, even if the system was currently started using it. This option is only available on EFI. --product-version=STRING use STRING as product version --recheck delete device map if it already exists --removable the installation device is removable. This option is only avail‐ able on EFI. -s, --skip-fs-probe do not probe for filesystems in DEVICE Usage: grub-install [OPTION...] [OPTION] [INSTALL_DEVICE] Install GRUB on your drive. --compress[=no,xz,gz,lzo] compress GRUB files [optional] -d, --directory=DIR use images and modules under DIR [default=/usr/lib/grub/<plat‐ form>] --fonts=FONTS install FONTS [default=unicode] --install-modules=MODULES install only MODULES and their dependencies [default=all] -k, --pubkey=FILE embed FILE as public key for signature checking --locale-directory=DIR use translations under DIR [default=/usr/share/locale] --locales=LOCALES install only LOCALES [default=all] --modules=MODULES pre-load specified modules MODULES --themes=THEMES install THEMES [default=starfield] -v, --verbose print verbose messages. --allow-floppy make the drive also bootable as floppy (default for fdX devices). May break on some BIOSes. --boot-directory=DIR install GRUB images under the directory DIR/grub instead of the boot/grub directory --bootloader-id=ID the ID of bootloader. This option is only available on EFI and Macs. --core-compress=xz|none|auto choose the compression to use for core image --disk-module=MODULE disk module to use (biosdisk or native). This option is only available on BIOS target. --efi-directory=DIR use DIR as the EFI System Partition root. --force install even if problems are detected --force-extra-removable force installation to the removable media path also. This option is only available on EFI. --force-file-id use identifier file even if UUID is available --label-bgcolor=COLOR use COLOR for label background --label-color=COLOR use COLOR for label --label-font=FILE use FILE as font for label --macppc-directory=DIR use DIR for PPC MAC install. --no-bootsector do not install bootsector --no-nvram don't update the `boot-device'/`Boot*' NVRAM variables. This option is only available on EFI and IEEE1275 targets. --no-rs-codes Do not apply any reed-solomon codes when embedding core.img. This option is only available on x86 BIOS targets. --no-uefi-secure-boot do not install an image usable with UEFI Secure Boot, even if the system was currently started using it. This option is only available on EFI. --product-version=STRING use STRING as product version --recheck delete device map if it already exists --removable the installation device is removable. This option is only avail‐ able on EFI. -s, --skip-fs-probe do not probe for filesystems in DEVICE --target=TARGET install GRUB for TARGET platform [default=i386-pc] --uefi-secure-boot install an image usable with UEFI Secure Boot. This option is only available on EFI and if the grub-efi-amd64-signed package is installed. -?, --help give this help list --usage give a short usage message -V, --version print program version Mandatory or optional arguments to long options are also mandatory or optional for any corresponding short options. INSTALL_DEVICE must be system device filename. grub-install copies GRUB images into boot/grub. On some platforms, it may also install GRUB into the boot sector. REPORTING BUGS Report bugs to <bug-grub@gnu.org>. SEE ALSO grub-mkconfig(8), grub-mkimage(1), grub-mkrescue(1) The full documentation for grub-install is maintained as a Texinfo man‐ ual. If the info and grub-install programs are properly installed at your site, the command info grub-install should give you access to the complete manual. grub-install (GRUB) 2.02~beta2-36November12017nuxmint1 GRUB-INSTALL(8)
UEFI でブートローダを壊したら
sda1 が ESP だったら(これは調べないといけない)
# mount /dev/sda1 /mnt # grub-install --target=x86_64-efi --efi-directory=/mnt --bootloader-id=grub
とかかな…。
現在の自分の VAIO の ESP は /dev/sdb2 のようだ。つまり Windows 側。Linux の方の ESP で boot しているのではなかったのだな。Windows の方に GRUB を放り込んでいいのかな。というか、いまそうなっているのだからいいらしい。なお、VAIO の BIOS を立ち上げるには [F3] または [F4] を押しながら電源を入れる。
/dev/sda1 が空なので、上の方法で grub-install してみる。しかし /boot/efi が変わらないので、変わりはない。ただ、今度は Windows の方が /dev/sda になった。
/etc/fstab を編集する。
#UUID=1A82-8B7B /boot/efi vfat umask=0077 0 1 UUID=A7F6-B2DF /boot/efi fat32 defaults 0 1
次を実行。
# mount /dev/sdb1 /boot/efi
これではうまくいかない。ちょっと怖いのでこれ以上はやめておく。
Python でフィボナッチ数列
最初の100個のフィボナッチ数のリストを計算する関数を記述せよ。定義では、フィボナッチ数列の最初の2つの数字は0と1で、次の数は前の2つの合計となる。例えば最初の10個のフィボナッチ数列は、0, 1, 1, 2, 3, 5, 8, 13, 21, 34となる。
1時間以内に解けなければプログラマ失格となってしまう5つの問題が話題に | ソフトアンテナブログ
コード。
def g(): a, b = 0, 1 while True: yield a a, b = b, a + b i = g() def fib(n): return [next(i) for _ in range(n)] print(fib(100))
ジェネレータと内包表記を使ってみた。
obelisk.hatenablog.com
Ruby のクラスメソッド、特異クラスのインスタンス変数
Ruby Gold合格できました。感想と振り返り - 気軽に楽しくプログラムと遊ぶ
ここでちょっとオッと思ったのでメモ。
class MyClass @v = 1 def foo @v #=>nil end class << self @v = 2 # 特異クラスへのメソッド定義はクラスメソッド定義 def foo @v #=>1 end end end p MyClass.foo #=>1 p MyClass.new.foo #=>nil
こうなるわけですね。
ではと疑問に思うのだが、ここでの @v = 2
の値を取り出すことができるのか。この場所で p self
をやると #<Class:MyClass>
となるが、これの意味するところは、self のクラスは Class で、そのインスタンスが MyClass ということである。繰り返すが、これが self なわけだ。ということは、MyClass.singleton_class.instance_variable_get(:@v)
をすれば 2
を得ることができる。
ということは、
class MyClass class << singleton_class def foo @v end end end p MyClass.singleton_class.foo #=>2
で OK ですね!
Qiita のデザインパターンまとめがおもしろかった
qiita.comおもしろかったので自己流にメモしておく。
Template Method
日記を書いて、複数のフォーマットで出力することを考える。日記の内容は、タイトルと何行かの本文、フォーマットは HTML とプレーンテキスト。
class Diary def initialize(title, text) @title = title @text = text end def output_diary output_title output_body_start output_body output_body_end puts end def output_title raise 'Called abstract method: output_title' end def output_body raise 'Called abstract method: output_body' end def output_body_start end def output_body_end end end class HTMLReport < Diary def output_title puts "<title>#{@title}</title>" end def output_body @text.each do |line| puts "<p>#{line}</p>" end end def output_body_start puts '<body>' end def output_body_end puts '</body>' end end class PlainReport < Diary def output_title puts "***#{@title}***" end def output_body @text.each do |line| puts "***#{line}***" end end end title = "2018/9/13" text = ["今日は本屋へ行った。", "夜、デザインパターンのお勉強がおもしろかった。"] diary1 = HTMLReport.new(title, text) diary1.output_diary diary2 = PlainReport.new(title, text) diary2.output_diary
継承を使う。Diary クラス内の空のメソッドは、PlainText では使わないのでこうなっている。これを「フック・メソッド」という。もちろん、共通の処理があればここで処理すればよい。
結果。
<title>2018/9/13</title> <body> <p>今日は本屋へ行った。</p> <p>夜、デザインパターンのお勉強がおもしろかった。</p> </body> ***2018/9/13*** ***今日は本屋へ行った。*** ***夜、デザインパターンのお勉強がおもしろかった。***
Strategy
Template Method は、同じレポートなのにフォーマットごとにちがったオブジェクトを作らねばならない。なので、フォーマットを表すクラスを使えば、Diary オブジェクトは同じで済む。
class Diary attr_reader :title, :text attr_writer :formatter #集約 def initialize(title, text, formatter) @title = title @text = text @formatter = formatter end def output_diary @formatter.output(self) #委譲 end end class HTMLFormatter def output(report) puts "<title>#{report.title}</title>" puts '<body>' report.text.each do |line| puts "<p>#{line}</p>" end print "</body>\n\n" end end class PlainTextFormatter def output(report) puts "***#{report.title}***" report.text.each do |line| puts "***#{line}***" end puts end end title = "2018/9/13" text = ["今日は本屋へ行った。", "夜、デザインパターンのお勉強がおもしろかった。"] diary = Diary.new(title, text, HTMLFormatter.new) diary.output_diary diary.formatter = PlainTextFormatter.new diary.output_diary
レポートを表すオブジェクトはひとつ(diary)で済んでいる。また、フォーマットのクラスは共通の output メソッドをもっていて、Ruby 流のダッグタイピングを使っている。
Observer
オブジェクトの状態が変ったら、他所(Observer)へ通知する。通知する場所は自由に追加、削除できる。
class Man def initialize(name) @name = name @observers = [] end def wake_up(time) @time = time notify_observers end attr_reader :name, :time # それぞれのオブザーバーに変更を通知 def notify_observers @observers.each do |observer| observer.update(self) end end # オブザーバーの追加 def add_observer(observer) @observers << observer end # オブザーバーの削除 def delete_observer(observer) @observers.delete(observer) end end class School def update(man) puts "#{man.name}ですが、#{man.time}に起きました。いまから行きます。" end end class NewYork def update(man) puts "Good morning (?) from #{man.name}. Current time is #{man.time} in Kyoto." end end tomoki = Man.new("Tomoki") tomoki.add_observer(School.new) tomoki.add_observer(NewYork.new) tomoki.wake_up("8:00")
目が覚めたときに Observer(School と NewYork)に現在時刻と名前を通知する。Observer は共通の update メソッドをもっていればよい。ここで通知を受けたときの処理をする。
結果。
Tomokiですが、8:00に起きました。いまから行きます。 Good morning (?) from Tomoki. Current time is 8:00 in Kyoto.
Composite
部品から全体を組み立てる。その中で、一日の外出時間を計算してみる。
class Task attr_reader :name def initialize(name) @name = name end # 所要時間を返すメソッド def get_time_required 0 end end class CompositeTask < Task def initialize(name) super(name) @sub_tasks = [] end def add_sub_task(task) @sub_tasks << task end def remove_sub_task(task) @sub_tasks.delete(task) end def get_time_required @sub_tasks.inject(0) {|time, task| time + task.get_time_required} end end class Library < Task def initialize super("図書館") end def get_time_required 20 end end class BookStore < Task def initialize super("本屋") end def get_time_required 15 end end class MisterDonut < Task def initialize super("ミスタードーナツ") end def get_time_required 10 end end class ReadBook < Task def initialize super("読書") end def get_time_required 45 end end class FoodCourt < CompositeTask def initialize super("フードコート") add_sub_task(MisterDonut.new) add_sub_task(ReadBook.new) end end class AEON < CompositeTask def initialize super("イオンモール") add_sub_task(BookStore.new) add_sub_task(FoodCourt.new) end end class OneDay < CompositeTask def initialize super("今日一日") add_sub_task(Library.new) add_sub_task(AEON.new) end end puts OneDay.new.get_time_required #=>90
Task クラスがいちばん小さい単位。それを CompositeTask クラスで組み立てるだけ。Task クラスを継承しているものを「葉」、CompositeTask クラスを継承しているものを「コンポジット」という。get_time_required メソッドが共通である。それぞれのクラスでは独自のメソッドを他にもってもよい。