Ruby

辞書順で何番目か(Ruby)

辞書順(lexicographical order)に並べて何番目か、あるはn番目のものは何か。要素に重複がないとして考える。数列 (1, 2, .... , n) の並べ替えとして解こう。 数列 (a1, .. , an) は辞書順で何番目か。 def number_in_lex_order(ary) n = ary.size return…

約数を求める(Ruby)

prime ライブラリを使う。結果は順不同。 require "prime" def divisors(n) result = [1] doit = ->(pd, acc) { return if pd.empty? x, *xs = pd (0..x[1]).each do |i| e = acc * x[0] ** i result << e doit.(xs, e) end } doit.(n.prime_division, 1) re…

numo-gnuplot sample

qiita.comウィンドウで表示する場合。Linux Mint 20.3。 require "numo/gnuplot" Numo.gnuplot do set terminal: "wxt font 'Noto Sans CJK JP,12'" set title: "グラフのタイトル" set xrange: 0..6 set yrange: 0..60 set xlabel: "x軸のラベル" set ylabe…

単調非減少と単調非増加で配列(Enumerator)を切断する

要するにこれです。 atcoder.jp 配列 A が与えられます。 A を何箇所かで切って、A の連続した部分であるようないくつかの数列に分けます。 この時、分けられたあとの数列は全て、単調非減少または単調非増加な列になっている必要があります。 コード Enumer…

Ractor でフィボナッチ数列

まずは小手調べ takeするまで待って、takeするたびに無限に同じオブジェクトを返してくれる Ractor は、「Pull型通信」を使ってこんな風に作れる。 r = Ractor.new do loop { Ractor.yield 1 } end Array.new(5) { r.take } #=>[1, 1, 1, 1, 1] わかりやすい…

Hit&Blow を Ruby で

qiita.comおもしろそうなので、自分でも書いてみた。 ルール コンピュータの決めた、各桁に重複のない3桁の数を当てるゲーム。 当たらなかった場合、 入力と桁の合っている数字の数を、ヒット 入力と桁は合っていないが重複はしている数字の数を、ブロウ と…

Enumerator#rest みたいなのが欲しい

Ruby の Enumerator で、列挙はひとつずつしかできない。まとめていくつか列挙できるメソッドが欲しい。こんな感じ。 class Enumerator def rest(n=nil) ary = [] case n in nil loop { ary << self.next } in Integer => a a.times { ary << self.next } en…

Ruby の slice が便利になった

Python の [1, 2, 3, 4, 5, 6, 7, 8, 9, 10][1:10:3] #=>[2, 5, 8] って便利ですよね。Ruby でこれをやろうとすると、ちょっと工夫が必要でした。例えばこんな感じに。 1.step(9, 3).map { [*1..10][_1] } #=>[2, 5, 8] しかし、これはいまではこんな風に書…

Ruby でコラッツの問題

ja.wikipedia.org 「コラッツの問題」というのは、自然数 n を取り、 n が偶数なら2で割る n が奇数なら、3倍して1を足す という操作を繰り返したところ、どうなるかという問題。じつはこれは難問で、いまだに解決されていない。いまのところ、初期値が268あ…

いまどきの Ruby なフィボナッチ数列

Enumerator.produceを使います。 fib = Enumerator.produce([1, 1]) { |a, b| [b, a + b] }.lazy.map(&:first) #最初の10個 fib.first(10) #=>[1, 1, 2, 3, 5, 8, 13, 21, 34, 55] #数列の100以上3000未満の部分 fib.drop_while { _1 < 100 }.take_while { _…

Ruby 的に自然な FizzBuzz

まことに FizzBuzz の種は盡きまじ。 fizzbuzz = Enumerator.new {|y| (1..).each do |i| f = (i % 3).zero? b = (i % 5).zero? y << case when f && b then "FizzBuzz" when f then "Fizz" when b then "Buzz" else i.to_s end end } puts fizzbuzz.take(40…

関数を微分して gnuplot で出力(Ruby)

コード。 require "numo/gnuplot" dx = 0.0001 dif = ->(f, x) { (f.(x+dx)-f.(x))/dx }.curry f = ->(x) { x*x-2*x+1 } dif_f = dif.(f) xs = -5.step(5, 0.1).to_a ys1 = xs.map(&f) ys2 = xs.map(&dif_f) Numo.gnuplot do set terminal: :x11 unset :key …

ビット操作メソッド三題(Ruby)

Ruby を使っているとビット操作はあまり必要なのだが、競技プログラミングをやっていたりすると時にはビット操作したくなることもある。で、Ruby をあらためて見てみると(当り前だが)ビット操作も一通り揃っているわけだ。競プロで便利だなと思うのは例え…

RactorEnum の使用例(Ruby)

obelisk.hatenablog.com前回作った RactorEnum を作ってみます。迷路のスタート(S)から水を流し、お宝が水没するたびにお宝の座標と種類を(リアルタイムで)出力するというものです。 幅優先探索で、お宝に到達するたびにre.pipeに流し込みます。 require…

Ractor の Enumerable 化?(Ruby)

オブジェクトを順に Ractor に流し込んで、(無限連鎖の)Enumerable(親クラス)として取り出すというものです。 こんな感じです。 ractor_enum.rb class RactorEnum class End end def initialize @pipe = Ractor.new do loop do e = Ractor.receive if e.…

不思議な"&"(Ruby)

こんなコードが可能なのだな。 (2..10).map(&"5".to_i.method(:to_s)) #=>["101", "12", "11", "10", "5", "5", "5", "5", "5"] やっていることは、"5" を 2~10 進数表記で表現するということですが…。意味はありません。もうひとつ。 (1..5).map(&"Ruby!".m…

Object#method とカリー化で関数型っぽく(Ruby)

Object#method はメソッドをオブジェクト化するものである。 Method は取り出しの対象であるメソッドがなければ作れませんが、Proc は準備なしに作れます。その点から Proc は使い捨てに向き、Method は何度も繰り返し生成する場合に向くと言えます。また内…

メソッドと Proc の相互変換(Ruby)

これらができたからとて、特にうれしいことはない感じです。メソッド→Proc。Object#method と Method#to_proc を使う。 m = 100.method(:to_s) p m #=>#<Method: Integer#to_s(*)> p m.call(2) #=>"1100100" pr = m.to_proc p pr #=>#<Proc:0x000055e967ad8300 (lambda)> p pr.call(16) #=>"64" Proc→メソッド。Proc は無</proc:0x000055e967ad8300></method:>…

最大値をもつものを集める(Ruby)

例えば都道府県名をローマ字化したものから、文字数の最大値と、その文字数をもつすべての県名を得たいとする。そのとき、こんなメソッドを作ってみるといいかも知れない。 module ExEnumerable refine Enumerable do def max_select pool = [] max_num = -F…

Enumerator::Lazy でエラトステネスの篩(Ruby)

Enumerator::Lazy は無限数列を扱うことができるが、それを使って「エラトステネスの篩」をちょっとおもしろく実装できることに気づいた。何はともあれコードである。lazy_prime.rb prime_seq = Enumerator.new do |y| sieve = 2.step.lazy loop do a = siev…

MP3ファイルの分割(ffmpeg, Ruby)

ffmpeg と Ruby を使って、MP3ファイルを分割します。こんな感じ。 cut_mp3.rb file = DATA.gets.chomp ts = DATA.gets.split.map {|t| t.split(":").map(&:to_i)} Dir.chdir(File.dirname(file)) bname = File.basename(file, ".mp3") ts.map {_1 * 3600 + …

ruby 3.0.0preview1 をちょっと使ってみる

環境は Linux Mint 20 です。 Ractor まずは Ractor。 https://github.com/ruby/ruby/blob/master/doc/ractor.md https://github.com/ko1/ruby/blob/ractor/ractor.ja.md 下を見ていじくるとよい。 qiita.com とりあえずこれ。 Ractor.new do 5.times do put…

カーリルAPIで遊んでみる(Ruby)

「カーリル」は全国の図書館の蔵書検索サイトです。APIが用意されているので、Ruby でちょっと遊んでみました。まずはサイトから「アプリケーションキー」を取得して下さい。以下の appkey には、実際に取得したキーが入ります。 図書館の検索 わたしの住ん…

mod p の世界における割り算とは(Ruby)

qiita.com mod p における「逆元」を考えるとよいそう。Ruby で実装する(元は C++)。 def modinv(a, m) b, u, v = m, 1, 0 until b.zero? t = a / b a -= t * b a, b = b, a u -= t * v u, v = v, u end u %= m u += m if u < 0 u end

自然数の約数の個数(Ruby)

自然数の約数の個数は、素因数分解をして求める。Ruby なら、prime ライブラリを require して、Inetger#prime_divisionメソッドを使う。 require "prime" n = 360 puts n.prime_division.inject(1) {|acc, (a, b)| acc * (b + 1)} #=>24

Ruby2D で穴掘り迷路

見てのとおり、穴掘り迷路です。Gem 'ruby2d' を使いました。Ruby2D についてはこちら。コード。 dig_maze.rb require "ruby2d" L = 20 #迷路の大きさ W = L * 2 + 3 Block_w = 10 set width: W * Block_w, height: W * Block_w, fps_cap: 10 blocks = W.tim…

Gem 'Ruby 2D' で遊ぶ(2)

過去記事のプログラムを少し改変したものです。 コード。 ruby2d_sample2a.rb require 'ruby2d' require 'matrix' include Math Width = 500 C = 15 #円の数 R = 20 #円の半径 L = 70 #三角形の外接円の半径 set width: Width, height: Width circles = C.ti…

inject が Enumerator を返さない(Ruby)

例えば true/false の配列をビット列に変換したいとして、こうしたかった。 cond = [true, false, false, true, false, true] cond.inject(0).with_index {|(acc, c), i| c ? acc | 1 << i : acc} #=>TypeError (0 is not a symbol nor a string) injectはブ…

Ruby で同値(必要十分)関係

Ruby で「p と q が同値」あるいは「必要十分」、つまり の関係を表すにはどうしたらよいでしょうか。これはp == qのことでも、p.equal?(q) のことでもありません。ではなくて、 p が T ならば q も T、p が F ならば q も F ということです。T とか F は何…

AOJ 0141 Spiral Pattern (Ruby)

問題。 http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=0141&lang=ja「ぐるぐる模様」を出力します。簡単そうでかなりむずかしかったので、印象に残っています。 6番目の「ぐるぐる模様」 ###### # # # ## # # # # # # # # #### コード。 result…