Task: Anagrams


C++: #include <iostream>
#include <fstream>
#include <string>
#include <map>
#include <vector>
#include <algorithm>
#include <iterator>
 
int main() {
  std::ifstream in("unixdict.txt");
  typedef  std::map<std::string, std::vector<std::string> > AnagramMap;
  AnagramMap anagrams;
 
  std::string word;
  size_t count = 0;
  while (std::getline(in, word)) {
    std::string key = word;
    std::sort(key.begin(), key.end());
    
    AnagramMap::mapped_type & v = anagrams[key];
    v.push_back(word);
    count = std::max(count, v.size());
  }
 
  in.close();
 
  for (AnagramMap::const_iterator it = anagrams.begin(), e = anagrams.end();
       it != e; it++)
    if (it->second.size() >= count) {
      std::copy(it->second.begin(), it->second.end(),
                std::ostream_iterator<std::string>(std::cout, ", "));
      std::cout << std::endl;
    }
  return 0;
}









Fortran: 
	module anagram_routines

	implicit none
	
	
	integer,parameter :: file_unit = 1000
	character(len=*),parameter :: filename = 'unixdict.txt'
	
	
	integer,parameter :: max_chars = 50
	
	
	integer,parameter :: str_len = 256
	
	type word 
	  character(len=max_chars) :: str = repeat(' ',max_chars)    
	  integer                  :: n = 0                          
	  integer                  :: n_anagrams = 0	             
	  logical                  :: checked = .false.              
	  character(len=str_len)   :: anagrams = repeat(' ',str_len) 
	end type word
	
	
	type(word),dimension(:),allocatable,target :: dict
	
	contains


	
		function count_lines_in_file(fid) result(n_lines)
	
		implicit none
	
		integer             :: n_lines
		integer,intent(in)  :: fid		
		character(len=1)    :: tmp
		integer             :: i
		integer             :: ios
		
		
		
		rewind(fid)	  
		
		n_lines = 0
		do 
			read(fid,'(A1)',iostat=ios) tmp
			if (ios < 0) exit      
			n_lines = n_lines + 1  
		end do

		rewind(fid)   
				
	
		end function count_lines_in_file
	
	
	
		pure elemental function is_anagram(x,y)
	
		implicit none
		character(len=*),intent(in) :: x
		character(len=*),intent(in) :: y
		logical :: is_anagram
	
		character(len=len(x)) :: x_tmp	
		integer :: i,j
		
		
		character(len=1),parameter :: null = achar(0)
			
		
		
		x_tmp = x
		do i=1,len_trim(x)
			j = index(x_tmp, y(i:i)) 
			if (j/=0) then
				x_tmp(j:j) = null  
			else
				is_anagram = .false. 
				return
			end if
		end do
	
		
		
		is_anagram = .true.
					
	
		end function is_anagram
	


	end module anagram_routines



	program main

	use anagram_routines
	implicit none
	
	integer :: n,i,j,n_max
	type(word),pointer :: x,y
	logical :: first_word
	real :: start, finish
	
	call cpu_time(start)	
	
	
	open(unit=file_unit,file=filename)      
	n = count_lines_in_file(file_unit)      
	allocate(dict(n))                       
	do i=1,n                                
		read(file_unit,'(A)') dict(i)%str   
		dict(i)%n = len_trim(dict(i)%str)   
	end do		
	close(file_unit)                        
	
	
	do i=1,n
		
		x => dict(i)	
		first_word = .true.	
		
		do j=i,n
		
			y => dict(j)	
			
			
			if (x%checked .or. y%checked) cycle     
			if (x%n/=y%n) cycle                     
			if (x%str(1:x%n)==y%str(1:y%n)) cycle   
			
			
			if (is_anagram(x%str(1:x%n), y%str(1:y%n))) then
				
				y%checked = .true. 	
				x%n_anagrams = x%n_anagrams + 1
				if (first_word) then
					
					first_word = .false.
					x%n_anagrams = x%n_anagrams + 1
					x%anagrams = trim(x%anagrams)//x%str(1:x%n)  
				end if
				x%anagrams = trim(x%anagrams)//','//y%str(1:y%n) 
			end if
	
		end do
		x%checked = .true.  
		 
	end do
	
	
	write(*,*) ''
	n_max = maxval(dict%n_anagrams)
	do i=1,n
		if (dict(i)%n_anagrams==n_max) write(*,'(A)') trim(dict(i)%anagrams)
	end do
	
	
	write(*,*) ''
	n_max = maxval(dict%n, mask=dict%n_anagrams>0)
	do i=1,n
		if (dict(i)%n_anagrams>0 .and. dict(i)%n==n_max) write(*,'(A)') trim(dict(i)%anagrams)
	end do
	write(*,*) ''

	call cpu_time(finish)	
	write(*,'(A,F6.3,A)') '[Runtime = ',finish-start,' sec]'
	write(*,*) ''


	end program main