ブログカスタマイズ備忘録

ブログの 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 同等を手動で

手製でキャプションを付けたい場合、はてなブログと同じスタイルで

4224696333392304878706725602341482782579852840250681098010280137314308584370130707224123599639141511088446087538909603607640194711643596029271983312598737326253555802606991585915229492453904998722256795316982874482472992263901833716778060607011615497886719879858311468870876264597369086722884023654422295243347964480139515349562972087652656069529806499841977448720155612802665404554171717881930324025204312082516817125
フィボナッチ数列の3001番目
とするには、

<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;"がキモ。

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-spacepre-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
}

課題: フィボナッチ数を出力せよ

qiita.com

素朴にやる

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