読者です 読者をやめる 読者になる 読者になる

tech.guitarrapc.cóm

C#, PowerShell, Unity, Cloud, Serverless Technical Update and Features

第24回◯◯o◯裏番組シェル芸勉強会 を PowerShell と C# でやってみる #シェル芸

久々のシェル芸です。

Bsh on Ubuntu on Windows でやろうと思ったのですが、手元の環境が入らないのでそっとじ...

f:id:guitarrapc_tech:20160827171053p:plain

今回は途中で飽きるまでということで、やってみました。

目次

問題

安定の一撃サイトです。

【問題のみ】第24回◯◯o◯裏番組シェル芸勉強会 – 上田ブログ

コード全体

今回の回答です。BoUW かなぁと思いつつ、PowerShell がインストールできなかったのでやめました*1

6問まで回答しています。

言語 回答数 環境
C# 1,2,3 問 LinqPad
PowerShell 1,2,3,5,6 問 PowerShell.exe on Windows 10

gist.github.com

回答

縛りは2つ、「ワンライナー」、「ファイル読み込み」、「複数行になっても問題ない」、です。

Q1. Q1ファイルについて、次のような出力を得てください。

Q1 ファイル

玉子 卵 玉子 玉子 玉子 玉子
玉子 玉子 卵 卵 卵 玉子
卵 玉子 卵 玉子 玉子 玉子
卵 玉子 卵 卵 卵 卵
玉子 卵 玉子

出力

玉子:5 卵:1 
玉子:3 卵:3 
玉子:4 卵:2 
玉子:1 卵:5 
玉子:2 卵:1 

PowerShell / C# ともに行ごとに読み取ってほげもげでした。

C# だと、Select して GroupBy して数をまとめて、OrderBy して並びを整えて、Selectで成形した文字列出力です。

f:id:guitarrapc_tech:20160827171539p:plain

PowerShell も同様です。オペレータの挙動が微妙に違うのですが大枠同じです。

f:id:guitarrapc_tech:20160827171909p:plain

Q2. 次のようなテキストについて、繰り返し出てきた文字の2つ目以降を省いて出力してください。

例えばQ2のファイル

へのへのもへじ

の場合、「へのもじ」が正解の出力になります。

これは、C#では .Distinct() を使えば一瞬です。

f:id:guitarrapc_tech:20160827172300p:plain

PowerShell でも同様ですが、二つ一応用意しました。一つはHashtable のキーが重複不許可なことを利用しているのと、同様に Distinct() です。Hashset でもなんでもいいと思いました。

f:id:guitarrapc_tech:20160827172434p:plain

ちなみに using NameSpace を使っていいなら、

using Namespace System.Linq;
cat .\Q2.txt -Encoding utf8 | %{[string]::new([Enumerable]::Distinct([char[]]$_))}

です。

Q3. 第一フィールドをキーにして%%でレコードを区切ってください。
金 日成
キム ワイプ
金 正日
キム タオル
金 正男

というデータを、

%%
キム タオル
キム ワイプ
%%
金 正男
金 正日
金 日成
%%

区切りをテキストで出す意味...は、おいておいてやります。

C# では、初期化変数を用意しちゃいました。なしで書くとどうなるか思いつかない当りできない子です。あと、ずるいと思いつつTuple使ってます。

f:id:guitarrapc_tech:20160827172801p:plain

PowerShell は、awk と同じ要領ですね。

f:id:guitarrapc_tech:20160827173024p:plain

Q4. Q4.xlsxのA1のセルには数字が書いてあります。その数字を出力してください。A4には文字列が書いてあるので余裕がある人はそれも特定してみましょう。

やりません*2

Q5. ファイルQ5について、xに好きな数を代入して各行の式を計算してください。
x + x^2
x + 1/x
x*x*x

余裕のある人は、例えばxに2を代入したければ、

$ echo 2 | ...

というようにecho <代入したい数>から始めてワンライナーで解いてみてください。

echo から初めてと言われた時点で C# はやめて、PowerShell のみで。また、2^2 という構文がないため、Math.Pow(x,2) に書き換えています。

PowerShell の場合、ScriptBlock を Invoke という手と Invoke-Expression を使うのが楽です。C# も似たようなものですね。

今回は Invoke-Expression (iex) を使っています。

f:id:guitarrapc_tech:20160827173345p:plain

Q6. 「玉子」と「卵」の数を数えて、数が少ない方を数が大きい方で置換してください。
卵卵玉子玉子玉子玉子玉子卵卵卵玉子玉子卵玉子玉子玉子玉子卵卵玉子卵玉子卵卵玉子卵玉子

ずるしちゃいました。汎用性がないのであまり好きじゃないのですが。

f:id:guitarrapc_tech:20160827173630p:plain

Q7. 飽きました
Q8. 飽きました

まとめ

C# というか、Linq できれいにつながると楽しいですね。PowerShell でつないでいくよりも可読性が圧倒的に高いのはいいなぁと。

ただ、コードは長くなりがちというのは仕方ないとはいえ感じました。

雑魚回答なので、もっと良い回答をぜひ。

*1:bashではやりません

*2:COM使ったら怒られそうだし。PowerShell はモジュール使っていいなら1 Cmdletでできちゃいます