paiza問題集「ナンバープレートのハッシュ値」をいろいろな言語で解く

目次

しばらくプログラミングから離れていて忘れていることも多かったので文法を確認するためpaizaの問題をいろいろな言語で解いてみました。

問題は「ハッシュメニュー応用編」-「ナンバープレートのハッシュ値」です。 paiza問題へのリンクです。

「ナンバープレートのハッシュ値」

動作はしますがあまり時間をかけていられないのもあってとりあえずやってみたでしかありません。

C++

/*
これはpaizaラーニングの「ハッシュメニュー応用編」-「ナンバープレートのハッシュ値」に
C++でチャレンジしたコードです。
https://paiza.jp/works/mondai/hash_advanced/hash_advanced__number_plate

作成環境
Ubuntu 22.04.5 LTS
g++ (Ubuntu 11.4.0-1ubuntu1~22.04) 11.4.0
*/
#include <iostream>

using namespace std;

// ナンバープレート
struct NumberPlate {
    // 地域名
    string s_1;
    // 分類番号
    int i_1;
    // ひらがな
    string s_2;
    // 一連指定番号
    int i_2;
};

// ナンバープレート情報を読み込みます
// Return: 読み込んだナンバープレート
NumberPlate readNumberPlate() {
    string s_1, s_2;
    int i_1, i_2;
    // 1 行目に地域名を表す文字列 s_1 が与えられます。
    cin >> s_1;
    // 2 行目に分類番号を表す整数 i_1 が与えられます。
    cin >> i_1;
    // 3 行目にひらがなを表す文字列 s_2 が与えられます。
    cin >> s_2;
    // 4 行目に一連指定番号を表す整数 i_2 が与えられます。
    cin >> i_2;

    return { s_1, i_1, s_2, i_2 };
}

// 文字コード(ASCII)の和を返します
// Parameters:
//   str: 文字列
// Return: ASCIIコードの和
int sumString(string str) {
    int result = 0;
    for (char c : str) {
        result += c;
    }
    return result;
}

// ハッシュ値を返します
// Parameters:
//   numberPlate: ナンバープレート
// Return: ハッシュ値
int hashFunction(NumberPlate numberPlate) {
    // (s_1 の各文字の文字コードの和 * i_1 + s_2 の各文字の文字コードの和 * i_2) % 1000
    int is1 = sumString(numberPlate.s_1);
    int is2 = sumString(numberPlate.s_2);
    int result = (is1 * numberPlate.i_1 + is2 * numberPlate.i_2) % 1000;
    return result;
}

int main() {
    // 入力
    NumberPlate numberPlate = readNumberPlate();
    // ハッシュ値を求める
    int hashValue = hashFunction(numberPlate);
    // 結果出力
    cout << hashValue << endl;
    return 0;
}
$ g++ -o number_plate number_plate.cpp
$ ./number_plate
shinagawa
813
wo
4649
181

C#

/*
これはpaizaラーニングの「ハッシュメニュー応用編」-「ナンバープレートのハッシュ値」に
C#でチャレンジしたコードです。
https://paiza.jp/works/mondai/hash_advanced/hash_advanced__number_plate

作成環境
Ubuntu 22.04.5 LTS
.NET SDK 9.0.101
C# Compiler version: '4.13.0-2.24557.6 (0007900e)'. Language version: 13.0.CS8304
*/
using System;

/// <summary>
/// ナンバープレート
/// </summary>
/// <param name="s_1">地域名</param>
/// <param name="i_1">分類番号</param>
/// <param name="s_2">ひらがな</param>
/// <param name="i_2">一連指定番号</param>
class NumberPlate(string s_1, int i_1, string s_2, int i_2)
{
    /// <summary>
    /// 地域名
    /// </summary>
    public string Region { get; set; } = s_1;
    /// <summary>
    /// 分類番号
    /// </summary>
    public int Classification { get; set; } = i_1;
    /// <summary>
    /// ひらがな
    /// </summary>
    public string Hiragana { get; set; } = s_2;
    /// <summary>
    /// 一連指定番号
    /// </summary>
    public int Number { get; set; } = i_2;

    /// <summary>
    /// 文字コード(ASCII)の和を返します
    /// </summary>
    /// <param name="str">文字列</param>
    /// <returns>ASCIIコードの和</returns>
    private static int SumString(string str)
    {
        int result = 0;
        foreach( char c in str )
        {
            int code = Convert.ToInt32(c);
            result += code;
        }
        return result;
    }

    /// <summary>
    /// ハッシュ値を返します
    /// </summary>
    /// <returns>ハッシュ値</returns>
    public int HashValue()
    {
        // (地域名の各文字の文字コードの和 * 分類番号 + ひらがなの各文字の文字コードの和 * 一連指定番号) % 1000
        int is1 = SumString(Region);
        int is2 = SumString(Hiragana);
        int result = (is1 * Classification + is2 * Number) % 1000;
        return result;
    }
}

class Program
{
    static void Main(string[] args)
    {
        // 入力
        NumberPlate numberPlate = ReadNumberPlate();
        // ハッシュ値を求める
        int hashValue = numberPlate.HashValue();
        // 結果出力
        Console.WriteLine(hashValue);
    }

    /// <summary>
    /// ナンバープレート情報を読み込みます
    /// </summary>
    /// <returns>読み込んだナンバープレート</returns>    
    static NumberPlate ReadNumberPlate()
    {        
        // 1 行目に地域名を表す文字列 s_1 が与えられます。
        string s_1 = Console.ReadLine()!.Trim();
        // 2 行目に分類番号を表す整数 i_1 が与えられます。
        string si_1 = Console.ReadLine()!.Trim();
        int i_1 = int.Parse(si_1);
        // 3 行目にひらがなを表す文字列 s_2 が与えられます。
        string s_2 = Console.ReadLine()!.Trim();
        // 4 行目に一連指定番号を表す整数 i_2 が与えられます。
        string si_2 = Console.ReadLine()!.Trim();
        int i_2 = int.Parse(si_2);

        return new NumberPlate(s_1, i_1, s_2, i_2);
    }
}
# .NET プロジェクトの作成
$ dotnet new console --framework net9.0 --use-program-main
# .NET プロジェクトのビルド
$ dotnet build
# 実行
$ ./bin/Debug/net9.0/cs
shinagawa
813
wo
4649
181

Go

/*
これはpaizaラーニングの「ハッシュメニュー応用編」-「ナンバープレートのハッシュ値」に
Go言語でチャレンジしたコードです。
https://paiza.jp/works/mondai/hash_advanced/hash_advanced__number_plate

作成環境
Ubuntu 22.04.5 LTS
go version go1.22.0 linux/amd64
*/
package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
)

// ナンバープレート情報
type NumberPlate struct {
	// 地域名
	s_1 string
	// 分類番号
	i_1 int
	// ひらがな
	s_2 string
	// 一連指定番号
	i_2 int
}

// ハッシュ値を返します
// Return: ハッシュ値
func (numberPlate NumberPlate) hashValue() int {
	// (地域名の各文字の文字コードの和 * 分類番号 + ひらがなの各文字の文字コードの和 * 一連指定番号) % 1000
	var is1 int = sumString(numberPlate.s_1)
	var is2 int = sumString(numberPlate.s_2)
	var result int = (is1*numberPlate.i_1 + is2*numberPlate.i_2) % 1000
	return result
}

// 文字コード(ASCII)の和を返します
// Parameters:
//
//	str: 文字列
//
// Return: ASCIIコードの和
func sumString(str string) int {
	var result int = 0
	for _, c := range str {
		result += int(c)
	}
	return result
}

// ナンバープレート情報を読み込みます
// Return: 読み込んだナンバープレート
func readNumberPlate() NumberPlate {
	sc := bufio.NewScanner(os.Stdin)
	// 1 行目に地域名を表す文字列 s_1 が与えられます。
	sc.Scan()
	var s_1 string = sc.Text()
	// 2 行目に分類番号を表す整数 i_1 が与えられます。
	sc.Scan()
	var i_1, _ = strconv.Atoi(sc.Text())
	// 3 行目にひらがなを表す文字列 s_2 が与えられます。
	sc.Scan()
	var s_2 string = sc.Text()
	// 4 行目に一連指定番号を表す整数 i_2 が与えられます。
	sc.Scan()
	var i_2, _ = strconv.Atoi(sc.Text())

	return NumberPlate{s_1, i_1, s_2, i_2}
}

func main() {
	// 入力
	var numberPlate NumberPlate = readNumberPlate()
	// ハッシュ値を求める
	var hashValue int = numberPlate.hashValue()
	// 結果出力
	fmt.Println(hashValue)
	return
}
$ go build number_plate.go
$ ./number_plate
shinagawa
813
wo
4649
181

Java

/*
これはpaizaラーニングの「ハッシュメニュー応用編」-「ナンバープレートのハッシュ値」に
javaでチャレンジしたコードです。
https://paiza.jp/works/mondai/hash_advanced/hash_advanced__number_plate

作成環境
Ubuntu 22.04.5 LTS
openjdk version "21.0.5" 2024-10-15
*/
import java.util.*;
import java.util.stream.Collectors;

public class Main {
    public static void main(String[] args) throws Exception {
        // 入力
        NumberPlate numberPlate = readNumberPlate();
        // ハッシュ値を求める
        int hashValue = numberPlate.hashValue();
        // 結果出力
        System.out.println(hashValue);
    }

    /// ナンバープレート情報を読み込みます
    ///
    /// - Returns: 読み込んだナンバープレート
    public static NumberPlate readNumberPlate() {
        Scanner sc =new Scanner(System.in);
        
        // 1 行目に地域名を表す文字列 s_1 が与えられます。
        String s_1 = sc.next();
        // 2 行目に分類番号を表す整数 i_1 が与えられます。
        int i_1 = sc.nextInt();
        // 3 行目にひらがなを表す文字列 s_2 が与えられます。
        String s_2 = sc.next();
        // 4 行目に一連指定番号を表す整数 i_2 が与えられます。
        int i_2 = sc.nextInt();
        sc.close();
        return new NumberPlate(s_1, i_1, s_2, i_2);
    }

    private static class NumberPlate {
        // 地域名
        String s_1;
        // 分類番号
        int i_1;
        // ひらがな
        String s_2;
        // 一連指定番号
        int i_2;
    
        NumberPlate(String s1, int i1, String s2, int i2) {
            s_1 = s1;
            i_1 = i1;
            s_2 = s2;
            i_2 = i2;
        }
    
        /// 文字コード(ASCII)の和を返します
        ///
        /// - Parameters:
        ///   - str: 文字列
        ///
        /// - Returns: ASCIIコードの和
        int sumString(String str) {
            int result = 0;
            List<Integer> listString = str.chars().boxed().collect(Collectors.toList());
            for (int i : listString) {
                result += i;
            }
            return result;
        }
    
        /// ハッシュ値を返します
        ///
        /// - Returns: ハッシュ値
        int hashValue() {
            // (地域名の各文字の文字コードの和 * 分類番号 + ひらがなの各文字の文字コードの和 * 一連指定番号) % 1000
            int is1 = sumString(s_1);
            int is2 = sumString(s_2);
            int result = (is1 * i_1 + is2 * i_2) % 1000;
            return result;
        }
    }
}
$ javac Main.java
$ java Main
shinagawa
813
wo
4649
181

Kotlin

/*
これはpaizaラーニングの「ハッシュメニュー応用編」-「ナンバープレートのハッシュ値」に
Kotlinでチャレンジしたコードです。
https://paiza.jp/works/mondai/hash_advanced/hash_advanced__number_plate

作成環境
Ubuntu 22.04.5 LTS
kotlinc-native 1.5.0-743 (JRE 21.0.5+11-Ubuntu-1ubuntu122.04)
*/
// ナンバープレート情報
data class NumberPlate(
    // 地域名
    val s_1: String,
    // 分類番号
    val i_1: Int,
    // ひらがな
    val s_2: String,
    // 一連指定番号
    val i_2: Int
) {
    // ハッシュ値を返します
    // Return: ハッシュ値
    fun hashValue(): Int {
        // (地域名の各文字の文字コードの和 * 分類番号 + ひらがなの各文字の文字コードの和 * 一連指定番号) % 1000
        val is1: Int = sumString(s_1)
        val is2: Int = sumString(s_2)
        val result: Int = (is1 * i_1 + is2 * i_2) % 1000
        return result
    }

    // 文字コード(ASCII)の和を返します
    // Parameters:
    //   str: 文字列
    // Return: ASCIIコードの和
    fun sumString(str: String): Int {
        var result: Int = 0
        val listChar: CharArray = str.toCharArray()
        for (c: Char in listChar) {
            result += c.code
        }
        return result
    }
}

// ナンバープレート情報を読み込みます
// Return: 読み込んだナンバープレート
fun readNumberPlate(): NumberPlate {
    // 1 行目に地域名を表す文字列 s_1 が与えられます。
    val s_1: String = readLine()!!
    // 2 行目に分類番号を表す整数 i_1 が与えられます。
    val i_1: Int = readLine()!!.toInt()
    // 3 行目にひらがなを表す文字列 s_2 が与えられます。
    val s_2: String = readLine()!!
    // 4 行目に一連指定番号を表す整数 i_2 が与えられます。
    val i_2: Int = readLine()!!.toInt()

    return NumberPlate(s_1, i_1, s_2, i_2)
}

fun main(args:Array<String>) {
    // 入力
    val numberPlate: NumberPlate = readNumberPlate()
    // ハッシュ値を求める
    val hashValue: Int = numberPlate.hashValue()
    // 結果出力
    println(hashValue)
}
$ kotlinc-native number_plate.kt -o number_plate
$ ./number_plate.kexe
shinagawa
813
wo
4649
181

PHP

<?php
/*
これはpaizaラーニングの「ハッシュメニュー応用編」-「ナンバープレートのハッシュ値」に
PHPでチャレンジしたコードです。
https://paiza.jp/works/mondai/hash_advanced/hash_advanced__number_plate

作成環境
Ubuntu 22.04.5 LTS
PHP 8.1.2-1ubuntu2.20 (cli) (built: Dec  3 2024 20:14:35) (NTS)
*/
// ナンバープレート
class NumberPlate {
    // 地域名
    public string $s_1;
    // 分類番号
    public int $i_1;
    // ひらがな
    public string $s_2;
    // 一連指定番号
    public int $i_2;

    public function __construct(string $s_1, int $i_1, string $s_2, int $i_2) {
        $this->s_1 = $s_1;
        $this->i_1 = $i_1;
        $this->s_2 = $s_2;
        $this->i_2 = $i_2;
    }
    // ハッシュ値を返します
    // Return: ハッシュ値
    public function hashValue(): int {
        // (地域名の各文字の文字コードの和 * 分類番号 + ひらがなの各文字の文字コードの和 * 一連指定番号) % 1000
        $is1 = self::sumString($this->s_1);
        $is2 = self::sumString($this->s_2);
        $result = ($is1 * $this->i_1 + $is2 * $this->i_2) % 1000;
        return $result;
    }
    // 文字コード(ASCII)の和を返します
    // Parameters:
    //   str: 文字列
    // Return: ASCIIコードの和
    private static function sumString(string $str): Int {
        $result = 0;
        foreach(str_split($str) as $c) {
            $result += ord($c);
        }
        return $result;
    }
}
// ナンバープレート情報を読み込みます
// Return: 読み込んだナンバープレート
function readNumberPlate(): NumberPlate {
    // 1 行目に地域名を表す文字列 s_1 が与えられます。
    $s_1 = trim(fgets(STDIN));
    // 2 行目に分類番号を表す整数 i_1 が与えられます。
    $i_1 = trim(fgets(STDIN));
    // 3 行目にひらがなを表す文字列 s_2 が与えられます。
    $s_2 = trim(fgets(STDIN));
    // 4 行目に一連指定番号を表す整数 i_2 が与えられます。
    $i_2 = trim(fgets(STDIN));

    $result = new NumberPlate($s_1, $i_1, $s_2, $i_2);
    return $result;
}

// 入力
$numberPlate = readNumberPlate();
// ハッシュ値を求める
$hashValue = $numberPlate->hashValue();
// 結果出力
echo $hashValue,PHP_EOL;
$ php number_plate.php
shinagawa
813
wo
4649
181

Python3

# これはpaizaラーニングの「ハッシュメニュー応用編」-「ナンバープレートのハッシュ値」に
# Python3でチャレンジしたコードです。
# https://paiza.jp/works/mondai/hash_advanced/hash_advanced__number_plate
# 
# 作成環境
# Ubuntu 22.04.5 LTS
# Python 3.10.12 (main, Nov  6 2024, 20:22:13) [GCC 11.4.0]

# ナンバープレート情報を読み込みます
# Return: 読み込んだナンバープレート
def readNumberPlate():
    # 1 行目に地域名を表す文字列 s_1 が与えられます。
    s_1 = input().strip()
    # 2 行目に分類番号を表す整数 i_1 が与えられます。
    i_1 = int(input())
    # 3 行目にひらがなを表す文字列 s_2 が与えられます。
    s_2 = input().strip()
    # 4 行目に一連指定番号を表す整数 i_2 が与えられます。
    i_2 = int(input())

    return NumberPlate(s_1, i_1, s_2, i_2)

# 文字コード(ASCII)の和を返します
# Parameters:
#   str: 文字列
# Return: ASCIIコードの和
def sumString(str):
    result = sum([ord(i) for i in str])
    return result

# ナンバープレート
class NumberPlate:
    def __init__(self, s_1, i_1, s_2, i_2):
        # 地域名
        self.s_1 = s_1
        # 分類番号
        self.i_1 = i_1
        # ひらがな
        self.s_2 = s_2
        # 一連指定番号
        self.i_2 = i_2

    # ハッシュ値を返します
    # Return: ハッシュ値
    def hashValue(self):
        # (地域名の各文字の文字コードの和 * 分類番号 + ひらがなの各文字の文字コードの和 * 一連指定番号) % 1000
        is1 = sumString(self.s_1)
        is2 = sumString(self.s_2)
        result = (is1 * self.i_1 + is2 * self.i_2) % 1000
        return result    

# 入力
numberPlate = readNumberPlate()
# ハッシュ値を求める
hashValue = numberPlate.hashValue()
# 結果出力
print(hashValue)
$ python3 number_plate.py
shinagawa
813
wo
4649
181

Swift

/*
これはpaizaラーニングの「ハッシュメニュー応用編」-「ナンバープレートのハッシュ値」に
swiftでチャレンジしたコードです。
https://paiza.jp/works/mondai/hash_advanced/hash_advanced__number_plate

作成環境
Ubuntu 22.04.5 LTS
Swift version 5.4 (swift-5.4-RELEASE) Target: x86_64-unknown-linux-gnu
*/
import Foundation

/// ナンバープレート
struct NumberPlate {
    /// 地域名
    var s_1: String
    /// 分類番号
    var i_1: Int
    /// ひらがな
    var s_2: String
    /// 一連指定番号
    var i_2: Int
}

/// ナンバープレート情報を読み込みます
///
/// - Returns: 読み込んだナンバープレート
func readNumberPlate() -> NumberPlate {
    
    // 1 行目に地域名を表す文字列 s_1 が与えられます。
    let s_1 = readLine()!.trimmingCharacters(in: .whitespacesAndNewlines)
    // 2 行目に分類番号を表す整数 i_1 が与えられます。
    let i_1: Int = Int(readLine()!.trimmingCharacters(in: .whitespacesAndNewlines)) ?? 0
    // 3 行目にひらがなを表す文字列 s_2 が与えられます。
    let s_2 = readLine()!.trimmingCharacters(in: .whitespacesAndNewlines)
    // 4 行目に一連指定番号を表す整数 i_2 が与えられます。
    let i_2: Int = Int(readLine()!.trimmingCharacters(in: .whitespacesAndNewlines)) ?? 0

    return NumberPlate(s_1: s_1, i_1: i_1, s_2: s_2, i_2: i_2)
}

/// 文字コード(ASCII)の和を返します
///
/// - Parameters:
///   - s: 文字列
///
/// - Returns: ASCIIコードの和
func sumString(_ s: String) -> Int {
    var result: Int = 0
    for character in s {
        let code = character.asciiValue ?? 0
        result += Int(code)
    }
    return result
}

/// ハッシュ値を返します
///
/// - Parameters:
///   - snumberPlate: ナンバープレート
///
/// - Returns: ハッシュ値
func hashFunction(_ numberPlate: NumberPlate) -> Int {
    // (s_1 の各文字の文字コードの和 * i_1 + s_2 の各文字の文字コードの和 * i_2) % 1000
    let is1 = sumString(numberPlate.s_1)
    let is2 = sumString(numberPlate.s_2)
    let result = (is1 * numberPlate.i_1 + is2 * numberPlate.i_2) % 1000
    return result
}

/// メイン関数
func main() {
    // 入力
    let numberPlate = readNumberPlate()
    // ハッシュ値を求める
    let hashValue = hashFunction(numberPlate)
    // 結果出力
    print(hashValue)
}

// エントリーポイント
main()
$ swiftc number_plate.swift
$ ./number_plate
shinagawa
813
wo
4649
181