🔢

SadServers解説#6 "Lhasa": Easy Math

2024/01/27に公開

https://ja.wikipedia.org/wiki/ラサ市

問題概要

シナリオ

簡単な数学

問題詳細

/home/admin/scores.txt というファイルに、2列の数字が書かれています。
1列目の数字は番号で、2列目の数字はテストの得点のようなものです。2列目の数字の平均を求めてください。

~$ head /home/admin/scores.txt 
1 7.4
2 0.4
3 1.6
4 6.2
5 7.6
...

なお、今回の仮想マシンには、bc、Python3、Go言語(Golang)、sqlite3がインストールされています。

解決判定

解答をファイル/home/admin/solutionに書いて、Check My Solutionボタンをクリックしてください。例えば、解答が"123.45"であれば、次のようなコマンドを実行し、Check My Solutionボタンをクリックしてください。

~$ echo "123.45" > ~/solution

解答は、小数点3桁以下を切り捨てて、ぴったり小数点2桁まで記入してください。たとえば、計算結果が21.349なら答えは21.34、計算結果が33.1なら答えは33.10です。

解答が正解かどうか、コマンドプロンプト上で確認することも可能です。ハッシュ値を求める次のコマンドを実行して、以下と同じ出力が得られた場合は正解です。

~$ md5sum /home/admin/solution 
6d4832eb963012f6d8a71a60fac77168  /home/admin/solution

 

問題解決の方針

【表示する】

今回の問題では、ファイル内容を編集・集計するコマンドを適切に使えるかが問われています。
どのようなコマンドをどういった手順で実行すれば、特定の列の平均値を計算することができるでしょうか。

解決の手順を表示する
  1. ファイルの2列目だけを抽出する
  2. 数字の合計と個数を求め、平均を計算する
  3. 小数第2位以下を切り捨てる

 

ヒント

一部、SadServers公式のヒントを改変しています。

ヒント1

cutコマンドを使用することで、2列名を取り出すことができます。

実行コマンド

区切り文字は" "(半角スペース)のため、-d ' 'オプションで、半角スペースを区切り文字に指定します。
また、-f 2オプションで、2列目を抽出する列に指定します。

~$ cut -d ' ' -f 2 /home/admin/scores.txt 
7.4
0.4
1.6
6.2
7.6
...
別解

awkコマンドを使用することでも、2列目を取り出すことができます。

実行コマンド
~$ awk '{print $2}' /home/admin/scores.txt
7.4
0.4
1.6
6.2
7.6
...
ヒント2

awkコマンドを使用して、各行の数字を足し合わせるとともに、足し合わせた回数を記録しておきます。そして、最後に数字の合計を回数で割ることで、平均を計算します。

実行コマンド
~$ cut -d ' ' -f 2 /home/admin/scores.txt |
   awk '{ sum += $1; n++ } END {  print sum / n }'
5.204
ヒント3

小数第2位以下を切り捨てます。手動で書き込んでも良いですし、出力の際に有効数字を指定してもよいです。

実行コマンド

出力の際に有効数字を指定することで、小数第2位以下を切り捨てる場合の処理です。

~$ cut -d ' ' -f 2 /home/admin/scores.txt
 | awk '{ sum += $1; n++ } END { printf "%.2f\n", sum / n }'
5.20
~$ cut -d ' ' -f 2 /home/admin/scores.txt
   | awk '{ sum += $1; n++ } END { printf "%.2f\n", sum / n }' > /home/admin/solution 

 

余談

Pythonで計算する方法

実行コマンド
calculate_average.py
sum = 0
count = 0

with open("/home/admin/scores.txt", 'r') as input_file:
    for line in input_file:
        sum += float(line.split()[1])
        count += 1

average = sum / count

with open("/home/admin/solution", 'w') as output_file:
    output_file.write(f"{average:.2f}\n")

print("計算結果は {:.2f} です。".format(average))
~$ python3 calculate_average.py 
計算結果は 5.20 です。

 
「いきなり問題を解き始めても調べるばかりになってしまう…」 「やりたいことが分かっても、コマンドが分からない…」 という方は、下記の記事でLinuxのコマンドを復習してから、SadServersの問題に取り掛かってみてはいかがでしょうか。
https://zenn.dev/comf_nakamura/articles/linux_command

問題一覧はこちら

https://zenn.dev/comf_nakamura/articles/sadservers_sitemap

Discussion