paizaオンラインハッカソン6に参加してみた(緑川つばめミッション, Perl, PHP, Ruby, Python)

当ブログ及びGitHubのページでも取り上げているが、今回はpaizaオンラインハッカソン6の緑川つばめミッションをスクリプト言語(Perl、PHP、Ruby、Python)で書いた場合の回答例と簡単な解説を行いたい。

回答例

Perl

[code lang=”perl”]use strict;
use warnings;

my $str = <STDIN>;
chomp($str);
my $num = $str + 0;
for my $idx (0…length($str) – 1) {
$num += substr($str, $idx, 1);
}
print $num."\n";[/code]

PHP

[code lang=”php”]<?php
$str = trim(fgets(STDIN));
$num = (int)$str;
for ($idx = 0; $idx < strlen($str); $idx++) {
$num += (int)$str[$idx];
}
print($num)
?>[/code]

Ruby

[code lang=”ruby”]str = gets.strip
num = str.to_i
str.chars{|ch|
num += ch.to_i
}
puts num[/code]

Python (2.7系)

[code lang=”python”]str = raw_input().strip()
num = int(str)
for ch in str:
num += int(ch)
print(num)[/code]

解説

今回はスクリプト言語を使った場合を例として挙げてみた。

いずれもC言語、C++、C#、Javaとは違い、文字列型を分割した場合、文字コードとして扱われておらず、分割された文字列、あるいは数値として扱われている模様で、int型にキャストあるいは変換しただけで問題なく変換を行えた。おそらく’0’の文字コード分減算を行ったら意図しない値が返ってくる可能性があるだろう。

いずれも標準入出力から得られた文字列は改行コードが含まれているため、RubyとPythonではstripメソッド、PHPではtrimメソッド、Perlではchomp関数を呼ぶ必要がある。こうしないと、のちのループで問題を起こす可能性があるからである。

各桁の数値を加算する際に、Perlはsubstr関数、PHPでは配列と見立ててfor文で回して数値に変換した上で加算、RubyとPythonでは範囲ベースのfor文に相当する処理を行って加算を行った。

PHP、Ruby、Perlでは文字列・文字・数値の型を意識すればここにおいては気をつけなければならないポイントはほとんどないが、Perlで行う場合、forループの処理に気をつけるべき点がある。

今回Perlではfor文として「for my $idx (0…length($str) – 1)」と記述したが、これは気分的には「for $my $idx (0…length($str))」と書きたくなるが、こうしてしまうと「for (my $idx = 0; $idx <= length($str); $str++)」と解釈されてしまい、実質的に処理が3回行われることとなり、余計な処理が入ってしまうことになる1 。もし1を減算する処理が気持ち悪いと考えるのであれば「for (my $idx = 0; $idx < length($str); $str++)」と書くべきである。

なお、今回ではC言語、C++、C#、Javaとは違い、数値チェック処理2 は行っていない。

最後に

今回は簡単なミッションのものをスクリプト言語を使って書いてみた。全体的にはC言語、C++、C#、Javaなどのネイティブ向けの言語と比較してかなり簡潔に書けるという点が大きな利点になっていると考えている。しかしながら、基本的には文字列型なのか数値なのか曖昧な部分があり、その点について意識する必要があるのが困ったところでもあると考えている。

次はリオミッションについても書いてみたい

ウェブマスター。本ブログでITを中心にいろいろな情報や意見などを提供しております。仕事依頼や相談などについては、Contact Formよりお願いいたします。
  1. use warnings;を使った場合、警告が出る []
  2. テストケースの条件を満たしていない数値が入っていたら例外あるいは異常終了とみなす処理 []