mll 2.2.1 → 2.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|