{ }codelper
戻り値関数の定義P0402

目盛りの外に出られない温度計

教室の温度計には lo 度から hi 度までしか目盛りがない。
実際の気温が lo より低ければ温度計は lo を指し、hi より高ければ hi を指す。
それ以外は実際の気温をそのまま指す。
一行目に lo と hi が空白一つで区切って与えられる。
二行目に気温を測った回数 n が与えられる。
続く n 行に実際の気温 t が一行に一つずつ与えられる。
測った順に、温度計が指した値を一行に一つずつ出力せよ。
最後の行には、温度計が指した値 n 個をすべて足した合計を出力せよ。
実際の気温と lo、hi を受け取り、温度計が指す値を返す関数を作り、返ってきた値を出力と合計の両方に使おう。
採点は出力だけを見る。

入力
-100 ≤ lo ≤ hi ≤ 100、1 ≤ n ≤ 100、-1,000 ≤ t ≤ 1,000(すべて整数)
出力
n + 1 行。
はじめの n 行は温度計が指した値、最後の行はその合計
例 1 · stdin
-5 30
4
12
-9
30
41
stdout
12
-5
30
30
67
main.py
入力(stdin)

実行すると、これらの行が順に input()・標準入力に渡されます(実行中に入力を求めません)。

$ 準備完了

コードを入力して解くにはパソコンで開いてください。モバイルでは問題と解答を見られます。

ほかの言語では?言語別の解答を見る · 8 言語の解答

関数を作る型は言語ごとに違います。
Python は def shown(t, lo, hi):、JS は function shown(t, lo, hi) で、型は書きません。
TS は function shown(t: number, lo: number, hi: number): number のように、かっこの後ろに返す値の型を書きます。
Java と C# は static int shown(int t, int lo, int hi)(C# はふつう Shown)、C・C++ は int shown(int t, int lo, int hi) で、返す型を名前の前に書きます。
Craykon は 名前(t, lo, hi) { … } のように名前とかっこだけを書き、値は 返す t; で返します。
return に出会うと関数はすぐ終わるので、if (t < lo) return lo; の下に else を書かなくてもかまいません。
関数を置く場所も違います。
Python は呼ぶ行より先に def が実行されていなければならず、下に置くと NameError で止まります。
C++ は呼ぶ場所より上に関数がないとコンパイルエラーで、C(gcc 11)は警告を出すだけでコンパイルします。
JS・TS の function 宣言、Java・C# のメソッド、Craykon の関数は、呼ぶ場所より下にあってもかまいません。
落とし穴その一:目盛りの中のときの最後の return t; を書き忘れることです。
Python の関数は return なしで終わると None を返すので、例では一行目に None を出し、合計に足す行で TypeError で止まります。
JS は undefined を返しますが、解答のように join でつなぐと undefined は空文字列になるので、例の出力は空行、-5、空行、30、NaN です。
Java は "missing return statement"、C# は CS0161 でコンパイルを止めてくれ、TS も : number を書いていれば TS2366 で止めます。
C と C++ は採点機の gcc 11(-Wall)で警告が出るだけでコンパイルされ、その後の動作は決まっていません。
落とし穴その二:関数の中で値を出力して、返さないことです。
画面に出した値は呼んだ側に戻ってきません。
Craykon で 返す の代わりに コンソール.書く(t) と書くと、例では 12 の一行だけを書き、合計に足す行で「なしでは計算できない」と言って止まります。
落とし穴その三:shown(t, lo, hi); と呼ぶだけで、返ってきた値を受け取らないことです。
八つの言語のどれでも整数は値がコピーされて渡されるので、関数の中で t を変えても呼んだ側の t はそのままです。
C でこう書くと警告なしでコンパイルされ、例の出力は 12、-9、30、41、74 です。
v = shown(t, lo, hi) のように返ってきた値を名前に入れておけば、出力と合計の二回に使えます。

Pythonmain.py · 17 行
def shown(t, lo, hi):    # 온도계가 가리키는 값을 돌려준다. return을 만나면 함수는 바로 끝난다    if t < lo:        return lo    if t > hi:        return hi    return t  lo, hi = map(int, input().split())n = int(input())total = 0for _ in range(n):    v = shown(int(input()), lo, hi)  # 돌려받은 값을 이름에 담아 두 번 쓴다    print(v)    total += vprint(total)
JavaScriptmain.js · 19 行
// 온도계가 가리키는 값을 돌려준다. return을 만나면 함수는 바로 끝난다function shown(t, lo, hi) {  if (t < lo) return lo;  if (t > hi) return hi;  return t;} const lines = require("fs").readFileSync(0, "utf8").split("\n");const [lo, hi] = lines[0].trim().split(/\s+/).map(Number);const n = Number(lines[1]);const out = [];let total = 0;for (let i = 0; i < n; i++) {  const v = shown(Number(lines[2 + i]), lo, hi); // 돌려받은 값을 이름에 담아 두 번 쓴다  out.push(v);  total += v;}out.push(total);console.log(out.join("\n"));
TypeScriptmain.ts · 21 行
import { readFileSync } from "node:fs"; // 온도계가 가리키는 값을 돌려준다. 괄호 뒤의 `: number`가 돌려주는 값의 타입이다function shown(t: number, lo: number, hi: number): number {  if (t < lo) return lo;  if (t > hi) return hi;  return t;} const lines: string[] = readFileSync(0, "utf8").split("\n");const [lo, hi]: number[] = lines[0].trim().split(/\s+/).map(Number);const n: number = Number(lines[1]);const out: number[] = [];let total = 0;for (let i = 0; i < n; i++) {  const v: number = shown(Number(lines[2 + i]), lo, hi); // 돌려받은 값을 이름에 담아 두 번 쓴다  out.push(v);  total += v;}out.push(total);console.log(out.join("\n"));
JavaMain.java · 25 行
import java.util.Scanner; public class Main {    // 온도계가 가리키는 값을 돌려준다. 이름 앞의 int가 돌려주는 값의 타입이다    static int shown(int t, int lo, int hi) {        if (t < lo) return lo;        if (t > hi) return hi;        return t;    }     public static void main(String[] args) {        Scanner sc = new Scanner(System.in);        int lo = sc.nextInt(), hi = sc.nextInt();        int n = sc.nextInt();        int total = 0;        StringBuilder out = new StringBuilder();        for (int i = 0; i < n; i++) {            int v = shown(sc.nextInt(), lo, hi); // 돌려받은 값을 변수에 담아 두 번 쓴다            out.append(v).append('\n');            total += v;        }        out.append(total).append('\n');        System.out.print(out);    }}
C#Main.cs · 27 行
using System; class Program{    // 온도계가 가리키는 값을 돌려준다. 이름 앞의 int가 돌려주는 값의 타입이다    static int Shown(int t, int lo, int hi)    {        if (t < lo) return lo;        if (t > hi) return hi;        return t;    }     static void Main()    {        string[] first = Console.ReadLine().Split(' ', StringSplitOptions.RemoveEmptyEntries);        int lo = int.Parse(first[0]), hi = int.Parse(first[1]);        int n = int.Parse(Console.ReadLine());        int total = 0;        for (int i = 0; i < n; i++)        {            int v = Shown(int.Parse(Console.ReadLine()), lo, hi); // 돌려받은 값을 변수에 담아 두 번 쓴다            Console.WriteLine(v);            total += v;        }        Console.WriteLine(total);    }}
C++main.cpp · 22 行
#include <iostream> // 온도계가 가리키는 값을 돌려준다. 이름 앞의 int가 돌려주는 값의 타입이다int shown(int t, int lo, int hi) {    if (t < lo) return lo;    if (t > hi) return hi;    return t;} int main() {    int lo, hi, n;    std::cin >> lo >> hi >> n;    int total = 0;    for (int i = 0; i < n; i++) {        int t;        std::cin >> t;        int v = shown(t, lo, hi);  // 돌려받은 값을 변수에 담아 두 번 쓴다        std::cout << v << '\n';        total += v;    }    std::cout << total << '\n';}
Cmain.c · 23 行
#include <stdio.h> // 온도계가 가리키는 값을 돌려준다. 이름 앞의 int가 돌려주는 값의 타입이다int shown(int t, int lo, int hi) {    if (t < lo) return lo;    if (t > hi) return hi;    return t;} int main(void) {    int lo, hi, n;    if (scanf("%d %d %d", &lo, &hi, &n) != 3) return 0;    int total = 0;    for (int i = 0; i < n; i++) {        int t;        if (scanf("%d", &t) != 1) return 0;        int v = shown(t, lo, hi);  // 돌려받은 값을 변수에 담아 두 번 쓴다        printf("%d\n", v);        total += v;    }    printf("%d\n", total);    return 0;}
Craykonmain.cray · 27 行
// 온도계가 가리키는 값을 돌려준다. 돌려주기를 만나면 함수는 바로 끝난다가리킨값(t, lo, hi){    もし (t < lo)    {        返す lo;    }    もし (t > hi)    {        返す hi;    }    返す t;} ends = コンソール.数読み();lo = ends[0];hi = ends[1];n = コンソール.行読み().数に();total = 0;繰り返す (i = 0; i < n; i++){    // 돌려받은 값을 이름에 담아 두 번 쓴다    v = 가리킨값(コンソール.行読み().数に(), lo, hi);    コンソール.書く(v);    total = total + v;}コンソール.書く(total);