CodeIQの「コード美人」に挑戦してみた
腕試しというよりも打ちのめされてることのほうが多いCodeIQでまた挑戦してみました。
問題&解説記事
Ozyさん出題「コード美人」問題の解説と解答コード公開~正統派美人、ビジュアル系美人、カワイイ系美人、自称系美人、数学だ系美人、美白系美人など面白解答多数|CodeIQ MAGAZINE
提出内容
3のn乗と加算でピンときて、シンプルに解いてみました。目指せスリム系。
シンプルイズベストでは?ということで。
上のJavaScriptが提出内容で、下のは解説記事見た後にPowerShellで解いてみたオマケ。
出題者の方からフィードバックでコメントいただきました。
■Ozyよりひとこと
私が解答例として書いたコードも同じでした。
やっぱりコレですよねI
コレですよね!
フィードバックと解説記事までみて思ったこと
アルゴリズムの部分。今回たまたま私は王道を選んでましたが、他にも様々な考え方、解き方がありすぎてビックリしました。
プログラミング言語、JavaScript6名で比較的少数派…。
Rubyのシンプルなソースも見て勉強したくなりましたが、JavaScriptと頭の中ごっちゃになりそうです。
頭の回転早くする練習と考えて、これからも打ちのめされても挑戦し続けます。
CodeIQのジェムストリング問題をPowerShellで解いてみた
結城浩さんがCodeIQで出題したジェムストリング問題。
限られた時間の中で解いて期限ギリギリに提出したのですが、使い慣れたJavaでかつマシンパワーに任せるという力技になってしまいました。
解答・解説を読み、高速化・省力化の手法を改めて学びなおしました。
というわけで、2月中ごろから本格的に手を付けてこれから習得しようとしているPowerShellで、改めてジェムストリング問題を解いてみました。
PowerShellで挑戦されている方は解答pdfの中には記載なかったかと思いますので初!かもしれません。
コード
まだPowerShell初心者丸出しですが生暖かい目でご覧下さい。
# Get-GemDays.ps1 ジェムストリング問題の計算 # usage # > Set-ExecutionPolicy -Scope CurrentUser Unrestricted # > .\Get-GemDays.ps1 # # 対象宝石パターンを発見したか $foundTarget = $false # メモ化の実施有無($true or $false) $memoized = $true #$memoized = $false # 宝石メモ $memo = @{} function Get-GemDays($gems, $target, $depth=0, $prevmatch=$false, $gemKeys=$null) { $days = 0 $match = $false if (!$gemKeys) { $gemKeys = $gems.Keys | %{$_} | sort } # アルファベット順に宝石の組合せ計算 $gemKeys | %{ if (!$match) { $gems.$_-- # メモ化のキー(配列だとうまくいかなかったので文字列) $gemMemoKey = $gems.Values | %{$_} | sort $gemMemoKey = $gemMemoKey -join "," if ($gems.$_ -ge 0) { $days++ # 対象宝石パターンと一致確認 $match = ($depth -eq 0 -or $prevmatch) -and $target[$depth] -eq $_ # 対象宝石パターンと完全一致した場合、以後の処理を行わない if ($match -and $depth -eq ($target.Length-1)) { $foundTarget = $true } if (!$foundTarget) { if (!$match -and $memo.Keys -contains $gemMemoKey -and $memoized) { # Write-Host "Memo-Hit:" $gemMemoKey $memo[$gemMemoKey] $days += $memo[$gemMemoKey] } else { $tmpdays = Get-GemDays $gems $target ($depth+1) $match $gemKeys $days += $tmpdays if (!$match -and $memoized) { $memo[$gemMemoKey] = $tmpdays # Write-Host "Memo-in:" $gemMemoKey $tmpdays } } } } $gems.$_++ } } # Write-Host "gems:" $gems.Values # Write-Host "days:" $days return $days } # "aaabcc" -> @{a=3;b=1;c=2} function Hash-Gems($gemstr) { $hashgems =@{}; $gemstr -split "" | %{if($_ -ne ""){$hashgems[$_]++}} return $hashgems } Measure-Command { # $days = Get-GemDays (Hash-Gems "aaabcc") "" $days = Get-GemDays (Hash-Gems "abbbbcddddeefggg") "eagcdfbe" } Write-Host "days:" $days
実行結果
メモ化有りの場合
約2秒。
> .\Get-GemDays.ps1 Days : 0 Hours : 0 Minutes : 0 Seconds : 2 Milliseconds : 148 Ticks : 21489916 TotalDays : 2.4872587962963E-05 TotalHours : 0.000596942111111111 TotalMinutes : 0.0358165266666667 TotalSeconds : 2.1489916 TotalMilliseconds : 2148.9916 days: 5578864439
メモ化無しの場合
# メモ化の実施有無($true or $false) #$memoized = $true $memoized = $false
に変えて実行。
・・・1時間経ちましたが終わる気配がありません。
気になること
break/continueの動作
for-each内で再帰呼出を行っているが、for-each内にbreakやcontinueを入れたら再帰呼出自体が終了してしまった。
ひとまずはif文のネストで回避したものの、動きが怪しいので余裕があれば調べてみます。
Where-Objectの扱い
「連想配列で、値が1以上のキー取り出し」がWhere-Objectを使ってできないか、気になったので後から調べてみました。
> $a = @{a=3;b=1;c=2;d=0;e=0;f=1} > $a.Keys | Where-Object {$a.$_ -gt 0} a f b c
どうもキー定義順にはならないようで、アルファベット順にするためにsortしています。
コードゴルフに初挑戦してみた (お正月版 各桁総和ダンジョン LV1-3)
「コードゴルフ」
言葉とその意味を知ったのは恐らく5年ほど前だったと思います。
ある目的を達成するための最短コードを競うもので、その魔術的なコードを見て、ただただ呆然とした覚えがあります。
そして2014年。
CodeIQというサービスに登録し、その中にコードゴルフの問題がありました。
今までは魔法の使えない「戦士」のような存在でしたが、この問題に挑戦することで「魔法使い見習い」くらいにはなれるかな?と思い、挑戦してみました。
問題
● 各桁総和の魔法
1から9999まで順に整数が与えられますので、以下の計算結果になる値を求めて、戻してください。
・数値を1桁ずつばらばらにして、和を求める。
・その和が1桁にならなかった場合は、同じ操作を続けて、1桁になるまで計算を行う。
例)
123 → 1+2+3 → 6 を戻す
9876 → 9+8+7+6 → 30 → 3+0 → 3 を戻す● コード入力
function yourCode() {
var arr = [];
for (var i = 1; i <= 9999; i ++) {
arr.push(???);
}
return arr;
}
LV1
挑戦者求む!【JavaScript】お正月版 各桁総和ダンジョン LV1 by クロノス・クラウン合同会社 柳井 政和│CodeIQ
入力欄の文字数:175文字以内
禁止文字:なし
制限無し。
先人の知恵をお借りして最短コードでいけました!
6文字
i%9||9
剰余1-8はTrue扱い→1-8
剰余0の場合はFalse扱い→9、になります。
LV2
挑戦者求む!【JavaScript】お正月版 各桁総和ダンジョン LV2 by クロノス・クラウン合同会社 柳井 政和│CodeIQ
入力欄の文字数:50文字以内
禁止文字:1 2 3 4 5 6 7 8 9
0が禁止されてないのがポイント、ということで「0xA-!0」→「10-1」で9を作りました。
18文字
(i-!0)%(0xa-!0)+!0
LV3
挑戦者求む!【JavaScript】お正月版 各桁総和ダンジョン LV3 by クロノス・クラウン合同会社 柳井 政和│CodeIQ
入力欄の文字数:100文字以内
禁止文字:1 2 3 4 5 6 7 8 9 0 , + % ? : this eval function Function Array join split repeat ' "
制限つきすぎて2晩くらい解けず眠れない日々を過ごしましたが。
「String(undefined).length」 →9という力技で解きました。70文字とか全然ゴルフじゃないです。
70文字
i-(i/String(undefined).length|!i)*String(undefined).length||String(undefined).length
最短コードの黒魔術っぷりに期待してます。
2/5追記
魔法使いの方からリプ頂きました!
@tmftake Lv2: ~-i%~-0xa-~0 (~-でデクリメント、-~でインクリメントを実現するのがポイント) Lv3: 私も最短ではないですが、(z=(~-~!!i)*(~-~!!i))でzに9が代入できます。
2014-02-04 11:07:15 via web to @tmftake
Java Webアプリケーション+jQuery DataTables 1.9.4のbStateSave=trueでCookieに状態保存できない
はまったのでメモ。
事象
Tomcatで動作するJava Webアプリケーション上でjQuery DataTablesを使用しています。
DataTablesでは前回表示した状態を保持する機能がある(以下参照)のですが、Java Webアプリケーションの中で使うと状態保持できず、常に初期状態の表示になってしまいます。
DataTables example
原因
jQuery DataTablesが生成するCookieのキーの一部に「;jsessionid=xxx」が入ってしまうため、保存に失敗する。
参考
When using DataTables in a J2EE application with the state cookie a bug occurs when jsessionid is appended to the URL. Since the cookie name uses the path it ends up including the jsessionid along with it. The bigger issue with this is that jsessionid is by markcuk · Pull Request #59 · DataTables/DataTables · GitHub
ただし、コミット内容を見ると状態の保存の場合のみで状態の読込部分に対応できていない…。
対処
jquery_datatables.jsの以下の部分を修正すると正常動作する。
1. _fnCreateCookie
変更前
/* * Shocking but true - it would appear IE has major issues with having the path not having * a trailing slash on it. We need the cookie to be available based on the path, so we * have to append the file name to the cookie name. Appalling. Thanks to vex for adding the * patch to use at least some of the path */ var aParts = window.location.pathname.split('/'); var sNameFile = sName + '_' + aParts.pop().replace(/[\/:]/g,"").toLowerCase(); var sFullCookie, oData; if ( fnCallback !== null )
変更後
/* * Shocking but true - it would appear IE has major issues with having the path not having * a trailing slash on it. We need the cookie to be available based on the path, so we * have to append the file name to the cookie name. Appalling. Thanks to vex for adding the * patch to use at least some of the path */ var aParts = window.location.pathname.split('/'); var sNameFile = sName + '_' + aParts.pop().replace(/[\/:]/g,"").toLowerCase(); var sFullCookie, oData; /* * Need to remove anything after a semicolon so that the cookie doesn't contain one. * This occurs when jsessionid is appended to the url for example. */ sNameFile = sNameFile.split(';', 1)[0]; if ( fnCallback !== null )
2._fnReadCookie
変更前
var aParts = window.location.pathname.split('/'), sNameEQ = sName + '_' + aParts[aParts.length-1].replace(/[\/:]/g,"").toLowerCase() + '=', sCookieContents = document.cookie.split(';');
変更後
var aParts = window.location.pathname.split('/'), sNameEQ = sName + '_' + aParts[aParts.length-1].replace(/[\/:]/g,"").toLowerCase().split(';', 1)[0] + '=', sCookieContents = document.cookie.split(';');
OracleDBでINSERT/DELETEエラーのテスト
DBエラーが発生した時のアプリの振る舞いをテストするときにDB側に細工して意図的にエラーを発生させることをやりますが、その一つの方法です。
単体テストの度に毎回調べてて、毎回見つからなくて困るのでメモ。
INSERT/DELETE限定ですが、INDEXをUNUSABLEにしてテストしてます。UPDATEの場合はこの方法だとできないので、個別対処してます。
事前準備
SQL>alter table tbl1 move; 表が変更されました。 SQL> select index_name,status from user_indexes where index_name = 'IDX1';
STATUSがUNUSABLEになっていることを確認。
エラー確認
SQL>DELETE FROM tbl1 where col1=1; ORA-01502: 索引'XXX.IDX1'またはそのパーティションが使用不可の状態です。
DELETEでエラーが発生することを確認。
事後のお片付け
SQL>alter index idx1 rebuild; 索引が変更されました。 SQL> select index_name,status from user_indexes where index_name = 'IDX1';
STATUSがVALIDになっていることを確認。
jmeterからWeb接続する際のプロキシサーバ設定
最近ちょこちょこ触るようになったjmeter。
社内のHTTPプロキシサーバがあり、jmeter経由で社外のWebページにアクセスするとアクセスエラーとなってしまったため、jmeterのプロキシサーバの設定方法を調べることになりました。
jmeter自体にもプロキシサーバの機能があるためキーワード検索では調査難航しましたが、マニュアルの中から該当箇所を見つけました。
-H [proxy server hostname or ip address]
-P [proxy server port]
-N [nonproxy hosts] (e.g. *.apache.org|localhost)
-u [username for proxy authentication - if required]
-a [password for proxy authentication - if required]
Example : jmeter -H my.proxy.server -P 8000 -u username -a password -N localhost
Apache JMeter - User's Manual: Getting Started
Windows環境で動かしていたので、Exampleにあるような内容のバッチファイルを作って解決。
ORA-24816の対処。
今日、初めて見た。事象と対処法だけメモ。
事象
BLOB列とVARCHAR2(4000)列を持つAテーブルに、それぞれ最大サイズのデータをINSERTしようとしたところ、ORA-24816発生。
ORA-24816: 実際のLONGまたはLOB列の後に、指定されたLONG以外のバインド・データが拡張されました
閾値は見てないけど、こんな感じで事象再現。
・BLOB列:8000バイト、VARCHAR2(4000)列:4000バイトだと再現
・BLOB列:1000バイト、VARCHAR2(4000)列:4000バイトだと再現しない
・BLOB列:8000バイト、VARCHAR2(4000)列:1000バイトだと再現しない
対処法
回避方法は、INSERT、UPDATEのカラム順をLOB型を最後に配置するようにすると成功したと書かれていました。
とりあえず検証したところ、問題なく登録できましたしました。。#ORA-24816
insert into TABLE01(data2, title, data1, id)values(?, ?, ?, ?)
#成功
insert into TABLE01(id, title, data1, data2)values(?, ?, ?, ?)
(UPDATEも同様に成功)
Oracle Technology Network (OTN) Japan - 掲示板 : ORA-24816: ...
ホントかよ、と疑いながらBLOB列を後ろにしたら解決。
S2JDBCの制約上、一番後ろにはできなかったけどVARCHAR2(4000)列の後ろにしたら再現しなかったので解決ってことで。