mll 2.2.1 → 2.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile.lock +4 -1
- data/README.md +1 -0
- data/lib/mll.rb +46 -17
- data/mll.gemspec +1 -1
- data/spec/_spec.rb +92 -2
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d67aa2bc083ee5926dba5e8ab794ec81579c3d94
|
4
|
+
data.tar.gz: 54b82009ff7fced4eadbdb48c663e9b046ae368d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fdc4e70514e2e323f53cda619ce8b16b4a05f672c05666a1062fb43a53c86d9169df93c0100599fd2725a4802fc5686816160396388ef619a8995bf2b4cef8f4
|
7
|
+
data.tar.gz: 1e977a6fad2adf25434f6f899b919b71b6df0300032c4029ce8147c00429111e3e06c31972ea60d04726bfc7483bf975c721adec07deda72b9a790efbb67ad31
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -136,6 +136,7 @@ module MLL
|
|
136
136
|
# TODO maybe make indexes count from 0 not 1
|
137
137
|
# TODO merge similar examples
|
138
138
|
# TODO deprecate tests that would obviously fail another tests
|
139
|
+
# TODO check if we check for ArgumentError without being sure we raise it
|
139
140
|
describe MLL do
|
140
141
|
describe "List Manipulation" do
|
141
142
|
describe "Constructing Lists" do
|
data/lib/mll.rb
CHANGED
@@ -161,6 +161,48 @@ module MLL
|
|
161
161
|
end
|
162
162
|
end
|
163
163
|
|
164
|
+
def subdivide
|
165
|
+
lambda do |*args|
|
166
|
+
case args.size
|
167
|
+
when 1 ; subdivide[1, args[0]]
|
168
|
+
when 2 ; subdivide[0, args[0], args[1]]
|
169
|
+
when 3
|
170
|
+
# raise ArgumentError.new("can't divide into 0 parts") if args[2].zero?
|
171
|
+
range[args[0], args[1], (args[1] - args[0]) * 1.0 / args[2]]
|
172
|
+
else
|
173
|
+
raise ArgumentError.new("wrong number of arguments (#{args.size} for 1..3)")
|
174
|
+
end
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
def riffle
|
179
|
+
lambda do |*args|
|
180
|
+
case args.size
|
181
|
+
when 2
|
182
|
+
next riffle[*args, [2,-2,2]] unless args[1].respond_to?(:each) && args[0].size == args[1].size
|
183
|
+
Enumerator.new do |e|
|
184
|
+
args[0].zip(args[1]){ |i, j| e << i << j }
|
185
|
+
end
|
186
|
+
when 3
|
187
|
+
args[2] = [args[2], -2, args[2]] unless args[2].respond_to? :each
|
188
|
+
Enumerator.new do |e|
|
189
|
+
min = (args[2][0] < 0) ? (args[0].size + args[2][0]) : args[2][0] - 1
|
190
|
+
max = (args[2][1] < 0) ? (args[0].size + args[2][1]) : args[2][1]
|
191
|
+
min, max = max, min if args[2][0] < 0
|
192
|
+
step = args[2][2]
|
193
|
+
pos = 0
|
194
|
+
args[0].each_with_index do |x, i|
|
195
|
+
# TODO make it not destructive
|
196
|
+
(pos += 1; e << x)
|
197
|
+
(pos += 1; e << (args[1].respond_to?(:each) ? args[1].rotate!.last : args[1])) if min - 1 <= i && i <= max && (pos - min) % step == 0
|
198
|
+
end
|
199
|
+
end
|
200
|
+
else
|
201
|
+
raise ArgumentError.new("wrong number of arguments (#{args.size} for 2..3)")
|
202
|
+
end
|
203
|
+
end
|
204
|
+
end
|
205
|
+
|
164
206
|
def define_listable_function name, &block
|
165
207
|
(class << self; self end).class_eval do
|
166
208
|
define_method name do
|
@@ -188,12 +230,13 @@ module MLL
|
|
188
230
|
when 3
|
189
231
|
case args[2] <=> 0
|
190
232
|
when 0 ; raise ArgumentError.new("step can't be zero")
|
191
|
-
when 1 ; Range.new(args[0], args[1]).step args[2]
|
233
|
+
# when 1 ; Range.new(args[0], args[1]).step args[2]
|
192
234
|
else
|
193
235
|
Enumerator.new do |e|
|
194
236
|
from, to, step = *args
|
195
|
-
|
196
|
-
while from >= to
|
237
|
+
step = step.abs * (to <=> from)
|
238
|
+
while (step > 0) ? (from <= to) : (from >= to)
|
239
|
+
# while from >= to
|
197
240
|
e << from
|
198
241
|
from += step
|
199
242
|
end
|
@@ -204,20 +247,6 @@ module MLL
|
|
204
247
|
end
|
205
248
|
end
|
206
249
|
|
207
|
-
def self.subdivide
|
208
|
-
lambda do |*args|
|
209
|
-
case args.size
|
210
|
-
when 1 ; subdivide[1, args[0]]
|
211
|
-
when 2 ; subdivide[0, args[0], args[1]]
|
212
|
-
when 3
|
213
|
-
# raise ArgumentError.new("can't divide into 0 parts") if args[2].zero?
|
214
|
-
range[args[0], args[1], (args[1] - args[0]) * 1.0 / args[2]]
|
215
|
-
else
|
216
|
-
raise ArgumentError.new("wrong number of arguments (#{args.size} for 1..3)")
|
217
|
-
end
|
218
|
-
end
|
219
|
-
end
|
220
|
-
|
221
250
|
define_listable_function(:subtract) { |*args| raise ArgumentError.new("need two arguments") unless args.size == 2 ; args[0] - args[1] }
|
222
251
|
define_listable_function(:divide) { |*args| raise ArgumentError.new("need two arguments") unless args.size == 2 ; args[0] / args[1] }
|
223
252
|
define_listable_function(:_plus) { |*args| raise ArgumentError.new("need two arguments") unless args.size == 2 ; args[0] + args[1] }
|
data/mll.gemspec
CHANGED
data/spec/_spec.rb
CHANGED
@@ -21,6 +21,8 @@ require_relative File.join "..", "lib", "mll"
|
|
21
21
|
# TODO merge similar examples
|
22
22
|
# TODO deprecate tests that would obviously fail another tests
|
23
23
|
|
24
|
+
# TODO check if we check for ArgumentError without being sure we raise it
|
25
|
+
|
24
26
|
|
25
27
|
# File.read("spec/_spec.rb").scan(/.*\n/).each_with_index{ |e,i| p [i+1,e] if e["\xe2\x80\x90"] || e["\xc3\x97"] }; 0
|
26
28
|
|
@@ -316,6 +318,10 @@ describe MLL do
|
|
316
318
|
example "no args raise ArgumentError" do
|
317
319
|
expect{ range[] }.to raise_error ArgumentError
|
318
320
|
end
|
321
|
+
example "two args that are not numbers raise ArgumentError" do
|
322
|
+
skip "already caught by Ruby as 'ArgumentError: bad value for range'"
|
323
|
+
expect{ range[8,times] }.to raise_error ArgumentError
|
324
|
+
end
|
319
325
|
example "more than 3 args raise ArgumentError" do
|
320
326
|
expect{ range[1,2,3,4] }.to raise_error ArgumentError
|
321
327
|
end
|
@@ -351,12 +357,18 @@ describe MLL do
|
|
351
357
|
|
352
358
|
end
|
353
359
|
|
354
|
-
# NOTE: Wolfram Mathematica can't do this
|
360
|
+
# NOTE: even Wolfram Mathematica can't do this
|
355
361
|
example "range[max, min, -step]" do
|
356
362
|
expect(range[10,-5,-2]).to be_a Enumerator
|
357
363
|
expect(range[10,-5,-2].to_a).to eq [10,8,6,4,2,0,-2,-4]
|
358
364
|
expect(range[3,1,-1].to_a).to eq [3,2,1]
|
359
365
|
end
|
366
|
+
# NOTE: even I'm not sure about this
|
367
|
+
example "range[max, min, +step]" do
|
368
|
+
expect(range[10,-5,2]).to be_a Enumerator
|
369
|
+
expect(range[10,-5,2].to_a).to eq [10,8,6,4,2,0,-2,-4]
|
370
|
+
expect(range[3,1,1].to_a).to eq [3,2,1]
|
371
|
+
end
|
360
372
|
|
361
373
|
describe "Generalizations & Extensions:" do
|
362
374
|
|
@@ -436,7 +448,7 @@ describe MLL do
|
|
436
448
|
|
437
449
|
example "generates a list of length n+1" do
|
438
450
|
expect(subdivide[5]).to be_a Enumerator
|
439
|
-
expect(subdivide[5].size).to eq 6
|
451
|
+
expect(subdivide[5].to_a.size).to eq 6
|
440
452
|
end
|
441
453
|
|
442
454
|
end
|
@@ -543,6 +555,84 @@ describe MLL do
|
|
543
555
|
|
544
556
|
end
|
545
557
|
|
558
|
+
# http://reference.wolfram.com/language/guide/RearrangingAndRestructuringLists.html
|
559
|
+
describe "Rearranging & Restructuring Lists" do
|
560
|
+
|
561
|
+
# http://reference.wolfram.com/language/ref/Riffle.html
|
562
|
+
describe "#riffle" do
|
563
|
+
|
564
|
+
example "Mathematica examples are missing the case where two arrays differ by length a lot?"
|
565
|
+
|
566
|
+
describe "Details:" do
|
567
|
+
|
568
|
+
example "riffle[[e],x] gives [e]" do
|
569
|
+
expect(riffle[[1], 0]).to be_a Enumerator
|
570
|
+
expect(riffle[[1], 0].to_a).to eq [1]
|
571
|
+
end
|
572
|
+
example "riffle[list,x] is equivalent to riffle[list,x,[2,-2,2]]" do
|
573
|
+
expect(riffle[[1,2,3,4,5], 0].to_a).to eq riffle[[1,2,3,4,5], 0, [2,-2,2]].to_a
|
574
|
+
end
|
575
|
+
example "riffle[list,x,n] is equivalent to riffle[list,x,[n,-2,n]]" do
|
576
|
+
expect(riffle[[1,2,3,4,5], 0, 3].to_a).to eq riffle[[1,2,3,4,5], 0, [3,-2,3]].to_a
|
577
|
+
end
|
578
|
+
|
579
|
+
end
|
580
|
+
|
581
|
+
describe "Basic Examples:" do
|
582
|
+
|
583
|
+
example "riffle 0 between successive elements in a list" do
|
584
|
+
expect(riffle[range[9], 0]).to be_a Enumerator
|
585
|
+
expect(riffle[range[9], 0].to_a).to eq [1,0,2,0,3,0,4,0,5,0,6,0,7,0,8,0,9]
|
586
|
+
end
|
587
|
+
example "riffle in 0 and 0.0 cyclically" do
|
588
|
+
expect(riffle[range[9], [0,0.0]]).to be_a Enumerator
|
589
|
+
expect(riffle[range[9], [0,0.0]].to_a).to eq [1,0,2,0.0,3,0,4,0.0,5,0,6,0.0,7,0,8,0.0,9]
|
590
|
+
end
|
591
|
+
example "riffle in 0 at every 3rd position" do
|
592
|
+
expect(riffle[range[9], 0, 3]).to be_a Enumerator
|
593
|
+
expect(riffle[range[9], 0, 3].to_a).to eq [1,2,0,3,4,0,5,6,0,7,8,0,9]
|
594
|
+
end
|
595
|
+
|
596
|
+
end
|
597
|
+
|
598
|
+
describe "Scope:" do
|
599
|
+
|
600
|
+
example "start riffling in 0 only at position 5" do
|
601
|
+
expect(riffle[range[9], 0, [5,-1,2]]).to be_a Enumerator
|
602
|
+
expect(riffle[range[9], 0, [5,-1,2]].to_a).to eq [1,2,3,4,0,5,0,6,0,7,0,8,0,9,0]
|
603
|
+
end
|
604
|
+
example "cyclically riffle in 0 and 0.0" do
|
605
|
+
expect(riffle[range[9], [0,0.0], [5,-1,2]]).to be_a Enumerator
|
606
|
+
expect(riffle[range[9], [0,0.0], [5,-1,2]].to_a).to eq [1,2,3,4,0,5,0.0,6,0,7,0.0,8,0,9,0.0]
|
607
|
+
end
|
608
|
+
example "intersperse two lists" do
|
609
|
+
# TODO check how it works for list2.size == list1.size + 1 in Mathematica
|
610
|
+
expect(riffle[[1,2,3,4], [5,6,7,8]]).to be_a Enumerator
|
611
|
+
expect(riffle[[1,2,3,4], [5,6,7,8]].to_a).to eq [1,5,2,6,3,7,4,8]
|
612
|
+
end
|
613
|
+
|
614
|
+
end
|
615
|
+
|
616
|
+
describe "Applications:" do
|
617
|
+
|
618
|
+
example "create a directory name from a path list" do
|
619
|
+
expect(riffle[%w{ usr local bin }, "/"].to_a.join).to eq "usr/local/bin"
|
620
|
+
end
|
621
|
+
example "alternate positive and negative integers" do
|
622
|
+
skip "unary #minus is yet to be implemented"
|
623
|
+
expect(riffle[range[9], minus[range[9]]]).to be_a Enumerator
|
624
|
+
expect(riffle[range[9], minus[range[9]]].to_a).to eq [1,-2,2,-2,3,-3,4,-4,5,-5,6,-6,7,-7,8,-8,9,-9]
|
625
|
+
end
|
626
|
+
example "insert commas at every 4th character" do
|
627
|
+
expect(riffle["4345252523535".chars, ",", [-4,1,-4]].to_a.join).to eq "4,345,252,523,535"
|
628
|
+
end
|
629
|
+
|
630
|
+
end
|
631
|
+
|
632
|
+
end
|
633
|
+
|
634
|
+
end
|
635
|
+
|
546
636
|
# http://reference.wolfram.com/language/guide/ApplyingFunctionsToLists.html
|
547
637
|
describe "Applying Functions to Lists" do
|
548
638
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mll
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Victor Maslov
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2016-02-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|