Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

pick in the setting #1210

Closed
p6rt opened this issue Aug 7, 2009 · 5 comments
Closed

pick in the setting #1210

p6rt opened this issue Aug 7, 2009 · 5 comments
Labels

Comments

@p6rt
Copy link

p6rt commented Aug 7, 2009

Migrated from rt.perl.org#68296 (status was 'resolved')

Searchable as RT68296$

@p6rt
Copy link
Author

p6rt commented Aug 7, 2009

From @dakkar

third patch from Lisbon​: pick in the setting

@p6rt
Copy link
Author

p6rt commented Aug 7, 2009

From @dakkar

0003-moved-pick-to-setting.patch
From 884a1799328f2bccaf7ec06d1910c4360227c625 Mon Sep 17 00:00:00 2001
From: dakkar <dakkar@sardina.(none)>
Date: Thu, 6 Aug 2009 18:43:09 +0200
Subject: [PATCH] moved pick to setting

---
 src/builtins/any-list.pir |   90 ---------------------------------------------
 src/setting/Any-list.pm   |   39 +++++++++++++++++++
 2 files changed, 39 insertions(+), 90 deletions(-)

diff --git a/src/builtins/any-list.pir b/src/builtins/any-list.pir
index cd78d87..6cbefd6 100644
--- a/src/builtins/any-list.pir
+++ b/src/builtins/any-list.pir
@@ -94,96 +94,6 @@ Return a List with the keys of the invocant.
     signature."!add_implicit_self"($P0)
 .end
 
-=item pick($num, :$repl)
-
-=cut
-
-.namespace []
-.sub 'pick' :multi(_)
-    .param int p_num
-    .param pmc values          :slurpy
-    .param pmc p_repl          :optional :named('repl')
-    .param int has_repl        :opt_flag
-    if has_repl goto have_repl
-    p_repl = get_hll_global ['Bool'], 'False'
-  have_repl:
-    .tailcall values.'pick'(p_num, 'repl'=>p_repl)
-.end
-
-.sub 'pick' :multi('Whatever')
-    .param pmc whatever
-    .param pmc values          :slurpy
-    .param pmc p_repl          :optional :named('repl')
-    .param int has_repl        :opt_flag
-    unless has_repl goto no_repl
-    unless p_repl goto no_repl
-    die "Infinite lazy pick not implemented"
-  no_repl:
-    .tailcall values.'pick'(whatever)
-.end
-
-.namespace ['Any']
-.sub 'pick' :method :multi()
-    .param int p_num           :optional
-    .param int has_num         :opt_flag
-    .param pmc p_repl          :optional :named('repl')
-    .param int has_repl        :opt_flag
-
-    .local pmc list, result, rand
-    .local int elems
-    list = self.'list'()
-    elems = list.'elems'()
-    result = 'list'()
-    rand = get_hll_global ['Any'], '$!random'
-
-    if has_num goto have_num
-    p_num = 1
-  have_num:
-
-    .local int repl
-    repl = 0
-    unless has_repl goto have_repl
-    repl = istrue p_repl
-  have_repl:
-    if repl goto skip_clone
-    list = clone list
-  skip_clone:
-
-  loop:
-    unless p_num > 0 goto done
-    unless elems > 0 goto done
-    $N0 = rand
-    $N0 *= elems
-    $I0 = $N0
-    $P0 = list[$I0]
-    push result, $P0
-    dec p_num
-    if repl goto loop
-    delete list[$I0]
-    elems = list.'elems'()
-    goto loop
-  done:
-    $I0 = result.'elems'()
-    dec $I0
-    unless $I0 goto single_item
-    .return (result)
-  single_item:
-     $P0 = result[0]
-    .return ($P0)
-.end
-
-.sub 'pick' :method :multi(_, 'Whatever')
-    .param pmc whatever
-    .param pmc p_repl          :optional :named('repl')
-    .param int has_repl        :opt_flag
-    unless has_repl goto no_repl
-    unless p_repl goto no_repl
-    die "Infinite lazy pick not implemented"
-  no_repl:
-    $I0 = self.'elems'()
-    .tailcall self.'pick'($I0)
-.end
-
 =item sort()
 
 Sort list.  In this case we copy into an FPA to make use of the
diff --git a/src/setting/Any-list.pm b/src/setting/Any-list.pm
index 9a9431a..18a31e2 100644
--- a/src/setting/Any-list.pm
+++ b/src/setting/Any-list.pm
@@ -36,6 +36,37 @@ class Any is also {
         }
     }
 
+    multi method pick(Int $num is copy = 1, :$repl) {
+
+        $num=floor($num);
+
+        if ($num == 1) {
+            return @.list[floor(@.list.elems.rand)];
+        }
+
+        my @l;
+        if ($repl) {
+            @l := @.list;
+        }
+        else {
+            @l = @.list;
+        }
+
+        gather {
+            while ($num > 0 and @l.elems > 0) {
+                my $idx = floor(@l.elems.rand());
+                take @l[$idx];
+                @l.splice($idx,1) unless $repl;
+                --$num;
+            }
+        }
+    }
+
+    multi method pick(Whatever $, :$repl) {
+        die "Infinite lazy pick not implemented" if $repl;
+        @.pick(@.elems);
+    }
+
     # RT #63700 - parse failed on &infix:<cmp>
     multi method max( $values: Code $by = sub { $^a cmp $^b } ) {
          my @list = $values.list;
@@ -152,6 +183,14 @@ our List multi map(Code $expr, *@values) {
     @values.map($expr)
 }
 
+multi pick(Int $num, :$repl, *@values) {
+    @values.pick($num,:repl($repl));
+}
+
+multi pick(Whatever $, :$repl, *@values) {
+    @values.pick(*,:repl($repl));
+}
+
 multi max(Code $by, *@values) {
     @values.max($by);
 }
-- 
1.5.6.3

@p6rt
Copy link
Author

p6rt commented Aug 24, 2009

From @moritz

Applied and pushed as 7512462c718a2f4eb978d7110f4832a38946d25e, thank
you very much.

Moritz

@p6rt
Copy link
Author

p6rt commented Aug 24, 2009

The RT System itself - Status changed from 'new' to 'open'

@p6rt
Copy link
Author

p6rt commented Aug 24, 2009

@moritz - Status changed from 'open' to 'resolved'

@p6rt p6rt closed this as completed Aug 24, 2009
@p6rt p6rt added the patch label Jan 5, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant