/
minmax.t
executable file
·269 lines (204 loc) · 12.4 KB
/
minmax.t
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
use v6;
use Test;
plan 101;
# L<S32::Containers/List/=item min>
# L<S32::Containers/List/=item max>
=begin description
As per S32, the sub form requires a comparison function. The form without
comparison function is spelled [min]
=end description
my @array = (5,-3,7,0,1,-9); #NOTICE! The <> don't work like they should, rakudo devels! That's why we use this :/ --lue
# Tests for C<min>:
is @array.min, -9, "basic method form of min works";
is min(@array), -9, 'min(list)';
is (@array.min: { $^a <=> $^b }), -9,
"method form of min with identity comparison block works";
is (@array.min:{ $^a <=> $^b }), -9,
"adverbial block form of min with identity comparison block works (RT #53804)";
is min(:by({ $^a <=> $^b }), @array), -9,
"subroutine form of min with identity comparison block works";
is (@array.min: { abs($^a) <=> abs($^b) }), 0,
"method form of min taking a comparison block works";
is min(:by({ abs($^a) <=> abs($^b) }), @array), 0,
"subroutine form of min taking a comparison block works";
is (@array.min: { abs $^a }), 0,
"method form of min taking a comparison block works";
is min(:by({ $^a.abs }), @array), 0,
"subroutine form of min taking a comparison block works";
# Tests for C<max>:
is (@array.max), 7, "basic method form of max works";
is max(:by({ $^a <=> $^b }), @array), 7, "basic subroutine form of max works";
is (@array.max: { $^a <=> $^b }), 7,
"method form of max with identity comparison block works";
is max(@array), 7, 'sub form of max';
is max(:by({ $^a <=> $^b }), @array), 7,
"subroutine form of max with identity comparison block works";
is (@array.max: { $^a.abs <=> $^b.abs }), -9,
"method form of max taking a comparison block works";
is max(:by({ $^a.abs <=> $^b.abs }), @array), -9,
"subroutine form of max taking a comparison block works";
is (@array.max: { $^a.abs }), -9,
"method form of max taking a modifier block works";
is max(:by({ $^a.abs }), @array), -9,
"subroutine form of max taking a modifier block works";
# Tests for C<minmax>:
is @array.minmax, -9..7, "basic method form of minmax works";
is minmax(@array), -9..7, 'minmax(list)';
is (@array.minmax: { $^a <=> $^b }), -9..7,
"method form of minmax with identity comparison block works";
is minmax(:by({ $^a <=> $^b }), @array), -9..7,
"subroutine form of minmax with identity comparison block works";
is (@array.minmax: { $^a.abs <=> $^b.abs }), 0..-9,
"method form of minmax taking a comparison block works";
is minmax(:by({ $^a.abs <=> $^b.abs }), @array), 0..-9,
"subroutine form of minmax taking a comparison block works";
is (@array.minmax: { abs $^a }), 0..-9,
"method form of minmax taking a comparison block works";
is minmax(:by({ $^a.abs }), @array), 0..-9,
"subroutine form of minmax taking a comparison block works";
is ((-10..9).minmax: { $^a.abs <=> $^b.abs }), 0..-10,
"method form of minmax on Ranges taking a comparison block works";
is ((1..10).minmax: { ($_-3) * ($_-5) }), 4..10,
"method form of minmax taking an arity-1 comparison block works";
# Error cases:
is 42.min, 42, ".min should work on scalars";
is 42.max, 42, ".max should work on scalars";
is (42,).min, 42, ".min should work on one-elem arrays";
is (42,).max, 42, ".max should work on one-elem arrays";
# Tests with literals:
is (1,2,3).max, 3, "method form of max with literals works";
is (1,2,3).min, 1, "method form of min with literals works";
is max(:by({$^a <=> $^b}), 1,2,3), 3, "subroutine form of max with literals works";
is min(:by({$^a <=> $^b}), 1,2,3), 1, "subroutine form of min with literals works";
# Try to read numbers from a file
{
my $fh = open "t/spec/S32-list/numbers.data";
@array = $fh.lines();
is @array.max, 5, "max of strings read from a file works";
is @array.min, -1, "min of strings read from a file works";
# Same, but numifying the numbers first
{
@array = map { +$_ }, @array;
is @array.max, 28, "max of strings read from a file works";
is @array.min, -80, "min of strings read from a file works";
}
}
is (1, Inf).max, Inf,"Inf is greater than 1";
is (-1, -Inf).min, -Inf,"-Inf is less than -1";
is (-Inf, Inf).min, -Inf,"-Inf is less than Inf";
is (-Inf, Inf).max, Inf,"Inf is greater than -Inf";
#############
#SIN FOUND!
#############
#The four below do not work in ANY implementation so far (the `right one' depends on your way of ordering the values 0, NaN, and Inf from least to greatest) The number of tests has been minused 4, from 46 to 42, for the time being.
#None of the three implementations (pugs, rakudo/alpha, rakudo/master) return what's set below. A trip to the Spec is the only solution, but I haven't enough time.
#for details, see http://irclog.perlgeek.de/perl6/2010-02-23#i_2022557
#sin found 22 Feb. 2010, 21:55 PST
#--lue
#############
#is (0, NaN).min, NaN, "min(0,NaN)=NaN";
#is (Inf, NaN).min, NaN, "max(Inf,NaN)=NaN";
#
#is (0, NaN).max, NaN, "max(0,NaN)=NaN";
#is (Inf, NaN).max, NaN, "max(Inf,NaN)=NaN";
#?rakudo 2 skip "post-GLR"
is ([min] 42..4200000000000000000), 42, '[min] does not flatten';
is ([max] -4200000000000000000..42), 42, '[max] does not flatten';
is ([min] 5,10,-15,20), -15, 'reduce min int';
is ([max] 5,10,-15,20), 20, 'reduce max int';
is ([min] 5.1,10.3,-15.7,20.9), -15.7, 'reduce min numeric';
is ([max] 5.4,10.7,-15.2,20.8), 20.8, 'reduce max numeric';
{
my @strings = <Inspiring bold John Barleycorn!
What dangers thou canst make us scorn!
Wi' tippenny, we fear nae evil;
Wi' usquabae, we'll face the devil!>;
is @strings.min, "Barleycorn!", 'Default .min works on array of strings';
is @strings.min(-> $a, $b { $a.chars <=> $b.chars || $a leg $b }), "us", '.min works with explicit comparator';
is ([min] @strings), "Barleycorn!", '[min] works on array of strings';
is @strings.max, "we'll", 'Default .max works on array of strings';
is @strings.max(-> $a, $b { $a.chars <=> $b.chars || $a leg $b }), "Barleycorn!",
'.max works with explicit comparator';
is ([max] @strings), "we'll", '[max] works on array of strings';
}
# RT #103178
{
class A { has $.d };
is (A.new(d => 5), A.new(d => 1), A.new(d => 10)).min(*.d).d,
1, 'can use non-numbers with .min and unary closures';
}
{
# check that .min, .max, and .minmax return values can be combined further
# using various forms of min/max/minmax such that the final result is
# independent from the grouping of data in intermediate steps
my @ints = (3, -1, 7, -2, 5, 10);
is @ints[0..1].min min @ints[2..*].min, -2, 'min combine .min of non-empty sublists of Ints';
is @ints[ () ].min min @ints[0..*].min, -2, 'min combine .min of empty and non-empty sublist of Ints';
is @ints[0..5].min min @ints[6..*].min, -2, 'min combine .min of non-empty and empty sublist of Ints';
is ([min] @ints[0..1].min, @ints[2..3].min, @ints[4..*].min), -2, '[min] combine .min of non-empty sublist of Ints';
is ([min] @ints[ () ].min, @ints[0..5].min, @ints[6..*].min), -2, '[min] combine .min of empty, non-empty, empty sublist of Ints';
is (@ints[0..1].min, @ints[2..3].min, @ints[4..*].min).min, -2, '.min combine .min of non-empty sublist of Ints';
is (@ints[ () ].min, @ints[0..5].min, @ints[6..*].min).min, -2, '.min combine .min of empty, non-empty, empty sublist of Ints';
is @ints[0..1].max max @ints[2..*].max, 10, 'max combine .max of non-empty sublists of Ints';
is @ints[ () ].max max @ints[0..*].max, 10, 'max combine .max of empty and non-empty sublist of Ints';
is @ints[0..5].max max @ints[6..*].max, 10, 'max combine .max of non-empty and empty sublist of Ints';
is ([max] @ints[0..1].max, @ints[2..3].max, @ints[4..*].max), 10, '[max] combine .max of non-empty sublist of Ints';
is ([max] @ints[ () ].max, @ints[0..5].max, @ints[6..*].max), 10, '[max] combine .max of empty, non-empty, empty sublist of Ints';
is (@ints[0..1].max, @ints[2..3].max, @ints[4..*].max).max, 10, '.max combine .max of non-empty sublist of Ints';
is (@ints[ () ].max, @ints[0..5].max, @ints[6..*].max).max, 10, '.max combine .max of empty, non-empty, empty sublist of Ints';
# combination of minmax results for Ints:
is (@ints[0..1].minmax minmax @ints[2..*].minmax), -2..10,
'infix:<minmax> combine .minmax of non-empty sublists of Ints';
is (@ints[ () ].minmax minmax @ints[0..*].minmax), -2..10,
'infix:<minmax> combine .minmax of empty and non-empty sublist of Ints';
is (@ints[0..5].minmax minmax @ints[6..*].minmax), -2..10,
'infix:<minmax> combine .minmax of non-empty and empty sublist of Ints';
is ([minmax] @ints[0..1].minmax, @ints[2..3].minmax, @ints[4..*].minmax), -2..10,
'[minmax] combine .minmax of non-empty sublist of Ints';
is ([minmax] @ints[ () ].minmax, @ints[0..5].minmax, @ints[6..*].minmax), -2..10,
'[minmax] combine .minmax of empty, non-empty, empty sublist of Ints';
is (@ints[0..1].minmax.item, @ints[2..3].minmax.item, @ints[4..*].minmax.item).minmax, -2..10,
'.minmax combine .minmax of non-empty sublist of Ints';
is (@ints[ () ].minmax.item, @ints[0..5].minmax.item, @ints[6..*].minmax.item).minmax, -2..10,
'.minmax combine .minmax of empty, non-empty, empty sublist of Ints';
# Play it again with strings:
my @words = <one two three four five six>;
is @words[0..1].min min @words[2..*].min, 'five', 'min combine .min of non-empty sublists of Strs';
is @words[ () ].min min @words[0..*].min, 'five', 'min combine .min of empty and non-empty sublist of Strs';
is @words[0..5].min min @words[6..*].min, 'five', 'min combine .min of non-empty and empty sublist of Strs';
is ([min] @words[0..1].min, @words[2..3].min, @words[4..*].min), 'five', '[min] combine .min of non-empty sublist of Strs';
is ([min] @words[ () ].min, @words[0..5].min, @words[6..*].min), 'five', '[min] combine .min of empty, non-empty, empty sublist of Strs';
is (@words[0..1].min, @words[2..3].min, @words[4..*].min).min, 'five', '.min combine .min of non-empty sublist of Strs';
is (@words[ () ].min, @words[0..5].min, @words[6..*].min).min, 'five', '.min combine .min of empty, non-empty, empty sublist of Strs';
is @words[0..1].max max @words[2..*].max, 'two', 'max combine .max of non-empty sublists of Strs';
is @words[ () ].max max @words[0..*].max, 'two', 'max combine .max of empty and non-empty sublist of Strs';
is @words[0..5].max max @words[6..*].max, 'two', 'max combine .max of non-empty and empty sublist of Strs';
is ([max] @words[0..1].max, @words[2..3].max, @words[4..*].max), 'two', '[max] combine .max of non-empty sublist of Strs';
is ([max] @words[ () ].max, @words[0..5].max, @words[6..*].max), 'two', '[max] combine .max of empty, non-empty, empty sublist of Strs';
is (@words[0..1].max, @words[2..3].max, @words[4..*].max).max, 'two', '.max combine .max of non-empty sublist of Strs';
is (@words[ () ].max, @words[0..5].max, @words[6..*].max).max, 'two', '.max combine .max of empty, non-empty, empty sublist of Strs';
# combination of minmax results for strings:
is (@words[0..1].minmax minmax @words[2..*].minmax).perl, ('five'..'two').perl,
'infix:<minmax> combine .minmax of non-empty sublists of Strs';
is (@words[ () ].minmax minmax @words[0..*].minmax).perl, ('five'..'two').perl,
'infix:<minmax> combine .minmax of empty and non-empty sublist of Strs';
is (@words[0..5].minmax minmax @words[6..*].minmax).perl, ('five'..'two').perl,
'infix:<minmax> combine .minmax of non-empty and empty sublist of Strs';
is ([minmax] @words[0..1].minmax, @words[2..3].minmax, @words[4..*].minmax).perl, ('five'..'two').perl,
'[minmax] combine .minmax of non-empty sublist of Strs';
is ([minmax] @words[ () ].minmax, @words[0..5].minmax, @words[6..*].minmax).perl, ('five'..'two').perl,
'[minmax] combine .minmax of empty, non-empty, empty sublist of Strs';
is (@words[0..1].minmax.item, @words[2..3].minmax.item, @words[4..*].minmax.item).minmax.perl, ('five'..'two').perl,
'.minmax combine .minmax of non-empty sublist of Strs';
is (@words[ () ].minmax.item, @words[0..5].minmax.item, @words[6..*].minmax.item).minmax.perl, ('five'..'two').perl,
'.minmax combine .minmax of empty, non-empty, empty sublist of Strs';
}
# RT #112250
{
my $rt112250 = [max] <2 11>;
is $rt112250, 11,
'[max] of <>-style list finds the numerically largest number';
is <1 2 3 4 5 10>.max, 10,
'.max on <>-style list finds the numerically largest number';
}
# vim: ft=perl6