perl6 min and max of mixed Str and Int arguments - max

What type gets converted first for min and max routine when the arguments contain mixture of Str and Int ?
To exit type 'exit' or '^D'
> say ("9", "10").max
9
> say ("9", "10").max.WHAT
(Str)
> say (9, "10").max
9
> say (9, "10").max.WHAT
(Int) # if convert to Int first, result should be 10
> say ("9", 10).max
9
> say ("9", 10).max.WHAT
(Str) # if convert to Str first, result should be 9
> say (9, "10").min
10
> say (9, "10").min.WHAT
(Str) # does min and max convert Str or Int differently?
If min or max converts arguments to be the type of the first argument, the results here are still inconsistent.
Thank you for your enlightenment !!!

Both min and max use the cmp infix operator to do the comparisons. If the types differ, then this logic is used (rewritten slightly to be pure Perl 6, whereas the real one uses an internals shortcut):
multi sub infix:<cmp>($a, $b) {
$a<> =:= $b<>
?? Same
!! a.Stringy cmp b.Stringy
}
Effectively, if the two things point to the exact same object, then they are the Same, otherwise stringify both and then compare. Thus:
say 9 cmp 10; # uses the (Int, Int) candidate, giving Less
say "9" cmp "10"; # uses the (Str, Str) candidate, giving More
say 9 cmp "10"; # delegates to "9" cmp "10", giving More
say "9" cmp 10; # delegates to "9" cmp "10", giving More
The conversion to a string is done for the purpose of comparison (as an implementation detail of cmp), and so has no impact upon the value that is returned by min or max, which will be that found in the input list.

Well, jnthn has answered. His answers are always authoritative and typically wonderfully clear and succinct too. This one is no exception. :) But I'd started so I'll finish and publish...
A search for "method min" in the Rakudo sources yields 4 matches of which the most generic is a match in core/Any-iterable-methods.pm6.
It might look difficult to understand but nqp is actually essentially a simple subset of P6. The key thing is it uses cmp to compare each value that is pulled from the sequence of values being compared against the latest minimum (the $pulled cmp $min bit).
Next comes a search for "sub infix:<cmp>" in the Rakudo sources. This yields 14 matches.
These will all have to be looked at to confirm what the source code shows for comparing these various types of value. Note also that the logic is pairwise for each pair which is slightly weird to think about. So if there's three values a, b, and c, each of a different type, then the logic will be that a is the initial minimum, then there'll be a b cmp a which will be whatever cmp logic wins for that combination of types in that order, and then c cmp d where d is whichever won the b cmp a comparison and the cmp logic will be whatever is suitable to that pair of types in that order.
Let's start with the first one -- the match in core/Order.pm6 -- which is presumably a catchall if none of the other matches are more specific:
If both arguments of cmp are numeric, then comparison is a suitable numeric comparison (eg if they're both Ints then comparison is of two arbitrary precision integers).
If one argument is numeric but not the other, then -Inf and Inf are sorted to the start and end but otherwise comparison is done after both arguments are coerced by .Stringyfication.
Otherwise, both arguments are coerced by .Stringyfication.
So, that's the default.
Next one would have to go thru the individual overloads. For example, the next one is the cmp ops in core/allomorphs.pm6 and we see how for allomorphic types (IntStr etc.) comparison is numeric first, then string if that doesn't settle it. Note the comment:
we define cmp ops for these allomorphic types as numeric first, then Str. If you want just one half of the cmp, you'll need to coerce the args
Anyhoo, I see jnthn's posted yet another great answer so it's time to wrap this one. :)

Related

What's the benefit of 3-ways comparison operator (<=>) in C++20?

I know the syntax of it.
I just wondering what's the benefit or whether does it make sens.
Without it, we must code like this:
void func1(int x, int y) {
if( x > y )
doSomeThing();
else if( x < y )
doSomeElse();
else
explosive();
}
With it, we can do like this:
void func1(int x, int y) {
auto result = x <=> y;
if( result > 0 )
doSomeThing();
else if( result < 0 )
doSomeElse();
else
explosive();
}
Except for returning a comparison result, I can NOT see any benefit of this feature.
Some one says it can make our codes more readable, but I don't think so.
It's very obvious, the former example has more readability.
As to return a result, like this:
int func1(int x, int y) {
return x <=> y;
}
It looks like that we get much more readability, but we still need to check the value with another if/else somewhere, e.g. outside of the func1.
I can NOT see any benefit of this feature.
Then you are thinking too narrowly about what is actually happening.
Direct use of <=> does not exist to serve the needs of ints. It can be used for comparing them, but ints are not why the functionality exists.
It exists for types that actually have complex comparison logic. Consider std::string. To know if one string is "less than" another, you have to iterate through both strings and compare each character. When you find a non-equivalent one, you have your answer.
Your code, when applied to string, does the comparison twice: once with less than and once with greater than. The problem is this: the first comparison already found the first non-equal character. But the second comparison does not know where that is. So it must start from the very beginning, doing the exact same comparisons the first one did.
That's a lot of repeated work for an answer than the first comparison already computed. In fact, there is a really easy way to compute <=> for strings: subtract the corresponding character in the second string from the first. If the value is zero, then they are equal. If the result is negative, the first string is less; if it's positive, the first string is greater.
Which is... exactly what <=> returns, isn't it? By using <=>, you do two expensive comparisons in the space of one; testing the return value is immaterial next to the cost of them.
The more complex your comparison logic, the more you are likely to save with <=> if you need to categorize them into less/greater/equal.
It should also be noted that processors often have special opcodes to tell if an integer is negative, zero, or positive. If we look at the x86 assembly for your integer comparison:
func1(int, int): # #func1(int, int)
cmp edi, esi
jle .LBB0_1
jmp a()#PLT # TAILCALL
.LBB0_1:
jge .LBB0_2
jmp b()#PLT # TAILCALL
.LBB0_2:
jmp c()#PLT # TAILCALL
We can see that it only executes cmp once; the jle and jge instructions use the results of the comparison. The <=> compiles to the same assembly, so the compiler fully understands these as being synonyms.

number of letters to be deleted from a string so that it is divisible by another string

I am doing this problem https://www.spoj.com/problems/DIVSTR/
We are given two strings S and T.
S is divisible by string T if there is some non-negative integer k, which satisfies the equation S=k*T
What is the minimum number of characters which should be removed from S, so that S is divisible by T?
The main idea was to match T with S using a pointer and count the number of instances of T occurring in S when the count is done, bring the pointer to the start of T and if there's a mismatch, compare T's first letter with S's present letter.
This code is working totally fine with test cases they provided and custom test cases I gave, but it could not get through hidden test cases.
this is the code
def no_of_letters(string1,string2):
# print(len(string1),len(string2))
count = 0
pointer = 0
if len(string1)<len(string2):
return len(string1)
if (len(string1)==len(string2)) and (string1!=string2):
return len(string1)
for j in range(len(string1)):
if (string1[j]==string2[pointer]) and pointer<(len(string2)-1):
pointer+=1
elif (string1[j]==string2[pointer]) and pointer == (len(string2)-1):
count+=1
pointer=0
elif (string1[j]!=string2[pointer]):
if string1[j]==string2[0]:
pointer=1
else:
pointer = 0
return len(string1)-len(string2)*count
One place where I think there should be confusion is when same letters can be parts of two counts, but it should not be a problem, because our answer doesn't need to take overlapping into account.
for example, S = 'akaka' T= 'aka' will give the output 2, irrespective of considering first 'aka',ka as count or second ak,'aka'.
I believe that the solution is much more straightforward that you make it. You're simply trying to find how many times the characters of T appear, in order, in S. Everything else is the characters you remove. For instance, given RobertBaron's example of S="akbaabka" and T="aka", you would write your routine to locate the characters a, k, a, in that order, from the start of S:
akbaabka
ak a^
# with some pointer, ptr, now at position 4, marked with a caret above
With that done, you can now recur on the remainder of the string:
find_chars(S[ptr:], T)
With each call, you look for T in S; if you find it, count 1 repetition and recur on the remainder of S; if not, return 0 (base case). As you crawl back up your recursion stack, accumulate all the 1 counts, and there is your value of k.
The quantity of chars to remove is len(s) - k*len(T).
Can you take it from there?

Efficient way to write ordering instances?

I'm working on a basic Haskell exercise that is set up as follows: a data definition is made, where Zero is declared to be a NaturalNumber, and a series of numbers (printed out by name, so, for instance, four) up to ten is constructed with this.
I didn't have too much trouble with understanding how the declaration of Eq instances works (apart from not having been given an exact explanation for the syntax), but I'm having trouble with declaring all instances I need for Ord -- I need to be able to construct an ordering over the entire set of numbers, such that I'll get True if I input "ten > nine" or something.
Right now, I have this snippet of code. The first two lines should be correct, as I copied them (as I was supposed to) from the exercise itself.
instance Ord NaturalNumber where
compare Zero Zero = EQ
compare Zero (S Zero) = LT
compare (S Zero) Zero = GT
compare x (S x) = LT
The first four lines work fine, but they can't deal with cases like "compare four five", and anything similar to what I typed in the last doesn't work even if I type in something like compare four four = EQ: I get a "conflicting definitions" error, presumably because the x appears twice. If I write something like compare two one = GT instead, I get a "pattern match(es) are overlapped" warning, but it works. However, I also get the result GT when I input compare one two into the actual Haskell platform, so clearly something isn't working. This happens even if I add compare one two = LT below that line.
So clearly I can't finish off this description of Ord instances by writing every instance I could possibly need, and even if I could, it would be incredibly inefficient to write out all 100 instances by hand.
Might anyone be able to provide me with a hint as to how I can resolve this problem and finish off the construction of an ordering mechanism?
What this task focuses on is finding base cases and recursion rules. The first two lines you were given were
instance Ord NaturalNumber where
compare Zero Zero = EQ
This is the first base case, in words:
zero is equal to zero
The other two base cases are:
zero is less than the successor of any NaturalNumber
the successor of any NaturalNumber is greater than zero
Note that your lines three and four only say that 0 < 1 and 1 > 0, but nothing about any other nonzero numbers.
The recursion rule, then, is that it makes no difference if you compare two nonzero numbers, or the numbers they are successors of:
comparing 1 + x and 1 + y is the same as comparing x and y.
Codifying that into Haskell should give you the solution to this exercise.
You'll need to organize your instances in a way that will cover all possible patterns. To make it simpler, remember how your numbers are defined:
one = S Zero
two = S one -- or S (S Zero)
and think in terms of S and Zero, not one, two etc. (they are merely aliases). Once you do this, it should become clear that you're missing a case like:
compare (S x) (S y) = compare x y
Edit:
Like Jakob Runge noticed, also the following base clauses should be improved:
compare Zero (S Zero) = LT
compare (S Zero) Zero = GT
As they're written, they allow comparison only between zero and one. You should change them to cover comparison between zero and any positive number:
compare Zero (S _) = LT
compare (S _) Zero = GT
Your compare function needs to be recursive. You will want your last case to capture the situation where both arguments are the successor of something, and then recurse on what they are the successor of. Additionally, your middle two cases, are probably not what you want, as they will only capture the following cases:
1 > 0
0 < 1
You would like this to be more general, so that you can handle cases like:
S x > 0, for all x
0 < S x, for all x

Scope of variables and the digits function

My question is twofold:
1) As far as I understand, constructs like for loops introduce scope blocks, however I'm having some trouble with a variable that is define outside of said construct. The following code depicts an attempt to extract digits from a number and place them in an array.
n = 654068
l = length(n)
a = Int64[]
for i in 1:(l-1)
temp = n/10^(l-i)
if temp < 1 # ith digit is 0
a = push!(a,0)
else # ith digit is != 0
push!(a,floor(temp))
# update n
n = n - a[i]*10^(l-i)
end
end
# last digit
push!(a,n)
The code executes fine, but when I look at the a array I get this result
julia> a
0-element Array{Int64,1}
I thought that anything that goes on inside the for loop is invisible to the outside, unless I'm operating on variables defined outside the for loop. Moreover, I thought that by using the ! syntax I would operate directly on a, this does not seem to be the case. Would be grateful if anyone can explain to me how this works :)
2) Second question is about syntex used when explaining functions. There is apparently a function called digits that extracts digits from a number and puts them in an array, using the help function I get
julia> help(digits)
Base.digits(n[, base][, pad])
Returns an array of the digits of "n" in the given base,
optionally padded with zeros to a specified size. More significant
digits are at higher indexes, such that "n ==
sum([digits[k]*base^(k-1) for k=1:length(digits)])".
Can anyone explain to me how to interpret the information given about functions in Julia. How am I to interpret digits(n[, base][, pad])? How does one correctly call the digits function? I can't be like this: digits(40125[, 10])?
I'm unable to reproduce you result, running your code gives me
julia> a
1-element Array{Int64,1}:
654068
There's a few mistakes and inefficiencies in the code:
length(n) doesn't give the number of digits in n, but always returns 1 (currently, numbers are iterable, and return a sequence that only contain one number; itself). So the for loop is never run.
/ between integers does floating point division. For extracting digits, you´re better off with div(x,y), which does integer division.
There's no reason to write a = push!(a,x), since push! modifies a in place. So it will be equivalent to writing push!(a,x); a = a.
There's no reason to digits that are zero specially, they are handled just fine by the general case.
Your description of scoping in Julia seems to be correct, I think that it is the above which is giving you trouble.
You could use something like
n = 654068
a = Int64[]
while n != 0
push!(a, n % 10)
n = div(n, 10)
end
reverse!(a)
This loop extracts the digits in opposite order to avoid having to figure out the number of digits in advance, and uses the modulus operator % to extract the least significant digit. It then uses reverse! to get them in the order you wanted, which should be pretty efficient.
About the documentation for digits, [, base] just means that base is an optional parameter. The description should probably be digits(n[, base[, pad]]), since it's not possible to specify pad unless you specify base. Also note that digits will return the least significant digit first, what we get if we remove the reverse! from the code above.
Is this cheating?:
n = 654068
nstr = string(n)
a = map((x) -> x |> string |> int , collect(nstr))
outputs:
6-element Array{Int64,1}:
6
5
4
0
6
8

How to compute one's complement using Ruby's bitwise operators?

What I want:
assert_equal 6, ones_complement(9) # 1001 => 0110
assert_equal 0, ones_complement(15) # 1111 => 0000
assert_equal 2, ones_complement(1) # 01 => 10
the size of the input isn't fixed as in 4 bits or 8 bits. rather its a binary stream.
What I see:
v = "1001".to_i(2) => 9
There's a bit flipping operator ~
(~v).to_s(2) => "-1010"
sprintf("%b", ~v) => "..10110"
~v => -10
I think its got something to do with one bit being used to store the sign or something... can someone explain this output ? How do I get a one's complement without resorting to string manipulations like cutting the last n chars from the sprintf output to get "0110" or replacing 0 with 1 and vice versa
Ruby just stores a (signed) number. The internal representation of this number is not relevant: it might be a FixNum, BigNum or something else. Therefore, the number of bits in a number is also undefined: it is just a number after all. This is contrary to for example C, where an int will probably be 32 bits (fixed).
So what does the ~ operator do then? Wel, just something like:
class Numeric
def ~
return -self - 1
end
end
...since that's what '~' represents when looking at 2's complement numbers.
So what is missing from your input statement is the number of bits you want to switch: a 32-bits ~ is different from a generic ~ like it is in Ruby.
Now if you just want to bit-flip n-bits you can do something like:
class Numeric
def ones_complement(bits)
self ^ ((1 << bits) - 1)
end
end
...but you do have to specify the number of bits to flip. And this won't affect the sign flag, since that one is outside your reach with XOR :)
It sounds like you only want to flip four bits (the length of your input) - so you probably want to XOR with 1111.
See this question for why.
One problem with your method is that your expected answer is only true if you only flip the four significant bits: 1001 -> 0110.
But the number is stored with leading zeros, and the ~ operator flips all the leading bits too: 00001001 -> 11110110. Then the leading 1 is interpreted as the negative sign.
You really need to specify what the function is supposed to do with numbers like 0b101 and 0b11011 before you can decide how to implement it. If you only ever want to flip 4 bits you can do v^0b1111, as suggested in another answer. But if you want to flip all significant bits, it gets more complicated.
edit
Here's one way to flip all the significant bits:
def maskbits n
b=1
prev=n;
mask=prev|(prev>>1)
while (mask!=prev)
prev=mask;
mask|=(mask>>(b*=2))
end
mask
end
def ones_complement n
n^maskbits(n)
end
This gives
p ones_complement(9).to_s(2) #>>"110"
p ones_complement(15).to_s(2) #>>"0"
p ones_complement(1).to_s(2) #>>"0"
This does not give your desired output for ones_compliment(1), because it treats 1 as "1" not "01". I don't know how the function could infer how many leading zeros you want without taking the width as an argument.
If you're working with strings you could do:
s = "0110"
s.gsub("\d") {|bit| bit=="1"?"0":"1"}
If you're working with numbers, you'll have to define the number of significant bits because:
0110 = 6; 1001 = 9;
110 = 6; 001 = 1;
Even, ignoring the sign, you'll probably have to handle this.
What you are doing (using the ~) operator, is indeed a one's complement. You are getting those values that you are not expecting because of the way the number is interpreted by Ruby.
What you actually need to do will depend on what you are using this for. That is to say, why do you need a 1's complement?
Remember that you are getting the one's complement right now with ~ if you pass in a Fixnum: the number of bits which represent the number is a fixed quantity in the interpreter and thus there are leading 0's in front of the binary representation of the number 9 (binary 1001). You can find this number of bits by examining the size of any Fixnum. (the answer is returned in bytes)
1.size #=> 4
2147483647.size #=> 4
~ is also defined over Bignum. In this case it behaves as if all of the bits which are specified in the Bignum were inverted, and then if there were an infinite string of 1's in front of that Bignum. You can, conceivably shove your bitstream into a Bignum and invert the whole thing. You will however need to know the size of the bitstream prior to inversion to get a useful result out after it is inverted.
To answer the question as you pose it right off the bat, you can find the largest power of 2 less than your input, double it, subtract 1, then XOR the result of that with your input and always get a ones complement of just the significant bits in your input number.
def sig_ones_complement(num)
significant_bits = num.to_s(2).length
next_smallest_pow_2 = 2**(significant_bits-1)
xor_mask = (2*next_smallest_pow_2)-1
return num ^ xor_mask
end

Resources