Easy_2
$Σ(X_i-P)^2$の最小値を求める。
$P$が実数でもよければ、$P$が$X_i$の平均値のときの値を求めれば終わり。
この問題では$P$は整数値に限定されている。$Σ(X_i-P)^2$は$P$についての2次関数で、放物線は下に凸で軸は$X_i$の平均値。よって近い方(遠くない方)の整数に丸めれば良いのではあるが。
想定解は全探索であろう。$P=1,2,…,100$の全てについて$Σ(X_i-P)^2$を求め、その最小値を取れば良い。
Range
a..bは[a,b]、a...bは[a,b)を意味する。Rustだとa..bが[a, b)で、[a, b]はa..=bなので注意が必要。
1, 2, …, 100という概念は1..100で表せる。
for文がない
for i in 1..10
puts i
end
# syntax error in eval:1
# Error: expecting token 'EOF', not 'in'
forはマクロの定義には登場するが、通常のループにはないらしい。Wolfram Languageでさえ採用してるのに。while文にしても良いが、むしろイテレータで書けということなのだろう。
標準入力を受けとる
n = read_line
x = read_line.split.map(&.to_i)
nは文字列になっているが、使わないのでこのままでいい。
2行目の右辺はEasy_1と同じくArray型なので、xもArray型になる。
Range#mapメソッド
Easy_1ではArrayに対してmapを適用したが、Rangeにも適用できる。
(1..100).map{|p| 配列xの各要素とpとの差の二乗和}.配列の最小値
「xの各要素と、あるpとの差の二乗」はx.map(|xi| (xi-p)**2)でArray型。
配列の和、最小値
配列の和はArray#sumで求まる。
x.map(|xi| (xi-p)**2).sumで「xの各要素と、あるpとの差の二乗和」が求まる。
(1..100).map{|p| x.map(|xi| (xi-p)**2).sum}で、p = 1, 2, …, 100それぞれについての「xの各要素とpとの差の二乗和の配列」が求まる。
配列の最小値はArray#minメソッドで求まる。
(1..100).map{|p| x.map(|xi| (xi-p)**2).sum}.minで、「xの各要素とpとの差の二乗和」の最小値が求まる。これが答え。
標準出力
puts (1..100).map{|p| x.map(|xi| (xi-p)**2).sum}.min
AC例
n = read_line
x = read_line.split.map(&.to_i)
puts (1..100).map{ |p| x.map{ |xi| (xi-p)**2 }.sum }.min