Special symbols as elements of strings array in Perl 6 - raku

If I understand correctly, when I assign values to an array of strings with < ... >, I should escape special symbols with \:
> my #array = < \\ a b>
[\ a b]
> my #array = < \< a b>
[< a b]
> my #array = < \<de\< a b>
[<de< a b]
Using backslashes is not always convenient, sometimes the code may become obscure.
Is there a better way to pass a list of strings containing special characters to an array?

Use << >> instead of < >, and use single quotes inside:
> my #array = << '<de<' a b>>
[<de< a b]

Related

How to divide every element in array by a certain number?

I have an array:
my #e = <60.922 20.946 8.721 7.292 4.306 2.821 2.765 2.752 2.741 2.725>
I would like to divide every element in the array by the minimum, however
#e /= #e.min
produced a single element, which isn't correct.
I've read https://docs.raku.org/type/Array but I don't understand the basic elements of Raku for this.
How can I divide every item in the array by the same number?
You can use the raku hyper & compound metaoperators like this:
#a >>/=>> #a.min
>>X>> means "apply operator X over all list items (with more items on the left)"
/= means "assign result of divide operator / to replace each original left hand item"
Use / instead of /= if you want to return the list of results but leave #a unchanged functional programming style.
[Edited according to #lizmat & #Sebastian comments]
my #a = 2, 3, 5, 7, 10;
my $div = #a.min;
$_ /= $div for #a;
say #a; # [1 1.5 2.5 3.5 5]
When you iterate over an array, you get mutable elements.
put #e.map( * / #e.min );
OR
put #e.map: * / #e.min;
Sample Input:
my #e = <60.922 20.946 8.721 7.292 4.306 2.821 2.765 2.752 2.741 2.725>;
Sample Output:
22.356697 7.686606 3.200367 2.675963 1.580183 1.035229 1.014679 1.009908 1.005872 1
If you want to continue working with the resultant values, assign the output to a new variable. Or overwrite the original #e array using the .= "back-assignment" operator [ short for #e = #e.map( … ) ]. In the Raku REPL:
~$ raku
Welcome to 𝐑𝐚𝐤𝐮𝐝𝐨™ v2021.06.
Implementing the 𝐑𝐚𝐤𝐮™ programming language v6.d.
Built on MoarVM version 2021.06.
To exit type 'exit' or '^D'
> my #e = <60.922 20.946 8.721 7.292 4.306 2.821 2.765 2.752 2.741 2.725>;
[60.922 20.946 8.721 7.292 4.306 2.821 2.765 2.752 2.741 2.725]
> #e .= map( * / #e.min );
[22.356697 7.686606 3.200367 2.675963 1.580183 1.035229 1.014679 1.009908 1.005872 1]
> put #e;
22.356697 7.686606 3.200367 2.675963 1.580183 1.035229 1.014679 1.009908 1.005872 1
>

perl 6 variable same name different sigils inconsistent behavior

There seems to be some inconsistent behavior when variables of the same letter-name but different sigils are used:
> my $a="foo";
foo
> my #a=1,2
[1 2]
> say $a
foo # this is what I have expected
> my $b = 1,2,3
(1 2 3)
> my #b = (0, $b.Slip)
[0 1] # I expect to get [0 1 2 3]; (0, |$b) not work either
> say $b
1 # I expect $b to be unchanged, (1,2,3), but it is now 1;
> say #a
[1 2]
> say #b
[0 1]
>
I am not sure why #a does not affect $a, whereas #b affects $b. Can someone please elucidate?
Thanks !!!
lisprog
In Rakudo Perl 6 there is actually no relationship at all between $b and #b.
$b didn't change. It simply didn't get assigned what you thought it had been assigned. Looking at the documentation on Operator Precedence, you'll see that = (assignment) has a tighter precedence than the comma ,.
Also, you are using the REPL, which automatically prints out the return value of each statement. That return value may or may not be the same as the value assigned to a variable.
my $b = 1,2,3 actually is the same as
(my $b = 1),2,3 because = has tighter precedence than ,, meaning that effectively all but the first value is ignored
> (my $b = 1),2,3
(1 2 3)
> $b
1
If you want to assign a list to $b, then put parentheses around the list:
> my $b = (1,2,3)
(1 2 3)
> $b
(1 2 3)

Perl6-ish expression for the bits of an integer

I've been trying to exercise my Perl 6 chops by looking at some golfing problems. One of them involved extracting the bits of an integer. I haven't been able to come up with a succinct way to write such an expression.
My "best" tries so far follow, using 2000 as the number. I don't care whether the most or least significant bit comes first.
A numeric expression:
map { $_ % 2 }, (2000, * div 2 ... * == 0)
A recursive anonymous subroutine:
{ $_ ?? ($_ % 2, |&?BLOCK($_ div 2)) !! () }(2000)
Converting to a string:
2000.fmt('%b') ~~ m:g/./
Of these, the first feels cleanest to me, but it would be really nice to be able to generate the bits in a single step, rather than mapping over an intermediate list.
Is there a cleaner, shorter, and/or more idiomatic way to get the bits, using a single expression? (That is, without writing a named function.)
The easiest way would be:
2000.base(2).comb
The .base method returns a string representation, and .comb splits it into characters - similar to your third method.
An imperative solution, least to most significant bit:
my $i = 2000; say (loop (; $i; $i +>= 1) { $i +& 1 })
The same thing rewritten using hyperoperators on a sequence:
say (2000, * +> 1 ...^ !*) >>+&>> 1
An alternative that is more useful when you need to change the base to anything above 36, is to use polymod with an infinite list of that base.
Most of the time you will have to reverse the order though.
say 2000.polymod(2 xx *);
# (0 0 0 0 1 0 1 1 1 1 1)
say 2000.polymod(2 xx *).reverse;
say [R,] 2000.polymod(2 xx*);
# (1 1 1 1 1 0 1 0 0 0 0)

Clojure - sequence of objects

I have a Clojure function:
(def obseq
(fn []
(let [a 0
b 1
c 2]
(println (seq '(a b c))))))
It outputs :
(a b c)
I want it to output a sequence containing the values of a, b, and c, not their names.
Desired output:
(1 2 3)
How do I implement this?
Short answer:
clj.core=> (defn obseq []
(let [a 0
b 1
c 2]
(println [a b c])))
#'clj.core/obseq
clj.core=> (obseq)
[0 1 2]
nil
Long answer:
Quoting a form like '(a b c) recursively prevents any evaluation inside the quoted form. So, the values for your 3 symbols a, b, and c aren't substituted. It is much easier to use a vector (square brackets), which never needs to be quoted (unlike a list). Since the vector is unquoted, the 3 symbols are evaluated and replaced by their values.
If you wanted it to stay a list for some reason, the easiest way is to type:
clj.core=> (defn obseq [] (let [a 0 b 1 c 2] (println (list a b c))))
#'clj.core/obseq
clj.core=> (obseq)
(0 1 2)
nil
This version also has no quoting, so the 3 symbols are replaced with their values. Then the function (list ...) puts them into a list data structure.
Note that I also converted your (def obseq (fn [] ...)) into the preferred form (defn obseq [] ...), which has the identical result but is shorter and (usually) clearer.

k consecutive integers constraint

How can I state the following constraint in Constraint Programming? (Preferably in Gurobi or Comet).
S is an array of integers of size n. The set of integers that I can use to fill the array are in the range 1-k. There is a constraint ci for each of the integers that can be used. ci denotes the minimum number of consecutive integers i.
For example if c1 = 3, c2 = 2 then 1112211112111 is not a valid sequence since there must be two consecutive 2's, whereas 1112211122111 is a valid sequence.
Perhaps using the regular constraint (automaton in Comet) would be the best approach.
However, here is a straightforward solution in MiniZinc which use a lot of reifications. It should be possible to translate it to Comet at least (I don't think Gurobi support reifications).
The decision variables (the sequences) are in the array "x". It also use a helper array ("starts") which contains the start positions of each sequences; this makes it easier to reason about the sequences in "x". The number of sequences is in "z" (e.g. for optimization problems).
Depending on the size of x and other constraints, one can probably add more (redundant) constraints on how many sequences there can be etc. This is not done here, though.
Here's the model: http://www.hakank.org/minizinc/k_consecutive_integers.mzn
It's also shown below.
int: n;
int: k;
% number of consecutive integers for each integer 1..k
array[1..k] of int: c;
% decision variables
array[1..n] of var 1..k: x;
% starts[i] = 1 -> x[i] starts a new sequence
% starts[i] = 0 -> x[i] is in a sequence
array[1..n] of var 0..k: starts;
% sum of sequences
var 1..n: z = sum([bool2int(starts[i] > 0) | i in 1..n]);
solve :: int_search(x, first_fail, indomain_min, complete) satisfy;
constraint
forall(a in 1..n, b in 1..k) (
(starts[a] = b ) ->
(
forall(d in 0..c[b]-1) (x[a+d] = b )
/\
forall(d in 1..c[b]-1) (starts[a+d] = 0 )
/\
(if a > 1 then x[a-1] != b else true endif) % before
/\
(if a <= n-c[b] then x[a+c[b]] != b else true endif) % after
)
)
/\
% more on starts
starts[1] > 0 /\
forall(i in 2..n) (
starts[i] > 0 <-> ( x[i]!=x[i-1] )
)
/\
forall(i in 1..n) (
starts[i] > 0 -> x[i] = starts[i]
)
;
output [
"z : " ++ show(z) ++ "\n" ++
"starts: " ++ show(starts) ++ "\n" ++
"x : " ++ show(x) ++ "\n"
];
%
% data
%
%% From the question above:
%% It's a unique solution.
n = 13;
k = 2;
c = [3,2];