「#カレンダープログラミング プチコンテスト 2014」ピックアップ Vol. 1
慧: こんにちは! 「カレンダープログラミング プチコンテスト」の応募されたコードをピックアップして紹介していくよ。これは、別に良い悪いって話じゃないからね! たくさん応募があるから、他の人のコードを参考にアップデートしてもいいし、バグがあったらつっこむのもアリだよ!
現在の応募状況!
10/15 20:15 の時点で、私の例を除くと、こんなに応募があるよ!
- PowerShell 1件
- Python 3件
- SmileBASIC(プチコン) 1件
- Windows cmd.exe 1件
- C# 1件
- VBA (Excel) 2件
- Android (Java) 1件
- Unity (C#) 1件
- Ruby 1件
- Java 1件
- Pascal 1件
- C 4件
- Perl 3件
- Objective-C 1件
- F# 1件
- Tcl 1件
- 一太郎マクロ 1件
- Clojure 1件
- HSP 1件
- PL/SQL 1件
- MSX BASIC 1件
- Forth (GForth) 1件
- Smalltalk 1件
みんなのコードを見るには、Togetter まとめ から。
まだまだ、メジャーなものからマイナーなものまで、オーソドックスなものからトリッキーなものまで、たくさん応募待ってるよ~。
カレンダー表示の基本的な処理?
はじめに、ちょっと確認。カレンダー表示をオーソドックスに記述した場合ポイントになりそうな処理はこんな感じかな?
- 1日目の曜日の取得と1週目の余白表示処理
- 1桁の日の空白パディング処理(があると見た目が良いね)
- 各週の改行処理
- 月の日数の取得と最終日の改行処理
以上を実装した例がこんな感じ。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
static void Main(string[] args) | |
{ | |
var t = DateTime.Today; | |
var offset = (int)t.AddDays(-t.Day + 1).DayOfWeek; // 曜日の取得 | |
var count = DateTime.DaysInMonth(t.Year, t.Month); // 月の日数の取得 | |
Console.Write(new string(' ', offset * 3)); // 1週目の余白 | |
for (var i = 1; i <= count; i++) | |
{ | |
Console.Write(i.ToString().PadLeft(2) + // 1桁の日の空白パディング処理と日の出力 | |
(((i + offset) % 7 == 0 || i == count) ? "\n" : " ")); // 日と日の間の空白出力と各週と最終日の改行処理 | |
} | |
} |
きれいな見た目にしようとすると、最終日が土曜日の時に改行2回連続しないよう注意が必要だね。
日付の操作ができる言語・できない言語
プログラミング言語によって、日付に関するライブラリやクラスの有無、日付の演算ができるかもポイントかな。さらに、言語によっては、カレンダー自体のライブラリやクラスがあったり。
日付関連の操作ができない言語は、上の処理をするには、次の処理がオーソドックスだね。
- 1日目の曜日の取得は「ツェラーの公式」を用いる
- 月の日数の取得は「うるう年の判定」が必要
月が変わった瞬間に実行すると……?
あと、月の最終日から翌月になる瞬間の前後に、正しく動作しそうかも気になるかな。1日目の曜日の取得と、月の日数の取得を、それぞれで「日付の取得」をしていると、おかしなことになりそう。そんなケースは気にしない?
ピックアップ No.1 VBA (Excel)
@pronama こんなのでも良いのでしょうか。http://t.co/Odpu6sBCUU VBA at Excel です。 #カレンダープログラミング GitHubの使い方わかりませんでした…
— みすと / 明衣(あかは) (@mist_akaha) October 12, 2014
ひとつ目は、VBA のコード!
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sub calendar() | |
Row = 1 | |
Col = Weekday(DateSerial(Year(Date), Month(Date), 1)) | |
DaysOfMonth = Day(DateSerial(Year(Date), Month(Date) + 1, 0)) | |
For Current = 1 To DaysOfMonth | |
Cells(Row, Col) = Current | |
Col = Col Mod 7 + 1 | |
If Col = 1 Then Row = Row + 1 | |
Next | |
End Sub |
スッキリした見た目だよね。Excel だと、行と列があるから、1週目の余白分の出力処理が不要で、直接表示する行と列の位置を指定しているね。最終日の改行や、Excel のデフォルトの状態を前提とすると、一桁の日の空白パディング処理も不要だね。
ちょっとだけ短くしようとすると、If Col = 1 Then Row = Row + 1
は、 Row = Row - (Col = 1)
ともできるかな。
もう1件の VBA の応募は、If ステートメントなしで、土日の色付けのオマケ付だよ。
https://twitter.com/Myoga1012/status/521329725868740610
ピックアップ No.2 Android (Java)
@pronama Androidでカレンダープログラミングしてみました。
「プロ生ちゃん #カレンダープログラミング プチコンテスト 2014」 https://t.co/sctDvBaS6a pic.twitter.com/mNHvL9HsDJ— Koji Okabe (@kojiokb) October 12, 2014
次は、1番最初に応募があったアイデア賞! CalendarView を画面に表示させるだけっていう。
基本部分のコードはこんな感じだね。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class PronamaChanCalendarActivity extends Activity { | |
@Override | |
protected void onCreate(Bundle savedInstanceState) { | |
super.onCreate(savedInstanceState); | |
RelativeLayout layout = new RelativeLayout(this); | |
setContentView(layout); | |
addContentView(new CalendarView(this), | |
new RelativeLayout.LayoutParams( | |
ViewGroup.LayoutParams.MATCH_PARENT, | |
ViewGroup.LayoutParams.MATCH_PARENT)); | |
} | |
} |
ピックアップ No.3 Unity (C#)
@pronama Unity初心者ですが作りました。http://t.co/pJIb6j6TvR src: https://t.co/4QZ4VyMTSL 「プロ生ちゃん #カレンダープログラミング プチコンテスト 2014」
— すか (@sukaaaaaaaaa) October 12, 2014
Unity 製の大作が!? 絶対カレンダーの用紙に収まりきらないよね。
コレ、マスコットアプリ文化祭 にも応募できるよ。
ピックアップ No.4 PHP
PHPって初めて触りました。短かく書けるのですね。 http://t.co/5YmdstnO0V @pronama #カレンダープログラミング
— みすと / 明衣(あかは) (@mist_akaha) October 13, 2014
次は PHP。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
echo str_repeat("\t", $fwday = date("w", mktime(0, 0, 0, date('n'), 1, date('Y')))); | |
for ($day = 1; checkdate(date('n'), $day, date('Y')); $day++) | |
echo ($day < 10 ? " " : "") . $day. (($day + $fwday) % 7 == 0 ? "\n" : "\t"); | |
?> |
オーソドックスなコードと違うポイントは、最終日を取得してないところ。checkdate 関数を使って、「2014/10/32」みたいな不正な日付になった時点でループ処理を終わるようにしているね。これは、他でも使えるコードを短くするテクニックかも?
以上、Vol.1 は、ここまで! まだまだ、コードを紹介していくから待っててね。関数型言語編とかレトロな言語編とかできそうな勢いだね。
最新記事 by kei (全て見る)
- プロ生ちゃんチョコプログラミングコンテスト2024開催! - 2024/02/13
- HSP プログラムコンテスト2023 結果発表&プロ生ちゃん賞発表! #hsp3 - 2023/12/04
- プロ生ちゃんクリスマスプログラミングコンテスト2023開催! - 2023/12/04