POH vol.7

ヤバい嫁ドロイドがかわいい。

水着

最初は小難しく考えてたけど、意外とすんなり解いた。でもrubyのおかげっていう点が多い気がする。
https://paiza.jp/poh/ando/share/2a940576

def answer(n)
    return 1 if n < 2
    t = (2..n).to_a
    until t.size == 1
        t = t.each_slice(10).map {|v| 
            f = v.compact.inject(1,&:*)
            f /= 10 while f % 10 == 0
            f % 10 ** 11
        }
    end
    t.first % 10 ** 9
end
puts answer(gets.to_i)

基本的には小分けにして積をとって末尾の0を削るというのを繰り返す。
10個ずつ取ると5の倍数が2つ含まれるけど、2,4,6,8の倍数が必ず含まれるので、5^7までは確実に削れる。

一回目のループでは小分けにした計算結果に5の倍数が含まれる場合もあるだろうけど、
余裕をもって10の11乗位で割って、最後に10の9乗で余りをとればよい。

コーナーケースがありそうだけど、5 ** 8とかでも大丈夫だった。

サンタ

最初each_consとeach_slice間違えたのは内緒。
https://paiza.jp/poh/ando/share/b0b60846

x,y,z,n = gets.split.map(&:to_i)
cx = []
cy = []
n.times do
    d, a = gets.split.map(&:to_i)
    if d == 0
        cx << a
    else
        cy << a
    end
end
cx << 0 << x
cy << 0 << y
cx.sort!
cy.sort!
minx = cx.each_cons(2).map{|i,j| j-i}.min
miny = cy.each_cons(2).map{|i,j| j-i}.min
puts minx * miny * z

メガネ

やっぱりメガネだよね。メガネ Getが一番うれしい。

https://paiza.jp/poh/ando/share/069acb96

m = gets.to_i
mm = m.times.map { gets.split.map(&:to_i) }
n = gets.to_i
nn = n.times.map { gets.split.map(&:to_i) }

(0 .. m - n).each do |ox|
    (0 .. m - n).each do |oy|
        b = (n ** 2).times.all? {|i|
            x,y = i.divmod(n)
            mm[oy + y][ox + x] == nn[y][x]
        }

        if b
            puts "#{oy} #{ox}"
            break
        end
    end
end

AndroidのVolume設定

サンプルとかブログとかみているとAudioManagerから最大ボリュームと現在のボリュームを取得して、割っているのをよく見かけるが、あれは間違いではないかとおもう。

MediaPlayerやSoundPoolのボリュームに1.0fを設定した場合は最大ボリュームと説明しているものがあるが、実際試すとAudioManager#getStreamVolumeの値で再生されている。

基本的には1.0fを設定してやればよいのだとおもうし、DUCKのときは0.5fとか適当に設定してやればよい。

gradle-jenkins-pluginというのを見つけてしまった。

github.com

Jenkinsのジョブ管理をどうしようとおもっていて、JenkinsのJobのDSLとかないかなとか探していたら、上記をみつけてしまった。

Wikiも結構内容が充実しているのでみれば大体わかる。
Job自体はjenkins-cli使えばxml形式でエクスポートできるし、xmlファイルをテンプレートに一部を上書きすることなんかもできるようだ。

またDSLつかって書くこともできる。

結構良さそう。

PKIが本格化しそうな気がする

Legal Tech / Fin Techがすこしづつ現実的になりつつある今日この頃。

ちょっと気持ち悪いけど、契約書をポストすると承認者に通知が飛んで、承認者が承認すると契約書に署名がされるとかいう未来が見える気がする。開発者的にはそれはGitHubのPRとマージ作業なんだけど、それがUI/UXの革新 + Legal Tech/Fin Techと結びつき、企業活動と一体になるみたいな。


kousuke.hatenablog.com
kousuke.hatenablog.com

誰得?だけどTomcatとかでつかうkeystoreのテスト書いてみた。

JKSのファイルが正しくできているかどうかを確かめたくて作ってみた。

JRuby + RSpecで実行する。JRubyあんまりつかったことなくて、to_javaとか、
to_inputstreamで引っかかった。

証明書のインポートがちゃんとできてるか、キーチェインがちゃんと解決できるかを確かめてる。

キーストアにはドメイン名をエイリアスにしてRSA鍵をつくっていて、発行された証明書をインポート、ルート証明書(root)、中間証明書(pubcag3)は括弧内のエイリアスにしている。

require 'spec_helper'
require 'java'

describe "tomcat.jks" do
  let(:keystore_passwd) { "KEYSTORE_PASSWD"}
  let(:keystore_file) { File.new("fixtures/tomcat.jks") }
  subject(:keystore) { java.security.KeyStore.getInstance("jks") }

  it "should be exists" do
    expect( File.exist?(keystore_file)).to be_truthy 
  end

  before do
    file = keystore_file.to_inputstream
    passwd = keystore_passwd.to_java.toCharArray
    keystore.load(file,passwd)
    file.close
  end

  %w/YOUR_DOMAIN root pubcag3/.each do |a|
    it "should has #{a} alias" do
      expect(subject.containsAlias(a)).to be_truthy 
    end
  end
  
  describe "YOUR_DOMAIN" do
    let(:target_cert) { keystore.getCertificate('YOUR_DOMAIN') }
    let(:cert_chain) { keystore.getCertificateChain('YOUR_DOMAIN') }
    let(:root_cert) { keystore.getCertificate('root') }
    let(:pubcag3_cert) { keystore.getCertificate('pubcag3') }

    it "should have key" do
      expect(keystore.isKeyEntry('YOUR_DOMAIN')).to be_truthy
    end

    it "should contains certificate" do
      expect(target_cert).not_to be_nil
    end

    it "should have signed certificate by SHA2withRSA" do
      expect(target_cert.getSigAlgName).to eq('SHA256withRSA')
    end

    it "should have certificate chain." do 
      expect(cert_chain.length).to eq(3) 
    end

    it "should be resolved with certificate chain." do 
      expect(cert_chain).to include(target_cert, pubcag3_cert, root_cert)
    end
  end

end

POH6 霧島ミッション

paiza.jp

動的計画法で解いてるのが多いけど、Union-Find木でといた。
今回のPOHは回文よりも、こっちのがコードゴルフ的にも解法のアプローチ的にもいろいろありそうで好き。

class UnionFind < Hash
  def initialize
    super do |hash,key|
      hash[key] = key
    end
  end
  def union(i,j)
    self[parent(i)] = self[parent(j)]
  end
  def parent(k)
    if k == self[k]
      k
    else
      self[k] = parent(self[k])
    end
  end
  def same?(i,j)
    parent(i) == parent(j)
  end
end

tree = UnionFind.new

n = gets.to_i
map = gets.split.map(&:to_i)
n.times do |i|
  j = i + map[i]
  tree.union(i,j)
end

m = gets.to_i
m.times do
  i = gets.to_i
  puts tree.same?(i,n-1) ? "Yes" : "No"
end


珍しくC++版も書いてみた。昔入門書よんだけどunion予約語だって忘れてた。

#include <iostream>
using namespace std;

#define N 101
#define RANGE(x,l,u) ((x)>=l && (x)<=u)

int group[N];
int parent(int i){
    return i == group[i] ? i : group[i] = parent(group[i]);
}
void merge(int i, int j){
    group[parent(i)] = parent(j);
}
bool same(int i,int j){
    return parent(i) == parent(j);
}

int main(void){
    int n, m, t, q, i;
    for(i = 0; i < N; i++){
        group[i] = i;
    }
    cin >> n;
    for(i = 0; i < n; i++){
        cin >> t;
        if(RANGE(t+i,0,n-1)) merge(i, t + i);
    }
    cin >> m;
    for(i = 0; i < m; i++){
        cin >> q;
        cout << (same(q,n-1) ? "Yes" : "No") << endl;
    }
    return 0;
}

Google Appsで対象の会議室の予定をメールで送るサンプル

依頼があって作ってみた。要件が違ったので、これはつかわないので貼り付け。



Google Spreadsheetに会議室ID一覧を記入して、対象の会議室の予定をメールで送るサンプル

  • Spreadsheetをつくって、A列に会議室IDをざっと貼り付ける。
  • ツールからスクリプトエディタを立ち上げて上のコードを貼り付ける。
  • mainを定期的に実行するようにする(一日一回)。

会議室IDはメンテナンス的にSpreadsheetがよいかなとおもったのでそうした。
会議室がたくさんあるときは面倒かもしれないけど、地域ごとに別の人に送りたいとかあるかもしれないし。

会議室IDはGoogle Calendarのカレンダー設定から取得する。