### ----------------------------------------------------
### -- Perl6::Parser
### -- Licenses: Artistic-2.0
### -- Authors: Jeffrey Goff <drforr@pobox.com>
### -- File: t/corpus/rosetta-a.t
### ----------------------------------------------------
### -- Chunk 2 of 2
0] = 2;
 
say @arr[0];
_END_
};

subtest {
	{ ok round-trips( Q:to[_END_] ), Q{version 1};
my %h1 = key1 => 'val1', 'key-2' => 2, three => -238.83, 4 => 'val3';
my %h2 = 'key1', 'val1', 'key-2', 2, 'three', -238.83, 4, 'val3';
_END_
	};

	{ ok round-trips( Q:to[_END_] ), Q{version 2};
my @a = 1..5;
my @b = 'a'..'e';
my %h = @a Z=> @b;
_END_
	};

#`{ XXX consistency check fails
	{ ok round-trips( Q:to[_END_] ), Q{version 3};
my %h1;
say %h1{'key1'};
say %h1<key1>;
%h1<key1> = 'val1';
%h1<key1 three> = 'val1', -238.83;
_END_
	};
}

	{ ok round-trips( Q:to[_END_] ), Q{version 4};
my $h = {key1 => 'val1', 'key-2' => 2, three => -238.83, 4 => 'val3'};
say $h<key1>;
_END_
	};

	{ ok round-trips( Q:to[_END_] ), Q{version 5};
my %hash{Any}; # same as %hash{*}
class C {};
my %cash{C};
%cash{C.new} = 1;
_END_
	};

	{ ok round-trips( Q:to[_END_] ), Q{version 6};
my @infinite = 1 .. Inf;  # 1, 2, 3, 4, ...
 
say @infinite[5000];  # 5001
say @infinite.elems;  # Throws exception "Cannot .elems a lazy list"
_END_
	};

	done-testing;
}, Q{Associative array/creation};

{ ok round-trips( Q:to[_END_] ), Q{Associative array/iteration};
my %pairs = hello => 13, world => 31, '!' => 71;
 
for %pairs.kv -> $k, $v {
    say "(k,v) = ($k, $v)";
}
 
{ say "$^a => $^b" } for %pairs.kv;
 
say "key = $_" for %pairs.keys;
 
say "value = $_" for %pairs.values;
_END_
};

{ ok round-trips( Q:to[_END_] ), Q{Average loop length};
constant MAX_N  = 20;
constant TRIALS = 100;
 
for 1 .. MAX_N -> $N {
    my $empiric = TRIALS R/ [+] find-loop(random-mapping($N)).elems xx TRIALS;
    my $theoric = [+]
	map -> $k { $N ** ($k + 1) R/ [*] $k**2, $N - $k + 1 .. $N }, 1 .. $N;
 
    FIRST say " N    empiric      theoric      (error)";
    FIRST say "===  =========  ============  =========";
 
    printf "%3d  %9.4f  %12.4f    (%4.2f%%)\n",
	    $N,  $empiric,
			$theoric, 100 * abs($theoric - $empiric) / $theoric;
}
 
sub random-mapping { hash .list Z=> .roll given ^$^size }
sub find-loop { 0, %^mapping{*} ...^ { (state %){$_}++ } }
_END_
};

{ ok round-trips( Q:to[_END_] ), Q{Averages/arithmetic mean};
multi mean([]){ Failure.new('mean on empty list is not defined') }; # Failure-objects are lazy exceptions
multi mean (@a) { ([+] @a) / @a }
_END_
};

{ ok round-trips( Q:to[_END_] ), Q{Averages/mean angle};
# Of course, you can still use pi and 180.
sub deg2rad { $^d * tau / 360 }
sub rad2deg { $^r * 360 / tau }
 
sub phase ($c)  {
    my ($mag,$ang) = $c.polar;
    return NaN if $mag < 1e-16;
    $ang;
}
 
sub meanAngle { rad2deg phase [+] map { cis deg2rad $_ }, @^angles }
 
say meanAngle($_).fmt("%.2f\tis the mean angle of "), $_ for
    [350, 10],
    [90, 180, 270, 360],
    [10, 20, 30];
_END_
};

{ ok round-trips( Q:to[_END_] ), Q{Averages/mean time of day};
sub tod2rad($_) { [+](.comb(/\d+/) Z* 3600,60,1) * tau / 86400 }
 
sub rad2tod ($r) {
    my $x = $r * 86400 / tau;
    (($x xx 3 Z/ 3600,60,1) Z% 24,60,60).fmt('%02d',':');
}
 
sub phase ($c) { $c.polar[1] }
 
sub mean-time (@t) { rad2tod phase [+] map { cis tod2rad $_ }, @t }
 
my @times = ["23:00:17", "23:40:20", "00:12:45", "00:17:19"];
 
say "{ mean-time(@times) } is the mean time of @times[]";
_END_
};

{ ok round-trips( Q:to[_END_] ), Q{Averages/median};
sub median {
  my @a = sort @_;
  return (@a[@a.end / 2] + @a[@a / 2]) / 2;
}
_END_
};

{ ok round-trips( Q:to[_END_] ), Q{Averages/mode};
sub mode (*@a) {
    my %counts;
    ++%counts{$_} for @a;
    my $max = [max] values %counts;
    return |map { .key }, grep { .value == $max }, %counts.pairs;
}
_END_
};

{ ok round-trips( Q:to[_END_] ), Q{Averages/Pythagorean means};
sub A { ([+] @_) / @_ }
sub G { ([*] @_) ** (1 / @_) }
sub H { @_ / [+] 1 X/ @_ }
 
say "A(1,...,10) = ", A(1..10);
say "G(1,...,10) = ", G(1..10);
say "H(1,...,10) = ", H(1..10);
_END_
};

subtest {
	{ ok round-trips( Q:to[_END_] ), Q{version 1};
sub rms(*@nums) { sqrt [+](@nums X** 2) / @nums }
 
say rms 1..10;
_END_
	};

	{ ok round-trips( Q:to[_END_] ), Q{version 2};
sub rms { sqrt @_ R/ [+] @_ X** 2 }
_END_
	};

	done-testing;
}, Q{Averages/root mean square};

{ ok round-trips( Q:to[_END_] ), Q{Averages/simple moving average};
sub sma(Int \P where * > 0) returns Sub {
    sub ($x) {
	state @a = 0 xx P;
	@a.push($x).shift;
	P R/ [+] @a;
    }
}
_END_
};

done-testing;

# vim: ft=perl6


