読者です 読者をやめる 読者になる 読者になる

無駄と文化

実用的ブログ

九九表のすべてのマスの和

Haskell JavaScript Python PHP

takatoh 様 が同じ問題を Ruby と Scheme で解いてくださいました。許可を得て転記させていたいています
Ruby 版の簡素さはさすがという感じです。そして、Scheme 版の S式 は慣れないと読めないし分からないのが面白いですね。takatoh 様、本当にありがとうございます。


f:id:todays_mitsui:20161012233845p:plain


小ネタです。九九表の81マスに書かれている全ての数を足し合わせる計算をやってみましょう。
いろんな言語で書きます。

意味?特に無いですね。


Python2

import itertools
print(sum(map(lambda (x, y): x*y, itertools.product(range(1, 10), repeat=2))))
# => 2025

実行結果

途中で直積を求める必要があるんですが、itertools を使えば一撃です。さすが。


PHP

<?php
$sum = 0;

foreach (range(1, 9) as $i) {
    foreach (range(1, 9) as $j) {
        $sum += $i*$j;
    }
}

echo $sum;
// => 2025

実行結果

もっと関数型っぽくして行圧縮したかったんですけど、PHP なので潔く PHP らしく。

PHP で直積計算 も出来るようですが、直積だけで20行使ってるのにオエッとなりました。
3引数以上にも対応した一般的な書き方だからですかねぇ。


Haskell

import Control.Applicative
main = putStrLn . show . sum $ (*) <$> [1..9] <*> [1..9]
-- => 2025

実行結果

私が最も愛する言語 Haskell です。

Applicative Functor が便利ですね。
(,) <$> xs <*> ys で直積が取れるし (*) <$> xs <*> ys で直積の生成をすっ飛ばして九九表の全てのマスの生成ができます。


JavaScript (ES2015)

console.log([].concat(...[...Array(9).keys()].map(i=>i+1).map((i,_,ns)=>ns.map(j=>i*j))).reduce((i,j)=>i+j,0))
// => 2025

実行結果

たぶん初見では読めないので適度に分解すると、

// range(1, 9) の代わり
const ns = [...Array(9).keys()].map(i => i+1);

// flatten() の代わり
const flatten = arr => [].concat(...arr);

// sum() の代わり
const sum = ns => ns.reduce((i, j) => i+j, 0);

let result = sum(flatten(ns.map((i, _, ms) => ms.map(j => i*j))));
console.log(result);
// => 2025

こうやってみると JavaScript 貧弱ですねぇ。個人的には好きなんですけど。

Array.range()Array.flatten() も Set.product()Math.sum() も無いとかさすがにツラいです。
直積計算を Array.prototype.map() で無理やりやってるところがダサさポイントですね。


Lazy_K

`k`````s``s``s`ksk`k``sii``s``s`ksk`k``sii``s`k`s``s`ks``s`ki``s``si`k`k`k`k`ki`
kk``s`k`s``s`ks``s`kk``s`k``s``s`ks``s`kk``s`ks``s`k`sik`kk``si`kk``s``s`ksk`k``
si`k`ki```s`k````s``s``s`ksk`k``sii``s``s`ksk`k``sii``s`k`s``s`ks``s`k`s``s`ki``
s``si`k`k`k`k`ki`kkk``s``s`ks``s`k`s`ks``s``s`ks``s`kk``s`ksk`k``s`k`s``s`k``s``
s`ks``s`kk``s`ks``s`k`sik`kk``si`kkk`k`k``si`k`ki```sii```sii``s``s`kski```s``s`
`s`ksk`k``sii``s``s`ksk`k``sii``s`k`s``s`k``s``s`ks``s`kk``s`ks``s`k`sik`kk``s`k
```s`ks``s`k`s`ks`s`kk````s`ks``s`k`s`ks`s`kk````s`ksk```sii``s``s`kski````s`ksk
``s``s`kski``s``s`ksk``s``s`ksk``s``s`ksk``s``s`kski```s``s`ksk``s``s`kski``s``s
`kski``s```s``s``s`ksk`k``sii``s``s`ksk`k``sii``s`k`s``s`ks``s``s`ks``s`k`s`ki``
s`k`s`k``s``si`k`k`ki`kk``s`k`s``si`k``s``s`ks``s`k`s`ks``s``s`ks``s`k`s`ks``s`k
`s`kk``s``s`ksk`k``s`k`s`k`si``s`k`s`kk``s`k`sik`k`kk`k`k`kik``s``s`ks``s``s`ks`
`s`k`s`ki``s`k`s`k``s``si`k`k`ki`kk``s`k`s``s`k`s``si`k``s``s`ks``s`k`s`ks``s``s
`ks``s`k`s`ks``s`k`s`kk``s``s`ksk`k``s`k`s`k`si``s`k`s`kk``s`k`sik`k`kk`k`k`kikk
`k`k`kik``s``s`ks``s`k`s`ks``s``s`ks``s`kk``s`ksk`k``s`k`s``si`k``s``s`ks``s`k`s
`ks``s``s`ks``s`k`s`ks``s`k`s`kk``s``s`ksk`k``s`k`s`k`si``s`k`s`kk``s`k`sik`k`kk
`k`k`kik`k`ki`k````s`ksk``s``s`kski``s``s`ksk``s``s`ksk``s``s`ksk``s``s`kski``s`
k`s``s``s`ki``s``s`k`s`k``s``si`k`k`ki`kk``s`k`s``si`k``s``s`ks``s`k`s`ks``s``s`
ks``s`k`s`ks``s`k`s`kk``s``s`ksk`k``s`k`s`k`si``s`k`s`kk``s`k`sik`k`kk`k`k`kik`k
```s``s`kski``s``s`ksk``s``s`kski`k`ki``s``s`ksk`k``s```s``s``s`ksk`k``sii``s``s
`ksk`k``sii``s`k`s``s`ks``s``s`ks``s`k`s`ki``s`k`s`k``s``si`k`k`ki`kk``s`k`s``si
`k``s``s`ks``s`k`s`ks``s``s`ks``s`k`s`ks``s`k`s`kk``s``s`ksk`k``s`k`s`k`si``s`k`
s`kk``s`k`sik`k`kk`k`k`kik``s``s`ks``s``s`ks``s`k`s`ki``s`k`s`k``s``si`k`k`ki`kk
``s`k`s``s`k`s``si`k``s``s`ks``s`k`s`ks``s``s`ks``s`k`s`ks``s`k`s`kk``s``s`ksk`k
``s`k`s`k`si``s`k`s`kk``s`k`sik`k`kk`k`k`kikk`k`ki`k`k`ki``s`k`s`k`s`k`s``s`ksk`
`s``s`ks``s`k`s`ks``s``s`ks``s`kk``s`ksk`k``s`k`s``si`k``s``s`ks``s`k`s`ks``s``s
`ks``s`k`s`ks``s`k`s`kk``s``s`ksk`k``s`k`s`k`si``s`k`s`kk``s`k`sik`k`kk`k`k`kik`
k`ki`k````s`ksk``s``s`kski``s``s`ksk``s``s`ksk``s``s`ksk``s``s`kski````s``s``s`k
sk`k``sii``s``s`ksk`k``sii``s`k`s``s``s`ki``s``si`k`k`k`k`ki`kk`k`ki``s`k`s``s`k
``s`ks``s`k`s`ks`s`kk``si`kk``s``s`ksk`k``si`k`ki````s``s``s`ksk`k``sii``s``s`ks
k`k``sii``s`k`s``s``s`ki``s``si`k`k`k`k`ki`kk`k`ki``s`k`s``s`k```s``s``s`ksk`k``
sii``s``s`ksk`k``sii``s`k`s``s`ks``s`ki``s``si`k`k`k`k`ki`kk``s`k`s``s`ks``s`kk`
`s`k``s``s`ks``s`kk``s`ks``s`k`sik`kk``si`kk``s``s`ksk`k``si`k`ki``si`kk``s``s`k
sk`k``si`k`ki`````s``s``s`ksk`k``sii``s``s`ksk`k``sii``s`k`s`k`s``s``s`ki``s``si
`k`k`k`k`ki`kk`k`ki``s`k`s``s`ks``s`k`s`k``s``s`ks``s`kk``s`ks``s`k`sik`kk``s``s
`ksk`k``si`kk``s``s`ks``s`k`s`ks`s`kk`k`k``si`k`ki``s``s`k```s``s``s`ksk`k``sii`
`s``s`ksk`k``sii``s`k`s`k`s``s``s`ki``s``si`k`k`k`k`ki`kk`k`ki``s`k`s``s`ks``s`k
`s`k``s``s`ks``s`kk``s`ks``s`k`sik`kk``s``s`ksk`k``si`kk``s``s`ks``s`k`s`ks`s`kk
`k`k``si`k`ki``s`ksk`k`````s``s``s`ksk`k``sii``s``s`ksk`k``sii``s`k`s`k`s``s``s`
ki``s``si`k`k`k`k`ki`kk`k`ki``s`k`s``s`ks``s`k`s`k``s``s`ks``s`kk``s`ks``s`k`sik
`kk``s``s`ksk`k``si`kk``s``s`ks``s`k`s`ks`s`kk`k`k``si`k`ki`s``s`ksk````s``s``s`
ksk`k``sii``s``s`ksk`k``sii``s`k`s``s``s`ks``s`kk``s`ks``s`k`sik`kk``s`k`s``s``s
`ki``s``si`k`k`ki`kk`k`ki``s``s`ksk`k``s``s`ks``s`k`s`ks``s``s`ks``s`k`s`ks``s`k
`s`kk``s``s`ksk`k``s`k`s`k`si``s`k`s`kk``s`k`sik`k`kk`k`k`ki```s``s`ksk``s``s`ks
ki``s``s`kski`````s``s``s`ksk`k``sii``s``s`ksk`k``sii``s`k`s`k`s``s``s`ki``s``si
`k`k`k`k`ki`kk`k`ki``s`k`s``s`ks``s`k`s`k``s``s`ks``s`kk``s`ks``s`k`sik`kk``s``s
`ksk`k``si`kk``s``s`ks``s`k`s`ks`s`kk`k`k``si`k`ki`s``s`ksk````s``s``s`ksk`k``si
i``s``s`ksk`k``sii``s`k`s``s``s`ks``s`kk``s`ks``s`k`sik`kk``s`k`s``s``s`ki``s``s
i`k`k`ki`kk`k`ki``s``s`ksk`k``s``s`ks``s`k`s`ks``s``s`ks``s`k`s`ks``s`k`s`kk``s`
`s`ksk`k``s`k`s`k`si``s`k`s`kk``s`k`sik`k`kk`k`k`ki```s``s`ksk``s``s`kski``s``s`
kski```sii```sii``s``s`kski

書きました!
Lazy K Playground で走らせてみたら結果を得るまでに150秒以上かかりました...。


Ruby

九九表のすべてのマスの和 | blog.PanicBlanket.com より転記。

# encoding: utf-8


def sum_of_kuku
  a = (1..9).to_a
  a.product(a).map{|x,y| x * y}.inject(:+)
end


puts sum_of_kuku

なるほど .inject(:+) のようなメソッド呼び出しで sum() が実現できるんですね。
.product() が標準で提供されているのも流石 Ruby といった感じ。


Scheme

九九表のすべてのマスの和 | blog.PanicBlanket.com より転記。

(use srfi-1)

(define direct-product
  (lambda (lis1 lis2)
    (append-map
      (lambda (x) (map (lambda (y) (list x y)) lis2))
      lis1)))


(define sum-of-kuku
  (lambda ()
    (let ((l1 '(1 2 3 4 5 6 7 8 9))
          (l2 '(1 2 3 4 5 6 7 8 9)))
      (apply + (map (lambda (x) (apply * x)) (direct-product l1 l2))))))


(print (sum-of-kuku))

読めない...。
(apply + (map (lambda (x) (apply * x)) (direct-product l1 l2))) のあたりが本題なんだろうなという感じはしますが、式が評価される様を頭でイメージできなければ、コードの解読も厳しい感じがしますね。


私からは以上です。