Paizaのオンラインハッカソンやってみた
土日特にすることもなく暇なので遊んでた。paiza.jp
1問目
与えられた文字列の基数番目のみを取り出せという問題。
使用言語: Ruby
input_lines = gets chars = input_lines.each_char odds = chars.select.with_index do |e, i| i % 2 == 0 end puts odds.join
これは非常に簡単。どの言語使おうがすぐ書けます。
もしかしたら、「え?2で割り切れるのは偶数じゃないの?」と思うかもしれません。
ただ、プログラミング言語の世界ではインデックスは0から始まるのが主流であるため、この場合は逆転します。
2問目
曜日ごとの売り上げデータが改行区切りで流れてくるのでそれぞれ集計してね、という問題。
使用言語: C#
using System; using System.Collections.Generic; using System.Linq; public class Hello{ public static void Main(){ var line = System.Console.ReadLine(); int max = int.Parse(line); var weekDays = (DayOfWeek[])Enum.GetValues(typeof(DayOfWeek)); var eachWeekDays = new Dictionary<DayOfWeek, List<int>>(); foreach (DayOfWeek weekDay in weekDays) { eachWeekDays[weekDay] = new List<int>(); } for (int i = 0; i < max; i++) { int value = int.Parse(Console.ReadLine()); var week = (DayOfWeek)((i + 1) % 7); eachWeekDays[week].Add(value); } new[]{"Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"} .Select(s => (DayOfWeek)Enum.Parse(typeof(DayOfWeek), s)) .Select(dow => eachWeekDays[dow]) .ToList().ForEach(list => Console.WriteLine(list.Sum())); } }
System.DayOfWeek
列挙体にキャストするために無駄に回りくどいコードになってしまいました。
曜日ごとにList<int>を作って、それぞれに加算していって、最後に合計して出力、と。
正直読みにくい。こんなコード書いた奴は死ねばいいと思う。
3問目
RENA または MINAMI のどちらかを出力しろ、という問題。
正直Brainf*ck使っても5分以内に解ける自信があります。
コメントするべきことがないです。
使用言語: Ruby
puts :RENA
Rubyを使った理由は文字数が少なくて済むから。
4問目
RENAを選んだ場合の問題。
表計算ソフトの架空のシートで、選択した範囲の合計値を出力しろという問題。
選択範囲は複数の場合もありますが、セルの内容はすべて自然数です。
使用言語: C#
using System; using System.Collections.Generic; using System.Linq; public class Hello { public static void Main() { int[] intValues = Console.ReadLine().Trim().Split(' ').Select(int.Parse).ToArray(); int columns = intValues[0]; int rows = intValues[1]; int selections = intValues[2]; Cell[,] cells = new Cell[columns, rows]; for (int y = 0; y < rows; y++) { int[] values = Console.ReadLine().Trim().Split(' ').Select(int.Parse).ToArray(); for (int x = 0; x < columns; x++) { cells[x, y].X = x; cells[x, y].Y = y; cells[x, y].Value = values[x]; } } var selected = new HashSet<Cell>(); for (int i = 0; i < selections; i++) { int[] positions = Console.ReadLine().Trim().Split(' ').Select(v => int.Parse(v) - 1).ToArray(); int startX = positions[0]; int startY = positions[1]; int endX = positions[2]; int endY = positions[3]; cells.Cast<Cell>().Where(c => { return startX <= c.X && c.X <= endX && startY <= c.Y && c.Y <= endY; }) .ToList().ForEach(c => selected.Add(c)); } Console.WriteLine(selected.Sum(c => c.Value)); } } struct Cell { public int X { get; set; } public int Y { get; set; } public int Value { get; set; } }
シート上のセルを表現するCell構造体を定義し、Cell型を持つ2次元配列を宣言、すべての要素に代入していきます。
選択範囲に含まれるセルをHashSet<Cell>
に追加していきます。
HashSetクラス自体が内包するコレクションの重複を許さないため、追加する際に既に追加したかどうか、などと気にする必要がなくて楽です。
そしてHashSetクラスも当然のようにIEnumerable<T>を実装しているためLINQが使えます。
Cell構造体のValueプロパティを合計して出力、と。
余談ですが、この問題の問題文に書かれたプログラミングコードが「なでしこ」で書かれていて、コメントがいちいちエイプリルフールでやれといわんばかりの内容なので、是非一度見てみるといいと思います。
5問目
MINAMIを選んだ場合の問題。
まだやってません。
寝て起きたらやってみたいです。