<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0">
  <channel>
    <title>思无邪</title>
    <description>Who in the world am I,that's the great puzzle.</description>
    <link>http://eastsun.javaeye.com</link>
    <language>UTF-8</language>
    <copyright>Copyright 2003-2008, JavaEye.com</copyright>
    <docs>http://blogs.law.harvard.edu/tech/rss</docs>
    <generator>JavaEye - 做最棒的软件开发交流社区</generator>
      <item>
        <title>澄清：Java中只有按值传递，没有按引用传递！</title>
        <author>Eastsun</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://eastsun.javaeye.com">Eastsun</a>&nbsp;
          链接：<a href="http://eastsun.javaeye.com/blog/214404" style="color:red;">http://eastsun.javaeye.com/blog/214404</a>&nbsp;
          发表时间: 2008年07月13日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          　　前言：在<a href="http://www.javaeye.com/topic/214374" target="_blank">JAVA面试题解惑系列（五）——传了值还是传了引用？</a>中作者提到了“<span style="color: red">JAVA中的传递都是值传递吗？有没有引用传递呢？</span> ”这个问题，最终得到：<br /><div class="quote_title">引用</div><div class="quote_div">最后我们得出如下的结论：<br /><br />   1. 基本类型和基本类型变量被当作参数传递给方法时，是值传递。在方法实体中，无法给原变量重新赋值，也无法改变它的值。<br />   2. 对象和引用型变量被当作参数传递给方法时，是引用传递。在方法实体中，无法给原变量重新赋值，但是可以改变它所指向对象的属性。 </div><br />　　事实上有着这种想法的人为数不少。但这个结论不完全正确。正确的说法应该是：<span style="color: red">在Java中，只有按值传递，没有按引用传递</span>！<br /><br />　　简单说，这里其实就是一个关于什么是“按引用传递”的问题。<br />　　如果你写了这样一个方法：<br /><pre name="code" class="c">
swap(Type arg1, Type arg2) {  
    Type temp = arg1;  
    arg1 = arg2;  
    arg2 = temp;  
} </pre><br /><br />　　并且像下面这样调用该方法：<br /><pre name="code" class="c">
Type var1 = ...;
Type var2 = ...;
swap(var1,var2);</pre><br />　　确实能调换var1与var2的值，才可能是“按引用传递”<br /><br />　　有关这个问题的进一步解释，我这儿不再赘述，只给出两篇不错的文章：<br />　　☆　　<a href="http://www.javaworld.com/javaworld/javaqa/2000-05/03-qa-0526-pass.html" target="_blank">Does Java pass by reference or pass by value?</a><br />　　☆　　<a href="http://javadude.com/articles/passbyvalue.htm" target="_blank">Java is Pass-by-Value, Dammit!</a><br /><br />　　下面是第二篇的全文，有空再翻译：<br /><br />Introduction<br /><br />I finally decided to write up a little something about Java's parameter passing. <span style="color: red">I'm really tired of hearing folks (incorrectly) state "primitives are passed by value, objects are passed by reference"</span>.<br /><br />I'm a compiler guy at heart. The terms "pass-by-value" semantics and "pass-by-reference" semantics have very precise definitions, and they're often horribly abused when folks talk about Java. I want to correct that... The following is how I'd describe these<br /><br /><span style="color: red">Pass-by-value</span><br />    The actual parameter (or argument expression) is fully evaluated and the resulting value is copied into a location being used to hold the formal parameter's value during method/function execution. That location is typically a chunk of memory on the runtime stack for the application (which is how Java handles it), but other languages could choose parameter storage differently.<br /><span style="color: red">Pass-by-reference</span><br />    The formal parameter merely acts as an alias for the actual parameter. Anytime the method/function uses the formal parameter (for reading or writing), it is actually using the actual parameter.<br /><br /><span style="color: red">Java is strictly pass-by-value, exactly as in C</span>. Read the Java Language Specification (JLS). It's spelled out, and it's correct. (See <a href="http://java.sun.com/docs/books/jls/second_edition/html/classes.doc.html#37472" target="_blank">http://java.sun.com/docs/books/jls/second_edition/html/classes.doc.html#37472</a>)<br /><br />In short: Java has pointers and is strictly pass-by-value. There's no funky rules. It's simple, clean, and clear. (Well, as clear as the evil C++-like syntax will allow ;)<br /><br />Note: See the note at the end of this article for the semantics of remote method invocation (RMI). What is typically called "pass by reference" for remote objects is actually incredibly bad semantics.<br />The Litmus Test<br /><br />There's a simple "litmus test" for whether a language supports pass-by-reference semantics:<br /><br />Can you write a traditional swap(a,b) method/function in the language?<br /><br />A traditional swap method or function takes two arguments and swaps them such that variables passed into the function are changed outside the function. Its basic structure looks like<br /><br /><pre name="code" class="java">// NON-JAVA!
swap(Type arg1, Type arg2) {
    Type temp = arg1;
    arg1 = arg2;
    arg2 = temp;
}</pre><br /><br />If you can write such a method/function in your language such that calling<br /><br /><pre name="code" class="java">// NON-JAVA
Type var1 = ...;
Type var2 = ...;
swap(var1,var2);</pre><br /><br />actually switches the values of the variables var1 and var2, the language supports pass-by-reference semantics.<br /><br />For example, in Pascal, you can write<br /><br />{ Pascal }<br /><pre name="code" class="java">procedure swap(var arg1, arg2: SomeType);
  var
    temp : SomeType;
  begin
    temp := arg1;
    arg1 := arg2;
    arg2 := temp;
  end;</pre><br /><br />...<br />{ in some other procedure/function/program }<br /><pre name="code" class="java">var
  var1, var2 : SomeType;
begin
  var1 := ...;
  var2 := ...;
  swap(var1, var2);
end;</pre><br /><br />or in C++ you could write<br /><br /><pre name="code" class="c++">// C++
void swap(SomeType& arg1, Sometype& arg2) {
  SomeType temp = arg1;
  arg1 = arg2;
  arg2 = temp;
}</pre><br /><br />...<br /><br /><pre name="code" class="c++">SomeType var1 = ...;
SomeType var2 = ...;
swap(var1, var2); // swaps their values!</pre><br /><br /><br />(Please let me know if my Pascal or C++ has lapsed and I've messed up the syntax...)<br /><br />But you cannot do this in Java!<br />Now the details...<br /><br />The problem we're facing here is statements like<br /><br />In Java, Objects are passed by reference, and primitives are passed by value.<br /><br />This is half incorrect. Everyone can easily agree that primitives are passed by value; there's no such thing in Java as a pointer/reference to a primitive.<br /><br />However, Objects are not passed by reference. A correct statement would be Object references are passed by value.<br /><br />This may seem like splitting hairs, bit it is far from it. There is a world of difference in meaning. The following examples should help make the distinction.<br /><br />In Java, take the case of<br /><br /><pre name="code" class="java">  public void foo(Dog d) {
    d = new Dog("Fifi");
  }

  Dog aDog = new Dog("Max");
  foo(aDog);</pre><br /><br />the variable passed in (aDog) is not modified! After calling foo, aDog still points to the "Max" Dog!<br /><br />Many people mistakenly think/state that something like<br /><br /><pre name="code" class="java">  public void foo(Dog d) { 
    d.setName("Fifi");
  }
</pre><br />shows that Java does in fact pass objects by reference.<br /><br />The mistake they make is in the definition of<br /><br /><pre name="code" class="java">  Dog d;</pre><br /><br />itself. When you write<br /><br /><pre name="code" class="java">  Dog d;</pre><br /><br />you are defining a pointer to a Dog object, not a Dog object itself.<br /><br />Calling<br /><br /><pre name="code" class="java">  foo(d);</pre><br /><br />passes the value of d to foo; it does not pass the object that d points to!<br /><br />The value of the pointer being passed is similar to a memory address. Under the covers it's a tad different, but you can think of it in exactly the same way. The value uniquely identifies some object on the heap.<br /><br />The use of the word "reference" in Java was an incredibly poor choice (in my not-so-humble opinion...) Java has pointers, plain and simple. The designers of Java wanted to try to make a distinction between C/C++ pointers and Java pointers, so they picked another term. Under the covers, pointers are implemented very differently in Java and C/C++, and Java protects the pointer values, disallowing operations such as pointer arithmetic and invalid runtime casting.<br /><br />However, it makes no difference how pointers are implemented under the covers. You program with them exactly the same way in Java as you would in C or C++. The syntax is just slightly different.<br /><br />In Java,<br /><br /><pre name="code" class="java">  Dog d;   // Java</pre><br /><br />is exactly like C or C++'s<br /><br /><pre name="code" class="c++">  Dog *d;  // C++</pre><br /><br />And using<br /><br /><pre name="code" class="java">  d.setName("Fifi");  // Java</pre><br /><br />is exactly like C++'s<br /><br /><pre name="code" class="c++">  d->setName("Fifi"); // C++</pre><br /><br />To sum up: Java has pointers, and the value of the pointer is passed in. There's no way to actually pass an object itself as a parameter. You can only pass a pointer to an object.<br /><br />Keep in mind, when you call<br /><br /><pre name="code" class="java">  foo(d);</pre><br /><br />you're not passing an object; you're passing a pointer to the object.<br /><br />For a slightly different (but still correct) take on this issue, please see http://www-106.ibm.com/developerworks/library/j-praxis/pr1.html. It's from Peter Haggar's excellent book, Practical Java.)<br /><br /><br /><span style="color: red">A Note on Remote Method Invocation (RMI)</span><br /><br />When passing parameters to remote methods, things get a bit more complex. First, we're (usually) dealing with passing data between two independent virtual machines, which might be on separate physical machines as well. Passing the value of a pointer wouldn't do any good, as the target virtual machine doesn't have access to the caller's heap.<br /><br />You'll often hear "pass by value" and "pass by reference" used with respect to RMI. These terms have more of a "logical" meaning, and really aren't correct for the intended use.<br /><br />Here's what is usually meant by these phrases with regard to RMI. Note that this is not proper usage of "pass by value" and "pass by reference" semantics:<br /><br />RMI Pass-by-value<br />    The actual parameter is serialized and passed using a network protocol to the target remote object. Serialization essentially "squeezes" the data out of an object/primitive. On the receiving end, that data is used to build a "clone" of the original object or primitive. Note that this process can be rather expensive if the actual parameters point to large objects (or large graphs of objects).<br />    This isn't quite the right use of "pass-by-value"; I think it should really be called something like "pass-by-memento". (See "Design Patterns" by Gamma et al for a description of the Memento pattern).<br />     <br />RMI Pass-by-reference<br />    The actual parameter, which is itself a remote object, is represented by a proxy. The proxy keeps track of where the actual parameter lives, and anytime the target method uses the formal parameter, another remote method invocation occurs to "call back" to the actual parameter. This can be useful if the actual parameter points to a large object (or graph of objects) and there are few call backs.<br />    This isn't quite the right use of "pass-by-reference" (again, you cannot change the actual parameter itself). I think it should be called something like "pass-by-proxy". (Again, see "Design Patterns" for descriptions of the Proxy pattern).
          <br/>
          <span style="color:red;">
            <a href="http://eastsun.javaeye.com/blog/214404#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Sun, 13 Jul 2008 22:23:20 +0800</pubDate>
        <link>http://eastsun.javaeye.com/blog/214404</link>
        <guid>http://eastsun.javaeye.com/blog/214404</guid>
      </item>
      <item>
        <title>Euler Project解题汇总 031 ~ 040</title>
        <author>Eastsun</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://eastsun.javaeye.com">Eastsun</a>&nbsp;
          链接：<a href="http://eastsun.javaeye.com/blog/210345" style="color:red;">http://eastsun.javaeye.com/blog/210345</a>&nbsp;
          发表时间: 2008年07月01日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          　　有几天没有贴<a href="http://projecteuler.net" target="_blank">Euler Project</a>上的解题代码了。主要是我发帖的速度很慢，有时可能比做题本身花的时间还要长，很麻烦的一件事。考虑到以后的题目难度会越来越大，某些题目我会加上<span style="color: red">题目分析</span>，对解题方法进行简单的提示。<br /><br /><a href="http://projecteuler.net/index.php?section=problems&id=31" target="_blank">问题31</a>：<span style="color: orange">Investigating combinations of English currency denominations.</span><br /><span style="color: red">题目简介</span>：英国的货币有便士(p)与英镑(£)两种，有以下8种常见的面值：<br />　　　1p, 2p, 5p, 10p, 20p, 50p, £1 (100p) and £2 (200p).<br />2英镑的总值可能是如下的一种组合方式：<br />　　1×£1 + 1×50p + 2×20p + 1×5p + 1×2p + 3×1p<br />现在要求总值为两英镑的所有可能的组合方式数。<br /><span style="color: red">题目分析</span>：这是典型的动态规划(DP)题，不过这里数据量很小，直接暴力之。<br /><span style="color: red">答    案</span>：73682<br /><pre name="code" class="java">// Scala
def ways(c:Int,ls:List[Int]):Int =ls match{
    case Nil   => if(c == 0) 1 else 0
    case x::xs => 0.to(c/x).foldLeft(0){ (s,n) => s+ways(c-x*n,xs) }
}
ways(200,200::100::50::20::10::5::2::1::Nil)</pre><br /><br /><br /><br /><a href="http://projecteuler.net/index.php?section=problems&id=32" target="_blank">问题32</a>：<span style="color: orange">Find the sum of all numbers that can be written as pandigital products.</span><br /><span style="color: red">题目简介</span>： 数字7254有着特殊的性质：<br />　　　　　　　39×186 = 7254<br />可以看到，乘数，被乘数与乘积连起来恰好是数字1到9的一个排列(391867254)。<br />现在求所有数c的和，其中c满足存在a,b使得a×b=c，且a,b,c连起来为123456789的一个排列。<br /><span style="color: red">题目分析</span>：简单的分析后可以知道数c只可能是一个4位数(why?自己想-_-)。然后就可以暴力之~<br /><span style="color: red">答    案</span>：45228<br /><pre name="code" class="java">// Scala
//a,b,c是否恰为123456789的一个排列
def suit(a:Int,b:Int,c:Int):Boolean ={
    var fs =new Array[Boolean](10)
    def test(n:Int){
        var t =n
        while(t != 0){
            fs(t%10) =true
            t = t/10
        }
    }
    test(a)
    test(b)
    test(c)
    fs.slice(1,10).forall(_==true)
}
1234.to(9876).filter{ n => 
    2.to(Math.sqrt(n)).filter{ n%_==0 }.exists{ k => suit(k,n/k,n) }
}.foldLeft(0){ _+_ }</pre><br /><br /><br /><a href="http://projecteuler.net/index.php?section=problems&id=33" target="_blank">问题33</a>：<span style="color: orange">Discover all the fractions with an unorthodox cancelling method.</span><br /><span style="color: red">题目简介</span>： 49/98 = 4/8<br />　　上面的分数化简是正确的，但一个没有学过数学的人可能会误以为是将分子与分母中的9同时消去得到的。这样的理解是错误的，但这儿确实有一些分数ab/bc，它的值与a/c相等。现在要求所有这样的分数(小于1)的积化成最简形式后分母的值。<br /><br /><span style="color: red">题目分析</span>：略<br /><span style="color: red">答    案</span>：100<br /><pre name="code" class="java">// Scala
def gcd(a:Int,b:Int):Int =if(a==0) b else gcd(b%a,a)
var ls = for{ a &lt;- 1 to 9
             b &lt;- 1 to 9
             c &lt;- 1 until b
             if 9*b*c+a*b == 10*a*c
         } yield (c,b)
var (a,b) = ls.foldLeft(Pair(1,1)){(p,v) =>(p._1*v._1,p._2*v._2)}
var res = b/gcd(a,b)</pre><br /><br /><a href="http://projecteuler.net/index.php?section=problems&id=34" target="_blank">问题34</a>：<span style="color: orange">	Find the sum of all numbers which are equal to the sum of the factorial of their digits.</span><br /><span style="color: red">题目简介</span>：求所有能表示为其各位数字的阶乘的和的数。<br /><span style="color: olive">譬如：145 = 1! + 4! + 5! </span><br /><span style="color: red">注意：</span>虽然1! = 1， 2! = 2 ，但这两个数不包括在内。<br /><span style="color: red">题目分析</span>：关键是算出这种数的一个上界。<br />　　　　<span style="color: olive">PS：比较意外的是，即便包括1，2在内，满足条件的这种数一共才4个</span><br /><span style="color: red">答    案</span>：40730<br /><pre name="code" class="java">// Scala
object Euler034 extends Application {
    var fac = Array.range(0,10).map{ n => 1.to(n).foldLeft(1){ _*_ } }
    var res = 0
    for(n &lt;- 10 to 7*fac(9)){
        var sum = n.toString.foldLeft(0){ (s,i) => s+fac(i-'0') }
        if(sum == n) res += n
    }
    println(res)
}</pre><br /><br /><br /><a href="http://projecteuler.net/index.php?section=problems&id=35" target="_blank">问题35</a>：<span style="color: orange">	<br />How many circular primes are there below one million?</span><br /><span style="color: red">题目简介</span>：197被称为环形素数(circular prime)，这是因为它所有的轮换：197, 971, 719都是素数。求1,000,000以内环形素数的个数。<br /><span style="color: red">题目分析</span>：略<br /><span style="color: red">答    案</span>：55<br /><pre name="code" class="java">// Scala
import java.util.Arrays.{binarySearch => find}
import java.util.BitSet
import scala.collection.jcl.LinkedList

object Euler035 extends Application{
    /**
       得到小于bound的素数从小到大组成的Array
       Sieve of Eratosthenes 
    */
    def takePrime(bound:Int):Array[Int] = {
        if(bound &lt;= 2) return Array()
        var set = new BitSet(bound)
        var idx = 2
        var lst = new LinkedList[Int]
        lst.add(2)
        while(idx &lt; bound){
            var sp = lst.last
            var st = sp*2
            while(st &lt;= bound){
                set.set(st)
                st += sp
            }
            st = sp+1
            while(st &lt; bound && set.get(st)) st += 1
            if(st &lt; bound) lst.add(st)
            idx = st
        }
        lst.toArray
    }
    val pa = takePrime(1000000)
    val po = Array(1000000,100000,10000,1000,100,10,1)
    
    def suit(p:Int):Boolean ={
        var pow = po.find{_&lt;p}.get
        var cpy = p
        do{
            cpy = cpy/10 + cpy%10*pow
            if(find(pa,cpy) &lt; 0) return false
        }while(cpy != p)
        true
    } 
    
    var res = pa.filter{ suit _ }.length
    println(res)
}</pre><br /><br /><br /><a href="http://projecteuler.net/index.php?section=problems&id=36" target="_blank">问题36</a>：<span style="color: orange">Find the sum of all numbers less than one million, which are palindromic in base 10 and base 2.</span><br /><span style="color: red">题目简介</span>：求1,000,000以内的10进制与2进制表示都为回文数的数之和。<br /><span style="color: red">题目分析</span>：略<br /><span style="color: red">答    案</span>：872187<br /><pre name="code" class="java">// Scala
def isPalin(n:Int):Boolean ={
    var cpy =n
    var inv =0
    while(cpy != 0){
        inv = inv*10 + cpy%10
        cpy = cpy/10
    }
    if(inv != n) return false
    while(inv != 0){
        cpy = cpy&lt;&lt;1
        if((inv&1) != 0) cpy = cpy|1
        inv = inv>>>1
    }
    cpy == n
}

1.until(1000000).filter{ n => isPalin(n) }.foldLeft(0){ _+ _}</pre><br /><br /><br /><br /><a href="http://projecteuler.net/index.php?section=problems&id=37" target="_blank">问题37</a>：<span style="color: orange">Find the sum of all eleven primes that are both truncatable from left to right and right to left.</span><br /><span style="color: red">题目简介</span>：数3797有个有趣的性质：<br />　　依次将它左边的数字一个个移去，得到：3797, 797, 97, 7<br />　　或者从右边进行：3797, 379, 37, 3<br />得到的这些数都是素数。已经证明这样的数只有11个(不包括2,3,5,7)。求所有这样的数之和。<br /><span style="color: red">题目分析</span>：懒得想了，直接把35题的代码改改就行。<br /><span style="color: red">答    案</span>：748317<br /><pre name="code" class="java">// Scala
import java.util.Arrays.{binarySearch => find}
import java.util.BitSet
import scala.collection.jcl.LinkedList

object Euler037 extends Application{
    /**
       得到小于bound的素数从小到大组成的Array
       Sieve of Eratosthenes 
    */
    def takePrime(bound:Int):Array[Int] = {
        if(bound &lt;= 2) return Array()
        var set = new BitSet(bound)
        var idx = 2
        var lst = new LinkedList[Int]
        lst.add(2)
        while(idx &lt; bound){
            var sp = lst.last
            var st = sp*2
            while(st &lt;= bound){
                set.set(st)
                st += sp
            }
            st = sp+1
            while(st &lt; bound && set.get(st)) st += 1
            if(st &lt; bound) lst.add(st)
            idx = st
        }
        lst.toArray
    }
    val pa = takePrime(1000000)
    val po = Array(1000000,100000,10000,1000,100,10,1)
    
    def suit(p:Int):Boolean ={
        var pow = po.find{_&lt;p}.get
        var cpy = p
        var cpx = p
        do{
            cpy = cpy%pow
            cpx = cpx/10
            pow = pow/10
            if(find(pa,cpx) &lt; 0||find(pa,cpy) &lt; 0) return false
        }while(pow > 1)
        true
    } 
    
    var res = pa.filter{ suit _ }.foldLeft(0){ _+_ }
    println(res)
}</pre><br /><br /><br /><a href="http://projecteuler.net/index.php?section=problems&id=38" target="_blank">问题38</a>：<span style="color: orange">What is the largest 1 to 9 pandigital that can be formed by multiplying a fixed number by 1, 2, 3, ... ?</span><br /><span style="color: red">题目简介</span>：求满足下列条件的最大的那个数A：<br />　　存在自然数数a及n(>1)，使得：<br />　　　　a×1 = m1<br />　　　　……<br />　　　　a×n = mn<br />　　将m1,...,mn依次相连恰好为123456789的一个排列，并且记A为连接成的那个数。<br /><span style="color: olive">譬如192384576就是满足条件的一个数，因为：<br />　　192×1 = 192<br />　　192×2 = 384<br />　　192×3 = 576</span><br /><span style="color: red">题目分析</span>：暴力是个好东东～<br /><span style="color: red">答    案</span>：932718654<br /><pre name="code" class="java">// Scala
object Euler038 extends Application {
    var res = "0"
    
    def suit(s:String):Boolean = {
        if(s.length != 9) return false
        var fs =new Array[Boolean](10)
        for(c &lt;- s)
            if(c=='0') return false
            else if(fs(c-'0')) return false
            else  fs(c-'0') =true
        true
    }
    
    for(n &lt;- 1 until 100000){
        var n2s =""
        var mul =1
        do{
            n2s += n*mul
            mul += 1
        }while(n2s.length&lt;9)
        if(suit(n2s) && n2s>res)  res = n2s
    }
    println(res)
}</pre><br /><br /><br /><a href="http://projecteuler.net/index.php?section=problems&id=39" target="_blank">问题39</a>：<span style="color: orange">	If p is the perimeter of a right angle triangle, {a, b, c}, which value, for p ≤ 1000, has the most solutions?</span><br /><span style="color: red">题目简介</span>：1000以内，求数p使得周长为p的直角三角形的种数最多。<br /><span style="color: olive">譬如周长为120的直角三角形有三种：{20,48,52}, {24,45,51}, {30,40,50}</span><br /><span style="color: red">题目分析</span>：略<br /><span style="color: red">答    案</span>：840<br /><pre name="code" class="java">// Scala
var res =0
var max =0
for(p &lt;- 1 until 1000){
    var c =0
    for{ a &lt;- 1 until p/2
         b &lt;- 1 to a
         if a*a+b*b==(p-a-b)*(p-a-b)
    } c += 1
    if(c > max){
        max =c
        res =p
    }
}
res</pre><br /><br /><br /><a href="http://projecteuler.net/index.php?section=problems&id=40" target="_blank">问题40</a>：<span style="color: orange">Finding the nth digit of the fractional part of the irrational number.</span><br /><span style="color: red">题目简介</span>：将所有的自然数依次连起来作为小数部分做成一个无线不循环小数：<br />　　　　0.12345678910<span style="color: red">1</span>112131415161718192021...<br />记该小数第n位的数字为d(n)，有d(12) = 1<br />求： d(1)×d(10)×d(100)×d(1000)×d(10000)×d(100000)×d(1000000)<br /><span style="color: red">题目分析</span>：暴力，又见暴力～<br />事实上这个题有高效的算法，不过此处数据量太小，暴力足已。<br /><span style="color: red">答    案</span>：210<br /><pre name="code" class="java">// Scala
var sb = new StringBuilder
var n =1
while(sb.length &lt; 1000000){
    sb.append(n)
    n += 1
}
var res = 1
var idx = 1
for(i &lt;- 0 to 6){
    res = res*(sb(idx-1)-'0')
    idx = idx*10
}
res</pre>
          <br/>
          <span style="color:red;">
            <a href="http://eastsun.javaeye.com/blog/210345#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Tue, 01 Jul 2008 23:41:22 +0800</pubDate>
        <link>http://eastsun.javaeye.com/blog/210345</link>
        <guid>http://eastsun.javaeye.com/blog/210345</guid>
      </item>
      <item>
        <title>按字典顺序生成所有的排列</title>
        <author>Eastsun</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://eastsun.javaeye.com">Eastsun</a>&nbsp;
          链接：<a href="http://eastsun.javaeye.com/blog/207614" style="color:red;">http://eastsun.javaeye.com/blog/207614</a>&nbsp;
          发表时间: 2008年06月24日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          　　因为最近在做<a href="http://eastsun.javaeye.com/category/34059" target="_blank">Project Euler</a>上的题，里面涉及到的都是和数学有关问题，有一些数学概念会反复出现。比如判断一个数是否为素数，求一些元素的全排列之类。为了方便起见，我把一些功能写成函数，以便以后重复使用。这个帖子介绍的是将一些元素所有的全排列按<a href="http://en.wikipedia.org/wiki/Lexicographical_order" target="_blank">字典顺序</a>依次生成的函数。<br /><br /><strong><span style="font-size: medium"><span style="color: red">☆</span> Scala代码</span></strong><br /><pre name="code" class="java">/**
   &#Util.scala
   utils for mathematical algorithm,include:
   # generate all permutations in lexicographical order
   
   @author Eastsun
*/
package eastsun.math

object Util {
    /**
      Rearranges the elements in the Array[T] src into the lexicographically next smaller permutation of elements.
      The comparisons of individual elements are performed using operators &lt;= and >= in Ordered[T]
      @return true if the function rearranged the array as a lexicographicaly smaller permutation.
    */
    def prevPermutation[T](src:Array[T])
                    (implicit view:(T) => Ordered[T]):Boolean = {
        var i = src.length - 2
        while(i >= 0 && src(i) &lt;= src(i+1)) i -= 1
        if(i &lt; 0) return false
        var j = src.length - 1
        while(src(j) >= src(i)) j -= 1
        adjustArray(src,i,j) 
        true
    }
    
    /**
      Rearranges the elements in the Array[T] src into the lexicographically next greater permutation of elements.
      The comparisons of individual elements are performed using operators &lt;= and >= Ordered[T]
      @return true if the function rearrange the array as a lexicographicaly greater permutation.
    */
    def nextPermutation[T](src:Array[T])
                    (implicit view:(T) => Ordered[T]):Boolean = {
        var i = src.length - 2
        while(i >= 0 && src(i) >= src(i+1)) i -= 1
        if(i &lt; 0) return false
        var j = src.length - 1
        while(src(j) &lt;= src(i)) j -= 1
        adjustArray(src,i,j)
        true
    }
    
    private def adjustArray[T](src:Array[T],i:Int,j:Int){
        var tmp = src(i)
        src(i) = src(j)
        src(j) = tmp
        var len = (src.length - i)/2
        for(k &lt;- 1 to len){
            tmp = src(src.length - k)
            src(src.length - k) = src(i + k)
            src(i + k) = tmp
        }
    }
}</pre><br />　　算法没什么特别的，如果不清楚google一下即可，这儿就简单说明一下代码。Util中含两个public方法：<br /><pre name="code" class="java">def prevPermutation[T](src:Array[T])(implicit view:(T) => Ordered[T]):Boolean
def nextPermutation[T](src:Array[T])(implicit view:(T) => Ordered[T]):Boolean</pre><br />　　顾名思义，第一个<span style="color: orange">prevPermutation</span>方法是将数组src重排成比当前字典顺序小的上一个排列。注意该方法的返回值为Boolean：如果存在比当前字典顺序小的排列，则重排src，并返回true；否则不影响src并返回false。还算有两点需要注意的地方：<br />　　1.该方法第二个参数view是implicit的，所以调用该方法的时候可以省略。只需要保证类型T有一个到Ordered[T]类型的隐式转换就可以了。<br />　　2.该方法第一个参数src中允许有重复的元素。<br />　　　<span style="color: olive">比如对于1,2,3,3,其所有排列按字典顺序排列为：<br />　　　　1233<br />　　　　1323<br />　　　　1332<br />　　　　2133<br />　　　　2313<br />　　　　2331<br />　　　　3123<br />　　　　3132<br />　　　　3213<br />　　　　3231<br />　　　　3312<br />　　　　3321</span><br /><br /><strong><span style="font-size: medium"><span style="color: red">☆</span> 应用</span></strong><br />　　下面就通过解决<a href="http://eastsun.javaeye.com/category/34059" target="_blank">Project Euler</a>中的两个题来示范一下如何使用这两个API。<br /><br /><a href="http://projecteuler.net/index.php?section=problems&id=24" target="_blank">题目24</a>：What is the millionth lexicographic permutation of the digits 0, 1, 2, 3, 4, 5, 6, 7, 8 and 9?<br /><span style="color: darkred">题目简介</span>：将数字0, 1, 2, 3, 4, 5, 6, 7, 8 ,9的所有排列按字典顺序排序，求排在第1,000,000位的那个数字。(注意：从第一位记起) <br />　　当然这个题有更高效的解决方法，可以参看<a href="http://eastsun.javaeye.com/blog/204837" target="_blank">Euler Project解题汇总 023 ~ 030</a>。这里就使用nextPermutation方法暴力解决：<br /><pre name="code" class="java">import eastsun.math.Util._

object Euler024 extends Application {
    var src = Array(0,1,2,3,4,5,6,7,8,9)
    for(idx &lt;- 1 until 1000000) nextPermutation(src)
    println(src.mkString(""))
}</pre><br /><br /><a href="http://projecteuler.net/index.php?section=problems&id=41" target="_blank">问题41</a>：What is the largest n-digit pandigital prime that exists?<br /><span style="color: darkred">题目简介</span>：一个数称为pandigital，如果它是数字1，2，……，n的一个排列。比如2143就是一个4位的pandigital。<br />　　现在求所有pandigital中最大的那个素数。<br /><span style="color: red">解题思路</span>：我们先不对这个问题进行进一步数学上的分析，直接想怎么用蛮力法去解决它。显然，我们可以先从9位的pandigital从大大小进行尝试，如果找到了一个素数，那么这个数就是所求；否则，再对8位的pandigital从大到小进行尝试……如此直到找到一个素数为止，这个素数就是问题的答案。<br />　　下面就是依照这个思路写的代码：<br /><pre name="code" class="java">import eastsun.math.Util._

object Euler041 extends Application {
    def isPrime(n:Int) = 2.to(Math.sqrt(n)).forall{ n%_ != 0}
    
    var buf = Array(9,8,7,6,5,4,3,2,1)
    var idx = 0
    var res = 0
    while(res == 0){
        var src = buf.subArray(idx,buf.length)
        do{
            var num = src.foldLeft(0){ _*10 + _ }
            if(isPrime(num)) res = num
        }while(res == 0&&prevPermutation(src))
        idx += 1
    }
    println(res)
}</pre><br />　　虽然是很野蛮的方法，但这段代码已经够用了，只需要2秒左右就能得到答案。不过只要再简单思考一下，就可以瞬时找到答案。如果你高中数学还学得马马虎虎，应该不难验证：<span style="color: green">一个数能被3整除当且仅当这个数的各位数字之和能被3整除</span>。这样就可以知道9位的pandigital里面不可能有素数，因为1+2+3+..+9 = 45能被三整除，同样可以知道8位的pandigital里面也没有素数。所以事实上我们从7位的pandigital试起就可以。
          <br/>
          <span style="color:red;">
            <a href="http://eastsun.javaeye.com/blog/207614#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Tue, 24 Jun 2008 17:59:19 +0800</pubDate>
        <link>http://eastsun.javaeye.com/blog/207614</link>
        <guid>http://eastsun.javaeye.com/blog/207614</guid>
      </item>
      <item>
        <title>Euler Project解题汇总 023 ~ 030</title>
        <author>Eastsun</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://eastsun.javaeye.com">Eastsun</a>&nbsp;
          链接：<a href="http://eastsun.javaeye.com/blog/204837" style="color:red;">http://eastsun.javaeye.com/blog/204837</a>&nbsp;
          发表时间: 2008年06月17日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          　　RT，接着上次<a href="http://eastsun.javaeye.com/blog/204434" target="_blank">Euler Project解题汇总 013 ~ 022</a>继续贴我写的解题代码。题目的难度相比之前的大了一些，有些题不是看一眼直接就能想出正确的方法了。建议想做这些题的同学先自己做下再来看我写的代码。<br /><br /><a href="http://projecteuler.net/index.php?section=problems&id=23" target="_blank">题目23</a>：<span style="color: orange">Find the sum of all the positive integers which cannot be written as the sum of two abundant numbers.</span><br /><span style="color: red">题目简介</span>：首先引入一个数学中的概念(呵呵，普及下数学知识)：<br />　　自然数n称为<a href="http://baike.baidu.com/view/1596350.htm" target="_blank">盈数</a>(又称过剩数abundant number)，如果除n之外的正约数之和大于n。<br />　　<span style="color: olive">譬如12是最小的盈数，因为：1+2+3+4+6 =16 > 12</span><br />　　已知数学中的一个结论：所有大于28123的自然数都能分解为两个盈数之和。现在要求所有不能分解为两个盈数之和的自然数之和。（有点绕口:-)）<br /><span style="color: red">答案</span>：4179871<br /><pre name="code" class="java"> //Scala
    val MAX =28123
    val fs  = new Array[Boolean](MAX+1)
    for(i &lt;- 0 to MAX){
        var k = 2
        var s = 1
        while(k*k &lt; i){ 
            if(i%k == 0) s =s+k+i/k
            k += 1
        }
        if(k*k == i) s += k
        fs(i) = s>i
    }
    var res =0
    for(n &lt;- 1 to MAX){
        val f =1.to(n/2).forall{k => !(fs(k)&&fs(n-k)) }
        if(f) res += n
    }
    res</pre><br /><br /><a href="http://projecteuler.net/index.php?section=problems&id=24" target="_blank">题目24</a>：What is the millionth lexicographic permutation of the digits 0, 1, 2, 3, 4, 5, 6, 7, 8 and 9?<br /><span style="color: red">题目简介</span>：将数字0, 1, 2, 3, 4, 5, 6, 7, 8 ,9的所有排列按字典顺序排序，求排在第1,000,000位的那个数字。(注意：从第一位记起)<br />　　<span style="color: olive">譬如，数字0,1,2的所有排列按字典排序为：<br />　　　　012   021   102   120   201   210<br />　　第3位为 102</span><br /><span style="color: red">答案</span>：2783915460<br /><pre name="code" class="java">    //Scala
    def nth(n:BigInt,a:Array[Char]):String ={
        var idx = a.length -1
        var fac = 1.to(idx).foldLeft(1:BigInt){ _*_ }
        var cpy = n
        for(i &lt;- 0 until idx){
            var k = (cpy/fac).intValue
            var t = a(i+k)
            for(p &lt;- (k+i).until(i,-1)) a(p) =a(p-1)
            a(i) = t
            cpy = cpy%fac
            fac = fac/(idx-i)
        }
        String.valueOf(a)
    }
    nth(1000000-1,"0123456789".toCharArray)</pre><br /><br /><br /><a href="http://projecteuler.net/index.php?section=problems&id=25" target="_blank">问题25</a>：<span style="color: orange">What is the first term in the Fibonacci sequence to contain 1000 digits?</span><br /><span style="color: red">题目简介</span>：对于斐波那契数列：<br />　　　F1 =1, F2 =1, Fn =Fn-1 +Fn-2 (n>=3)<br />　　求第一个为1000位数的项数。<br /><span style="color: red">答案</span>：4782<br /><pre name="code" class="java">//Scala
var fib:Stream[BigInt] = Stream.cons(1,Stream.cons(1,
                              fib.zip(fib.tail).map{case(x,y) => x+y}
                         ))
fib.findIndexOf{ _.toString.length == 1000 }+1</pre><br /><br /><br /><a href="http://projecteuler.net/index.php?section=problems&id=26" target="_blank">问题26</a>：<span style="color: orange">Find the value of d &lt; 1000 for which 1/d contains the longest recurring cycle.</span><br /><span style="color: red">题目简介</span>：我们知道有些分数不能用有限位的小数表示出来，那些分数的小数表示叫无限循环小数，其循环部分称为循环节，循环节的长度称为周期。<br />　　现在求小于1000的自然数d，使得1/d的循环周期最大。<br />　　<span style="color: olive">譬如，d从2到10的小数表示为：(括号里面的为循环节)<br />　　　　1/2	= 	0.5<br />　　　　1/3	= 	0.(3)<br />　　　　1/4	= 	0.25<br />　　　　1/5	= 	0.2<br />　　　　1/6	= 	0.1(6)<br />　　　　1/7	= 	0.(142857)<br />　　　　1/8	= 	0.125<br />　　　　1/9	= 	0.(1)<br />　　　　1/10	= 	0.1<br />　　其中d=7时的循环节为142857，其长度为6。</span><br /><span style="color: red">答案</span>：983<br /><pre name="code" class="java">    //Scala
    def cycle(n:Int):Int ={
        var k:BigInt =10
        var c =1
        while((k-1)%n != 0){
            k =k*10
            c +=1
        }
        c
    }
    var max =0
    var res =0
    for( n &lt;- 2 until 1000;if !(n%2==0||n%5==0)){
        var c =cycle(n)
        if(c>max){
            max =c
            res =n
        }
    }
    res</pre><br /><br /><br /><a href="http://projecteuler.net/index.php?section=problems&id=27" target="_blank">问题27</a>：<span style="color: orange">Find a quadratic formula that produces the maximum number of primes for consecutive values of n.</span><br /><span style="color: red">题目简介</span>：对于整数a,b,定义函数 f：<br />　　　　f(n) = n*n + a*n +b<br />　　又记len(f)表示f(n)从n =0开始能连续生成素数（质数）的最大长度。也就是：<br />　　　　len(f) = max{n : f(0),f(1),...,f(n-1)都是素数}<br />　　现在对|a|&lt;1000,|b|&lt;1000，求a,b使得len(f)最大。<br />　　输出a,b的乘积<br />　　<span style="color: olive">譬如： a =1,b =41的时候，f(n) =n^2+n+41。<br />　　f(0),f(1),...,f(39)都是质数，并且f(40)不是质数。<br />　　所以此时len(f) =40。 （这个式子是Euler发现的）</span><br /><span style="color: red">答案</span>：-59231 (a = -61,b = 971)<br /><pre name="code" class="java">//Scala
    val ps:Stream[Int] = Stream.cons(2,
                             Stream.from(3).filter{ n =>
                                 ps.takeWhile(p => p*p &lt;= n).forall(n%_ !=0)
                             })
    def suit(a:Int,b:Int,n:Int):Boolean ={
        val v = n*n+a*n+b
        if(v &lt;= 0) false
        else ps.takeWhile{p =>p*p&lt;=v}.forall{ v%_ !=0 }
    }
    
    var max = 40
    var res = (1,41)
    for(a &lt;- -999 to 999;b &lt;- ps.takeWhile{_&lt;1000};if suit(a,b,max)){
        var n =0
        while(suit(a,b,n)) n += 1
        if(n > max){
            res =(a,b)
            max =n
        }
    }
    res._1*res._2</pre><br /><br /><br /><a href="http://projecteuler.net/index.php?section=problems&id=28" target="_blank">问题28</a>：<span style="color: orange">What is the sum of both diagonals in a 1001 by 1001 spiral?</span><br /><span style="color: red">题目简介</span>：将自然化按顺时针方向螺旋形依次排列形成一个方阵。<br />　　求这样的1001*1001的方阵的两条对角线上数字之和。<br />　　<span style="color: olive">譬如，对于5*5的方阵：</span><br />　　　　<span style="color: red">21</span>  22  23  24  <span style="color: red">25</span><br />　　　　20　<span style="color: red">7</span>  8　<span style="color: red">9</span>　10<br />　　　　19　6　<span style="color: red">1</span>  2　11<br />　　　　18　<span style="color: red">5</span>　4　<span style="color: red">3</span> 12<br />　　　　<span style="color: red">17</span>  16  15  14 <span style="color: red">13</span><br />　　<span style="color: olive">其对角线上的和为101。</span><br /><span style="color: red">答案</span>：669171001<br /><pre name="code" class="java">//Scala
var num =1
var res =1
for(k &lt;- 2.until(1001,2);p &lt;- 1 to 4){
    num += k
    res += num
}
res</pre><br /><br /><a href="http://projecteuler.net/index.php?section=problems&id=29" target="_blank">问题29</a>：<span style="color: orange">How many distinct terms are in the sequence generated by a^b for 2 ≤ a ≤ 100 and 2 ≤ b ≤ 100?</span><br /><span style="color: red">题目简介</span>：对 2 ≤ a ≤ 100 ，2 ≤ b ≤ 100：a^b一共产生了多少个不同的数。<br /><span style="color: red">答案</span>：9183<br /><pre name="code" class="java">/**
    &#Euler029.scala
    @author Eastsun
*/
import scala.util.Sorting.quickSort

object Euler029 extends Application {
    var buf =new Array[BigInt](99*99)
    for(a &lt;- 2 to 100;b &lt;- 2 to 100){
        var ba:BigInt =a
        buf((a-2)*99+b-2) =ba.pow(b)
    }
    quickSort(buf)
    var res =0
    var pre:BigInt =0
    for(n &lt;- buf)
        if(n != pre){
            res += 1
            pre = n
        }
    println(res)
}</pre><br /><br /><br /><a href="http://projecteuler.net/index.php?section=problems&id=30" target="_blank">问题30</a>：<span style="color: orange">Find the sum of all the numbers that can be written as the sum of fifth powers of their digits.</span><br /><span style="color: red">题目简介</span>：求所有能表示为其各位数字五次方之和的自然数的和。<br />　　注意：虽然1 = 1^5，但由于这不是“各位数字五次方之和”，所以不包括在内。<br /><span style="color: red">答案</span>：443839<br /><pre name="code" class="java">//Scala
10.to(1000000).filter{ n =>
     var t =n
     var s =0
     while(t != 0){
         var r =t%10
         s += r*r*r*r*r
         t = t/10
     }
     s ==n
}.foldLeft(0){ _+_ }</pre>
          <br/>
          <span style="color:red;">
            <a href="http://eastsun.javaeye.com/blog/204837#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Tue, 17 Jun 2008 22:07:35 +0800</pubDate>
        <link>http://eastsun.javaeye.com/blog/204837</link>
        <guid>http://eastsun.javaeye.com/blog/204837</guid>
      </item>
      <item>
        <title>Euler Project解题汇总 013 ~ 022</title>
        <author>Eastsun</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://eastsun.javaeye.com">Eastsun</a>&nbsp;
          链接：<a href="http://eastsun.javaeye.com/blog/204434" style="color:red;">http://eastsun.javaeye.com/blog/204434</a>&nbsp;
          发表时间: 2008年06月16日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          　　<strong><span style="color: darkred">前言</span></strong>:<a href="http://projecteuler.net/" target="_blank">Project Euler</a>是一个很有趣的网站，上面提供了一系列有一定挑战性的数学问题，这些问题如果单凭手工计算做不了几个，但如果使用编程并采用适当的算法就可以解决之。如果你对数学感兴趣并且会编程不妨去试试。<br />　　这篇帖子接着<a href="http://eastsun.javaeye.com/blog/203289" target="_blank">Euler Project解题汇总 001 ~ 012</a>的内容继续将我最近做的一些题的答案贴上来。<span style="color: red">注意</span>，有一个不同的地方是：上一个贴中的<a href="http://eastsun.javaeye.com/category/30003" target="_blank">Scala</a>代码都能够直接复制到<a href="http://eastsun.javaeye.com/category/30003" target="_blank">Scala</a>控制台运行。由于某些原因，<span style="color: red">以后贴出的Scala代码有些可能需要先保存为文本文件，然后编译运行，而不能直接复制到控制台来运行</span>。这样的代码会包含一个完整的类<span style="color: red">EulerXXX</span>(XXX表示题号)，并且最后一行的代码一定是一个<span style="color: blue">println</span>语句。<br /><br /><a href="http://projecteuler.net/index.php?section=problems&id=13" target="_blank">问题13</a>:<span style="color: orange">Find the first ten digits of the sum of one-hundred 50-digit numbers.</span><br />求给定的100个50位数之和的前10个数字。<br /><span style="color: red">答案</span>:5537376230<br /><pre name="code" class="java">/**
  &#Euler013.scala
  @author: Eastsun
*/
object Euler013 extends Application {                 
    var src = """37107287533902102798797998220837590246510135740250
                 46376937677490009712648124896970078050417018260538
                 74324986199524741059474233309513058123726617309629
                 91942213363574161572522430563301811072406154908250
                 23067588207539346171171980310421047513778063246676
                 89261670696623633820136378418383684178734361726757
                 28112879812849979408065481931592621691275889832738
                 44274228917432520321923589422876796487670272189318
                 47451445736001306439091167216856844588711603153276
                 70386486105843025439939619828917593665686757934951
                 62176457141856560629502157223196586755079324193331
                 64906352462741904929101432445813822663347944758178
                 92575867718337217661963751590579239728245598838407
                 58203565325359399008402633568948830189458628227828
                 80181199384826282014278194139940567587151170094390
                 35398664372827112653829987240784473053190104293586
                 86515506006295864861532075273371959191420517255829
                 71693888707715466499115593487603532921714970056938
                 54370070576826684624621495650076471787294438377604
                 53282654108756828443191190634694037855217779295145
                 36123272525000296071075082563815656710885258350721
                 45876576172410976447339110607218265236877223636045
                 17423706905851860660448207621209813287860733969412
                 81142660418086830619328460811191061556940512689692
                 51934325451728388641918047049293215058642563049483
                 62467221648435076201727918039944693004732956340691
                 15732444386908125794514089057706229429197107928209
                 55037687525678773091862540744969844508330393682126
                 18336384825330154686196124348767681297534375946515
                 80386287592878490201521685554828717201219257766954
                 78182833757993103614740356856449095527097864797581
                 16726320100436897842553539920931837441497806860984
                 48403098129077791799088218795327364475675590848030
                 87086987551392711854517078544161852424320693150332
                 59959406895756536782107074926966537676326235447210
                 69793950679652694742597709739166693763042633987085
                 41052684708299085211399427365734116182760315001271
                 65378607361501080857009149939512557028198746004375
                 35829035317434717326932123578154982629742552737307
                 94953759765105305946966067683156574377167401875275
                 88902802571733229619176668713819931811048770190271
                 25267680276078003013678680992525463401061632866526
                 36270218540497705585629946580636237993140746255962
                 24074486908231174977792365466257246923322810917141
                 91430288197103288597806669760892938638285025333403
                 34413065578016127815921815005561868836468420090470
                 23053081172816430487623791969842487255036638784583
                 11487696932154902810424020138335124462181441773470
                 63783299490636259666498587618221225225512486764533
                 67720186971698544312419572409913959008952310058822
                 95548255300263520781532296796249481641953868218774
                 76085327132285723110424803456124867697064507995236
                 37774242535411291684276865538926205024910326572967
                 23701913275725675285653248258265463092207058596522
                 29798860272258331913126375147341994889534765745501
                 18495701454879288984856827726077713721403798879715
                 38298203783031473527721580348144513491373226651381
                 34829543829199918180278916522431027392251122869539
                 40957953066405232632538044100059654939159879593635
                 29746152185502371307642255121183693803580388584903
                 41698116222072977186158236678424689157993532961922
                 62467957194401269043877107275048102390895523597457
                 23189706772547915061505504953922979530901129967519
                 86188088225875314529584099251203829009407770775672
                 11306739708304724483816533873502340845647058077308
                 82959174767140363198008187129011875491310547126581
                 97623331044818386269515456334926366572897563400500
                 42846280183517070527831839425882145521227251250327
                 55121603546981200581762165212827652751691296897789
                 32238195734329339946437501907836945765883352399886
                 75506164965184775180738168837861091527357929701337
                 62177842752192623401942399639168044983993173312731
                 32924185707147349566916674687634660915035914677504
                 99518671430235219628894890102423325116913619626622
                 73267460800591547471830798392868535206946944540724
                 76841822524674417161514036427982273348055556214818
                 97142617910342598647204516893989422179826088076852
                 87783646182799346313767754307809363333018982642090
                 10848802521674670883215120185883543223812876952786
                 71329612474782464538636993009049310363619763878039
                 62184073572399794223406235393808339651327408011116
                 66627891981488087797941876876144230030984490851411
                 60661826293682836764744779239180335110989069790714
                 85786944089552990653640447425576083659976645795096
                 66024396409905389607120198219976047599490197230297
                 64913982680032973156037120041377903785566085089252
                 16730939319872750275468906903707539413042652315011
                 94809377245048795150954100921645863754710598436791
                 78639167021187492431995700641917969777599028300699
                 15368713711936614952811305876380278410754449733078
                 40789923115535562561142322423255033685442488917353
                 44889911501440648020369068063960672322193204149535
                 41503128880339536053299340368006977710650566631954
                 81234880673210146739058568557934581403627822703280
                 82616570773948327592232845941706525094512325230608
                 22918802058777319719839450180888072429661980811197
                 77158542502016545090413245809786882778948721859617
                 72107838435069186155435662884062257473692284509516
                 20849603980134001723930671666823555245252804609722
                 53503534226472524250874054075591789781264330331690"""
        var res = src.split("\\D+")
                     .map{ _.foldLeft(0:BigInt){ (a,b) => a*10+(b-'0') } }
                     .reduceLeft[BigInt]{ _+_ }
                     .toString
                     .substring(0,10)
        println(res)
}</pre><br /><br /><a href="http://projecteuler.net/index.php?section=problems&id=14" target="_blank">问题14</a>: <span style="color: orange">Find the longest sequence using a starting number under one million. </span><br />对于正整数n，定义如下变换：<br />　　　n -> n/2　　如果n是偶数<br />　　　n -> 3*n+1　如果n是奇数<br />对13，反复使用上述变换，可以得到一个自然数序列：<br />　　　13 → 40 → 20 → 10 → 5 → 16 → 8 → 4 → 2 → 1<br />这个序列的长度为10。<br />对任意一个自然数，都能通过上述方式产生一个序列，该序列的结尾为1。<br />现在求1,000,000以内，产生序列最长的那个正整数。<br /><span style="color: red">答案</span>:837799<br /><pre name="code" class="java">    //Scala
    def lenOfPath(n:Long):Int ={
        var len =1
        var copy =n
        while(copy != 1){
            copy = if(copy%2 == 0) copy/2 else copy*3+1
            len += 1
        }
        len
    }
    var res =0
    var len =0
    for(n &lt;- 1 until 1000000){
        val tmp =lenOfPath(n)
        if(tmp > len){
            len =tmp
            res =n
        }
    }
    res</pre><br /><br />	<br /><a href="http://projecteuler.net/index.php?section=problems&id=15" target="_blank">问题15</a>:<span style="color: orange">Starting in the top left corner in a 20 by 20 grid, how many routes are there to the bottom right corner?</span><br />一个20×20的方格，从左上角走到右下角，每次走一格，并且方向只能向右或向下。问一共有多少种走法。<br /><span style="color: red">答案</span>:137846528820<br /><pre name="code" class="java">    //Scala
    //Hint:就是求组合数C(40,20)
    1.to(20).foldLeft(1:BigInt){ (i,n) => i*(n+20)/n }</pre><br /><br /><a href="http://projecteuler.net/index.php?section=problems&id=16" target="_blank">问题16</a>:<span style="color: orange"> What is the sum of the digits of the number 2^1000?</span><br />求2的1000幂的各位数字之和。<br /><span style="color: red">答案</span>:1366<br /><pre name="code" class="java">//Scala
var num = (1:BigInt)&lt;&lt;1000
num.toString.foldLeft(0){ _+_-'0' }</pre><br /><br /><br /><a href="http://projecteuler.net/index.php?section=problems&id=17" target="_blank">问题17</a>:<span style="color: orange">How many letters would be needed to write all the numbers in words from 1 to 1000?</span><br />从1到1000（包括）的英文表示共需要多少英文字母？<br /><span style="color: olive">　　比如342用英语表述为：three hundred and forty-two<br />　　一共含23个字母（空格与连线符不算）</span><br /><span style="color: red">答案</span>:21124<br /><pre name="code" class="java">    //Scala
    val tens = Array(0,0,6,6,5,5,5,7,6,6)
    val units = Array(0,3,3,5,4,4,3,5,5,4,
                      3,6,6,8,8,7,7,9,8,8)
    def lenOf(n:Int):Int ={
        val high =n/100
        val low =n%100
        var len =0
        if(high !=0) len = 7 + units(high)
        if(high!=0 && low!=0) len += 3
        if(low &lt;20) len+units(low)
        else len+tens(low/10)+units(low%10)
    }
    1.to(999).foldLeft(11){ (a,b) => a+lenOf(b) }</pre><br /><br /><a href="http://projecteuler.net/index.php?section=problems&id=18" target="_blank">问题18</a>:<span style="color: orange">Find the maximum sum travelling from the top of the triangle to the base.</span><br />给定一个数字组成的三角形，从三角形的顶点往下走一直到底部，将所经过的数字相加，求这个和的最大值。<br /><span style="color: red">答案</span>:1074<br /><pre name="code" class="java">/**
   &#Euler018.scala
   @author Eastsun
*/
object Euler018 extends Application {
    var src ="""75
                95 64
                17 47 82
                18 35 87 10
                20 04 82 47 65
                19 01 23 75 03 34
                88 02 77 73 07 63 67
                99 65 04 28 06 16 70 92
                41 41 26 56 83 40 80 70 33
                41 48 72 33 47 32 37 16 94 29
                53 71 44 65 25 43 91 52 97 51 14
                70 11 33 28 77 73 17 78 39 68 17 57
                91 71 52 38 17 14 91 43 58 50 27 29 48
                63 66 04 68 89 53 67 30 73 16 69 87 40 31
                04 62 98 27 23 09 70 98 73 93 38 53 60 04 23
             """
    var num = src.split("(?m:$\\s*)")
                 .map{ _.split("\\s+")
                        .map{ _.foldLeft(0){ _*10+_-'0' } } 
                 }
    def path(row:Int,col:Int):Int =
        if(row ==num.length-1) num(row)(col)
        else num(row)(col) +path(row+1,col).max(path(row+1,col+1))
    
    println(path(0,0))
}</pre><br /><br /><br /><a href="http://projecteuler.net/index.php?section=problems&id=19" target="_blank">问题19</a>:<span style="color: orange">How many Sundays fell on the first of the month during the twentieth century?</span><br />已知1900年一月一日是星期一，求从1901.1.1到2000.12.31这段时间，既是星期天又是一个月的第一天的日子有多少天？<br /><span style="color: red">答案</span>:171<br /><pre name="code" class="java">    //Scala
    def daysOfMonth(year:Int,month:Int):Int = month match{
        case 4|6|9|11        => 30
        case 1|3|5|7|8|10|12 => 31
        case _  => if(year%400==0||(year%4==0&&year%100!=0)) 29 else 28
    }
    var offset = 1.to(12).foldLeft(1){(s,m) => s+daysOfMonth(1900,m)}
    var res = 0
    for(year &lt;- 1901 to 2000;month &lt;- 1 to 12){
        if(offset%7 == 0) res += 1
        offset += daysOfMonth(year,month)
    }
    res</pre><br /><br /><a href="http://projecteuler.net/index.php?section=forum&id=20" target="_blank">问题20</a>:<span style="color: orange">Find the sum of digits in 100!</span><br />求100的阶乘的各位数字之和。<br /><span style="color: red">答案</span>:648<br /><pre name="code" class="java">//Scala
1.to(100).foldLeft(1:BigInt){ _*_ }.toString.foldLeft(0){ _+_-'0' }</pre><br /><br /><a href="http://projecteuler.net/index.php?section=problems&id=21" target="_blank">问题21</a>:<span style="color: orange">Evaluate the sum of all amicable pairs under 10000.</span><br />记d(n)为正整数n的真约数（小于其自身的因子）之和。<br />称正整数对（a，b）为亲和数，如果a，b满足：<br />　　　　a != b 且 d(a) =b, d(b) =a<br />求小于10000的所有亲和数之和。<br /><span style="color: red">答案</span>:31626<br /><pre name="code" class="java">//Scala
    def sumOfDivisor(n:Int):Int ={
        if(n &lt;= 1) return 0
        var sum =1
        var div =2
        while(div*div &lt; n){
            if(n%div == 0) sum =sum+div+n/div
            div += 1
        }
        if(div*div == n) sum+div else sum
    }
    var res =0
    for(n &lt;- 2 until 10000){
        val sd =sumOfDivisor(n)
        if(sd&lt;n && sumOfDivisor(sd)==n) res =res+sd+n
    }
    res</pre><br /><br /><br /><a href="http://projecteuler.net/index.php?section=problems&id=22" target="_blank">问题22</a>:<span style="color: orange">What is the total of all the name scores in the file of first names?</span><br />给定一个文本文件<a href="http://projecteuler.net/project/names.txt" target="_blank">names.txt</a>，里面含有超过5000个的英文名字。你需要首先将它们按字典顺序排序，然后对于每一个名字给定一个权重，每个名字的得分为其权重与其在列表中的位置（这个位置从1算起）的乘积。计算所有名字得分之和。<br />比如名字“COLIN“，它的权重是3(3表示C是字母表中的第三个) + 15 + 12 + 9 + 14 = 53，它在列表中的位置是938th，故“COLIN“的得分是938 × 53 = 49714。<br /><span style="color: red">答案</span>:871198282<br /><pre name="code" class="java">/**
   &#Euler022.scala
   @author Eastsun
*/
import java.util.Scanner
import java.io.File
import scala.collection.jcl.LinkedList
import scala.util.Sorting._

object Euler022 extends Application {
    var scan = new Scanner(new File("names.txt")).useDelimiter("\"(,\")?")
    var list = new LinkedList[String]
    while(scan.hasNext()) list.add(scan.next())
    scan.close()
    var array =list.toArray
    quickSort(array)
    var res = array.zipWithIndex.foldLeft(0){(v,s) =>
                  v +(s._2+1)*s._1.foldLeft(0){ _+_-'A'+1 }
              }
    println(res)
}</pre>
          <br/>
          <span style="color:red;">
            <a href="http://eastsun.javaeye.com/blog/204434#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Mon, 16 Jun 2008 22:34:51 +0800</pubDate>
        <link>http://eastsun.javaeye.com/blog/204434</link>
        <guid>http://eastsun.javaeye.com/blog/204434</guid>
      </item>
      <item>
        <title>英语数字表达法</title>
        <author>Eastsun</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://eastsun.javaeye.com">Eastsun</a>&nbsp;
          链接：<a href="http://eastsun.javaeye.com/blog/204284" style="color:red;">http://eastsun.javaeye.com/blog/204284</a>&nbsp;
          发表时间: 2008年06月16日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <span style="font-size: medium"><span style="color: green">一、熟读牢记关键数字</span> </span><br />　　迅速无误识别数字的前提是必须能够流利地读出数字。要从读两位数起，然后练习读三位和四位数乃至五 位或六位以上的数字。其中两位和三位数的读法是读所有数字的基础。<br />　　英文数字中的每一个逗点的读法也要牢 记：<br />　　有一个逗点读“thousand”<br />　　两个逗点读“million”<br />　　三个逗点读“billion”<br /><br />　　还要清楚，每个逗点间 由三位数组成。 英文数字中的第四位数、第七位数、第十位数是很关键的数位。 <br />Examples： <br />　　1,234 读作：one thousand, two hundred and thirty-four <br />　　4,567,809 读作：four million, five hundred and sixty-seven thousand, eight hundred and nine <br />　　5,678,120,000 读作：five billion, six hundred and seventy-eight million, one hundred and twenty thousand <br /><br /><span style="font-size: medium"><span style="color: green">二、“-teen和“-ty”的区别</span> </span><br />　　“-teen”和“-ty”是比较容易混淆的一对读音。我们可以通过音和音素的差异来区别两者。 含有“- teen ”的词有两个重音， 即“-teen”要重读，且“-teen”中的元音为长元音[ti:n]，发音长而清晰；而含有 “-ty”的词只有一个重音，即“-ty”不重读，且“-ty ”中的元音为短元音[ti]，发音短而急促。 <br />Examples： <br />　　fifteen['fif'ti:n] fifty['fifti] <br />　　nineteen['nai'ti:n] ninety['naiti]<br /><br /><span style="font-size: medium"><span style="color: green">三、英美数字读法的差异 </span></span><br />　　有时，同样一个数字，英国人和美国人的读法也不尽相同，这无疑会使本来就棘手的数字雪上加霜。如：部分有一个逗点的数字（四位数），英国人用“thousand”表示，而美国人则多用“hundred”。 再如，有三个逗点的数字（十位数），美式读法为“billion”， 而英式读法为“thousand million”。因此，熟悉英美 两种不同的读法对消除数字理解上的歧义是十分必要的。<br /><br />例词 <br />　　英式 1,900 one thousand, nine hundred <br />　　美式1,900 nineteen hundred <br />　　英式4,000,000,000 four thousand million <br />　　美式4,000,000,000 four billion <br /><br />　　再者，英国英语在百位和十位之间加读“and”， 而美国英语往往不用“and”。比如754这个数字。英国英语读成seven hundred and fifty-four，而美国英语则读为seven hundred fifty-four。 <br />　　此外，在某些时间表达上，英美也有不同的读法。
          <br/>
          <span style="color:red;">
            <a href="http://eastsun.javaeye.com/blog/204284#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Mon, 16 Jun 2008 18:46:47 +0800</pubDate>
        <link>http://eastsun.javaeye.com/blog/204284</link>
        <guid>http://eastsun.javaeye.com/blog/204284</guid>
      </item>
      <item>
        <title>Euler Project解题汇总 001 ~ 012</title>
        <author>Eastsun</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://eastsun.javaeye.com">Eastsun</a>&nbsp;
          链接：<a href="http://eastsun.javaeye.com/blog/203289" style="color:red;">http://eastsun.javaeye.com/blog/203289</a>&nbsp;
          发表时间: 2008年06月14日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          　　前日在网上闲逛，发现了这个有意思的网站<a href="http://projecteuler.net/" target="_blank">Project Euler</a>。这个网站给出了一系列数学相关的题目，你可以使用编程去解答。<br /><div class="quote_title">引用</div><div class="quote_div"><span style="font-size: medium"><span style="color: blue">What is Project Euler?</span></span><br /><br /><span style="color: orange">　　Project Euler is a series of challenging mathematical/computer programming problems that will require more than just mathematical insights to solve. Although mathematics will help you arrive at elegant and efficient methods, the use of a computer and programming skills will be required to solve most problems.<br /><br />　　The motivation for starting Project Euler, and its continuation, is to provide a platform for the inquiring mind to delve into unfamiliar areas and learn new concepts in a fun and recreational context.</span></div><br />　　蛮有趣的，我准备在空余时间依次做做这些题。这系列帖子用于列出我所做出的题（每个贴包括5~15道问题的答案）：对于简单的题，直接给出程序代码及答案；对于我认为比较复杂的题目，只在该贴给出答案，然后另开新帖给出详细点的解答。<br />　　对于解题所用的编程语言，那些简单的题可能只给出<a href="http://eastsun.javaeye.com/category/30003" target="_blank">Scala</a>代码（<span style="color: orange">可以直接使用Scala控制台运行，最后一行的运行结果即为答案</span>）；复杂一些的题可能会使用Java/C/Mathmatica/Matlab（注：Mathmatica与Matlab是两个常用的数学工具）。<br />　　对于所写的代码，在能够解决问题的前提下，尽量做到简单&漂亮，<span style="color: blue">所以所给的代码效率上未必是最佳的，能够解决问题足矣。</span><br /><br /><br /><a href="http://projecteuler.net/index.php?section=problems&id=1" target="_blank">问题1</a>:	<br /><span style="color: orange">Add all the natural numbers below one thousand that are multiples of 3 or 5.</span><br />求小于1000的自然数中3或5的倍数之和。<br /><span style="color: red">答案</span>:233168<br /><pre name="code" class="java">//Scala代码
Stream.range(0,1000).filter{ n => n%3==0||n%5==0 }.foldLeft(0){ _+_ }</pre><br /><br /><a href="http://projecteuler.net/index.php?section=problems&id=2" target="_blank">问题2</a>:	<br /><span style="color: orange">Find the sum of all the even-valued terms in the Fibonacci sequence which do not exceed four million.</span><br />对于数列f(n):<br />　　f(1) =1,f(2) =2<br />　　f(n) =f(n-1)+f(n-2) (n>2)<br />求数列f(n)中不大于4000,000且为偶数项数之和。<br /><span style="color: red">答案</span>:4613732<br /><pre name="code" class="java">    //Scala代码
    var fib:Stream[Int] = Stream.cons(1,Stream.cons(2,
                              fib.zip(fib.tail).map{case(x,y) => x+y}
                          ))
    fib.takeWhile{_&lt;=4000000}.filter{_%2==0}.foldLeft(0){_+_}</pre><br /><br /><br /><a href="http://projecteuler.net/index.php?section=problems&id=3" target="_blank">问题3</a>:<span style="color: orange">Find the largest prime factor of a composite number.</span><br />求600851475143的最大质因数。<br /><span style="color: red">答案</span>:6857<br /><pre name="code" class="java">    //Scala代码
    var num = 600851475143L
    var res = 2
    while(res != num) if(num%res == 0) num = num/res else res += 1
    res</pre><br /><br /><a href="http://projecteuler.net/index.php?section=problems&id=4" target="_blank">问题4</a>:	<br /><span style="color: orange">Find the largest palindrome made from the product of two 3-digit numbers.</span><br />求能分解为两个三位数乘积的最大回文数。<br /><span style="color: red">答案</span>:906609<br /><pre name="code" class="java">    //Scala代码
    def isPalin(n:Int):Boolean = {
        var inv =0
        var tmp =n
        while(tmp != 0){
            inv = inv*10 + tmp%10
            tmp = tmp/10
        }
        inv == n
    }
    var res =0
    for(i &lt;- 100 to 999;j &lt;- 100 to 999;if isPalin(i*j))
        if(i*j > res) res = i*j
    res</pre><br /><br /><a href="http://projecteuler.net/index.php?section=problems&id=5" target="_blank">问题5</a>:<span style="color: orange">What is the smallest number divisible by each of the numbers 1 to 20?</span><br />求1,2,..,19,20的最小公倍数。<br /><span style="color: red">答案</span>:232792560<br /><pre name="code" class="java">    //Scala代码
    def gcd(a:Long,b:Long):Long = if(a==0) b else gcd(b%a,a)
    1.to(20).foldLeft(1L){ (a,b) => a*b/gcd(a,b)}</pre><br /><br /><a href="http://projecteuler.net/index.php?section=problems&id=6" target="_blank">问题6</a>:<span style="color: orange">Find the difference between the sum of the squares of the first one hundred natural numbers and the square of the sum.</span><br />求1至100和的平方与1至100的平方和之差。<br /><span style="color: red">答案</span>:25164150<br /><pre name="code" class="java">    //Scala
    var sumOfSquare = 1.to(100).foldLeft(0){ (a,b) => a+b*b }
    var sum = 1.to(100).foldLeft(0){ _+_ }
    var squareOfSum = sum*sum
    squareOfSum-sumOfSquare</pre><br /><br /><a href="http://projecteuler.net/index.php?section=problems&id=7" target="_blank">问题7</a>:<span style="color: orange">Find the 10001st prime.</span><br />求第10001个素数（质数）。<br /><span style="color: red">答案</span>:104743<br /><pre name="code" class="java">    //Scala
    var ps:Stream[Int] = Stream.cons(2,
                             Stream.from(3).filter{ n =>
                                 ps.takeWhile(p => p*p &lt;= n).forall(n%_ !=0)
                             })
    ps(10000)</pre><br /><br /><a href="问题8" target="_blank">问题8</a>:	<br /><span style="color: orange">Discover the largest product of five consecutive digits in the 1000-digit number.</span><br />在给定的1000个数中，求出连续5个数的最大乘积。<br /><span style="color: red">答案</span>:40824<br /><pre name="code" class="java">//Scala
    var nums ="""73167176531330624919225119674426574742355349194934
                96983520312774506326239578318016984801869478851843
                85861560789112949495459501737958331952853208805511
                12540698747158523863050715693290963295227443043557
                66896648950445244523161731856403098711121722383113
                62229893423380308135336276614282806444486645238749
                30358907296290491560440772390713810515859307960866
                70172427121883998797908792274921901699720888093776
                65727333001053367881220235421809751254540594752243
                52584907711670556013604839586446706324415722155397
                53697817977846174064955149290862569321978468622482
                83972241375657056057490261407972968652414535100474
                82166370484403199890008895243450658541227588666881
                16427171479924442928230863465674813919123162824586
                17866458359124566529476545682848912883142607690042
                24219022671055626321111109370544217506941658960408
                07198403850962455444362981230987879927244284909188
                84580156166097919133875499200524063689912560717606
                05886116467109405077541002256983155200055935729725
                71636269561882670428252483600823257530420752963450""".replaceAll("\\s+","")
     var max =0
     for(i &lt;- 0 until nums.length-5){
         var value =nums.slice(i,i+5).foldLeft(1){ (a,b) => a*(b-'0')}
         if(value>max) max =value
     }
     max</pre><br /><br /><a href="http://projecteuler.net/index.php?section=problems&id=9" target="_blank">问题9</a>:	<br /><span style="color: orange">Find the only Pythagorean triplet, {a, b, c}, for which a + b + c = 1000.</span><br />求满足a+b+c = 1000的勾股数的积。（注：勾股数指满足a^2+b^2=c^2的自然数a,b,c）<br /><span style="color: red">答案</span>:31875000<br /><pre name="code" class="java">    //Scala
    for{a &lt;- 1 until 500
        b &lt;- a until 500
        if a*a + b*b == (1000-a-b)*(1000-a-b)
    } yield a*b*(1000-a-b)</pre><br /><br /><a href="http://projecteuler.net/index.php?section=problems&id=10" target="_blank">问题10</a>:	<br />Calculate the sum of all the primes below two million.<br />求2,000,000以内所有素数的和。<br /><span style="color: red">答案</span>:142913828922<br /><pre name="code" class="java">    //这里用的求素数算法同题7一样
    //但这个问题数据量稍大了点，该代码需要运行15秒左右
    //如果遇到更大的数据，我会采用稍复杂一点的算法，会快很多（快一到两个数量级）
    var ps:Stream[Int] = Stream.cons(2,
                           Stream.from(3).filter(n =>
                             ps.takeWhile(p => p*p &lt;= n).forall(n%_ !=0)
                           )
                         )
    ps.takeWhile(_ &lt; 2000000).foldLeft(0L){ _+_ }</pre><br /><br /><a href="http://projecteuler.net/index.php?section=problems&id=11" target="_blank">问题11</a>:<span style="color: orange">What is the greatest product of four numbers on the same straight line in the 20 by 20 grid?</span><br />对于给定的20×20的数字方阵，求相邻4个数之积的最大值。（相邻数包括同一行、同一列或同一对角线上的连续相邻4个数）<br /><span style="color: red">答案</span>:70600674<br /><pre name="code" class="java">    //Scala
    var src ="""08 02 22 97 38 15 00 40 00 75 04 05 07 78 52 12 50 77 91 08
                49 49 99 40 17 81 18 57 60 87 17 40 98 43 69 48 04 56 62 00
                81 49 31 73 55 79 14 29 93 71 40 67 53 88 30 03 49 13 36 65
                52 70 95 23 04 60 11 42 69 24 68 56 01 32 56 71 37 02 36 91
                22 31 16 71 51 67 63 89 41 92 36 54 22 40 40 28 66 33 13 80
                24 47 32 60 99 03 45 02 44 75 33 53 78 36 84 20 35 17 12 50
                32 98 81 28 64 23 67 10 26 38 40 67 59 54 70 66 18 38 64 70
                67 26 20 68 02 62 12 20 95 63 94 39 63 08 40 91 66 49 94 21
                24 55 58 05 66 73 99 26 97 17 78 78 96 83 14 88 34 89 63 72
                21 36 23 09 75 00 76 44 20 45 35 14 00 61 33 97 34 31 33 95
                78 17 53 28 22 75 31 67 15 94 03 80 04 62 16 14 09 53 56 92
                16 39 05 42 96 35 31 47 55 58 88 24 00 17 54 24 36 29 85 57
                86 56 00 48 35 71 89 07 05 44 44 37 44 60 21 58 51 54 17 58
                19 80 81 68 05 94 47 69 28 73 92 13 86 52 17 77 04 89 55 40
                04 52 08 83 97 35 99 16 07 97 57 32 16 26 26 79 33 27 98 66
                88 36 68 87 57 62 20 72 03 46 33 67 46 55 12 32 63 93 53 69
                04 42 16 73 38 25 39 11 24 94 72 18 08 46 29 32 40 62 76 36
                20 69 36 41 72 30 23 88 34 62 99 69 82 67 59 85 74 04 36 16
                20 73 35 29 78 31 90 01 74 31 49 71 48 86 81 16 23 57 05 54
                01 70 54 71 83 51 54 69 16 92 33 48 61 43 52 01 89 19 67 48""" 
        def getValue(array:Array[Int],row:Int,col:Int):Int ={
            var res =0
            if(col+4 &lt;= 20){
                var pc = array.slice(row*20+col,row*20+col+4).foldLeft(1){ _*_ }
                res =res max pc
            }
            if(row+4 &lt;= 20){
                var pr =1
                for(n &lt;- 0 until 4) pr = pr*array((row+n)*20+col)
                res =res max pr
            }
            if(row+4&lt;=20 && col+4&lt;=20){
                var pd1 =1
                var pd2 =1
                for(n &lt;-0 until 4){
                    pd1 = pd1*array((row+n)*20+col+n)
                    pd2 = pd2*array((row+n)*20+col+3-n)
                }
                res =res max pd1 max pd2
            }
            res
        }
        var nums =src.split("\\s+").map{ _.foldLeft(0){ (a,b) => a*10+b-'0' } }
        var res  =0
        for(row &lt;- 0 until 20;col &lt;- 0 until 20)
            res =res max getValue(nums,row,col)
        res</pre><br /><br /><a href="http://projecteuler.net/index.php?section=problems&id=12" target="_blank">问题12</a>:<span style="color: orange">What is the value of the first triangle number to have over five hundred divisors?</span><br />求第一个因子个数超过500的三角数。(三角数t(n) =n*(n+1)/2)<br /><span style="color: red">答案</span>:76576500<br /><pre name="code" class="java">    var ts = Stream.cons(0,Stream.from(1).map{ n =>
                 var t =n*(n+1)/2
                 var f =0
                 var k =1
                 while(k*k&lt;t){
                    if(t%k ==0) f +=2
                    k +=1
                 }
                 if(t == k*k) f+1 else f
             })
    var len =ts.takeWhile{_&lt;=500}.length
    len*(len+1)/2</pre>
          <br/>
          <span style="color:red;">
            <a href="http://eastsun.javaeye.com/blog/203289#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Sat, 14 Jun 2008 19:05:02 +0800</pubDate>
        <link>http://eastsun.javaeye.com/blog/203289</link>
        <guid>http://eastsun.javaeye.com/blog/203289</guid>
      </item>
      <item>
        <title>操作指南：在iPhone上安装运行Java</title>
        <author>Eastsun</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://eastsun.javaeye.com">Eastsun</a>&nbsp;
          链接：<a href="http://eastsun.javaeye.com/blog/201721" style="color:red;">http://eastsun.javaeye.com/blog/201721</a>&nbsp;
          发表时间: 2008年06月10日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          你想在iPhone上运行Java么？这里有一个<a href="http://java4iphone.com/all-news/tutorial-install-and-use-java-on-the-iphone/" target="_blank">操作指南</a>,根据该指南，你就可以在iPhone上编译并运行Java了。<br /><br /><span style="font-size: medium"><span style="color: brown">这个指南分为两部分：</span></span><br />★　<a href="http://java4iphone.com/all-news/tutorial-install-java-on-the-iphone/" target="_blank">在iPhone上安装Java环境</a><br />　　这部分告诉你如何将iPhone解锁，以及如何在上面安装Java环境step by step。<br />　　　　<img src="http://www.javaeye.com/upload/picture/pic/15863/094f7e89-d9e3-3375-8913-78d8e3e4e035.jpg?1213069059" /><br /><br />★　<a href="http://java4iphone.com/all-news/tutorial-compile-and-run-java-application-on-the-iphone/" target="_blank">在iPhone上编译并运行Java程序</a><br />　　这部分详细讲解了如何在iPhone上使用控制台命令编译以及运行Java程序。<br />　　　　<img src="http://www.javaeye.com/upload/picture/pic/15865/41098563-48be-3146-93c9-15dd028102fb.jpg?1213069212" /><br />　　如果你在操作过程中有任何问题，或者有什么心得想和大家分享，可以去<a href="http://java4iphone.com/forum/" target="_blank">这儿</a>和大家交流。
          <br/>
          <span style="color:red;">
            <a href="http://eastsun.javaeye.com/blog/201721#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Tue, 10 Jun 2008 11:50:26 +0800</pubDate>
        <link>http://eastsun.javaeye.com/blog/201721</link>
        <guid>http://eastsun.javaeye.com/blog/201721</guid>
      </item>
      <item>
        <title>最科幻的笔：Java Pen</title>
        <author>Eastsun</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://eastsun.javaeye.com">Eastsun</a>&nbsp;
          链接：<a href="http://eastsun.javaeye.com/blog/201050" style="color:red;">http://eastsun.javaeye.com/blog/201050</a>&nbsp;
          发表时间: 2008年06月06日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          　　笔是很常见也很普通的一个东西，虽然价格上可能差异很大：有几毛钱一支的圆珠笔也有高达上百万的“贵族笔”；但其功能不外乎用来书写。<br />　　但你有没有想象过这样一支笔：它能把你写下的东西记录下来，也可以把你说的话记录下来，还可以把这些记录下来的东西做成动画上传到电脑上；更神奇的是它还支持及时翻译功能，比如你选择了English-to-Spanish模式，那么当你写下“one”这个单词的时候，该笔就会发出"uno"（西班牙语中的one）的读音……<br />　　很科幻，不是吗？不过你不必等到未来，现在就可以得到它了。这就是过去不久的JavaOne2008上展示的<a href="http://www.livescribe.com/" target="_blank">Java Pen</a>，该笔的外形和普通的笔没太大的区别。<br />　　<img src="http://www.javaeye.com/upload/picture/pic/15727/ff119830-aa7a-3051-9021-17bb072e630a.png?1212754957" /><br />　　但是不要小瞧它，里面的内容可丰富了，包括：<br />　　　　<span style="color: orange">★　Samsung ARM 9 (32-bit, 150 MHz)　处理器<br />　　　　★　96x18 的OLED显示屏 <br />　　　　★　高速红外摄像头(不低于70 images/sec)<br />　　　　★　1GB（可记录超过100小时）或2GB的NAND 存储介质<br />　　　　★　300 mAH的可充电锂电池 <br />　　　　★　内置扬声器与麦克风</span><br />　　该笔支持Java ME CLDC规范，并且有相应的开发工具。关于该笔更详细的信息见<a href="http://www.livescribe.com/" target="_blank">livescribe</a>或查看<a href="http://eastsun.javaeye.com/upload/attachment/26792/7132d34d-2e07-30ec-a3db-488edc6e8e2c.rar" target="_blank">该文档</a>。<br />　　毫无疑问，其价格也比普通的笔要贵一些。根据其官网上的报价，具有1GB存储容量的需要149美元，2GB的是199美元，是不是让你心动了呢？
          <br/>
          <span style="color:red;">
            <a href="http://eastsun.javaeye.com/blog/201050#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Fri, 06 Jun 2008 20:48:30 +0800</pubDate>
        <link>http://eastsun.javaeye.com/blog/201050</link>
        <guid>http://eastsun.javaeye.com/blog/201050</guid>
      </item>
      <item>
        <title>Ruby，Python不能威胁到Java的13个理由</title>
        <author>Eastsun</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://eastsun.javaeye.com">Eastsun</a>&nbsp;
          链接：<a href="http://eastsun.javaeye.com/blog/198031" style="color:red;">http://eastsun.javaeye.com/blog/198031</a>&nbsp;
          发表时间: 2008年05月28日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          　　最近，<a href="http://www.dzone.com/links/users/profile/283759.html" target="_blank">danielstoner</a>发表了一篇题为<a href="http://littletutorials.com/2008/05/28/13-reasons-java-die-old-age/" target="_blank">13 reasons why Ruby, Python and the gang will push Java to die… of old age</a>的文章。文中作者的观点是：<span style="color: orange">目前这些XX语言都不足以威胁到Java，Java真正的危险不是来自外部，而是其本身。</span>作者通过列举一些数据并进行分析得到了13个理由来支持自己的结论。<br />　　首先，作者从<a href="http://www.javaeye.com/news/2396" target="_blank">TIOBE上公布的2008年5月语言排行榜</a>的数据得到一个有趣的事实：<br /><div class="quote_title">引用</div><div class="quote_div"><br />What I find significant here is the huge share the “C like syntax” languages have.<br /><br />C (15.292) + C++ (10.484) + Java (20.176) + C# (3.963) = 49.915%<br /><br />This means 4 languages get half of all the attention on the web.<br />If we add PHP (10.637) here (somehow uses a similar syntax) we get 60.552%</div><br />　　可见，“类C”语言占统治地位。由此作者得到第一个理由：<br /><div class="quote_title">引用</div><div class="quote_div"><span style="color: red">Reason number 1</span>: Syntax is very important because it builds on previous knowledge. Also similar syntax means similar concepts. Programmers have to make less effort to learn the new syntax, can reuse the old concepts and thus they can concentrate on understanding the new concepts.</div><br />　　我们再来看看这些“挑战者”所占的份额：<br /><div class="quote_title">引用</div><div class="quote_div">Python (4.613) + Ruby (2.851) + Lisp/Scheme (0.449) + Lua (0.393) + SmallTalk (0.138) +<br />Haskell (0.137) + Groovy (0.131) + Erlang (0.110) + Caml (0.090) + Scala (0.073) = 8.985%</div><br />　　它们被关注度的总和都没有超过Visual Basic所占的百分比：10.782%。作者归纳出第二个原因：<br /><div class="quote_title">引用</div><div class="quote_div"><span style="color: red">Reason number 2</span>: Too much noise is distracting. Programmers are busy and learning 10 languages to the level where they can evaluate them and make an educated decision is too much effort. The fact that most of these languages have a different syntax and introduce different (sometimes radically different) concepts doesn’t help either.</div><br />　　然后，作者分析了这几年来各种主流语言被关注程度的趋势<br /><img src="http://www.javaeye.com/upload/picture/pic/15171/4cac3127-c725-3a1f-8d98-7154a73dcf31.gif?1211982708" /><br />　　从图中可以看到，这些变化趋势从整体上看都比较平稳。并没有出现“语言暴发户”，也没有出现“一夜暴亡”的。这就是作者的第三个理由：<br /><div class="quote_title">引用</div><div class="quote_div"><span style="color: red">Reason number 3</span>: Lack of pressure on the programmers to switch. The market is pretty stable, the existing languages work pretty well and the management doesn’t push programmers to learn new languages.</div><br /><br />　　然后，作者分析了另一个<a href="http://www.langpop.com/" target="_blank">关于编程语言流行程度的网站</a>上给出的一些数据。<br />　　首先，作者从<a href="http://freshmeat.net" target="_blank">Freshmeat.net</a>与<a href="http://code.google.com" target="_blank">Google Code</a>上使用各种语言建立项目数目的得到：<br /><div class="quote_title">引用</div><div class="quote_div"><span style="color: red">Reason number 4</span>: Challenger languages don’t seem to catch momentum in order to create an avalanche of new projects started with them. This can be again due to the fact that they spread thin when they are evaluated. They are too many.</div><br /><br />　　余下的就不一一说明了，直接列举之：<br /><div class="quote_title">引用</div><div class="quote_div"><br /><span style="color: red">Reason number 5</span>: Challenger languages communities don’t do a good job at attracting programmers from established languages. Telling to somebody why she is wrong will most likely create a counter reaction not interest.<br /><br /><span style="color: red">Reason number 6</span>: There is no great incentive to switch to one of the challenger languages since gaining this skill is not likely to translate into income in the near future.<br /><br /><span style="color: red">Reason number 7</span>: The new languages don’t introduce an earth shattering improvement in the life of most of the programmers and projects.<br /><br /><span style="color: red">Reason number 8</span>: There is no killer application on the horizon. This means new languages compete in old markets with established players.<br /><br /><span style="color: red">Reason number 9</span>: None of these new languages has a powerful sponsor with the will and the money to push them on the market. Powerful sponsor translates in investment in the libraries - see Java. All these new languages are born in universities and research institutes or are coming from very specific niche domains.<br /><br /><span style="color: red">Reason number 10</span>: Most of these languages lingered around too much without stepping decisively into the big arena. <br /><br /><span style="color: red">Reason number 11</span>: “Features” that look and are dangerous for big projects. Since there are not a lot of big projects written in any of these languages it is hard to make an unbiased evaluation. But bias is in the end a real obstacle for their adoption.<br /><br /><span style="color: red">Reason number 12</span>: Unnatural concepts (for majority of programmers) raise the entry level. Functional languages make you write code like mathematical equations. But how many people actually love math so much to write everything in it? Object oriented languages provide a great advantage: they let programmers think about the domain they want to model, not about the language or the machine.<br /><br /><span style="color: red">Reason number 13</span>: Lack of advanced tools for development and refactoring cripple the programmer and the development teams when faced with big amounts of lines of code.<br /></div><br />　　作者还对几种以“Java挑战者”姿态出现的语言进行了分析：<br /><div class="quote_title">引用</div><div class="quote_div">For scripting <span style="color: red">Python</span> has potential, huge potential. But it has to do something about the indentation fetish to be able penetrate the big project market. Without that the web looks PHPish.<br /><br /><span style="color: red">Ruby</span> is elegant but alien. I saw its syntax described like “the bastard son of Perl” (just google it). Its new popularity is based not on the language itself but on a framework (Rails) that can be reproduced in other languages even if with less elegance. Struts 2 attempts just that.<br /><br /><span style="color: red">Scripting languages (Groovy, Rhino…) on top of Java and the JVM </span>are interesting but they will never be primadonnas. They cannot compete with Java because they are slower. They can be useful when scripting a Java application is a desirable feature (VBA is an excellent tool for Microsoft products and other Windows products and it pushed Visual Basic up the scale).<br /><br /><span style="color: red">Scala</span> has a lot of good cards. Building on the JVM, familiar syntax, huge inherited library, can be as fast as Java on the JVM… But where is the sponsor and where is the killer application in a shifting market?</div><br />　　最后，作者提出：<br /><div class="quote_title">引用</div><div class="quote_div">The danger for Java doesn’t come from outside. None of these new (actually most of them are pretty old) languages have the potential to displace Java.<br />The danger for Java comes from inside and it is caused by too many “features” making their way into the language and transforming if from a language that wanted to keep only the essential features of C++ into a trash box for features and concepts from all languages. </div>
          <br/>
          <span style="color:red;">
            <a href="http://eastsun.javaeye.com/blog/198031#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Wed, 28 May 2008 22:50:12 +0800</pubDate>
        <link>http://eastsun.javaeye.com/blog/198031</link>
        <guid>http://eastsun.javaeye.com/blog/198031</guid>
      </item>
      <item>
        <title>Java：进化的尽头</title>
        <author>Eastsun</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://eastsun.javaeye.com">Eastsun</a>&nbsp;
          链接：<a href="http://eastsun.javaeye.com/blog/197951" style="color:red;">http://eastsun.javaeye.com/blog/197951</a>&nbsp;
          发表时间: 2008年05月28日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          　　<span style="color: red">原文地址</span>:<a href="http://blog.csdn.net/beckel/archive/2008/05/27/2488305.aspx" target="_blank">http://blog.csdn.net/beckel/archive/2008/05/27/2488305.aspx</a><br /><br />Java: Evolutionary Dead End<br />January 3, 2008<br /><br /><br />　　我在比利时安特卫普举办的Javapolis大会上刚做完一个主题演讲。现在是周五早上，前一天Josh Bloch作了发言，谈到了在closures(闭包)建议方面的争论。现在他就坐在我的对面吃早餐，我们更进一步谈论了这个话题。   <br />当初我开始抱怨的时候，理由就很简单：Java作为一种语言过于繁杂（noisy）了。读代码要比写代码费劲得多，凭这一点就直接增加了软件开发的实际成本。计算机的时钟周期是一类非常稀缺的资源，凡是毫无效益地耗光这些资源的东西—即使是表面看无伤大雅的一句多余的System.out.println()—都会剥夺可能有重要用途的循环周期，并降低编程语言的效率（<a href="http://steve-yegge.blogspot.com/2007/12/codes-worst-enemy.html" target="_blank">Steve Yegge在最近的文章中谈到了这个问题</a>）。<br /><br />　　Josh在演讲中提到向Java generics添加最后一个通配符可能会极大增加语言复杂性。Neal Gafter则建议应该具体化generics。而这两个人最开始都是Java generics的绝对支持者，他们对于我的批评文章的反应就说明了这一点。现在似乎出现了变化，我注意到一些人开始提出“generics确实很不错，但是…”（虽然最近Tim Bray称这些人是个<a href="http://www.tbray.org/ongoing/When/200x/2007/12/16/On-Closures" target="_blank">祸害</a>）。<br /><br />　　我们对于复杂度唯一能够掌控的是抽象：隐藏无关紧要的部分（“分而治之”就是一种变化）。Java的自身矛盾性就在于它忽略了复杂性问题的一个关键方面，就是代码的可读性没有被看作为一个重要问题。似乎如果是IDE为你写的代码，那么这些代码即使是再复杂（本来不必这么复杂）也没关系。<br /><br />　　Josh进一步阐述了他关于复杂性的观点。他说，这并不是某一孤立的特性才具有的复杂性，因为这经常是直观可见的。这是一个将一个新特性以各种可能的方式与语言其它特性结合而形成的合成复杂性。当你将一个特性硬塞进已有的语言而不是从头开始认真仔细地进行设计时，你就不可能控制这种特性是如何与其他已有特性相融合的了。合成复杂性可以导致令人吃惊的问题，特别是在增加了特性后且做什么都于事无补的时候。吃早餐时Josh说这种复杂性会为Java困惑者们提供丰富的参考依据，令他们兴趣盎然，可是对于整个社区来说却没有一丁点好处。<br /><br />                     <br /><strong><span style="font-size: medium"><span style="color: blue">稳定性 VS 特性嗜好者</span></span></strong><br /><br />　　我从与Josh共进早餐中领悟到的是我是一名特性嗜好者（feature junkie）。特性是这样一类好玩的游戏：一旦你掌握了它们，它们就可以以令人着迷的方式来运用。所以我总是在思考在新特性方面语言的演化问题。你也许会发现你也是一名特性嗜好者。<br /><br />　　所以，当Java Generics一类的特性被糟糕地（我认为）加入到语言中时，我感到十分沮丧，我认为在增加特性时他们没有做该做的事。<br /><br />　　但在我看来，该做的事绝不是一点不增加新特性。而是如果你不能正确处理，那么该语言可能就会不再成长并变得更相对稳定些，直到放弃对每一种已有语言特性的追求。<br /><br />　　勿需证明，C最好的特性之一就是很多年以来它没有作任何改变。C++也十分稳固。所以这么说来让Java稳定下来也不见得是坏事。<br /><br />　　这并不是说类似generics和closures的特性就“不好”。完全相反，当将它们精心设计到一种语言中时，它们可以十分清晰且功能强大。然而回想当初，Java是有这样的机会的。Bill Joy在语言最初版本之前<a href="http://www.artima.com/weblogs/viewpost.jsp?thread=173229" target="_blank">强烈要求加入closures和generics</a>等内容，但没人理睬。<br /><br />　　很多年以来人们一直容忍着，然后突然间generics就必须要硬塞进语言之中。这显然和当年C#出现generics的情形极为相似。后者也是要在Java5中制造出几个其他特性。似乎增加这些特性的紧迫性不是来自于要使用Java解决现实问题，而是Sun在试图保持与微软的C#进行竞争的感觉。这或许并非是空穴来风，因为Java必须首先要以粗犷方式破茧而出的原因，是其认为存在一个必须要赢取的市场窗口。一个依仗市场推进力设计出来的程序设计语言最终要以白忙活一场而步入终结。<br /><br />                      <br /><strong><span style="font-size: medium"><span style="color: blue">兼容性的圣杯</span></span></strong><br /><br />　　一种选择是正确地加入新特性并破坏向后兼容性。作为一个特性嗜好者我会选择这样做，因为它不会将降低语言的完整性。而该方法一直以来未被采纳是因为向后兼容性总是语言的利器之一。我注意到Python在早期版本中战战兢兢地小范围破坏了向后兼容性。这个变化实际上没有引发任何反对声音。结果是Python正计划扩大向后不兼容的范围。Ruby也在考虑去掉一些Perl特性以简化语言。那些不想拥抱这些变化的人不会进步，他们实际也是出于保守而不愿进步。很多公司出于这个原因仍旧一直使用Java1.1。他们也将不会受这场争论的影响，因为无论如何他们都没打算接受这些变化。<br /><br />　　我们如果由于向后不兼容而无法正确地加入新特性，当语言的变化到来时我们就无法施展拳脚了。我们处在的位置和C++一样。C++常常在设计方面饱受批评。而我作为标准委员会的成员的这八年里，经历了在每一个语言特性上的争论。这些特性并非是反复善变，而是谨小慎微和深思熟虑过的。导致语言最终变得复杂和困难的正是要保持对C的向后兼容性。一旦你打算与任何一样事物都保持向后兼容性，你就必须准备好因增加特性而破坏语言。如果Java不想破坏向后兼容性，那么它就不可避免要接受新特性所具有的毫无收益的复杂性以及无法完整实现等特点。我在《Thinking in Java（第四版）》中谈到过这个问题，Java Generics只是对真正generics的一个苍白的模仿，而对于closures更有价值的建议之一（我想它该叫做“CPA”，但在Javapolis大会的演讲中没听到过该词—也许有人会告诉我正确叫法）是对真正closures的不完整实现。但实际上有个完整实现会更好些，因为它会使代码更清晰、更简单易懂。<br /><br />　　基础级新特性应该在新的语言中有所体现，其作为语言整个体系的一部分来精雕细琢地进行设计，而不是事后才想起来添加进去。在我看来，Java当前最好的退出策略（exit strategy）是<a href="http://www.scala-lang.org/" target="_blank">Scala</a>。我甚至听到了一些顶尖的程序员说在这个问题上他们并不在乎Java发生了什么事，因为他们正打算转向<a href="http://www.scala-lang.org/" target="_blank">Scala</a>。<br /><br />　　如果Java要完整地存在下去，它就必须像C一样：成为一匹能靠得住的“驮马”。实际上，将来任何语言上的变化都必须能够使语言和其使用方法变得简单和清晰（比如修复classpath问题），并且充实丰富（比如说）那些被打入冷宫的不完整的库（像JMF）。<br /><br />　　然而，类似closures这样重要且基础级的语言特性虽然在理论上极其吸引人，但一旦将其强行加进在抽象清晰性上重视向后兼容的语言中时，就会在实践过程中付出巨大的成本。因此在这个问题上我们必须变得异常保守。<br /><br />（我们会在即将到来的JavaPosse摘要中讨论这个以及其他Java方面的重要问题：<a href="http://www.mindviewinc.com/Conferences/JavaPosseRoundup" target="_blank">http://www.mindviewinc.com/Conferences/JavaPosseRoundup</a>）
          <br/>
          <span style="color:red;">
            <a href="http://eastsun.javaeye.com/blog/197951#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Wed, 28 May 2008 17:45:36 +0800</pubDate>
        <link>http://eastsun.javaeye.com/blog/197951</link>
        <guid>http://eastsun.javaeye.com/blog/197951</guid>
      </item>
      <item>
        <title>《Effective Java》: Joshua Bloch访谈</title>
        <author>Eastsun</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://eastsun.javaeye.com">Eastsun</a>&nbsp;
          链接：<a href="http://eastsun.javaeye.com/blog/195861" style="color:red;">http://eastsun.javaeye.com/blog/195861</a>&nbsp;
          发表时间: 2008年05月23日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          　　<span style="color: red">原文地址</span>：<a href="http://java.dzone.com/articles/effective-java-an-interview-wi" target="_blank">Effective Java: An Interview with Joshua Bloch</a><br />　　<span style="color: violet">翻　　译</span>：<a href="http://eastsun.javaeye.com" target="_blank">Eastsun</a><br /><br />　　<span style="color: orange">The most anticipated book among Java developers over the past few years has been the second edition of Effective Java by Joshua Bloch. The book was finally launched during JavaONE this year. I caught up with Josh and discussed the book, the changes in industry since the last edition and his thoughts on closures.</span><br />　　在最近几年来，Java开发者最期待的技术书籍莫过于Joshua Bloch的《Effective Java》第二版了。该书在今年的JavaOne大会上正式发布。我(<a href="http://eastsun.javaeye.com" target="_blank">Eastsun注</a>:指James Sugrue)对Josh进行了采访，我们谈到了这本书，自从上一版以来业界发生的变化以及他对闭包的看法。<br /><br />　　<span style="color: blue">James Sugrue: </span><span style="color: orange">The book was made available at JavaONE. Did you do any technical sessions to coincide with the release?</span><br />　　<span style="color: blue">James Sugrue: </span>这本书是在JavaOne大会上发布的，你是否做了一些技术讲座以配合这个发布？<br />　　<span style="color: blue">Joshua Bloch: </span><span style="color: orange">I did two sessions. On was directly related to the book. It was called "More Effective Java." It was largely devoted to enum types (Items 30-34, 77), but also included a mnemonic for the use of bounded wildcard types (Item 28) and a guide to lazy initialization (Item 71).</span><br />　　<span style="color: blue">Joshua Bloch: </span>我有两个讲座。一个与这本书直接相关，叫做"More Effective Java"。主要是关于枚举类型(条目 30-34, 77)，以及一些关于如何使用通配符(条目 28)。还有一个关于延迟初始化的讲座。(条目 71)<br /><br />　　<span style="color: blue">Sugrue:</span> <span style="color: orange">What changes have been added to bring to book up to date?</span><br />　　<span style="color: blue">Sugrue:</span>　在该书的新版中有那些变化？<br />　　<span style="color: blue">Bloch:</span> <span style="color: orange">I added two chapters, one on Generics, and another on Enums and Annotations. Also I added items describing best practices for each of the new language features in Java 5 (for-each loop, autoboxing, varargs, static import). I changed the title of the Threads chapter to Concurrency and rewrote it to reflect programming in the java.util.concurrent era (where the basic abstractions are tasks and executors, rather than threads, wait and notify). There's a table on page 1 that points you to all of this material.<br /><br />In addition to adding material on features that were added to the platform since the first edition of the book, I added items or modified existing ones to reflect the evolution of best practices. For example, I added an item describing the Builder pattern (Item 2), and one describing the Serialization Proxy pattern (Item 78). I went over every line of every item, and did my best to make sure they were up to date.</span><br />　　<span style="color: blue">Bloch:</span> 我增加了两章。一章是关于泛型，另一章是关于Enum与Annotation；还增加了一些讲述Java5中新增的语言特性最佳实践的条目。我将Threads一章的标题修改为Concurrency，并且针对java.util.concurrent重写了该章。在该书的第一页有一个列表指出了这些变化。<br />　　除了自该书第一版以来Java平台上新添的特性以外，我还增加或修改了一些条目以反映最佳实践的演化。譬如，我增加了一个讲述Builder模式的条目(条目 2)以及一个讲述Serialization Proxy模式的条目(条目 78)。我仔细检查了书里面的每一条的每一行，尽我最大的努力确保它们反映出当前最新的变化。<br /><br />　　<span style="color: blue">Sugrue:</span> <span style="color: orange">Is it fair to consider this as a whole new book?</span><br />　　<span style="color: blue">Sugrue:</span> 我们是否可以把它看做全新的一本书？<br />　　<span style="color: blue">Bloch: </span><span style="color: orange">No! I did my best not to change the character of the work. I hope it feels like an old friend to readers of the first edition.</span><br />　　<span style="color: blue">Bloch: </span>不，恰恰相反。我尽量不改变这本书的整体感官，我希望第一版的读者看到该书时就像遇到了老朋友。<br /><br />　　<span style="color: blue">Sugrue:</span> <span style="color: orange">Since the first book in 2001, what key changes have you observed in Java development?</span><br />　　<span style="color: blue">Sugrue:</span> 自从2001年发布该书的第一版以来，你认为在Java开发领域有那些关键性的变化？<br />　　<span style="color: blue">Bloch:</span> <span style="color: orange">The biggest changes are the rise of modern IDEs, such as Eclipse, IntelliJ, and NetBeans, and static analysis tools, such as FindBugs. Agile techniques, which were just making inroads in 2001, have become mainstream.</span><br />　　<span style="color: blue">Bloch:</span> 最大的变化是现代IDE的增长，例如Eclipse、IntelliJ以及Netbeans。还有静态分析工具，如FindBugs。敏捷技术在2001年的时候才刚刚起步，而现在已经成为主流。<br /><br />　　<span style="color: blue">Sugrue:</span><span style="color: orange"> Effective Java is seen as one of the most important books for Java. Considering it's popularity, were you wary of making any changes to such a well established book?</span><br />　　<span style="color: blue">Bloch:</span> <span style="color: orange">Very much so. That's why I tried so hard not to change the character of the book. Of course I had to cover all of the new material, and I had to critically examine everything I said in the first edition. But I did everything in my power to make sure that nothing got hurt in the process. I hope I succeeded, but I won't know for sure until I've heard from readers of the second edition.</span><br /><br />　　<span style="color: blue">Sugrue:</span> <span style="color: orange">Every developer should read this book - but some might not be able to make time. For those, if you were to promote just one message from the book what would it be?</span><br />　　<span style="color: blue">Sugrue:</span> 每一个Java开发者都应该阅读这本书，但可能有一些人没有充裕的时间。对于这些人，你能否简单介绍一下你这本书的主旨？<br />　　<span style="color: blue">Bloch: </span><span style="color: orange">I was asked the same question the very first time I was interviewed about Effective Java, back in June 2001. This is what I replied: Always strive to write simple, clear, and correct programs. It is penny wise and pound foolish to do otherwise. Style does matter. It pays real dividends in terms of correctness, usability, robustness, and maintainability. Also, it's way more fun to write good programs than bad ones.<br />　　I still believe every word.</span><br />　　<span style="color: blue">Bloch: </span>我第一次被采访关于《Effective Java》的时候也被问到了这个问题，那还是2001年。这是我当时的回答：力求写简单、清晰、正确的代码，而不是其它。代码风格很重要，它能在团队中对代码的正确性、可用性、鲁棒性以及可维护性产生实际的效用。同样，写好的代码比差的代码可以带来更多的快乐。<br />　　我依然坚信这些。<br /><br />　　<span style="color: blue">Sugrue: </span><span style="color: orange">What is the most common fault in Java developers in your opinion?</span><br />　　<span style="color: blue">Sugrue: </span> 你认为Java开发者普遍易犯的错误是什么？<br />　　<span style="color: blue">Bloch: </span><span style="color: orange">Like most programmers, we have a natural tendency to optimize our code even when we should know better. Our attempted optimizations don't always make the code run faster. Sometimes they just make it more complicated.</span><br />　　<span style="color: blue">Bloch: </span> 大多数程序员都有一个自然的倾向，在开始写代码时就试图优化以提高性能。但我们这种企图并不总是有用，甚至在某些时候只会把程序复杂化。<br /><br />　　<span style="color: blue">Sugrue: </span><span style="color: orange">The book includes hints for class and interface design. In one paragraph, can you describe a guideline for a good design?</span><br />　　<span style="color: blue">Sugrue: </span> 这本书里有一些关于类与接口设计的建议。你能否简单的讲述一下你对于良好设计的指导准则？<br />　　<span style="color: blue">Bloch:</span> <span style="color: orange">I apologize if this sounds trite, but each class should do one thing, and do it well. There's a great litmus test: can you, in one short, clear noun phrase, describe what an instance of the class represents? If not, you should probably spend more time thinking about the design.</span><br />　　<span style="color: blue">Bloch:</span> 我讲的东西可能没有什么新意，那就是每一个类只应该做一件事情，并且把它做好。这儿有一个很好的检验方法：你能否用一个简短的、明了的名词短语描述这个类的实例所代表的东西？如果不能，那你可能需要多花一些时间考虑一下你的设计了。<br /><br />　　<span style="color: blue">Sugrue:</span> <span style="color: orange">Scripting on top of the JVM has become very popular over the past year or so. What do you think of it?</span><br />　　<span style="color: blue">Sugrue:</span> 在这些年来，JVM上的动态语言变得流行起来。你是怎么看待这个现象呢？<br />　　<span style="color: blue">Bloch:</span><span style="color: orange"> I'm a pragmatist. Often it's the easy way to get things done, and that makes it good. Of course you should write your scripts with all the care that you write your programs, because they'll have to be maintained in parallel with the programs.</span><br />　　<span style="color: blue">Bloch:</span> 我是个实用主义者。使用动态语言通常使解决问题变得更加容易，这很好。当然使用动态语言也要注意一些问题，因为它们需要与其他代码共同被维护。<br /><br />　　<span style="color: blue">Sugrue: </span><span style="color: orange">What is your opinion on the inclusion Closures in Java 7?</span><br />　　<span style="color: blue">Sugrue: </span>　你如何看待Java7中将要引入的闭包？<br />　　<span style="color: blue">Bloch: </span><span style="color: orange">As readers of the first edition know, I value simplicity and clarity above all else. So it should come as no surprise that I don't want to see anymore major additions to the Java programming language. It's already as complex as a language should be. If Java programmers want to use features that aren't present in the language, I think they're probably best off using another langauge that targets the JVM, such a Scala and Groovy.</span><br />　　<span style="color: blue">Bloch: </span>正如该书第一版读者所了解的那样，我一直将简洁与清晰放到首要位置。因此我不希望看到Java在语言上有太大的变化，Java语言现在已经很好，不应该变得更加复杂。如果Java程序员想使用那些Java语言里面所不具有的特性，我认为他们最好是去使用JVM上的其他语言，譬如<a href="http://www.scala-lang.org/" target="_blank">Scala</a>与Groovy。(<a href="http://eastsun.javaeye.com" target="_blank">Eastsun注</a>：在<a href="http://www.infoq.com/interviews/joshua-bloch" target="_blank">另一个访谈</a>中Bloch提到他也很喜欢闭包，但是他认为当前流行的那些闭包提议过于复杂，会破坏Java语言的简洁性。事实上，他支持在Java中采用Bob Lee, Doug Lea,Josh Bloch三人所提出的<a href="http://docs.google.com/View?docid=k73_1ggr36h" target="_blank">CICE</a>方式；但Java之父Gosling则希望采用另一个更加彻底同时也更加复杂的实现方式：<a href="http://www.javac.info/" target="_blank">BGGA</a>)<br /><br />　　<span style="color: blue">Sugrue:</span> <span style="color: orange">To Java developers your book is seen as a bible. Can you recommend any other books to sit alongside yours on the developer's bookshelf?</span><br /><br />　　<span style="color: blue">Bloch:</span> <span style="color: orange">Sure. For concurrency, I recommend Java Concurrency in Practice by Goetz, Peierls, et al. For bit twiddling, go with Hacker's Delight, by Henry S. Warren. A couple of classics that only improve with age are Frederic P. Brooks's The Mythical Man Month, and Jon Bentley's Programming Pearls. And every programmer should read Strunk and White's The Elements of Style. Not only will it make you a better writer (which is an important part of being a software engineer) but it will make you a better programmer. Programming and writing have a lot in common: both are about expressing yourself clearly and concisely. </span>
          <br/>
          <span style="color:red;">
            <a href="http://eastsun.javaeye.com/blog/195861#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Fri, 23 May 2008 00:52:54 +0800</pubDate>
        <link>http://eastsun.javaeye.com/blog/195861</link>
        <guid>http://eastsun.javaeye.com/blog/195861</guid>
      </item>
      <item>
        <title>金庸小说另类标题</title>
        <author>Eastsun</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://eastsun.javaeye.com">Eastsun</a>&nbsp;
          链接：<a href="http://eastsun.javaeye.com/blog/195690" style="color:red;">http://eastsun.javaeye.com/blog/195690</a>&nbsp;
          发表时间: 2008年05月22日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          　　飞：我爱的尼姑和爱我的毒女<br />　　雪：推倒他的女儿，砍倒她的父亲<br />　　连：墙中的男人女人们<br />　　天：3个男人和他们的女人们<br />　　射：6个男人1个女人调教正太<br />　　白：撕下老男人的假面<br />　　鹿：我的超级YY<br />　　笑：音乐里的杀伐<br />　　书：一个黑帮组织的覆灭<br />　　神：断臂.非处.鸟<br />　　侠：傻小子闯天涯<br />　　倚：江山美人<br />　　碧：金钱与女人<br />　　鸳：我爱上了我的哥哥
          <br/>
          <span style="color:red;">
            <a href="http://eastsun.javaeye.com/blog/195690#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Thu, 22 May 2008 15:34:45 +0800</pubDate>
        <link>http://eastsun.javaeye.com/blog/195690</link>
        <guid>http://eastsun.javaeye.com/blog/195690</guid>
      </item>
      <item>
        <title>Java与Scala中的闭包</title>
        <author>Eastsun</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://eastsun.javaeye.com">Eastsun</a>&nbsp;
          链接：<a href="http://eastsun.javaeye.com/blog/195649" style="color:red;">http://eastsun.javaeye.com/blog/195649</a>&nbsp;
          发表时间: 2008年05月22日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载