Skip to content

Instantly share code, notes, and snippets.

@emanon001
Created January 6, 2013 08:56
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save emanon001/4466138 to your computer and use it in GitHub Desktop.
Save emanon001/4466138 to your computer and use it in GitHub Desktop.
Project Euler Problem 20 #mitori_clj
;;; Project Euler Problem 20
;;; 「100! の各桁の数字の和を求めよ」
;;; http://odz.sakura.ne.jp/projecteuler/index.php?cmd=read&page=Problem%2020
(ns emanon001.projecteuler-answers.problem-020
(:require [clojure.test :refer [are]]))
(defn factorial
"n の階乗を返します"
[n]
(apply *' (range 1 (inc n))))
(are [n expected]
(= (factorial n) expected)
0 1
1 1
10 3628800)
(defn sum-digits
"n の各桁の和を返します"
[n]
(->> n
str
(map #(Character/digit % 10))
(apply +')))
(are [n expected]
(= (sum-digits n) expected)
1 1
12 3
3628800 27)
(defn solve
"n の階乗の、各桁の和を返します"
([] (solve 100))
([n]
(->> n
factorial
sum-digits)))
(are [n expected]
(= (solve n) expected)
1 1
4 6
10 27)
(time (solve))
; "Elapsed time: 1.06 msecs"
@emanon001
Copy link
Author

解説

  1. 階乗を計算する
  2. 階乗値を文字列に変換し、さらに各桁を数値に変換する
  3. 各桁の和を計算する

20問目まで来ると類似の問題も出てくるわけで、それらの解答を参考にしながら楽に解くことができました。

factorial

明示的な再帰(recur)は用いず、計算に必要なリストを作成して、それらを掛け合わせています。

sum-digits

文字から数値に変換する処理は、Problem 8 のコメント を参考にしました。

@kohyama
Copy link

kohyama commented Jan 7, 2013

順当な解法と思います.

各桁の数値の和を求めるところは Problem 16 とも共通してますね.
文字列化して各桁の数字を数値としてパーズする方法に加え,
Problem 16 の方の @ypsilon-takai さんのコメント が, 10で割った余りを足して行く別解として, そのまま適用できそうです.

@bouzuya
Copy link

bouzuya commented Jan 7, 2013

素直なコードですね。 問題文の説明をそのままコードで表現できているように思います。

are でパラメタライズドテストされているので、入力と対応する出力がすぐに分かりますね。

他の問題から活かせるのは嬉しいですね。

@tnoda
Copy link

tnoda commented Jan 9, 2013

👍 あまり突っ込むところが無いので,逆に困ってしまいます.

@ypsilon-takai
Copy link

僕もぜんぜん突っ込むところが無いです。

問題の意図は多倍長整数を扱うということだと思うので、何かそれ関連の話題を考えたのですが、思いつきません。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment