MATHEMATICS

Jumat, 29 Juli 2011

Mathematica is self-documenting.

( *** WARNING: CONTAINS SPOILERS FOR EULER 22 *** )

Mathematica is self-documenting. ( That is if you use a mild form of Literary Programming. ) Anyway let me try to prove my point by looking at some code and compare it with two other languages.

Using names.txt (right click and 'Save Link/Target As...'), a 46K text file containing over five-thousand first names, begin by sorting it into alphabetical order. Then working out the alphabetical value for each name, multiply this value by its alphabetical position in the list to obtain a name score.

For example, when the list is sorted into alphabetical order, COLIN, which is worth 3 + 15 + 12 + 9 + 14 = 53, is the 938th name in the list. So, COLIN would obtain a score of 938 53 = 49714.

What is the total of all the name scores in the file?

Source: Euler 22

My solution was:

file = ToFileName[{"C:", "My Dropbox", "Mathematica", "Project Euler"}, "names.txt"];
dta = Sort[ReadList[file, Word, WordSeparators -> { ",", "\",\""}]];
Timing[Sum[ k*Plus @@ (ToCharacterCode[#] - 64 &) /@ Characters[dta[[k]]], {k, 1, Length[dta]}]]


Do you really need the following comments to get an idea what the program does?
Line 1. Address file.
Line 2. Read and parse data
Line 3. Process ( time and present ) data ( ToCharacterCode[] assigns 65 to A and so forth, the file contains names in all uppercase. ) Timing shows the time it took the computer to process line 3. Alternatives for @@ and /@ are the usage of Map and Apply.

Compare this to a solution in Java:

import java.io.*;

import java.util.*;



public class Problem22 {

public static void main(String[] args) throws Exception {



BufferedReader br = new BufferedReader(new FileReader(new File(\"names.txt\")));

String[] names = br.readLine().split(\",\");

Arrays.sort(names);

long sum = 0;

long count = 1;

for (int i = 0; i < names.length; i++) {

sum += count++ * sum(names[i]);



}

System.out.println(\"The sum is: \" + sum);

}



static long sum(String name) {

char[] letters = name.toLowerCase().toCharArray();

long sum = 0;

for (int i = 1; i < letters.length - 1; i++) {

sum += letters[i] - 96;

}

return sum;

}

}

Java is known to be verbose, but therefore very readable as well.

Some people get high from coding Haskell... ( I can't guarantee this code works, Haskell is not my thing. No thanks. )

import Control.Monad

import Data.List

import Char

import Control.Applicative



main = (read :: String -> [String]) `liftM` readFile "problem22.data" >>= \list -> putStrLn $ show $ sum $ zipWith (*) [1..] $ sum . map (\x->ord x - ord 'A' + 1) <$> sort list


I tried to show that Mathematica is self-documenting. Not that any other language is bad or otherwise inferior.

Tidak ada komentar:

Posting Komentar