ガジェット通信

見たことのないものを見に行こう

【謎解きプログラム】怪盗の現在地を当てよ!【タイムゾーン】解答と解説

DATE:
  • ガジェット通信を≫

【謎解きプログラム】怪盗の現在地を当てよ!【タイムゾーン】

本問題は、「怪盗の現在地を当てよ!」というテーマで、プログラムにちなんだ謎を解くというものでした。

それでは以下、各問題とその解答を見ていきましょう。

問題のオープニング

ある日、出社すると、あなたのPCのログイン画面に、謎の挑戦状が表示されていた。

「24時間以内に謎が解けない場合は、このPCのデータは消失する。

 謎は、あなたが真のプログラマーなら解けるものだ」

これは挑戦状ではなく脅迫状だ!

そこには、見たことのない謎が掲載されていた。

あなたは歴戦のプログラマーとして、データを救うために、この謎に挑むことになった。

説明

現在位置を特定しよう!

画面には、以下の情報が表示されています。

「怪盗が最初にいた場所と現地時間」
「移動に要した時間」
「怪盗が現在いる場所の現地時間」

この情報から、怪盗の現在いる場所を当ててください。

問題1

// 資料:タイムゾーン
UTC-9 アラスカ (US/Alaska)
UTC-5 キューバ (Cuba)
UTC-3 グリーンランド (America/Godthab)
UTC
ロンドン (Europe/London)
UTC+3 カタール (Asia/Qatar)
UTC+7 バンコク (Asia/Bangkok)
UTC+9 日本 (Asia/Tokyo)

// 問題
開始場所
  存在場所:ロンドン
  現地時間:13:00
移動
  移動時間:1:00
現在場所
  存在場所:?
  現地時間:9:00

// 選択肢
キューバ
グリーンランド
ロンドン
カタール
バンコク

地球は丸いため、世界各地で昼や夜のタイミングが異なります。そのため、本初子午線(経度0度0分0秒)の時間を基準にして、各地域で採用されている時間が、どれだけ前か後かを計算します。

こうした時間は協定世界時(UTC)と呼ばれ、「UTC+3」「UTC-3」と書くことで、協定世界時から+3時間、-3時間の地域であることを表しています。

こうした処理は「タイムゾーンの処理」として、プログラミング言語によってはライブラリが用意されています(タイムゾーン:同じ標準時を利用する地域や区分を指す言葉)。

以下、「資料:タイムゾーン」の表を参考にして、怪盗の現在位置を割り出します。

開始場所:「ロンドン」のUTCは「0」。
開始時間:現地時間「13:00」から「0」を引いて、UTCは「13:00」。

移動:UTC「13:00」から「1」時間経過して、UTC「14:00」。

現在時間:現地時間「9:00」からUTC「14:00」を引いて、「-5」時間。
現在場所:「UTC-5」の「キューバ」が正解。

というわけで、1番目の選択肢の『キューバ』が答えになります。

Javaサンプル

以下、サンドボックス(言語は「Java8」)で、実行確認できるコードを示します。コード欄に、下記のコードをコピペして、INPUTは空で、RUNボタンを押してください。

// 参考コード
import java.util.*;
import java.util.stream.Collectors;
import java.text.SimpleDateFormat;

class Main{
// 初期設定
static String strtPos = “Europe/London”;
static String strtTm = “2000-01-01 13:00:00″;
static int
mvTm
= 1;
static int
endTm
= 9;
// TimeZone のリスト
static List tz = Arrays.asList(
“US/Alaska”, “Cuba”, “America/Godthab”, “Europe/London”
,”Asia/Qatar”, “Asia/Bangkok”, “Asia/Tokyo”).stream()
.map(itm -> {return TimeZone.getTimeZone(itm);})
.collect(Collectors.toList());
// main
public static void main(String[]args) throws Exception {
// データ フォーマット
SimpleDateFormat sdf = new SimpleDateFormat(“yyyy-MM-dd HH:mm:ss”);
SimpleDateFormat sdfH = new SimpleDateFormat(“H”);
// カレンダーの初期化
sdf.setTimeZone(TimeZone.getTimeZone(strtPos));
Calendar cal = Calendar.getInstance();
cal.setTime(sdf.parse(strtTm));
// 初期設定の出力
p(sdf.format(cal.getTime()), strtPos, “move ” + mvTm, “end ” + endTm);
sdf.setTimeZone(TimeZone.getTimeZone(“UTC”));
p(sdf.format(cal.getTime()), “UTC start”);
// 移動
cal.set(Calendar.HOUR_OF_DAY, cal.get(Calendar.HOUR_OF_DAY) + mvTm);
p(sdf.format(cal.getTime()), “UTC now”);
p(“———-“);
// 現在地の現地時間を確認
tz.stream().forEach(itm -> {
sdfH.setTimeZone(itm);
boolean isMtch = sdfH.format(cal.getTime()).equals(“” + endTm);
sdf.setTimeZone(itm);
p(sdf.format(cal.getTime()), isMtch ? “o” : “x”, itm.getID());
});
}
// 出力
public static void p(String… a) {
System.out.println(String.join(“, “, a));
}
}

// 出力
2000-01-01 13:00:00, Europe/London, move 1, end 9
2000-01-01 13:00:00, UTC start
2000-01-01 14:00:00, UTC now
———-
2000-01-01 05:00:00, x, US/Alaska
2000-01-01 09:00:00, o, Cuba
2000-01-01 11:00:00, x, America/Godthab
2000-01-01 14:00:00, x, Europe/London
2000-01-01 17:00:00, x, Asia/Qatar
2000-01-01 21:00:00, x, Asia/Bangkok
2000-01-01 23:00:00, x, Asia/Tokyo

問題2

// 資料:タイムゾーン
UTC-9 アラスカ (US/Alaska)
UTC-5 キューバ (Cuba)
UTC-3 グリーンランド (America/Godthab)
UTC
ロンドン (Europe/London)
UTC+3 カタール (Asia/Qatar)
UTC+7 バンコク (Asia/Bangkok)
UTC+9 日本 (Asia/Tokyo)

// 問題
開始場所
  存在場所:日本
  現地時間:13:00
移動
  移動時間:2:00
現在場所
  存在場所:?
  現地時間:9:00

// 選択肢
グリーンランド
ロンドン
カタール
バンコク
日本

以下、「資料:タイムゾーン」の表を参考にして、怪盗の現在位置を割り出します。

開始場所:「日本」のUTCは「+9」。
開始時間:現地時間「13:00」から「+9」を引いて、UTCは「4:00」。

移動:UTC「4:00」から「2」時間経過して、UTC「6:00」。

現在時間:現地時間「9:00」からUTC「6:00」を引いて、「+3」時間。
現在場所:「UTC+3」の「カタール」が正解。

というわけで、3番目の選択肢の『カタール』が答えになります。

Javaサンプル

以下、サンドボックス(言語は「Java8」)で、実行確認できるコードを示します。コード欄に、下記のコードをコピペして、INPUTは空で、RUNボタンを押してください。

// 参考コード
import java.util.*;
import java.util.stream.Collectors;
import java.text.SimpleDateFormat;

class Main{
// 初期設定
static String strtPos = “Asia/Tokyo”;
static String strtTm = “2000-01-01 13:00:00″;
static int
mvTm
= 2;
static int
endTm
= 9;
// TimeZone のリスト
static List tz = Arrays.asList(
“US/Alaska”, “Cuba”, “America/Godthab”, “Europe/London”
,”Asia/Qatar”, “Asia/Bangkok”, “Asia/Tokyo”).stream()
.map(itm -> {return TimeZone.getTimeZone(itm);})
.collect(Collectors.toList());
// main
public static void main(String[]args) throws Exception {
// データ フォーマット
SimpleDateFormat sdf = new SimpleDateFormat(“yyyy-MM-dd HH:mm:ss”);
SimpleDateFormat sdfH = new SimpleDateFormat(“H”);
// カレンダーの初期化
sdf.setTimeZone(TimeZone.getTimeZone(strtPos));
Calendar cal = Calendar.getInstance();
cal.setTime(sdf.parse(strtTm));
// 初期設定の出力
p(sdf.format(cal.getTime()), strtPos, “move ” + mvTm, “end ” + endTm);
sdf.setTimeZone(TimeZone.getTimeZone(“UTC”));
p(sdf.format(cal.getTime()), “UTC start”);
// 移動
cal.set(Calendar.HOUR_OF_DAY, cal.get(Calendar.HOUR_OF_DAY) + mvTm);
p(sdf.format(cal.getTime()), “UTC now”);
p(“———-“);
// 現在地の現地時間を確認
tz.stream().forEach(itm -> {
sdfH.setTimeZone(itm);
boolean isMtch = sdfH.format(cal.getTime()).equals(“” + endTm);
sdf.setTimeZone(itm);
p(sdf.format(cal.getTime()), isMtch ? “o” : “x”, itm.getID());
});
}
// 出力
public static void p(String… a) {
System.out.println(String.join(“, “, a));
}
}

// 出力
2000-01-01 13:00:00, Asia/Tokyo, move 2, end 9
2000-01-01 04:00:00, UTC start
2000-01-01 06:00:00, UTC now
———-
1999-12-31 21:00:00, x, US/Alaska
2000-01-01 01:00:00, x, Cuba
2000-01-01 03:00:00, x, America/Godthab
2000-01-01 06:00:00, x, Europe/London
2000-01-01 09:00:00, o, Asia/Qatar
2000-01-01 13:00:00, x, Asia/Bangkok
2000-01-01 15:00:00, x, Asia/Tokyo

問題3

// 資料:タイムゾーン
UTC-9 アラスカ (US/Alaska)
UTC-5 キューバ (Cuba)
UTC-3 グリーンランド (America/Godthab)
UTC
ロンドン (Europe/London)
UTC+3 カタール (Asia/Qatar)
UTC+7 バンコク (Asia/Bangkok)
UTC+9 日本 (Asia/Tokyo)

// 問題
開始場所
  存在場所:日本
  現地時間:13:00
移動
  移動時間:14:00
現在場所
  存在場所:?
  現地時間:15:00

// 選択肢
アラスカ
キューバ
グリーンランド
ロンドン
カタール
バンコク

以下、「資料:タイムゾーン」の表を参考にして、怪盗の現在位置を割り出します。

開始場所:「日本」のUTCは「+9」。
開始時間:現地時間「13:00」から「+9」を引いて、UTCは「4:00」。

移動:UTC「4:00」から「14」時間経過して、UTC「18:00」。

現在時間:現地時間「15:00」からUTC「18:00」を引いて、「-3」時間。
現在場所:「UTC-3」の「グリーンランド」が正解。

というわけで、3番目の選択肢の『グリーンランド』が答えになります。

Javaサンプル

以下、サンドボックス(言語は「Java8」)で、実行確認できるコードを示します。コード欄に、下記のコードをコピペして、INPUTは空で、RUNボタンを押してください。

// 参考コード
import java.util.*;
import java.util.stream.Collectors;
import java.text.SimpleDateFormat;

class Main{
// 初期設定
static String strtPos = “Asia/Tokyo”;
static String strtTm = “2000-01-01 13:00:00″;
static int
mvTm
= 14;
static int
endTm
= 15;
// TimeZone のリスト
static List tz = Arrays.asList(
“US/Alaska”, “Cuba”, “America/Godthab”, “Europe/London”
,”Asia/Qatar”, “Asia/Bangkok”, “Asia/Tokyo”).stream()
.map(itm -> {return TimeZone.getTimeZone(itm);})
.collect(Collectors.toList());
// main
public static void main(String[]args) throws Exception {
// データ フォーマット
SimpleDateFormat sdf = new SimpleDateFormat(“yyyy-MM-dd HH:mm:ss”);
SimpleDateFormat sdfH = new SimpleDateFormat(“H”);
// カレンダーの初期化
sdf.setTimeZone(TimeZone.getTimeZone(strtPos));
Calendar cal = Calendar.getInstance();
cal.setTime(sdf.parse(strtTm));
// 初期設定の出力
p(sdf.format(cal.getTime()), strtPos, “move ” + mvTm, “end ” + endTm);
sdf.setTimeZone(TimeZone.getTimeZone(“UTC”));
p(sdf.format(cal.getTime()), “UTC start”);
// 移動
cal.set(Calendar.HOUR_OF_DAY, cal.get(Calendar.HOUR_OF_DAY) + mvTm);
p(sdf.format(cal.getTime()), “UTC now”);
p(“———-“);
// 現在地の現地時間を確認
tz.stream().forEach(itm -> {
sdfH.setTimeZone(itm);
boolean isMtch = sdfH.format(cal.getTime()).equals(“” + endTm);
sdf.setTimeZone(itm);
p(sdf.format(cal.getTime()), isMtch ? “o” : “x”, itm.getID());
});
}
// 出力
public static void p(String… a) {
System.out.println(String.join(“, “, a));
}
}

// 出力
2000-01-01 13:00:00, Asia/Tokyo, move 14, end 15
2000-01-01 04:00:00, UTC start
2000-01-01 18:00:00, UTC now
———-
2000-01-01 09:00:00, x, US/Alaska
2000-01-01 13:00:00, x, Cuba
2000-01-01 15:00:00, o, America/Godthab
2000-01-01 18:00:00, x, Europe/London
2000-01-01 21:00:00, x, Asia/Qatar
2000-01-02 01:00:00, x, Asia/Bangkok
2000-01-02 03:00:00, x, Asia/Tokyo

CodeIQ運営事務局より

柳井さん、ありがとうございました!
現在、柳井さんの最新問題が出題中です。
ぜひ挑戦してみてくださいね!

カテゴリー : デジタル・IT タグ :
CodeIQ MAGAZINEの記事一覧をみる ▶
  • 誤字を発見した方はこちらからご連絡ください。
  • ガジェット通信編集部への情報提供はこちらから
  • 記事内の筆者見解は明示のない限りガジェット通信を代表するものではありません。

TOP