173 lines
		
	
	
		
			4.3 KiB
		
	
	
	
		
			Perl
		
	
	
	
	
	
		
		
			
		
	
	
			173 lines
		
	
	
		
			4.3 KiB
		
	
	
	
		
			Perl
		
	
	
	
	
	
|   | % ---------------------------------------------------------------------- | ||
|  | % The Computer Language Benchmarks Game | ||
|  | % http://shootout.alioth.debian.org/ | ||
|  | % | ||
|  | % contributed by Anthony Borla | ||
|  | % modified to run with YAP by Glendon Holst | ||
|  | % ---------------------------------------------------------------------- | ||
|  | 
 | ||
|  | :- yap_flag(unknown,error). | ||
|  | 
 | ||
|  | :- use_module(library(readutil)). | ||
|  | :- use_module(library(lists)). | ||
|  | :- use_module(library(assoc)). | ||
|  | 
 | ||
|  | :- initialization(main). | ||
|  | 
 | ||
|  | main :- | ||
|  |    current_input(Cin), | ||
|  |    load_sequence(Cin, Seq), | ||
|  | 
 | ||
|  |    FragmentLengths = [1, 2], | ||
|  |    forall(member(E, FragmentLengths), (print_frequencies(Seq, E), nl)), | ||
|  | 
 | ||
|  |    Fragments = ["GGT", "GGTA", "GGTATT", "GGTATTTTAATT", "GGTATTTTAATTTATAGT"], | ||
|  |    forall(member(E, Fragments), print_count(Seq, E)), | ||
|  | 
 | ||
|  |    statistics, | ||
|  |    statistics_jit. | ||
|  | 
 | ||
|  | % ------------------------------- % | ||
|  | 
 | ||
|  | print_frequencies(Seq, KeyLen) :- | ||
|  |    generate_counts(Seq, KeyLen, CountTable), | ||
|  |    sum_counts_(CountTable, 0, SumCounts), | ||
|  |    make_freq_table_(CountTable, SumCounts, [], FTable), | ||
|  |    keysort(FTable, SFTable), reverse(SFTable, FreqTable), | ||
|  |    print_freq_table_(FreqTable). | ||
|  | 
 | ||
|  | % ------------- % | ||
|  | 
 | ||
|  | sum_counts_([_-C|T], Acc, Sum) :- Acc1 is Acc + C, !, sum_counts_(T, Acc1, Sum). | ||
|  | sum_counts_([], Acc, Acc). | ||
|  | 
 | ||
|  | % ------------- % | ||
|  | 
 | ||
|  | make_freq_table_([K-C|T], SumCounts, FTA, FreqTable) :- | ||
|  |    F is C / SumCounts * 100.0, append([F-K], FTA, FTA1), | ||
|  |    !, make_freq_table_(T, SumCounts, FTA1, FreqTable). | ||
|  | make_freq_table_([], _, FTA, FTA). | ||
|  | 
 | ||
|  | % ------------- % | ||
|  | 
 | ||
|  | print_freq_table_([F-K|T]) :- | ||
|  |    format('~w ~3f\n', [K, F]), | ||
|  |    !, print_freq_table_(T). | ||
|  | print_freq_table_([]). | ||
|  | 
 | ||
|  | % ------------------------------- % | ||
|  | 
 | ||
|  | print_count(Seq, Fragment) :- | ||
|  |    length(Fragment, FragLen), | ||
|  |    generate_counts(Seq, FragLen, CountTable), | ||
|  |    atom_codes(FragKey, Fragment), | ||
|  |    ( | ||
|  |       select(FragKey-Count, CountTable, _) | ||
|  |    ; | ||
|  |       Count = 0 | ||
|  |    ), !, | ||
|  |    format('~d\t~s\n', [Count, Fragment]). | ||
|  | 
 | ||
|  | % ------------- % | ||
|  | 
 | ||
|  | generate_counts(Seq, Length, CountTable) :- | ||
|  |    length(Seq, SeqLen), Last is SeqLen - Length + 1, | ||
|  |    make_count_table(Length, Last, Seq, CountTable). | ||
|  | 
 | ||
|  | % ------------------------------- % | ||
|  | 
 | ||
|  | make_count_table(Length, Last, Seq, CountTable) :- | ||
|  |    empty_assoc(A), | ||
|  |    mct_i_loop_(0, Length, Last, Seq, A, ACT), | ||
|  |    assoc_to_list(ACT, CountTable). | ||
|  | 
 | ||
|  | % ------------- % | ||
|  | 
 | ||
|  | mct_i_loop_(I, Length, Last, Seq, CTA, CountTable) :- | ||
|  |    I < Length, !, | ||
|  |    mct_j_loop_(Last, Length, Seq, CTA, CTA1), | ||
|  |    I1 is I + 1, !, | ||
|  |    Seq = [_|Ss], Last1 is Last - 1, | ||
|  |    mct_i_loop_(I1, Length, Last1, Ss, CTA1, CountTable). | ||
|  | mct_i_loop_(Length, Length, _, _, CTA, CTA). | ||
|  | 
 | ||
|  | 
 | ||
|  | % ------------- % | ||
|  | 
 | ||
|  | mct_j_loop_(Last, Length, Seq, CTA, CountTable) :- | ||
|  |    Last > 0, !, | ||
|  |    sub_list_(Seq, Length, KeyString, Rest), atom_codes(Key, KeyString), | ||
|  |    ( | ||
|  |       get_assoc(Key, CTA, Value) -> | ||
|  |       V1 is Value + 1, put_assoc(Key, CTA, V1, CTA1) | ||
|  |    ; | ||
|  |       put_assoc(Key, CTA, 1, CTA1) | ||
|  |    ), | ||
|  |    !, Last1 is Last - Length, | ||
|  |    mct_j_loop_(Last1, Length, Rest, CTA1, CountTable). | ||
|  | mct_j_loop_(Last, _, _, CTA, CTA) :- Last =< 0, !. | ||
|  | 
 | ||
|  | % ------------------------------- % | ||
|  | 
 | ||
|  | load_sequence(S, Seq) :- load_sequence_(S, fail, "", Seq). | ||
|  | 
 | ||
|  | % ------------- % | ||
|  | 
 | ||
|  | load_sequence_(S, Loading, Seq, RetSeq) :- | ||
|  |    catch(read_line_to_codes(S, L), _, fail), is_list(L), !, | ||
|  |    ( | ||
|  |       Loading -> | ||
|  |       process_sequence(L, S, Seq, RetSeq) | ||
|  |    ; | ||
|  |       ignore_sequence(L, S, Seq, RetSeq) | ||
|  |    ). | ||
|  | load_sequence_(S, _, Seq, Seq). | ||
|  | 
 | ||
|  | % ------------- % | ||
|  | 
 | ||
|  | ignore_sequence([62,84,72,82,69,69|_], S, Seq, RetSeq) :- !, | ||
|  |    load_sequence_(S, true, Seq, RetSeq). | ||
|  | ignore_sequence(_, S, Seq, RetSeq) :- !, | ||
|  |    load_sequence_(S, fail, Seq, RetSeq). | ||
|  | 
 | ||
|  | process_sequence([62|_], _, Seq, Seq) :- !. | ||
|  | process_sequence([59|_], S, Seq, RetSeq) :- !, | ||
|  |    load_sequence_(S, true, Seq, RetSeq). | ||
|  | 
 | ||
|  | process_sequence(L, S, Seq, RetSeq) :- | ||
|  |    to_upper(L, UL), | ||
|  |    append(Seq, UL, NewSeq), | ||
|  |    !, load_sequence_(S, true, NewSeq, RetSeq). | ||
|  | 
 | ||
|  | % ------------------------------- % | ||
|  | 
 | ||
|  | to_upper(L, U) :- to_upper_(L, [], U). | ||
|  | 
 | ||
|  | % ------------- % | ||
|  | 
 | ||
|  | to_upper_([], UA, U) :- reverse(UA, U), !. | ||
|  | 
 | ||
|  | to_upper_([C|T], UA, U) :- | ||
|  |    is_lower(C), C1 is C - 32, | ||
|  |    !, to_upper_(T, [C1|UA], U). | ||
|  | 
 | ||
|  | to_upper_([C|T], UA, U) :- | ||
|  |    !, to_upper_(T, [C|UA], U). | ||
|  | 
 | ||
|  | % ------------- % | ||
|  | 
 | ||
|  | is_lower(C) :- C >= 97, C =< 122. | ||
|  | 
 | ||
|  | % ------------------------------- % | ||
|  | 
 | ||
|  | forall(Gen, Proc) :- findall(_,(Gen, Proc), _). | ||
|  | 
 | ||
|  | % ------------- % | ||
|  | 
 | ||
|  | sub_list_([S|Seq], L, [S|Ks], Rs) :- L > 0, !, | ||
|  |    L1 is L - 1, | ||
|  |    sub_list_(Seq, L1, Ks, Rs). | ||
|  | sub_list_(Rs, 0, [], Rs). | ||
|  | 
 | ||
|  | % ------------------------------- % |