Rosetta Code/Count examples

From Rosetta Code
Revision as of 21:44, 2 November 2013 by Jono (talk | contribs) (→‎{{header|Lasso}}: adding Lasso count from API & raw file example)
Task
Rosetta Code/Count examples
You are encouraged to solve this task according to the task description, using any language you may know.

Find the total number of programming examples for each task and the total for all tasks.

Essentially, count the number of occurrences of =={{header| on each task page.

Output:

100 doors: 20 examples.
99 Bottles of Beer: 29 examples.
Abstract type: 10 examples.

Total: X examples.

You'll need to use the Media Wiki API, which you can find out about locally, here, or in Media Wiki's API documentation at, API:Query

Ada

Library: AWS

Parsing XML file with XMLAda from AdaCore <lang Ada>with Aws.Client, Aws.Messages, Aws.Response, Aws.Resources, Aws.Url; with Dom.Readers, Dom.Core, Dom.Core.Documents, Dom.Core.Nodes, Dom.Core.Attrs; with Input_Sources.Strings, Unicode, Unicode.Ces.Utf8; with Ada.Strings.Unbounded, Ada.Strings.Fixed, Ada.Text_IO, Ada.Command_Line; with Ada.Containers.Vectors;

use Aws.Client, Aws.Messages, Aws.Response, Aws.Resources, Aws.Url; use Dom.Readers, Dom.Core, Dom.Core.Documents, Dom.Core.Nodes, Dom.Core.Attrs; use Aws, Ada.Strings.Unbounded, Ada.Strings.Fixed, Input_Sources.Strings; use Ada.Text_IO, Ada.Command_Line;

procedure Count_Examples is

  package Members_Vectors is new Ada.Containers.Vectors (
     Index_Type => Positive,
     Element_Type => Unbounded_String);
  use Members_Vectors;
  Exemples      : Vector;
  Nbr_Lg, Total : Natural := 0;
  procedure Get_Vector (Category : in String; Mbr_Vector : in out Vector) is
     Reader  : Tree_Reader;
     Doc     : Document;
     List    : Node_List;
     N       : Node;
     A       : Attr;
     Page    : Aws.Response.Data;
     Uri_Xml : constant String :=
        "http://rosettacode.org/mw/api.php?action=query&list=categorymembers"
        &
        "&format=xml&cmlimit=500&cmtitle=Category:";
  begin
     Page := Client.Get (Uri_Xml & Category);
     if Response.Status_Code (Page) not  in Messages.Success then
        raise Client.Connection_Error;
     end if;
     declare
        Xml    : constant String := Message_Body (Page);
        Source : String_Input;
     begin
        Open
          (Xml'Unrestricted_Access,
           Unicode.Ces.Utf8.Utf8_Encoding,
           Source);
        Parse (Reader, Source);
        Close (Source);
     end;
     Doc  := Get_Tree (Reader);
     List := Get_Elements_By_Tag_Name (Doc, "cm");
     for Index in 1 .. Length (List) loop
        N := Item (List, Index - 1);
        A := Get_Named_Item (Attributes (N), "title");
        Append (Mbr_Vector, To_Unbounded_String (Value (A)));
     end loop;
     Free (List);
     Free (Reader);
  end Get_Vector;
  function Scan_Page (Title : String) return Natural is
     Page                      : Aws.Response.Data;
     File                      : Aws.Resources.File_Type;
     Buffer                    : String (1 .. 1024);
     Languages, Position, Last : Natural := 0;
  begin
     Page :=
        Client.Get
          ("http://rosettacode.org/mw/index.php?title=" &
           Aws.Url.Encode (Title) &
           "&action=raw");
     Response.Message_Body (Page, File);
     while not End_Of_File (File) loop
        Resources.Get_Line (File, Buffer, Last);
        Position :=
           Index
             (Source  => Buffer (Buffer'First .. Last),
              Pattern => "=={{header|");
        if Position > 0 then
           Languages := Languages + 1;
        end if;
     end loop;
     Close (File);
     return Languages;
  end Scan_Page;

begin

  Get_Vector ("Programming_Tasks", Exemples);
  for I in First_Index (Exemples) .. Last_Index (Exemples) loop
     declare
        Title : constant String :=
           To_String (Members_Vectors.Element (Exemples, I));
     begin
        Nbr_Lg := Scan_Page (Title);
        Total  := Total + Nbr_Lg;
        Put_Line (Title & " :" & Integer'Image (Nbr_Lg) & " exemples.");
     end;
  end loop;
  Put_Line ("Total :" & Integer'Image (Total) & " exemples.");

end Count_Examples; </lang> Output :

100 doors : 107 exemples.
24 game : 30 exemples.
....
Yahoo! search interface : 10 exemples.
Zig-zag matrix : 49 exemples.
Total : 17238 exemples.

AutoHotkey

<lang AutoHotkey>UrlDownloadToFile

 , http://www.rosettacode.org/w/api.php?action=query&list=categorymembers&cmtitle=Category:Programming_Tasks&cmlimit=500&format=xml
 , tasks.xml

FileRead, tasks, tasks.xml pos = 0 quote = "  ; " regtitle := "<cm.*?title=" . quote . "(.*?)" . quote While, pos := RegExMatch(tasks, regtitle, title, pos + 1) {

 UrlDownloadToFile
   , % "http://www.rosettacode.org/w/index.php?title=" . title1 . "&action=raw"
   , task.xml
 FileRead, task, task.xml
 RegExReplace(task, "\{\{header\|", "", count)
 current :=  title1 . ": " . count . " examples.`n"
 output .= current
 TrayTip, current, % current

} MsgBox % output Return</lang>

BBC BASIC

<lang bbcbasic> VDU 23,22,640;512;8,16,16,128+8 : REM Enable UTF-8 support

     SYS "LoadLibrary", "URLMON.DLL" TO urlmon%
     SYS "GetProcAddress", urlmon%, "URLDownloadToFileA" TO UDTF
     special$ = "+()'"
     
     url$ = "http://www.rosettacode.org/w/api.php?action=query" + \
     \      "&list=categorymembers&cmtitle=Category:Programming_Tasks" + \
     \      "&cmlimit=500&format=xml"
     file$ = @tmp$ + "tasks.xml"
     SYS UDTF, 0, url$, file$, 0, 0 TO fail%
     IF fail% ERROR 100, "File download failed (tasks)"
     
     Total% = 0
     file% = OPENIN(file$)
     WHILE NOT EOF#file%
       a$ = GET$#file%
       i% = 0
       REPEAT
         i% = INSTR(a$, "title=", i%+1)
         IF i% THEN
           j% = INSTR(a$, ">", i%)
           title$ = MID$(a$, i%+7, j%-i%-10)
           REM Replace HTML codes:
           REPEAT
             k% = INSTR(title$, "&")
             IF k% THEN
               l% = INSTR(title$, ";", k%)
               title$ = LEFT$(title$,k%-1) + \
               \        FNhtml(MID$(title$,k%,l%-k%+1)) + MID$(title$,l%+1)
             ENDIF
           UNTIL k% = 0
           t$ = title$
           REM Substitute characters not allowed in a URL:
           FOR s% = 1 TO LEN(special$)
             REPEAT
               s$ = MID$(special$, s%, 1)
               k% = INSTR(t$, s$)
               IF k% t$ = LEFT$(t$,k%-1) + "%" + STR$~ASCs$ + MID$(t$,k%+1)
             UNTIL k% = 0
           NEXT
           url$ = "http://www.rosettacode.org/w/index.php?title=" + t$ + \
           \      "&action=raw"
           file$ = @tmp$ + "title.htm"
           SYS UDTF, 0, url$, file$, 0, 0 TO fail%
           IF fail% ERROR 100, "File download failed " + t$
           examples% = 0
           task% = OPENIN(file$)
           WHILE NOT EOF#task%
             IF INSTR(GET$#task%, "=={{header|") examples% += 1
           ENDWHILE
           CLOSE #task%
           Total% += examples%
           PRINT title$ ": " ; examples% " examples."
         ENDIF
       UNTIL i% = 0
       i% = INSTR(a$, "cmcontinue=")
       IF i% THEN
         CLOSE #file%
         j% = INSTR(a$, """", i%+1)
         k% = INSTR(a$, """", j%+1)
         url$ = "http://www.rosettacode.org/w/api.php?action=query" + \
         \      "&list=categorymembers&cmtitle=Category:Programming_Tasks" + \
         \      "&cmlimit=500&format=xml&cmcontinue=" + MID$(a$,j%+1,k%-j%)
         REPEAT
           i% = INSTR(url$, "|")
           IF i% url$ = LEFT$(url$,i%-1) + "%7C" + MID$(url$,i%+1)
         UNTIL i% = 0
         file$ = @tmp$ + "tasks.xml"
         SYS UDTF, 0, url$, file$, 0, 0 TO fail%
         IF fail% ERROR 100, "File download failed (continue)"
         file% = OPENIN(file$)
       ENDIF
     ENDWHILE
     CLOSE #file%
     PRINT ' "Total: " ; Total% " examples."
     END
     
     DEF FNhtml(h$)
     IF LEFT$(h$,2) = "&#" THEN = CHR$(VALMID$(h$,3))
     CASE h$ OF
       WHEN """: = """"
     ENDCASE
     = h$</lang>

Sample output:

100 doors: 154 examples.
24 game: 53 examples.
24 game/Solve: 30 examples.
99 Bottles of Beer: 181 examples.
A+B: 124 examples.
Abstract type: 49 examples.
Accumulator factory: 65 examples.
Ackermann function: 126 examples.
Active Directory/Connect: 12 examples.
Active Directory/Search for a user: 13 examples.
......
XML/DOM serialization: 33 examples.
XML/Input: 50 examples.
XML/Output: 41 examples.
XML/XPath: 33 examples.
Y combinator: 51 examples.
Yahoo! search interface: 13 examples.
Yin and yang: 36 examples.
Zebra puzzle: 11 examples.
Zeckendorf number representation: 14 examples.
Zig-zag matrix: 64 examples.

Total: 27004 examples.

C#

Object-oriented solution.

<lang csharp>using System; using System.Collections.Generic; using System.Linq; using System.Text.RegularExpressions; using System.Net;

class Task {

   private string _task;
   private int _examples;
   public Task(string task, int examples) {
       _task = task;
       _examples = examples;
   }
   public string Name {
       get { return _task; }
   }
   public int Examples {
       get { return _examples; }
   }
   public override string ToString() {
       return String.Format("{0}: {1} examples.", this._task, this._examples);
   }

}

class Program {

   static List<string> GetTitlesFromCategory(string category, WebClient wc) {
       string content = wc.DownloadString(
           String.Format("http://www.rosettacode.org/w/api.php?action=query&list=categorymembers&cmtitle=Category:{0}&cmlimit=500&format=json", category)
       );
       return new Regex("\"title\":\"(.+?)\"").Matches(content).Cast<Match>().Select(x => x.Groups[1].Value.Replace("\\/", "/")).ToList();
   }
   static string GetSourceCodeFromPage(string page, WebClient wc) {
       return wc.DownloadString(
           String.Format("http://www.rosettacode.org/w/index.php?title={0}&action=raw", page)
       );
   }
   static void Main(string[] args) {
       WebClient wc = new WebClient();
       List<Task> tasks = new List<Task>();
       List<string> tasknames = GetTitlesFromCategory("Programming_Tasks", wc);
       foreach (string task in tasknames) {
           string content = GetSourceCodeFromPage(task, wc);
           int count = new Regex("=={{header", RegexOptions.IgnoreCase).Matches(content).Count;
           Task t = new Task(task, count);
           Console.WriteLine(t);
           tasks.Add(t);
       }
       Console.WriteLine("\nTotal: {0} examples.", tasks.Select(x => x.Examples).Sum());
   }

}</lang>

Clojure

<lang clojure>(ns count-examples

 (:import [java.net URLEncoder])
 (:use [clojure.contrib.http.agent :only (http-agent string)]
       [clojure.contrib.json :only (read-json)]
       [clojure.contrib.string :only (join)]))

(defn url-encode [v] (URLEncoder/encode (str v) "utf-8"))

(defn rosettacode-get [path params]

 (let [param-string (join "&" (for [[n v] params] (str (name n) "=" (url-encode v))))]
   (string (http-agent (format "http://www.rosettacode.org/w/%s?%s" path param-string)))))

(defn rosettacode-query [params]

 (read-json (rosettacode-get "api.php" (merge {:action "query" :format "json"} params))))

(defn list-cm

 ([params] (list-cm params nil))
 ([params continue]
    (let [cm-params (merge {:list "categorymembers"} params (or continue {}))
          result (rosettacode-query cm-params)]
      (concat (-> result (:query) (:categorymembers))
              (if-let [cmcontinue (-> result (:query-continue) (:categorymembers))]
                (list-cm params cmcontinue))))))

(defn programming-tasks []

 (let [result (list-cm {:cmtitle "Category:Programming_Tasks" :cmlimit 50})]
   (map #(:title %) result)))

(defn task-count [task]

 [task (count
        (re-seq #"==\{\{header"
                (rosettacode-get "index.php" {:action "raw" :title task})))])

(defn print-result []

 (let [task-counts (map task-count (programming-tasks))]
   (doseq [[task count] task-counts]
     (println (str task ":") count)
     (flush))
   (println "Total: " (reduce #(+ %1 (second %2)) 0 task-counts))))

</lang> <lang clojure>count-examples> (print-result) 100 doors: 73 24 game: 18 24 game/Solve: 14 99 Bottles of Beer: 89 Abstract type: 27 Accumulator factory: 23 Ackermann function: 73 Active Directory/Connect: 4 Active Directory/Search for a user: 3 Active object: 14 Add a variable to a class instance at runtime: 21 Address of a variable: 20 ... Total: 11216 nil </lang>

D

Works with: Tango

<lang D> import tango.io.Stdout; import tango.net.http.HttpClient; import tango.net.http.HttpHeaders; import tango.text.xml.Document; import tango.text.Util;

alias HttpHeader.ContentLength CL;

auto url = "http://www.rosettacode.org/w/api.php?action=query&list=categorymembers&cmtitle=Category:Programming_Tasks&cmlimit=500&format=xml"; void main() {

   auto client = new HttpClient (HttpClient.Get, url);
   client.open();
   char[] mainData, tmp;
   int total, i;
   void cat(void[] content) { tmp ~= cast(char[]) content; }
   if (client.isResponseOK) {
       client.read(&cat, client.getResponseHeaders.getInt(CL));
       mainData = tmp;
       tmp = null;
       auto doc = new Document!(char);
       doc.parse(mainData);
       foreach (n; doc.query.descendant("cm").attribute("title")) {
           auto subClient = new HttpClient(HttpClient.Get, 
                   "http://www.rosettacode.org/w/index.php?title=" ~
                   replace(n.value.dup, ' ', '_') ~ "&action=raw");
           subClient.open();
           if (! subClient.isResponseOK) {
               Stderr (client.getResponse);
                break;
           }
           subClient.read(&cat, subClient.getResponseHeaders.getInt(CL));
           foreach (segment; patterns(cast(char[])tmp, "=={{header|")) i++;
           --i;
           if (i) --i;
           Stdout.formatln ("{0,-40} - {}", n.value, i);
           total += i;
           tmp = null;
           i = 0;
       }
       Stdout("total examples: ", total).newline;
   } else {
       Stderr (client.getResponse);
   }

} </lang>

EGL

Works with: EDT
EGL: Graphical client implementation

A graphical implementation with a grid showing the number of implementations for each Rosetta Code task as well as total task and implementation counts. Uses MediaWiki API service call to fetch tasks/categories in a JSON format and meets API data limit and continuation requirements to consume 100% of the items.

User Interface: RosettaCodeHandler.egl <lang EGL>package com.eglexamples.client;

import org.eclipse.edt.rui.widgets.*;

handler RosettaCodeHandler type RUIhandler{initialUI =[ui], title = "Rosetta Code Tasks and Counts"}

   ui GridLayout{columns = 3, rows = 4, cellPadding = 4, children = [ b1, dg1, l1, l2, l3, l4 ]};
   
   b1 Button{ layoutData = new GridLayoutData{ row = 1, column = 1 }, text = "Go!", onClick ::= b1_onClick };
   l1 TextLabel{ layoutData = new GridLayoutData{ row = 1, column = 2 }, text = "Total Tasks:" };
   l2 TextLabel{ layoutData = new GridLayoutData{ row = 1, column = 3 }, text = "0" };
   l3 TextLabel{ layoutData = new GridLayoutData{ row = 2, column = 2 }, text = "Total Implementations:" };
   l4 TextLabel{ layoutData = new GridLayoutData{ row = 2, column = 3 }, text = "0" };
   
   dg1 DataGrid{ layoutData = new GridLayoutData{ row = 3, column = 1, horizontalSpan = 3 },
   	pageSize = 10, showScrollbar = true,

columns = [ new DataGridColumn{name = "title", displayName = "Task", width=220}, new DataGridColumn{name = "count", displayName = "Count", width=100} ] };

   cmcontinue string?;
   title string?;
   allTasks Task[];
   restBindingTasks IHttp? = new HttpRest{
       restType = eglx.rest.ServiceType.TrueRest, 
  	request.uri = "http://rosettacode.org/mw/api.php?action=query&list=categorymembers&cmtitle=Category:Programming_Tasks&cmlimit=1&format=json"};
   restBindingPageDetail IHttp? = new HttpRest{
       restType = eglx.rest.ServiceType.TrueRest, 
  	request.uri = "http://rosettacode.org/mw/index.php"};
   function b1_onClick(event Event in)

call ProxyFunctions.listTasks("") using restBindingTasks

   	    returning to listTasksCallBack onException exceptionHandler;
   end
  
   function listTasksCallBack(retResult RosettaCodeJSON in)

title = retResult.query.categorymembers[1].title; cmcontinue = retResult.queryContinue.categorymembers.cmcontinue;

call ProxyFunctions.fetchPageDetail(title) using restBindingPageDetail

	    returning to pageDetailCallBack onException exceptionHandler;
   end
   function pageDetailCallBack(pageResults string in)
  	count int = countSubstring("=={{header", pageResults);
  	allTasks.appendElement(new Task { title = title, count = count });

l2.text = l2.text as int + 1; l4.text = l4.text as int + count;

  	if(cmcontinue != null)

call ProxyFunctions.listTasks(cmcontinue) using restBindingTasks returning to listTasksCallBack onException exceptionHandler; else dg1.data = allTasks as any[]; end

   end
  
   function countSubstring(substr string in, str string in) returns(int)

if(str.length() > 0 and substr.length() > 0) return (str.length() - str.replaceStr(subStr, "").length()) / subStr.length(); else return 0; end

   end 
  function exceptionHandler(exp AnyException in)
  end

end

record Task title string; count int; end</lang>

Service Interface: ProxyFunctions.egl <lang EGL>package com.eglexamples.client;

library ProxyFunctions

   function listTasks(continueLocation String in) returns (RosettaCodeJSON) {

@Rest{method = _GET, uriTemplate = "&cmcontinue={continueLocation}", requestFormat = None, responseFormat = JSON}

   }
   end	
   function fetchPageDetail(title String in) returns (String) {

@Rest{method = _GET, uriTemplate = "?title={title}&action=raw", requestFormat = None, responseFormat = None}

   }
   end	

end

record RosettaCodeJSON

   query Query;
   queryContinue QueryContinue{JSONName = "query-continue"};

end

record Query

   categorymembers Categorymembers[];

end

record Categorymembers

   cmcontinue string?;
   pageid int?;
   ns int?;
   title string?;

end

record QueryContinue

   categorymembers Categorymembers;

end</lang>


Erlang

Library: xmerl

<lang erlang> -module(rosseta_examples). -include_lib("xmerl/include/xmerl.hrl").

-export([main/0]).

main() ->

  application:start(inets), 
  Titles = read_titles(empty),
  Result = lists:foldl(fun(Title,Acc) -> Acc + calculate_one(Title) end, 0, Titles),
  io:format("Total: ~p examples.\n",[Result]),
  application:stop(inets).

read_titles(CurrentContinue) ->

  URL0 = "http://rosettacode.org/mw/api.php?" ++
        "action=query&list=categorymembers&cmtitle=Category:Programming_Tasks" ++
        "&cmlimit=500&format=xml",
  URL = 
     case CurrentContinue of 
        empty -> URL0;
        _ -> URL0 ++ "&cmcontinue=" ++ CurrentContinue
     end,
  {ok,Answer} = httpc:request(URL),
  {Document,_} = xmerl_scan:string(lists:last(tuple_to_list(Answer))),
  Continue = 
     [Value || #xmlAttribute{value = Value} <- xmerl_xpath:string("//@cmcontinue", Document)],
  Titles = 
    [Value || #xmlAttribute{value = Value} <- xmerl_xpath:string("//@title", Document)],
  case Continue of
     []->
        Titles;
     [ContValue | _] -> 
        Titles ++ read_titles(ContValue)
  end.

calculate_one(Title0) ->

  Title = replace_chars(Title0),
  URL = "http://www.rosettacode.org/w/index.php?title=" ++
        Title ++ "&action=raw",
  case httpc:request(URL) of
     {ok,Result} ->
           {match,Found} = 
              re:run(lists:last(tuple_to_list(Result)), "\n=={{header(|)", [global]),
           io:format("~ts: ~p examples.\n",[Title0,length(Found)]),
           length(Found);
     {error,socket_closed_remotely} -> 
        io:format("Socket closed remotely. Retry.\n"),
        calculate_one(Title0)
  end.

replace_chars(String) ->

  replace_chars(String,[]).
 

replace_chars([$ | T],Acc) ->

  replace_chars(T, [$_| Acc]);

replace_chars([$+| T],Acc) ->

  replace_chars(T, lists:reverse("%2B") ++ Acc);

replace_chars([8211| T],Acc) ->

  replace_chars(T, lists:reverse("%E2%80%93") ++ Acc);

replace_chars([Other| T],Acc) ->

  replace_chars(T, [Other| Acc]);

replace_chars([],Acc) ->

  lists:reverse(Acc).

</lang>


Outputs:

> rosseta_examples:main().
100 doors: 165 examples.
24 game: 56 examples.
24 game/Solve: 33 examples.
...
Zebra puzzle: 12 examples.
Zeckendorf number representation: 18 examples.
Zig-zag matrix: 65 examples.
Total: 28629 examples.

F#

Using asynchronous workflows to perform downloads concurrently:

<lang fsharp>#r "System.Xml.Linq.dll"

let uri1 = "http://www.rosettacode.org/w/api.php?action=query&list=categorymembers&cmtitle=Category:Programming_Tasks&cmlimit=500&format=xml" let uri2 task = sprintf "http://www.rosettacode.org/w/index.php?title=%s&action=raw" task

[|for xml in (System.Xml.Linq.XDocument.Load uri1).Root.Descendants() do

   for attrib in xml.Attributes() do
     if attrib.Name.LocalName = "title" then
       yield async {
         let uri = uri2 (attrib.Value.Replace(" ", "_") |> System.Web.HttpUtility.UrlEncode)
         use client = new System.Net.WebClient()
         let! html = client.AsyncDownloadString(System.Uri uri)
         let sols' = html.Split([|"{{header|"|], System.StringSplitOptions.None).Length - 1
         lock stdout (fun () -> printfn "%s: %d examples" attrib.Value sols')
         return sols' }|]

|> Async.Parallel |> Async.RunSynchronously |> fun xs -> printfn "Total: %d examples" (Seq.sum xs)</lang>

This is 21× faster than the python thanks to the concurrency.

Factor

Runs in about a minute. The number of threads is limited to 10 avoid cloudfare's protection mechanism.

<lang factor>USING: arrays assocs concurrency.combinators concurrency.semaphores formatting hashtables http.client io json.reader kernel math math.parser sequences splitting urls.encoding ; IN: rosetta-code.count-examples

CONSTANT: list-url "http://rosettacode.org/mw/api.php?action=query&list=categorymembers&cmtitle=Category:Programming_Tasks&cmlimit=500&cmprop=title&format=json"

titles ( query -- titles )
 "query" of "categorymembers" of [ "title" of ] map ;
continued-url ( query -- url/f )
 "query-continue" of "categorymembers" of
 [ assoc>query list-url swap "&" glue ] [ f ] if* ;
(all-programming-titles) ( titles url -- titles' url' )
 http-get nip json> [ titles append ] [ continued-url ] bi
 [ (all-programming-titles) ] [ f ] if* ;
all-programming-titles ( -- titles ) { } list-url (all-programming-titles) drop ;

CONSTANT: content-base-url "http://rosettacode.org/mw/index.php?title=&action=raw"

content-url ( title -- url )
 " " "_" replace
 "title" associate assoc>query
 content-base-url swap "&" glue ;
occurences ( seq subseq -- n ) split-subseq length 1 - ;
count-examples ( title -- n )
 content-url http-get nip "=={{header|" occurences ;
print-task ( title n -- ) "%s: %d examples.\n" printf ;
print-total ( assoc -- ) values sum "Total: %d examples.\n" printf ;
fetch-counts ( titles -- assoc )
 10 <semaphore> [
   [ dup count-examples 2array ] with-semaphore
 ] curry parallel-map ;
print-counts ( titles -- )
 [ [ print-task ] assoc-each nl ] [ print-total ] bi ;
rosetta-examples ( -- )
 all-programming-titles fetch-counts print-counts ;

MAIN: rosetta-examples</lang> Outputs:

100 doors: 169 examples.
24 game: 58 examples.
...
Zeckendorf number representation: 22 examples.
Zig-zag matrix: 66 examples.

Total: 30745 examples.

Go

<lang go>package main

import (

   "bytes"
   "encoding/xml"
   "fmt"
   "io"
   "io/ioutil"
   "net/http"
   "net/url"
   "strings"

)

func req(u string, foundCm func(string)) string {

   resp, err := http.Get(u)
   if err != nil {
       fmt.Println(err) // connection or request fail
       return ""
   }
   defer resp.Body.Close()
   for p := xml.NewDecoder(resp.Body); ; {
       t, err := p.RawToken()
       switch s, ok := t.(xml.StartElement); {
       case err == io.EOF:
           return ""
       case err != nil:
           fmt.Println(err)
           return ""
       case !ok:
           continue
       case s.Name.Local == "cm":
           for _, a := range s.Attr {
               if a.Name.Local == "title" {
                   foundCm(a.Value)
               }
           }
       case s.Name.Local == "categorymembers" && len(s.Attr) > 0 &&
           s.Attr[0].Name.Local == "cmcontinue":
           return url.QueryEscape(s.Attr[0].Value)
       }
   }
   return ""

}

func main() {

   taskQuery := "http://rosettacode.org/mw/api.php?action=query" +
       "&format=xml&list=categorymembers&cmlimit=500" +
       "&cmtitle=Category:Programming_Tasks"
   continueAt := req(taskQuery, count)
   for continueAt > "" {
       continueAt = req(taskQuery+"&cmcontinue="+continueAt, count)
   }
   fmt.Printf("Total: %d examples.\n", total)

}

var marker = []byte("=={{header|") var total int

func count(cm string) {

   taskFmt := "http://rosettacode.org/mw/index.php?title=%s&action=raw"
   taskEsc := url.QueryEscape(strings.Replace(cm, " ", "_", -1))
   resp, err := http.Get(fmt.Sprintf(taskFmt, taskEsc))
   var page []byte
   if err == nil {
       page, err = ioutil.ReadAll(resp.Body)
       resp.Body.Close()
   }
   if err != nil {
       fmt.Println(err)
       return
   }
   examples := bytes.Count(page, marker)
   fmt.Printf("%s: %d\n", cm, examples)
   total += examples

}</lang>

Output
(May 25, 2011):
...
Y combinator: 40
Yahoo! search interface: 10
Yin and yang: 18
Zig-zag matrix: 50
Total: 18290 examples.

Haskell

Library: HTTP XML

from HackageDB

<lang haskell>import Network.Browser import Network.HTTP import Network.URI import Data.List import Data.Maybe import Text.XML.Light import Control.Arrow

justifyR w = foldl ((.return).(++).tail) (replicate w ' ') showFormatted t n = t ++ ": " ++ justifyR 4 (show n)

getRespons url = do

   rsp <- Network.Browser.browse $ do
     setAllowRedirects True
     setOutHandler $ const (return ())     -- quiet
     request $ getRequest url
   return $ rspBody $ snd rsp

getNumbOfExampels p = do

 let pg = intercalate "_" $ words p
 rsp <- getRespons $ "http://www.rosettacode.org/w/index.php?title=" ++ pg ++ "&action=raw"
 let taskPage = rsp
     countEx = length $ filter (=="=={{header|") $ takeWhile(not.null) $ unfoldr (Just. (take 11 &&& drop 1)) taskPage
 return countEx
 

progTaskExamples = do

 rsp <- getRespons "http://www.rosettacode.org/w/api.php?action=query&list=categorymembers&cmtitle=Category:Programming_Tasks&cmlimit=500&format=xml"
 let xmls = onlyElems $ parseXML $ rsp
     tasks = concatMap (map (fromJust.findAttr (unqual "title")). filterElementsName (== unqual "cm")) xmls
 taskxx <- mapM getNumbOfExampels tasks
 let ns = taskxx
     tot = sum ns
 mapM_ putStrLn $ zipWith showFormatted tasks ns
 putStrLn $ ("Total: " ++) $ show tot</lang>

some output: <lang haskell>*Main> progTaskExamples 100 doors: 56 24 game: 11 24 game Player: 9 99 Bottles of Beer: 73 Abstract type: 23 Ackermann Function: 61 Active object: 9 ... Total: 9156</lang>

Icon and Unicon

The following code uses features exclusive to Unicon. This version handles all tasks, not just the first 500.

<lang Unicon>$define RCINDEX "http://rosettacode.org/mw/api.php?format=xml&action=query&list=categorymembers&cmtitle=Category:Programming_Tasks&cmlimit=500" $define RCTASK "http://rosettacode.org/mw/index.php?action=raw&title=" $define RCUA "User-Agent: Unicon Rosetta 0.1" $define RCXUA "X-Unicon: http://unicon.org/" $define TASKTOT "* Total Tasks *" $define TOTTOT "* Total Headers*"

link strings link hexcvt

procedure main(A) # simple single threaded read all at once implementation

   Tasks := table(0)
   every task := taskNames() do {
      Tasks[TASKTOT] +:= 1                            # count tasks
      every lang := languages(task) do {              # count languages
         Tasks[task] +:= 1                     
         Tasks[TOTTOT] +:= 1
         }
      }
   every insert(O := set(),key(Tasks))                # extract & sort keys 
   O := put(sort(O--set(TOTTOT,TASKTOT)),TASKTOT,TOTTOT)  # move totals to end
   every write(k := !O, " : ", Tasks[k]," examples.") # report

end

  1. Generate task names

procedure taskNames()

   continue := ""
   while \(txt := ReadURL(RCINDEX||continue)) do {
       txt ? {
           while tab(find("<cm ") & find(s :="title=\"")+*s) do
               suspend tab(find("\""))\1
           if tab(find("cmcontinue=")) then {
               continue := "&"||tab(upto(' \t'))
               }
           else break
           }
       }

end

  1. Generate language headers in a task

procedure languages(task)

   static WS
   initial WS := ' \t'
   page := ReadURL(RCTASK||CleanURI(task))
   page ? while (tab(find("\n==")),tab(many(WS))|"",tab(find("{{"))) do {
              header := tab(find("=="))
              header ? {
                  while tab(find("[[:Category:|]] [[Category:]] IsTitle}
     fun {$ A} {Atom.toString A.value} end}
 end
 
 fun {PercentEncode Xs}
    case Xs of nil then nil
    [] X|Xr then
       if {Char.isDigit X} orelse {Member X [&- &_ &.  &~]}
          orelse X >= &a andthen X =< &z
          orelse X >= &z andthen X =< &Z then
          X|{PercentEncode Xr}
       else
          {Append &%|{ToHex2 X} {PercentEncode Xr}}
       end
    end
 end
 
 fun {ToHex2 X}
    [{ToHex1 X div 16} {ToHex1 X mod 16}]
 end
 
 fun {ToHex1 X}
    if X >= 0 andthen X =< 9 then &0 + X
    elseif X >= 10 andthen X =< 15 then &A + X - 10
    end
 end

in

 {Main}</lang>

Example output:

100 doors: 86 examples.
24 game: 22 examples.
24 game/Solve: 15 examples.
99 Bottles of Beer: 108 examples.
A+B: 59 examples.
...
Xiaolin Wu's line algorithm: 5 examples.
Y combinator: 29 examples.
Yahoo! Search: 10 examples.
Zig-zag matrix: 43 examples.
Total: 14099 examples.

Perl

<lang Perl>use LWP::Simple;

my $site = "http://rosettacode.org"; my $list_url = "/mw/api.php?action=query&list=categorymembers&cmtitle=Category:Programming_Tasks&cmlimit=500&format=xml";

for (get("$site$list_url") =~ /cm.*?title="(.*?)"/g) {

   (my $slug = $_) =~ tr/ /_/;
   my $count = () = get("$site/wiki/$slug") =~ /toclevel-1/g;
   print "$_: $count examples\n";

}</lang>

Library: Mojolicious

<lang Perl>use v5.10; use Mojo::UserAgent;

my $site = "http://rosettacode.org"; my $list_url = "/mw/api.php?action=query&list=categorymembers&cmtitle=Category:Programming_Tasks&cmlimit=500&format=xml";

my $ua = Mojo::UserAgent->new; $ua->get("$site$list_url")->res->dom->find('cm')->each(sub {

   (my $slug = $_->{title}) =~ tr/ /_/;
   my $count = $ua->get("$site/wiki/$slug")->res->dom->find("#toc .toclevel-1")->size;
   say "$_->{title}: $count examples";

});</lang>

PicoLisp

<lang PicoLisp>(load "@lib/http.l")

(client "rosettacode.org" 80

  "mw/api.php?action=query&list=categorymembers&cmtitle=Category:Programming_Tasks&cmlimit=500&format=xml"
  (while (from " title=\"")
     (let Task (till "\"")
        (client "rosettacode.org" 80 (pack "wiki/" (replace Task " " "_"))
           (let Cnt 0
              (while (from "")
                 (unless (sub? "." (till "<" T))
                    (inc 'Cnt) ) )
              (out NIL (prinl (ht:Pack Task) ": " Cnt)) ) ) ) ) )</lang>

Output (05may10):

100 doors: 79
24 game: 21
24 game/Solve: 15
99 Bottles of Beer: 95
A+B: 37
Abstract type: 29
...


PureBasic

<lang PureBasic>OpenConsole() URLDownloadToFile_( #Null, "http://www.rosettacode.org/w/api.php?action=query&list=categorymembers&cmtitle=Category:Programming_Tasks&cmlimit=500&format=xml", "tasks.xml", 0, #Null) ReadFile(0, "tasks.xml")

  x1$ =  ReadString(0)
  Repeat
     x2 = FindString(x1$, "title=", x2 + 1)
     If x2 
        title$ = Mid(x1$, x2 + 7, 99) 
        title$ = Left(title$, FindString(title$, ">", 1) - 4) 
        URLDownloadToFile_( #Null, "http://www.rosettacode.org/w/index.php?title=" + title$ + "&action=raw", "task.xml", 0, #Null)
        ReadFile(1, "task.xml") 
        While Not Eof(1)
           y1$ =  ReadString(1)
           If FindString(y1$, "=={{header|", 1)
              j + 1
           EndIf
        Wend
        PrintN( title$ +": " + Str(j) + " examples")
        k + j
        j = 0
        CloseFile(1) 
     EndIf  
 Until x2 = 0
 PrintN("Total: " + Str(k) + " examples")
 Input()</lang>

Python

<lang python>import urllib, xml.dom.minidom

x = urllib.urlopen("http://www.rosettacode.org/w/api.php?action=query&list=categorymembers&cmtitle=Category:Programming_Tasks&cmlimit=500&format=xml")

tasks = [] for i in xml.dom.minidom.parseString(x.read()).getElementsByTagName("cm"):

   t = i.getAttribute('title').replace(" ", "_")
   y = urllib.urlopen("http://www.rosettacode.org/w/index.php?title=%s&action=raw" % t.encode('utf-8'))
   tasks.append( y.read().lower().count("{{header|") )
   print t.replace("_", " ") + ": %d examples." % tasks[-1]

print "\nTotal: %d examples." % sum(tasks)</lang>

R

Library: XML (R)
Library: RCurl

<lang R> library(XML) library(RCurl) doc <- xmlInternalTreeParse("http://www.rosettacode.org/w/api.php?action=query&list=categorymembers&cmtitle=Category:Programming_Tasks&cmlimit=500&format=xml") nodes <- getNodeSet(doc,"//cm") titles = as.character( sapply(nodes, xmlGetAttr, "title") ) headers <- list() counts <- list() for (i in 1:length(titles)){ headersi <- getURL( paste("http://rosettacode.org/mw/index.php?title=", gsub(" ", "_", titles[i]), "&action=raw", sep="") ) countsi <- strsplit(headersi,split=" ")1 countsi <- grep("\\{\\{header", countsi) cat(titles[i], ":", length(countsi), "examples\n") } cat("Total: ", length(unlist(counts)), "examples\n") </lang>

Racket

<lang racket>

  1. lang racket

(require net/url net/uri-codec json (only-in racket/dict [dict-ref ref]))

(define (RC-get verb params)

 ((compose1 get-pure-port string->url format)
  "http://rosettacode.org/mw/~a.php?~a" verb (alist->form-urlencoded params)))

(define (get-category catname)

 (let loop ([c #f])
   (define t
     ((compose1 read-json RC-get) 'api
      `([action . "query"] [format . "json"]
        [list . "categorymembers"] [cmtitle . ,(format "Category:~a" catname)]
        [cmcontinue . ,(and c (ref c 'cmcontinue))] [cmlimit . "500"])))
   (define (c-m key) (ref (ref t key '()) 'categorymembers #f))
   (append (for/list ([page (c-m 'query)]) (ref page 'title))
           (cond [(c-m 'query-continue) => loop] [else '()]))))

(printf "Total: ~a\n"

 (for/sum ([task (get-category 'Programming_Tasks)])
   (define s ((compose1 length regexp-match-positions*)
              #rx"=={{" (RC-get 'index `([action . "raw"] [title . ,task]))))
   (printf "~a: ~a\n" task s)
   s))

</lang>

Ruby

Library: REXML

First, a RosettaCode module, saved as rosettacode.rb: <lang ruby>require 'open-uri' require 'rexml/document'

module RosettaCode

 URL_ROOT = "http://rosettacode.org/mw"
 def self.get_url(page, query)
   begin
     # Ruby 1.9.2
     pstr = URI.encode_www_form_component(page)
     qstr = URI.encode_www_form(query)
   rescue NoMethodError
     require 'cgi'
     pstr = CGI.escape(page)
     qstr = query.map {|k,v|
       "%s=%s" % [CGI.escape(k.to_s), CGI.escape(v.to_s)]}.join("&")
   end
   url = "#{URL_ROOT}/#{pstr}?#{qstr}"
   p url if $DEBUG
   url
 end
 def self.get_api_url(query)
   get_url "api.php", query
 end
 def self.category_members(category)
   query = {
     "action" => "query",
     "list" => "categorymembers",
     "cmtitle" => "Category:#{category}",
     "format" => "xml",
     "cmlimit" => 500,
   }
   while true
     url = get_api_url query
     doc = REXML::Document.new open(url)
     REXML::XPath.each(doc, "//cm") do |task|
       yield task.attribute("title").value
     end
     continue = REXML::XPath.first(doc, "//query-continue")
     break if continue.nil?
     cm = REXML::XPath.first(continue, "categorymembers")
     query["cmcontinue"] = cm.attribute("cmcontinue").value
   end
 end

end</lang>

Then, we implement the task with: <lang ruby>require 'rosettacode'

total_examples = 0

RosettaCode.category_members("Programming_Tasks") do |task|

 url = RosettaCode.get_url("index.php", {"action" => "raw", "title" => task})
 examples = open(url).read.scan("=={{header").length
 puts "#{task}: #{examples}"
 total_examples += examples

end

puts puts "Total: #{total_examples}"</lang>


Run BASIC

<lang runbasic>html "

"

a$ = httpGet$("http://rosettacode.org/wiki/Category:Programming_Tasks")

a$ = word$(a$,1,"
NumTaskExamples

")

i = instr(a$,"<a href=""/wiki/") i = instr(a$,"<a href=""/wiki/",i+1) while i > 0

 count	= count + 1
 i	= instr(a$,"<a href=""/wiki/",i+1)
 j	= instr(a$,">",i+5)
 a1$	= mid$(a$,i+15,j-i)
 taskId$ = word$(a1$,1,"""")
 task$   = word$(a1$,3,"""")
 url$	= "http://rosettacode.org/wiki/";taskId$
 a2$	= httpGet$(url$)
 ii	= instr(a2$,"")
 jj	= 0
 while ii > 0
   jj	= ii
   ii	= instr(a2$,"",ii+10)
 wend
 if jj = 0 then 
   examp = 0
  else
   kk	= instr(a2$,"<",jj+24)
   examp = int(val(mid$(a2$,jj+24,kk-jj-24)))
 end if

html "";count;"";task$;"";examp;""

 totExamp = totExamp + examp

wend

html "**** Total **";totExamp;""

end</lang>

NumTaskExamples
1100 doors165
224 game56
324 game/Solve34
499 Bottles of Beer192
5A+B129
6Abstract type51
7Accumulator factory65
8Ackermann function132
9Active Directory/Connect13
10Active Directory/Search for a user13
11Active object22
12Add a variable to a class instance at runtime37
.........
655Y combinator53
656Yahoo! search interface16
657Yin and yang38
658Zebra puzzle12
659Zeckendorf number representation18
660Zig-zag matrix65
**** Total **28611

Scala

This was writen for Scala 2.8, but Scala 2.7 can be used with slight modifications to the IO library.

Different than the example for other languages, it parallelizes the reading and counting, and it also encode the URL, because some URLs are now causing problems. These modifications are minor, though.

It was written in script style.

<lang scala>import java.net.{URL, URLEncoder} import scala.io.Source.fromURL

val allTasksURL = "http://www.rosettacode.org/w/api.php?action=query&list=categorymembers&cmtitle=Category:Programming_Tasks&cmlimit=500&format=xml" val allTasks = xml.parsing.XhtmlParser(fromURL(new URL(allTasksURL)))

val regexExpr = "(?i)==\\{\\{header\\|".r def oneTaskURL(title: String) = "http://www.rosettacode.org/w/index.php?title=%s&action=raw" format URLEncoder.encode(title.replace(' ', '_'), "UTF-8") def count(title: String) = regexExpr findAllIn fromURL(new URL(oneTaskURL(title)))(io.Codec.UTF8).mkString length

val counts = for (task <- allTasks \\ "cm" \\ "@title" map (_.text)) yield scala.actors.Futures.future((task, count(task)))

counts map (_.apply) map Function.tupled("%s: %d examples." format (_, _)) foreach println println("\nTotal: %d examples." format (counts map (_.apply._2) sum)) </lang>

Tcl

Library: Tcllib (Package: json)

<lang tcl>package require Tcl 8.5 package require http package require json

fconfigure stdout -buffering none

proc get_tasks {category} {

   set start [clock milliseconds]
   puts -nonewline "getting $category members..."
   set base_url http://www.rosettacode.org/w/api.php
   set query {action query list categorymembers cmtitle Category:%s format json cmlimit 500}
   set this_query [dict create {*}[split [format $query $category]]]
   set tasks [list]
   while {1} {
       set url [join [list $base_url [http::formatQuery {*}$this_query]] ?]
       set response [http::geturl $url]
       if {[set s [http::status $response]] ne "ok" || [http::ncode $response] != 200} {
           error "Oops: url=$url\nstatus=$s\nhttp code=[http::code $response]"
       }
       set data [json::json2dict [http::data $response]]
       http::cleanup $response
       
       # add tasks to list
       foreach task [dict get $data query categorymembers] {
           lappend tasks [dict get [dict create {*}$task] title]
       }
       
       if {[catch {dict get $data query-continue categorymembers cmcontinue} continue_task] != 0} {
           # no more continuations, we're done
           break
       }
       dict set this_query cmcontinue $continue_task
   }
   puts " found [llength $tasks] tasks in [expr {[clock milliseconds] - $start}] milliseconds"
   return $tasks

}

  1. This proc can be replaced by a single regexp command:
  2. set count [regexp -all "***=$needle" $haystack]
  3. However this proc is more efficient -- we're dealing with plain strings only.

proc count_substrings {needle haystack} {

   set count 0
   set idx 0
   while {[set idx [string first $needle $haystack $idx]] != -1} {
       incr count
       incr idx
   }
   return $count

}

set total 0 foreach task [get_tasks Programming_Tasks] {

   set url [format "http://www.rosettacode.org/w/index.php?title=%s&action=raw" [string map {{ } _} $task]]
   set response [http::geturl $url]
   if {[set s [http::status $response]] ne "ok" || [http::ncode $response] != 200} {
       error "Oops: url=$url\nstatus=$s\nhttp code=[http::code $response]"
   }
   set count [count_substrings "\{\{header|" [http::data $response]]
   puts [format "%3d examples in %s" $count $task]
   http::cleanup $response
   incr total $count

}

puts "\nTotal: $total examples"</lang>

TUSCRIPT

<lang tuscript>$$ MODE TUSCRIPT url="http://www.rosettacode.org/w/api.php?action=query&list=categorymembers&cmtitle=Category:Programming_Tasks&cmlimit=500&format=xml" data=REQUEST (url)

BUILD S_TABLE beg=* DATA :title=": BUILD S_TABLE end=* DATA :":

titles=EXTRACT (data,beg|,end,1,0,"~~") titles=SPLIT (titles,":~~:") sz_titles=SIZE (titles)

BUILD R_TABLE header=":==\{\{header|:" all=*

ERROR/STOP CREATE ("tasks",seq-e,-std-)

COMPILE LOOP title=titles ask=* ask =SET_VALUE(ask,"title",title) ask =SET_VALUE(ask,"action","raw") ask =ENCODE (ask,cgi) http ="http://www.rosettacode.org/mw/index.php" url =CONCAT (http,"?",ask) data =REQUEST (url) header =FILTER_INDEX (data,header,-) sz_header=SIZE(header) line =CONCAT (title,"=",sz_header," members") FILE "tasks" = line all =APPEND(all,sz_header) ENDLOOP

ENDCOMPILE all =JOIN(all),sum=SUM(all),time=time() line=CONCAT (time,": ", sz_titles, " Programing Tasks: ", sum, " solutions")

FILE "tasks" = line </lang> Output in file "tasks":

100 doors=104 members
24 game=27 members
24 game/Solve=21 members
99 Bottles of Beer=124 members
A+B=76 members
Abstract type=35 members
Accumulator factory=44 members
...
XML/Input=39 members
XML/Output=32 members
XML/XPath=24 members
Xiaolin Wu's line algorithm=0 members
Y combinator=33 members
Yahoo! search interface=10 members
Zig-zag matrix=46 members
2011-01-15 03:41:30: 455 Programing Tasks: 16009 solutions