ブログカスタマイズ備忘録
ブログの a要素をデコれるようにした。具体的には
<span class="deco"><a class="non deco" href="http://hoge.com/">ジャンプするよ</a></span>
のように class で指定する。a要素の class のnon
は、これがあるとオプションの JavaScript による a要素に対する強制的な改変をゆるさない。その JavaScript コードは
var ndlist = document.querySelectorAll("div.entry-content a"); var f = function(e) { return e.hasAttribute("class") && e.classList.contains("non") }; for (var i = 0; i < ndlist.length; i++) { if (ndlist[i].innerText != "続きを読む") { ndlist[i].setAttribute("target", "_blank"); if (!f(ndlist[i])) {ndlist[i].setAttribute("style", "color: #1dbde1;");} } }
というもの。
デザインCSSに
span.deco {border: 2px solid moccasin; padding: 1px 2px 1px; background-color: lemonchiffon;} a.deco {color: darkkhaki; text-decoration: none; font-size: 95%;}
を指定した。
オベリスク備忘録
みたいな感じになる。
はてなブログの caption 同等を手動で
手製でキャプションを付けたい場合、はてなブログと同じスタイルで
とするには、
<figure style="width: 400px;"> <pre style="border: 2px solid red; padding: 10px; white-space: normal; overflow-wrap: break-word;">42246963333923....</pre> <figcaption style="font-size: 95%; opacity: .7; margin: 0 auto 1.5em; text-align: center;">フィボナッチ数列の2001番目</figcaption> </figure>
という感じ。style="font-size: 95%; opacity: .7; margin: 0 auto 1.5em; text-align: center;"
がキモ。
Ruby の net/http のコードを少し読む
require 'net/http' uri = URI.parse("http:example/image.jpg") response = Net::HTTP.get_response(uri) response.code response.body
これで画像がダウンロードできるわけだが、ライブラリを探る。
続きを読むHTML の pre を使って長い文字列を右端で折り返す
4224696333392304878706725602341482782579852840250681098010280137314308584370130707224123599639141511088446087538909603607640194711643596029271983312598737326253555802606991585915229492453904998722256795316982874482472992263901833716778060607011615497886719879858311468870876264597369086722884023654422295243347964480139515349562972087652656069529806499841977448720155612802665404554171717881930324025204312082516817125
HTMLのpre
でスクロールバーを出さずこのようにしたい場合、css はこんな感じ。
pre { width: 400px; border: 2px solid red; padding: 10px; white-space: normal; overflow-wrap: break-word; }
white-space: normal;
とoverflow-wrap: break-word;
が必要。white-space
はpre-wrap
でも折り返すが、スペースや改行の扱いがちがう。
Linux Mint 20.3 に ASDF で Elixir をインストールする
簡単に apt で入れようと思ったのですが、なぜかうまくいかなかったので、せっかくなので ASDF を使って入れてみました。ASDF はバージョン管理システムで、複数のバージョンを管理できます。
asdf-vm.com
ここを参考にしました。
www.pluralsight.com
作業
Elixir には Erlang が必要なので、これもインストールします。
まずは curl と git をいれます。
sudo apt update sudo apt install curl git
まあ、既に入っている人が多いですよね。
ASDF をクローンします。
git clone https://github.com/asdf-vm/asdf.git ~/.asdf
端末を設定します。僕が使っているのは Bash なので、~/.bashrc
の最後の行に以下を追加します。
. $HOME/.asdf/asdf.sh
端末を再起動します。
プラグインをインストールします。
asdf plugin add erlang asdf plugin add elixir
インストールできる Erlang のバージョンを調べます。
asdf list-all erlang
こんな風に出ます。
(...) 24.1 24.1.1 24.1.2 24.1.3 24.1.4 24.1.5 24.1.6 24.1.7 24.2 24.2.1 24.2.2 24.3 25.0-rc1
安定版の最新は24.3
のようなので、これをインストールしてみます。
asdf install erlang 24.3
こんな風に表示されました。(いろいろ出てくるので、備忘録として記録しておきます。)
asdf_24.3 is not a kerl-managed Erlang/OTP installation No build named asdf_24.3 Downloading 24.3 to /home/tomoki/.asdf/downloads/erlang/24.3... % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 652 100 652 0 0 8467 0 --:--:-- --:--:-- --:--:-- 8467 100 102M 100 102M 0 0 4221k 0 0:00:24 0:00:24 --:--:-- 6066k Extracting source code Building Erlang/OTP 24.3 (asdf_24.3), please wait... WARNING: It appears that a required development package 'libssl-dev' is not installed. APPLICATIONS DISABLED (See: /home/tomoki/.asdf/plugins/erlang/kerl-home/builds/asdf_24.3/otp_build_24.3.log) * jinterface : No Java compiler found * odbc : ODBC library - link check failed APPLICATIONS INFORMATION (See: /home/tomoki/.asdf/plugins/erlang/kerl-home/builds/asdf_24.3/otp_build_24.3.log) * wx : wxWidgets was not compiled with --enable-webview or wxWebView developer package is not installed, wxWebView will NOT be available * wxWidgets must be installed on your system. * Please check that wx-config is in path, the directory * where wxWidgets libraries are installed (returned by * 'wx-config --libs' or 'wx-config --static --libs' command) * is in LD_LIBRARY_PATH or equivalent variable and * wxWidgets version is 3.0.2 or above. DOCUMENTATION INFORMATION (See: /home/tomoki/.asdf/plugins/erlang/kerl-home/builds/asdf_24.3/otp_build_24.3.log) * documentation : * xsltproc is missing. * fop is missing. * The documentation cannot be built. Erlang/OTP 24.3 (asdf_24.3) has been successfully built Installing Erlang/OTP 24.3 (asdf_24.3) in /home/tomoki/.asdf/installs/erlang/24.3... You can activate this installation running the following command: . /home/tomoki/.asdf/installs/erlang/24.3/activate Later on, you can leave the installation typing: kerl_deactivate Cleaning up compilation products for Cleaned up compilation products for under /home/tomoki/.asdf/plugins/erlang/kerl-home/builds
いろいろ警告など出ていますが、いちおう Erlang をインストールできたようです。
次は Elixir です。
同じようにインストールできるバージョンを調べます。
asdf list-all elixir
こんな風に出ます。
(...) 1.13.2 1.13.2-otp-22 1.13.2-otp-23 1.13.2-otp-24 1.13.3 1.13.3-otp-22 1.13.3-otp-23 1.13.3-otp-24 main main-otp-22 main-otp-23 main-otp-24 master master-otp-21 master-otp-22 master-otp-23 master-otp-24
otp が付いたバージョンの方がよいらしいので、その最新安定版と思われる1.13.3-otp-24
をインストールします。この24
は、インストールした Erlang のバージョンだと思います。
asdf install elixir 1.13.3-otp-24
これで Elixir がインストールされた筈です。
全体で使うバージョンを指定します。
asdf global erlang 24.3 asdf global elixir 1.13.3-otp-24
global
のところをlocal
に替えれば、そのパスでのみ使われるバージョンが指定できます。
本当にインストールできたのか、試してみます。iex
で Elixir の REPL を立ち上げてみます。
Erlang/OTP 24 [erts-12.3] [source] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:1] [jit] Interactive Elixir (1.13.3) - press Ctrl+C to exit (type h() ENTER for help) iex(1)> IO.puts "Hello, World!" Hello, World! :ok iex(2)>
無事インストールされていました。
AOJ(問題集)26
0272: The Lonely Girl's Lie
むずかしそうだったが、よく考えたら解けてうれしい。
while true n = gets.to_i break if n.zero? as = gets.split.map(&:to_i).sort bs = gets.split.map(&:to_i).sort try = ->{ (1...n).each do |k| l = (k / 2r).ceil min1 = bs[n - l] min2 = as[n - k] return k if min1 < min2 end "NA" } puts try.() end
k
の過半数をl
とすると、相手のmax(l)
の最小値min1
よりも、こちらのmax(k)
の最小値min2
が大きければいい。ソートしておけば、実際には Array#max を使わなくて済む。
0273: Cats Going Straight II
これはまず、柱と壁から、部屋をデータ化しないといけない。あとはグラフの問題に帰着できそう。
0275: Railroad
ダイクストラ法?
0276: Temperature Difference
abs = Array.new(7) { gets.split.map(&:to_i) } puts abs.map { |a, b| a - b }
0277: Ticket Sales
data = Array.new(4) { gets.split.map(&:to_i) } table = [6000, 4000, 3000, 2000] puts data.map { |t, n| table[t - 1] * n }
0278: Admission Fee
n = gets.to_i days = Array.new(n) { gets.split.map(&:to_i) } puts days.map {|x, y, b, p| fee1 = x * b + y * p fee2 = (x * [b, 5].max + y * [p, 2].max) * 4 / 5 [fee1, fee2].min }
0279: A Pair of Prizes
while true n = gets.to_i break if n.zero? capsule = gets.split.map(&:to_i) result = if capsule.all? { |n| n <= 1 } "NA" else capsule.count { |n| n >= 1 } + 1 end puts result end
0280: The Outcome of Bonze
百人一首の「坊主めくり」。Player
クラスを作って、なかなかきれいに書けた。
class Player @@field = nil def self.clear @@field = 0 end def self.field @@field end def initialize @num = 0 end attr_reader :num def draw(card) case card when "M" @num += 1 when "S" @@field += @num + 1 @num = 0 when "L" @num += @@field + 1 @@field = 0 else raise end end end while true n = gets.to_i break if n.zero? deck = gets.chomp Player.clear players = Array.new(n) { Player.new } player = players.cycle deck.each_char { |card| player.next.draw(card) } puts (players.map(&:num).sort + [Player.field]).join(" ") end
0281: Formation
素朴なDFSで解いてみたが、当然のようにTLE。
q = gets.to_i data = Array.new(q) { gets.split.map(&:to_i) } table = [[2, 1, 0], [3, 0, 0], [1, 1, 1]] puts data.map {|rest0| max = 0 try = ->(rest, team=0) { max = [max, team].max 3.times do |i| nxt = rest.zip(table[i]).map { |a, b| a - b } if nxt.all? { |e| e >= 0 } try.(nxt, team + 1) end end } try.(rest0) max }
どうやら、CAN→CCA→CCC の順に詰めていけばいいらしい。そういやそうか。
AOJ(問題集)25
0256: Points for a Perfect Scorer
puts Array.new(10) { gets.to_i }.sum
0257: Railway Ticket
b = gets.split.join.to_i(2) table = {4=>false, 2=>false, 6=>true, 1=>true, 0=>false} puts table[b] ? "Open" : "Close"
0258: Kitchen Garden
簡単そうでむずかしかった!
while true n = gets.to_i break if n.zero? hs = gets.split.map(&:to_i) dif = hs.each_cons(2).map { |a, b| b - a } h = Hash.new(0) dif.each { |d| h[d] += 1 } many_dif = h.key(h.values.max) idx = dif.index { |d| d != many_dif } if idx.zero? && dif[1] == many_dif puts hs[0] else puts hs[idx + 1] end end
0259: All Numbers Lead to 6174
def try(num, co=0) num = "%04d" % num return co if num == "6174" s = num.chars.sort.join try(s.reverse.to_i - s.to_i, co + 1) end while true n = gets.chomp break if n == "0000" if n.chars.uniq.size == 1 puts "NA" else puts try(n.to_i) end end
0261: Mayan Crucial Prediction
西暦とマヤ暦の相互変換。
require "date" Table1 = [20, 20, 18, 20, 1] acc = 1 Table2 = Table1.reverse_each.map { |e| acc *= e }.reverse def we_to_ma(days) result = [] Table2.each do |e| result << days / e days %= e end result[0] %= 13 result.join(".") end def ma_to_we(days) d = Date.new(2012, 12, 21) + days [d.year, d.month, d.day].join(".") end while true s = gets.chomp break if s == "#" d = s.split(".").map(&:to_i) if d.size == 3 days = Date.new(*d) - Date.new(2012, 12, 21) puts we_to_ma(days.to_i) else days = d.zip(Table2).sum { |a, b| a * b } puts ma_to_we(days) end end
0262: Making Sugoroku
WA。自分でもわけわからんコード。→問題を読みちがえていた。
while true max = gets.to_i break if max.zero? n = gets.to_i ds = Array.new(n) { gets.to_i } check = Array.new(n + 1) try = ->(pos) { return true if pos > n return false if check[pos] check[pos] = true step = ds[pos - 1] return true unless step if step.zero? not (1..max).all? { |i| try.(pos + i) } else nxt = pos + step return false if nxt < 0 return true if nxt > n try.(nxt) end } puts try.(0) ? "OK" : "NG" end
0266: Aka-beko and 40 Thieves
Table = {a: {0=>:x, 1=>:y}, x: {0=>nil, 1=>:z}, y: {0=>:x, 1=>nil}, z: {0=>:w, 1=>:b}, w: {0=>:b, 1=>:y}, b: {0=>:y, 1=>:x}} def try(route) now = :a route.each_char do |c| now = Table[now][c.to_i] return "No" unless now end now == :b ? "Yes" : "No" end while true p = gets.chomp break if p == "#" puts try(p) end
0222: Prime Quadruplet
予めすべて計算しておくという方法。
table = [13, 19, 109, 199, 829, 1489, 1879, 2089, 3259, 3469, 5659, 9439, 13009, 15649, 15739, 16069, 18049, 18919, 19429, 21019, 22279, 25309, 31729, 34849, 43789, 51349, 55339, 62989, 67219, 69499, 72229, 77269, 79699, 81049, 82729, 88819, 97849, 99139, 101119, 109849, 116539, 119299, 122209, 135469, 144169, 157279, 165709, 166849, 171169, 187639, 194869, 195739, 201499, 201829, 217369, 225349, 240049, 243709, 247609, 247999, 257869, 260419, 266689, 268819, 276049, 284749, 285289, 294319, 295879, 299479, 300499, 301999, 326149, 334429, 340939, 346399, 347989, 354259, 358909, 361219, 375259, 388699, 389569, 392269, 394819, 397549, 397759, 402139, 402769, 412039, 419059, 420859, 427249, 442579, 444349, 452539, 463459, 465169, 467479, 470089, 477019, 490579, 495619, 500239, 510619, 518809, 536449, 536779, 539509, 549169, 559219, 563419, 570049, 572659, 585919, 594829, 597679, 607309, 622249, 626629, 632089, 632329, 633469, 633799, 654169, 657499, 661099, 663589, 664669, 666439, 680299, 681259, 691729, 705169, 715159, 734479, 736369, 739399, 768199, 773029, 795799, 803449, 814069, 822169, 823729, 829729, 833719, 837079, 845989, 854929, 855739, 857959, 875269, 876019, 881479, 889879, 907399, 930079, 938059, 946669, 954979, 958549, 959479, 976309, 978079, 983449, 1002349, 1003369, 1006309, 1006339, 1008859, 1015369, 1022389, 1022509, 1023949, 1027759, 1043599, 1063969, 1065019, 1068259, 1068709, 1091269, 1093069, 1093999, 1100839, 1117609, 1117819, 1118869, 1120549, 1121839, 1122139, 1126669, 1137889, 1146799, 1155619, 1156039, 1157839, 1163719, 1167709, 1168249, 1170139, 1172029, 1172539, 1173589, 1182289, 1210879, 1228399, 1230379, 1233439, 1246249, 1246369, 1257079, 1272289, 1285519, 1298119, 1322179, 1322599, 1324579, 1329709, 1337269, 1339909, 1340329, 1351249, 1352209, 1358809, 1360789, 1368469, 1381279, 1400809, 1402369, 1410979, 1440589, 1447009, 1451839, 1461409, 1468639, 1508629, 1514329, 1524079, 1525969, 1540969, 1571749, 1573549, 1573939, 1577299, 1584439, 1588759, 1592869, 1603339, 1615849, 1616809, 1621729, 1627609, 1631059, 1653109, 1659109, 1670569, 1678759, 1681879, 1685449, 1691869, 1711819, 1718869, 1727779, 1747729, 1748479, 1749499, 1755829, 1764229, 1780489, 1791739, 1797379, 1798639, 1802659, 1819849, 1830349, 1833529, 1834039, 1837399, 1857679, 1890529, 1902619, 1904479, 1910269, 1912069, 1912459, 1915939, 1917739, 1925389, 1943659, 1954159, 1954369, 1959319, 1979149, 1979899, 2002339, 2007619, 2007919, 2016409, 2020729, 2050339, 2062009, 2063779, 2065579, 2075839, 2079199, 2083519, 2084449, 2087389, 2107669, 2116579, 2136139, 2141809, 2143489, 2144509, 2157739, 2159239, 2168659, 2176639, 2177509, 2193889, 2202799, 2203969, 2223679, 2225059, 2246149, 2248249, 2256349, 2262979, 2266639, 2289649, 2290039, 2294059, 2303599, 2340259, 2342779, 2362279, 2373409, 2376169, 2381089, 2403889, 2413429, 2418679, 2423419, 2443789, 2458669, 2470339, 2478529, 2479669, 2499949, 2508049, 2535109, 2541949, 2546239, 2552119, 2552659, 2561269, 2564329, 2576599, 2594959, 2594989, 2596669, 2604739, 2614069, 2635489, 2668249, 2673529, 2674549, 2679499, 2683789, 2696929, 2704909, 2712379, 2715289, 2728549, 2731699, 2731909, 2759299, 2761729, 2764129, 2790259, 2805169, 2822719, 2839939, 2840269, 2846869, 2849689, 2875339, 2879299, 2893489, 2918569, 2927599, 2927809, 2952799, 2954689, 2989039, 2990839, 3047419, 3058879, 3062209, 3063499, 3066829, 3076399, 3089329, 3092569, 3101479, 3103279, 3129619, 3153589, 3157579, 3171739, 3187609, 3200209, 3207439, 3208819, 3215749, 3224869, 3243349, 3277699, 3295549, 3308959, 3326629, 3328909, 3340879, 3366829, 3371449, 3374479, 3378049, 3400219, 3416059, 3436249, 3437719, 3467539, 3479899, 3512059, 3512239, 3512989, 3513079, 3514549, 3518329, 3550699, 3584929, 3586909, 3593509, 3621469, 3652939, 3669769, 3690529, 3713449, 3727729, 3735169, 3741169, 3798079, 3817819, 3837139, 3837859, 3849829, 3854119, 3894049, 3919219, 3919249, 3951559, 3974359, 3974689, 3975709, 3995449, 3996529, 4015939, 4016569, 4032409, 4039669, 4042609, 4058479, 4059199, 4092709, 4098469, 4110349, 4138249, 4144969, 4155919, 4157899, 4174609, 4185919, 4208629, 4218289, 4224379, 4234429, 4257529, 4262179, 4265089, 4265719, 4285669, 4300189, 4316779, 4326409, 4332619, 4336099, 4353319, 4361479, 4370089, 4377679, 4396789, 4404559, 4405699, 4413589, 4415449, 4453489, 4467019, 4487809, 4510489, 4529389, 4540099, 4543249, 4544209, 4561639, 4575289, 4579879, 4596079, 4606579, 4609309, 4615609, 4627879, 4635979, 4647289, 4660549, 4675249, 4693699, 4706419, 4707979, 4734679, 4740649, 4743709, 4796089, 4809949, 4832419, 4833139, 4852459, 4868659, 4875259, 4900459, 4950139, 4956829, 4959049, 4972069, 4977439, 4997389, 5025079, 5037919, 5047129, 5073379, 5074879, 5146489, 5154769, 5158039, 5168929, 5184799, 5201299, 5205469, 5229409, 5234689, 5239189, 5248099, 5251789, 5253769, 5261749, 5274169, 5274679, 5278579, 5318899, 5327899, 5381869, 5382109, 5417389, 5425759, 5436289, 5450119, 5461999, 5465359, 5484139, 5499079, 5527009, 5610469, 5614159, 5651749, 5675149, 5698579, 5732149, 5733529, 5734699, 5760109, 5774149, 5805259, 5839579, 5841469, 5851429, 5860249, 5892709, 5908459, 5922229, 5928829, 5930929, 5937859, 5938789, 5969659, 5977339, 5986039, 6005899, 6013159, 6016099, 6023659, 6024049, 6054289, 6056209, 6066589, 6102919, 6106489, 6130549, 6136219, 6144379, 6153319, 6156979, 6177889, 6187459, 6193309, 6201499, 6213799, 6250429, 6261379, 6287929, 6297589, 6299149, 6324559, 6329509, 6332869, 6334879, 6359239, 6378139, 6402169, 6404779, 6406579, 6419299, 6438199, 6464209, 6471139, 6474829, 6484069, 6495949, 6498229, 6501799, 6503599, 6509689, 6510199, 6512089, 6528679, 6556609, 6561019, 6578659, 6582469, 6595579, 6600499, 6601789, 6602209, 6613339, 6616789, 6621289, 6631909, 6641359, 6655549, 6655639, 6692269, 6699619, 6700699, 6708859, 6715279, 6715999, 6727549, 6735019, 6740479, 6753829, 6758959, 6760009, 6787639, 6796639, 6843379, 6880879, 6884749, 6900919, 6915199, 6918019, 6918349, 6925159, 6937969, 6942499, 6945559, 6949339, 7014619, 7016749, 7025659, 7027459, 7039849, 7045699, 7051399, 7079719, 7081189, 7097809, 7130869, 7151149, 7159519, 7161859, 7166149, 7177069, 7187779, 7201639, 7235959, 7267459, 7273999, 7286689, 7305379, 7316299, 7328779, 7335949, 7340239, 7348639, 7356079, 7367029, 7369339, 7371649, 7417519, 7422229, 7433059, 7448479, 7464559, 7465489, 7475389, 7477999, 7483789, 7499209, 7527259, 7534069, 7534609, 7537339, 7540459, 7541929, 7545919, 7580389, 7583509, 7599049, 7610929, 7641379, 7645669, 7659019, 7669819, 7681369, 7701769, 7703239, 7734829, 7754899, 7774309, 7802239, 7806439, 7813369, 7814299, 7846549, 7861039, 7879849, 7882879, 7913239, 7934659, 7945039, 7960159, 7961959, 7989469, 8023669, 8059069, 8062009, 8070919, 8101789, 8108539, 8166079, 8178259, 8183899, 8194939, 8208919, 8248069, 8281579, 8312419, 8313919, 8318419, 8326609, 8336599, 8339629, 8344159, 8348539, 8381539, 8385109, 8431069, 8445979, 8460589, 8467639, 8487379, 8497039, 8513179, 8519479, 8540509, 8557729, 8561809, 8568409, 8573449, 8576599, 8594689, 8604649, 8616919, 8619439, 8621869, 8623039, 8648839, 8658109, 8669629, 8677399, 8685379, 8691589, 8717749, 8729059, 8741149, 8748589, 8773159, 8799619, 8827549, 8831989, 8833249, 8844379, 8868529, 8878279, 8898319, 8914189, 8926459, 9020989, 9081469, 9081889, 9083029, 9127639, 9138139, 9146989, 9154969, 9165259, 9220249, 9276859, 9280549, 9291649, 9299449, 9320329, 9324439, 9353299, 9365599, 9369559, 9394969, 9426499, 9439279, 9440449, 9446869, 9463249, 9479419, 9494209, 9503959, 9508069, 9511429, 9538099, 9541999, 9549109, 9550399, 9585889, 9589429, 9600559, 9600589, 9617989, 9627469, 9640489, 9721429, 9723019, 9725959, 9733819, 9739909, 9743479, 9744409, 9750079, 9774469, 9778039, 9783889, 9792709, 9835759, 9876109, 9892039, 9910759, 9917059, 9923989, 9933619, 9950209, 9950539, 9973219] table.reverse! while true n = gets.to_i break if n.zero? puts table.bsearch { |t| t <= n } end
0267: Triangle of Blocks
テトリスのブロック消しみたいなの。
def tri_num(s, nxt=1, k=1) return k if s == nxt return nil if nxt > s tri_num(s, nxt + k + 1, k + 1) end def tri?(field, k) field == (1..k).to_a end while true n = gets.to_i break if n.zero? bs = gets.split.map(&:to_i) k = tri_num(bs.sum) if k co = 0 while true if tri?(bs, k) puts co break else bs.map!(&:pred) bs << bs.size bs.delete(0) co += 1 if co > 10000 puts -1 break end end end else puts -1 end end
0268: Kongo Type
32ビット固定点小数。
q = gets.to_i ss = Array.new(q) { gets.chomp } puts ss.map {|s| bits = "%032b" % s.to_i(16) result = bits[1..24].to_i(2).to_s + "." result = "-" + result if bits[0] == "1" dec0 = bits[25..-1].each_char dec = dec0.enum_for(:inject, 0.0).with_index(1) {|(acc, b), i| acc + b.to_i(2) * (0.5) ** i } result << dec.to_s[2..-1] }
0269: East Wind
これはトップダウンで上手く解けた。自慢自慢。
def inner?(s, e, θ) θ = θ / Math::PI * 180 θ = (θ >= 0) ? θ : 360 + θ if s < 0 (0 <= θ && θ < e) || (s + 360 < θ && θ < 360) elsif e >= 360 (s < θ && θ < 360) || (0 <= θ && θ < e - 360) else s < θ && θ < e end end def reachable?(tree_x, tree_y, hx, hy, w, a, d) tree = Complex(tree_x, tree_y) house = Complex(hx, hy) l, θ = (house - tree).polar l < a && inner?(w - 0.5 * d, w + 0.5 * d, θ) end def my_ume_reachable?(house, wind) reachable?(0, 0, *house, *wind, $du) end def others_unreachable?(house, wind) fu = $ume.none? { |tree| reachable?(*tree, *house, *wind, $du) } fm = $momo.none? { |tree| reachable?(*tree, *house, *wind, $dm) } fs = $sakura.none? { |tree| reachable?(*tree, *house, *wind, $ds) } fu && fm && fs end while true h, r = gets.split.map(&:to_i) break if (h + r).zero? houses = Array.new(h) { gets.split.map(&:to_i) } u, m, s, $du, $dm, $ds = gets.split.map(&:to_i) $ume = Array.new(u) { gets.split.map(&:to_i) } $momo = Array.new(m) { gets.split.map(&:to_i) } $sakura = Array.new(s) { gets.split.map(&:to_i) } winds = Array.new(r) { gets.split.map(&:to_i) } days = houses.map {|house| winds.count {|wind| my_ume_reachable?(house, wind) && others_unreachable?(house, wind) } } m = days.max result = if m.zero? "NA" else days.map.with_index(1) { |d, i| d == m ? i : nil }.compact.join(" ") end puts result end
一発で通って気持ちがよかった。
0270: Modular Query
もっとも素直な解法だと思うが、もちろん時間切れ。
n, q = gets.split.map(&:to_i) cards = gets.split.map(&:to_i) queries = Array.new(q) { gets.to_i } puts queries.map {|n| max = 0 cards.each do |c| e = c % n max = e if max < e end max }
課題: フィボナッチ数を出力せよ
素朴にやる
b, c = ARGV.map(&:to_i) tm = Time.now nxt = 1 + c b1 = 1 s, t = 0, 1 (0..).each do |n| break if Time.now - tm > 1.0 if nxt == n str = s.to_s result = "f(#{n})=" result << if (l = str.length) <= 5 str else str[0, 2] + "(ommit #{l - 4} digits)" + str[-2, 2] end puts result b1 *= b nxt = b1 + c end s, t = t, s + t end
結果。
$ ruby fibo.rb 12 12 f(13)=233 f(24)=46368 f(156)=17(ommit 29 digits)92 f(1740)=19(ommit 360 digits)80 f(20748)=53(ommit 4332 digits)76 f(248844)=93(ommit 52001 digits)08 $ ruby fibo.rb 34 25 f(26)=12(ommit 2 digits)93 f(59)=95(ommit 8 digits)41 f(1181)=29(ommit 243 digits)81 f(39329)=84(ommit 8215 digits)29
一桁足りないな。
他の人のを参考に
https://github.com/angel-p57/qiita-sample/blob/master/fibonacci/plain.rb
require "matrix" b, c = ARGV.map(&:to_i) syscall(37, 1) a = Matrix[[0, 1], [1, 1]] v = (a ** c) * Vector[0, 1] r = 1 loop do x = (a * v)[0] str = x.to_s result = "f(#{r + c})=" result << if (l = str.length) <= 5 str else str[0, 2] + "(ommit #{l - 4} digits)" + str[-2, 2] end puts result r *= b a **= b end
アルゴリズム・パズル(Ruby)
問題
ひとつのテーブルに配置できる最大の人数が10人のとき、1人だけのテーブルができないように100人を配置したい。そのパターン数を求めよ。
なお、分け方のパターンだけ求め、誰がどこに座るかは考えないものとする。例えば6人の場合、[2, 2, 2], [2, 4], [3, 3], [6] の4通りになる。
解いてみた
co = 0 try = ->(left, max) { if left.zero? co += 1 else max.downto(2) do |num| next if left < num try.(left - num, num) end end } try.(100, 10) puts co #=>437420
答えは正しいが、1.3秒ほどかかる。
模範解答
メモ化している。
memo = {} try = ->(left, min) { return memo[[left, min]] if memo[[left, min]] return 0 if left < 0 return 1 if left.zero? co = 0 (min..10).each do |num| co += try.(left - num, num) end memo[[left, min]] = co } puts try.(100, 2) #=>437420
メモ化する前は3.1秒、メモ化後は0.01秒。自分の回答例ではメモ化できない。
AOJ(問題集)24
0230 Ninja Climbing
WA。いいと思うんだけれどなあ。
KABE = 0 HASHIGO = 1 SUBERU = 2 loop do n = gets.to_i break if n.zero? bils = Array.new(2) { gets.split.map(&:to_i) } bil_ck_init = Array.new(n) #trueだと到達済み #aがいま居るビル、bが反対側のビル(0 or 1)。nowは階数、coはジャンプした回数 try = ->(a, b, now, a_bil_ck, b_bil_ck, co) { return nil if a_bil_ck[now] a_bil_ck[now] = true return co if now >= n - 1 && bils[a][now] != SUBERU jump = ->{ f1 = try.(b, a, now + 2, b_bil_ck, a_bil_ck, co + 1) if now + 2 < n f2 = try.(b, a, now + 1, b_bil_ck, a_bil_ck, co + 1) if now + 1 < n f3 = try.(b, a, now, b_bil_ck, a_bil_ck, co + 1) if f1 || f2 || f3 [f1, f2, f3].compact.min else nil end } case bils[a][now] when KABE jump.() when HASHIGO if bils[a][now + 1] != HASHIGO jump.() else try.(a, b, now + 1, a_bil_ck, b_bil_ck, co) end when SUBERU try.(a, b, now - 1, a_bil_ck, b_bil_ck, co) else raise "Error" end } n1 = try.(0, 1, 0, bil_ck_init.dup, bil_ck_init.dup, 0) n2 = try.(1, 0, 0, bil_ck_init.dup, bil_ck_init.dup, 0) puts n1 || n2 ? [n1, n2].compact.min : "NA" end
再帰版もWA。
KABE = 0 HASHIGO = 1 SUBERU = 2 loop do n = gets.to_i break if n.zero? bils = Array.new(2) { gets.split.map(&:to_i) } bil_ck_init = Array.new(n) stack = [[0, 0, bil_ck_init.dup, bil_ck_init.dup, 0], [1, 0, bil_ck_init.dup, bil_ck_init.dup, 0]] result = Float::INFINITY while (tmp = stack.pop) bil, now, a_bil_ck, b_bil_ck, co = tmp loop do break if a_bil_ck[now] a_bil_ck[now] = true if now >= n - 1 && bils[bil][now] != SUBERU result = [result, co].min break end jump = ->{ stack << [1 - bil, now + 2, b_bil_ck, a_bil_ck, co + 1] if now + 2 < n stack << [1 - bil, now + 1, b_bil_ck, a_bil_ck, co + 1] if now + 1 < n stack << [1 - bil, now, b_bil_ck, a_bil_ck, co + 1] } case bils[bil][now] when KABE jump.() break when HASHIGO if bils[bil][now + 1] != HASHIGO jump.() break else now += 1 end when SUBERU now -= 1 else raise "Error" end end end result = "NA" if result == Float::INFINITY puts result end
0231 Dangerous Bridge
loop do n = gets.to_i break if n.zero? persons = Array.new(n) { gets.split.map(&:to_i) } dp = Hash.new(0) persons.each do |m, a, b| dp[a] += m dp[b] -= m end weight = 0 result = "OK" dp.sort.each do |t, w| weight += w if weight > 150 result = "NG" break end end puts result end
0232 Life Game
素朴なDFS。TLE。
loop do x, y, z = gets.split.map(&:to_i) break if x + y + z == 0 vs = gets.split.map(&:to_i) nea = Array.new(z) { gets.split.map(&:to_i) } events = Array.new(y + 1, 0) nea.each do |n, e, a| events[n] = case e when 1 then a * 1000 when 2 then a when 3 then -a else raise "Error" end end q = [[0, 1.0, 0]] mean = 0 while (now = q.pop) pos, p, money = now next if pos >= y e = events[pos] if e >= 1000 q << [pos + e / 1000, p, money] next elsif e.nonzero? tmp = money + e money = [tmp, 0].max mean += p * e if money > 0 end p /= x vs.each do |step| q << [pos + step, p, money] end end puts mean.to_i end
0238 Time to Study
while true t = gets.to_i break if t.zero? n = gets.to_i sfs = Array.new(n) { gets.split.map(&:to_i) } dif = t - sfs.sum { |s, f| f - s } puts dif <= 0 ? "OK" : dif end
0239 Calorie Counting
while true n = gets.to_i break if n.zero? sweets = Array.new(n) { gets.split.map(&:to_i) } limit = gets.split.map(&:to_i) result = sweets.select {|swt| cal = [4, 9, 4].zip(swt[1, 3]).inject(0) { |acc, (a, b)| acc + a * b } [*swt[1, 3], cal].zip(limit).all? { |a, b| a <= b } } puts result.empty? ? "NA" : result.map { |e| e[0] } end
0240 Interest Rates
f1 = ->(y, r) { 1.0 + y * (r / 100.0) } f2 = ->(y, r) { (1.0 + r / 100.0) ** y } while true n = gets.to_i break if n.zero? y = gets.to_i banks = Array.new(n) { gets.split.map(&:to_i) } max = 0 bank_num = nil banks.each do |b, r, t| gold = [f1, f2][t - 1].call(y, r) if max < gold max = gold bank_num = b end end puts bank_num end
0241 Quaternion Multiplication
四元数の積を求める問題。実装は悩んだが、四元数をクラスにして、和と積を定義した。
class Q def initialize(r, i, j, k) @ary = [r, i, j, k] end attr_reader :ary def +(obj) Q.new(*ary.zip(obj.ary).map { |a, b| a + b }) end def *(obj) x = ary.product(obj.ary).map { |a, b| a * b } e = x.each_slice(4).to_a ans = Array.new(4) ans[0] = Q.new(*e[0]) ans[1] = Q.new(-e[1][1],e[1][0],-e[1][3],e[1][2]) ans[2] = Q.new(-e[2][2],e[2][3],e[2][0],-e[2][1]) ans[3] = Q.new(-e[3][3],-e[3][2],e[3][1],e[3][0]) ans.inject(:+) end end while true n = gets.to_i break if n.zero? data_n = Array.new(n) { gets.split.map(&:to_i) } puts data_n.map {|data| a = Q.new(*data[0, 4]) b = Q.new(*data[4, 4]) (a * b).ary.join(" ") } end
0242 Input Candidates
最初、問題の意図を読み違えていた。
while true n = gets.to_i break if n.zero? lines = Array.new(n) { gets.split } k0 = gets.chomp tally = Hash.new(0) lines.inject(:concat).each do |word| tally[word] += 1 end result = tally.select { |k, v| k.start_with?(k0) } .sort_by { |k, v| [-v, k] } .take(5) .map { |e| e[0] } .join(" ") puts result.empty? ? "NA" : result end
0243 Filling Game
頑張ったがTLE。Ruby では通過者なし。
def all?(field) tmp = field.join tmp[0..-2] == tmp[1..-1] end def copy(field) field.map { |row| row.dup } end def push_button(w, h, col0, field) checked = copy(field) q = [[0, 0]] while (po = q.shift) x, y = po checked[y][x] = "." col = field[y][x] field[y][x] = col0 [[1, 0], [0, -1], [-1, 0], [0, 1]].each do |dx, dy| x1 = x + dx y1 = y + dy next if x1 < 0 || y1 < 0 || x1 >= w || y1 >= h next if checked[y1][x1] == "." q << [x1, y1] if field[y1][x1] == col end end end while true x, y = gets.split.map(&:to_i) break if (x + y).zero? field0 = Array.new(y) { gets.split.join } if all?(field0) puts 0 next end table = %w(R G B) q = [] (table - [field0[0][0]]).each { |col| q << [col, 1, copy(field0)] } while (e = q.shift) col, n, field = e push_button(x, y, col, field) if all?(field) puts n break end (table - [field[0][0]]).each { |col| q << [col, n + 1, copy(field)] } end end