|
220 | 220 | (/ (+ (@ _s (- (/ _n 2) 1)) (@ _s (/ _n 2))) 2) |
221 | 221 | (@ _s (/ _n 2))) }) })) |
222 | 222 |
|
223 | | -# @brief Drop the first n elements of a list |
224 | | -# @param _L the list to work on |
225 | | -# @param _n the number of elements to drop |
226 | | -# @details The original list is not modified. |
227 | | -# =begin |
228 | | -# (let cool-stuff [1 2 3 4 5 6 7 8 9]) |
229 | | -# (print (list:drop cool-stuff 4)) # [5 6 7 8 9] |
230 | | -# =end |
231 | | -# @author https://github.com/rstefanic, https://github.com/SuperFola |
232 | | -(let drop (fun ((ref _L) _n) |
233 | | - (if (< _n (/ (len _L) 2)) |
234 | | - (if (> _n 0) |
235 | | - (drop (tail _L) (- _n 1)) |
236 | | - _L) |
237 | | - { |
238 | | - (mut _index (math:max 0 _n)) |
239 | | - (mut _output []) |
240 | | - |
241 | | - (while (< _index (len _L)) { |
242 | | - (append! _output (@ _L _index)) |
243 | | - (set _index (+ 1 _index)) }) |
244 | | - _output }))) |
245 | | - |
246 | | -# @brief Drop the first elements of a list, while they match a given predicate |
247 | | -# @param _L the list to work on |
248 | | -# @param _f the predicate |
249 | | -# @details The original list is not modified. |
250 | | -# =begin |
251 | | -# (let cool-stuff [1 2 3 4 5 6 7 8 9]) |
252 | | -# (print (list:dropWhile cool-stuff (fun (a) (< a 4)))) # [4 5 6 7 8 9] |
253 | | -# =end |
254 | | -# @author https://github.com/SuperFola |
255 | | -(let dropWhile (fun ((ref _L) _f) { |
256 | | - (mut _index 0) |
257 | | - (mut _output []) |
258 | | - |
259 | | - (while (< _index (len _L)) |
260 | | - (if (_f (@ _L _index)) |
261 | | - (set _index (+ 1 _index)) |
262 | | - (while (< _index (len _L)) { |
263 | | - (append! _output (@ _L _index)) |
264 | | - (set _index (+ 1 _index)) }))) |
265 | | - _output })) |
266 | | - |
267 | 223 | # @brief Keep elements in a given list if they follow a predicate |
268 | 224 | # @param _L the list to work on |
269 | 225 | # @param _f the predicate |
|
323 | 279 | (set _index (+ 1 _index)) }) |
324 | 280 | _output })) |
325 | 281 |
|
| 282 | +# @brief Fold a given list, starting from the left side |
| 283 | +# @param _L the list to work on |
| 284 | +# @param _init an init value |
| 285 | +# @param _f a function to apply to the list |
| 286 | +# @details The original list is not modified. |
| 287 | +# =begin |
| 288 | +# (let a [1 2 3 4]) |
| 289 | +# (print (list:foldLeft a 0 (fun (a b) (+ a b)))) # 10 |
| 290 | +# =end |
| 291 | +# @author https://github.com/SuperFola |
| 292 | +(let foldLeft (fun ((ref _L) _init _f) { |
| 293 | + (mut _index 0) |
| 294 | + (mut _val _init) |
| 295 | + |
| 296 | + (while (< _index (len _L)) { |
| 297 | + (set _val (_f _val (@ _L _index))) |
| 298 | + (set _index (+ 1 _index)) }) |
| 299 | + _val })) |
| 300 | + |
326 | 301 | # @brief Apply a function to the elements of a list to reduce it |
327 | 302 | # @param _L the list to work on |
328 | 303 | # @param _f the function to apply |
|
423 | 398 | (set _continue false))) |
424 | 399 | _output })) |
425 | 400 |
|
| 401 | +# @brief Drop the first n elements of a list |
| 402 | +# @param _L the list to work on |
| 403 | +# @param _n the number of elements to drop |
| 404 | +# @details The original list is not modified. |
| 405 | +# =begin |
| 406 | +# (let cool-stuff [1 2 3 4 5 6 7 8 9]) |
| 407 | +# (print (list:drop cool-stuff 4)) # [5 6 7 8 9] |
| 408 | +# =end |
| 409 | +# @author https://github.com/rstefanic, https://github.com/SuperFola |
| 410 | +(let drop (fun ((ref _L) _n) |
| 411 | + (if (< _n (/ (len _L) 2)) |
| 412 | + (if (> _n 0) |
| 413 | + (drop (tail _L) (- _n 1)) |
| 414 | + _L) |
| 415 | + { |
| 416 | + (mut _index (math:max 0 _n)) |
| 417 | + (mut _output []) |
| 418 | + |
| 419 | + (while (< _index (len _L)) { |
| 420 | + (append! _output (@ _L _index)) |
| 421 | + (set _index (+ 1 _index)) }) |
| 422 | + _output }))) |
| 423 | + |
| 424 | +# @brief Drop the first elements of a list, while they match a given predicate |
| 425 | +# @param _L the list to work on |
| 426 | +# @param _f the predicate |
| 427 | +# @details The original list is not modified. |
| 428 | +# =begin |
| 429 | +# (let cool-stuff [1 2 3 4 5 6 7 8 9]) |
| 430 | +# (print (list:dropWhile cool-stuff (fun (a) (< a 4)))) # [4 5 6 7 8 9] |
| 431 | +# =end |
| 432 | +# @author https://github.com/SuperFola |
| 433 | +(let dropWhile (fun ((ref _L) _f) { |
| 434 | + (mut _index 0) |
| 435 | + (mut _output []) |
| 436 | + |
| 437 | + (while (< _index (len _L)) |
| 438 | + (if (_f (@ _L _index)) |
| 439 | + (set _index (+ 1 _index)) |
| 440 | + (while (< _index (len _L)) { |
| 441 | + (append! _output (@ _L _index)) |
| 442 | + (set _index (+ 1 _index)) }))) |
| 443 | + _output })) |
| 444 | + |
426 | 445 | # @brief Partition a list in two, given a predicate |
427 | 446 | # @param _L the list to work on |
428 | 447 | # @param _f the predicate, accepting the value and its index |
|
527 | 546 | (set _index (+ 1 _index)) }) |
528 | 547 | _output })) |
529 | 548 |
|
530 | | -# @brief Fold a given list, starting from the left side |
531 | | -# @param _L the list to work on |
532 | | -# @param _init an init value |
533 | | -# @param _f a function to apply to the list |
534 | | -# @details The original list is not modified. |
535 | | -# =begin |
536 | | -# (let a [1 2 3 4]) |
537 | | -# (print (list:foldLeft a 0 (fun (a b) (+ a b)))) # 10 |
538 | | -# =end |
539 | | -# @author https://github.com/SuperFola |
540 | | -(let foldLeft (fun ((ref _L) _init _f) { |
541 | | - (mut _index 0) |
542 | | - (mut _val _init) |
543 | | - |
544 | | - (while (< _index (len _L)) { |
545 | | - (set _val (_f _val (@ _L _index))) |
546 | | - (set _index (+ 1 _index)) }) |
547 | | - _val })) |
548 | | - |
549 | 549 | # @brief Check if a condition is verified for all elements of a list |
550 | 550 | # @param _L the list to work on |
551 | 551 | # @param _f the condition |
|
784 | 784 | (set _i (+ 1 _i)) }) |
785 | 785 |
|
786 | 786 | (builtin__dict:keys _vals) })) |
| 787 | + |
| 788 | +# @brief Create a new list from a list of values and indices to get from the first list |
| 789 | +# @details The original list is not modified. |
| 790 | +# @param _L list to get values from |
| 791 | +# @param _indices list of indices of values in _L |
| 792 | +# =begin |
| 793 | +# (let data [1 1 2 3 4 3 4 5]) |
| 794 | +# (print (list:select data [0 0 0])) # [1 1 1] |
| 795 | +# (print (list:select data [0 2 3 4])) # [1 2 3 4] |
| 796 | +# =end |
| 797 | +# @author https://github.com/SuperFola |
| 798 | +(let select (fun ((ref _L) (ref _indices)) { |
| 799 | + (mut _output []) |
| 800 | + (mut _i 0) |
| 801 | + (while (< _i (len _indices)) { |
| 802 | + (let _idx (@ _indices _i)) |
| 803 | + (if (< _idx (len _L)) |
| 804 | + (append! _output (@ _L _idx))) |
| 805 | + (set _i (+ 1 _i)) }) |
| 806 | + _output })) |
| 807 | + |
| 808 | +# @brief Compute permutations of length _r from a given list |
| 809 | +# @details The original list is not modified. |
| 810 | +# @param _L list to get values from |
| 811 | +# @param _r number of elements per permutation |
| 812 | +# @param _f function to call on each permutation. It can return list:stopIteration to stop iteration early |
| 813 | +# =begin |
| 814 | +# (let data [0 1 2 3]) |
| 815 | +# (list:permutations data 3 (fun (perm) (print perm))) |
| 816 | +# # [0 1 2] |
| 817 | +# # [0 1 3] |
| 818 | +# # [0 2 3] |
| 819 | +# # [1 2 3] |
| 820 | +# =end |
| 821 | +# @author https://github.com/SuperFola |
| 822 | +(let permutations (fun ((ref _L) _r _f) { |
| 823 | + (let _len (len _L)) |
| 824 | + (if (and (<= _r _len) (> _r 0)) |
| 825 | + { |
| 826 | + (mut _indices (iota 0 _r)) |
| 827 | + (if (!= stopIteration (_f (select _L _indices))) |
| 828 | + { |
| 829 | + (mut _continue true) |
| 830 | + (let _reversed_indices (reverse _indices)) |
| 831 | + (while _continue { |
| 832 | + (mut _i nil) |
| 833 | + (if |
| 834 | + (forEach _reversed_indices (fun (_val) { |
| 835 | + (set _i _val) |
| 836 | + (if (!= (@ _indices _i) (+ _i _len (* -1 _r))) stopIteration) })) |
| 837 | + { |
| 838 | + (@= _indices _i (+ 1 (@ _indices _i))) |
| 839 | + (mut _j (+ 1 _i)) |
| 840 | + (while (< _j _r) { |
| 841 | + (@= _indices _j (+ 1 (@ _indices (- _j 1)))) |
| 842 | + (set _j (+ 1 _j)) }) |
| 843 | + (if (= stopIteration (_f (select _L _indices))) |
| 844 | + (set _continue false)) } |
| 845 | + (set _continue false)) }) }) }) })) |
0 commit comments