Task: Rosetta Code_Rank languages by popularity


C++: #include <string>
#include <boost/regex.hpp>
#include <boost/asio.hpp>
#include <vector>
#include <utility>
#include <iostream>
#include <sstream>
#include <cstdlib>
#include <algorithm>
#include <iomanip>

struct Sort { 
   bool operator( ) ( const std::pair<std::string,int> & a , const std::pair<std::string,int> & b ) 
      const {
	 return a.second > b.second ;
      }
} ;

int main( ) {
   try {
      
      boost::asio::io_service io_service ; 
      boost::asio::ip::tcp::resolver resolver ( io_service ) ;
      boost::asio::ip::tcp::resolver::query query ( "rosettacode.org" , "http" ) ;
      boost::asio::ip::tcp::resolver::iterator endpoint_iterator = resolver.resolve( query ) ;
      boost::asio::ip::tcp::resolver::iterator end ;
      boost::asio::ip::tcp::socket socket( io_service ) ;
      boost::system::error_code error = boost::asio::error::host_not_found ;
      
      while ( error && endpoint_iterator != end ) {
	 socket.close( ) ;
	 socket.connect( *endpoint_iterator++ , error ) ;
      }
      if ( error ) 
	 throw boost::system::system_error ( error ) ;
      
      boost::asio::streambuf request ;
      std::ostream request_stream( &request ) ;
      request_stream << "GET " << "/mw/index.php?title=Special:Categories&limit=5000" << " HTTP/1.0\r\n" ;
      request_stream << "Host: " << "rosettacode.org" << "\r\n" ;
      request_stream << "Accept: */*\r\n" ;
      request_stream << "Connection: close\r\n\r\n" ;
      
      boost::asio::write( socket , request ) ;
      
      boost::asio::streambuf response ;
      std::istream response_stream ( &response ) ;
      boost::asio::read_until( socket , response , "\r\n\r\n" ) ;
      boost::regex e( "<li><a href=\"[^<>]+?\">([a-zA-Z\\+#1-9]+?)</a>\\s?\\((\\d+) members\\)</li>" ) ;
      
      std::ostringstream line ;
      std::vector<std::pair<std::string , int> > languages ; 
      boost::smatch matches ;
      while ( boost::asio::read( socket , response , boost::asio::transfer_at_least( 1 ) , error ) ) {
	 line << &response ;
	 if ( boost::regex_search( line.str( ) , matches , e ) ) {
	    std::string lang( matches[2].first , matches[2].second ) ;
	    int zahl = atoi ( lang.c_str( ) ) ;
	    languages.push_back( std::make_pair( matches[ 1 ] , zahl ) ) ;
	 }
	 line.str( "") ;
      }
      if ( error != boost::asio::error::eof ) 
	 throw boost::system::system_error( error ) ;
      
      std::sort( languages.begin( ) , languages.end( ) , Sort( ) ) ;
      int n = 1 ;
      for ( std::vector<std::pair<std::string , int> >::const_iterator spi = languages.begin( ) ;
	    spi != languages.end( ) ; ++spi ) {
	 std::cout << std::setw( 3 ) << std::right << n << '.' << std::setw( 4 ) << std::right <<  
	 spi->second   << " - " << spi->first << '\n' ;
	 n++ ;
      }
   } catch ( std::exception &ex ) {
      std::cout << "Exception: " << ex.what( ) << '\n' ;
   }
   return 0 ;
}



Go: package main

import (
	"encoding/xml"
	"fmt"
	"io"
	"io/ioutil"
	"log"
	"net/http"
	"net/url"
	"regexp"
	"sort"
	"strconv"
	"strings"
)

var baseQuery = "http:
	"&format=xml&list=categorymembers&cmlimit=500"

func req(u string, foundCm func(string)) string {
	resp, err := http.Get(u)
	if err != nil {
		log.Fatal(err) 
	}
	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:
			log.Fatal(err)
		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 ""
}


type pop struct {
	string
	int
}
type popList []pop

func (pl popList) Len() int      { return len(pl) }
func (pl popList) Swap(i, j int) { pl[i], pl[j] = pl[j], pl[i] }
func (pl popList) Less(i, j int) bool {
	switch d := pl[i].int - pl[j].int; {
	case d > 0:
		return true
	case d < 0:
		return false
	}
	return pl[i].string < pl[j].string
}

func main() {
	
	langMap := make(map[string]bool)
	storeLang := func(cm string) {
		if strings.HasPrefix(cm, "Category:") {
			cm = cm[9:]
		}
		langMap[cm] = true
	}
	languageQuery := baseQuery + "&cmtitle=Category:Programming_Languages"
	continueAt := req(languageQuery, storeLang)
	for continueAt != "" {
		continueAt = req(languageQuery+"&cmcontinue="+continueAt, storeLang)
	}
	
	s := make(popList, 0, len(langMap))

	
	resp, err := http.Get("http:
		"?title=Special:Categories&limit=5000")
	if err != nil {
		log.Fatal(err)
	}
	page, err := ioutil.ReadAll(resp.Body)
	resp.Body.Close()

	
	rx := regexp.MustCompile("<li><a.*>(.*)</a>.*[(]([0-9]+) member")
	for _, sm := range rx.FindAllSubmatch(page, -1) {
		ls := string(sm[1])
		if langMap[ls] {
			if n, err := strconv.Atoi(string(sm[2])); err == nil {
				s = append(s, pop{ls, n})
			}
		}
	}

	
	sort.Sort(s)
	lastCnt, lastIdx := -1, 1
	for i, lang := range s {
		if lang.int != lastCnt {
			lastCnt = lang.int
			lastIdx = i + 1
		}
		fmt.Printf("%3d. %3d - %s\n", lastIdx, lang.int, lang.string)
	}
}