For example I want to declare
let len, (*mutable*) i =
if s.Length >= 2 && s.[0] = '0' && (s.[1] = 'x' || s.[1] = 'X') then
(s.Length - 2, 2)
else (s.Length, 0)
constant binding len and mutable i, is it possible ?
Added :
I will use references then
let len, i =
if s.Length >= 2 && s.[0] = '0' && (s.[1] = 'x' || s.[1] = 'X') then
(s.Length - 2, ref 2)
else (s.Length, ref 0)
No. mutable applies to the entire let binding. You'll have to do:
let len, i = ...
let mutable i = i
Related
I want to know. How did the Map type work when finding the value of a key?
Is this create an index like SQL?
Why these times are same as when I tried this code?
I don't have studied a programming class. Can someone explain in a simple way for me to understand?
import 'dart:math';
void main() {
int limit = 1000000;
Random random = new Random();
Map<String, int> map = {};
List<String> list = [];
for (int i = 0; i < limit; i++) {
String key = i.toString() + random.nextInt(limit).toString();
map[key] = i;
if (i == 0 ||
i == limit - 1 ||
i == limit / 2 ||
i == limit / 4 ||
i == limit / 10) {
list.add(key);
print("$key : $i");
}
}
for (var e in list) {
print("\n$e");
int time = DateTime.now().microsecondsSinceEpoch;
print(
"$e : ${map[e]} -> time = ${DateTime.now().microsecondsSinceEpoch - time}");
}
}
The result is:
0225402 : 0
100000478677 : 100000
250000355840 : 250000
50000052625 : 500000
999999681585 : 999999
0225402
0225402 : 0 -> time = 0
100000478677
100000478677 : 100000 -> time = 0
250000355840
250000355840 : 250000 -> time = 0
50000052625
50000052625 : 500000 -> time = 0
999999681585
999999681585 : 999999 -> time = 0
The code below is generating an error and fails to run as the expression was too 'complex'.
for row in 0...NumRows {
for column in 0...NumColumns {
let topLeft = (column > 0) && (row < NumRows)
&& level.tileAt(column: column - 1, row: row) != nil
let bottomLeft = (column > 0) && (row > 0)
&& level.tileAt(column: column - 1, row: row - 1) != nil
let topRight = (column < NumColumns) && (row < NumRows)
&& level.tileAt(column: column, row: row) != nil
let bottomRight = (column < NumColumns) && (row > 0)
&& level.tileAt(column: column, row: row - 1) != nil
let value = Int(topLeft.hashValue) | Int(topRight.hashValue) << 1 | Int(bottomLeft.hashValue) << 2 | Int(bottomRight.hashValue) << 3
if value != 0 && value != 6 && value != 9 {
let name = String(format: "Tile_%ld", value)
let tileNode = SKSpriteNode(imageNamed: name)
tileNode.size = CGSize(width: TileWidth, height: TileHeight)
var point = pointFor(column: column, row: row)
point.x -= TileWidth/2
point.y -= TileHeight/2
tileNode.position = point
tilesLayer.addChild(tileNode)
}
}
}
Specifically this line:
let value = Int(topLeft.hashValue) | Int(topRight.hashValue) << 1 | Int(bottomLeft.hashValue) << 2 | Int(bottomRight.hashValue) << 3
The error is as follows:
Expression was too complex to be solved in reasonable time; consider breaking up the expression into distinct sub-expressions
How would you break up the expression for value in such a way that the code following it keeps the same answer?
hashValue is already an Int, so the Int(...) constructors are not
needed. This compiles in Xcode 9:
let value = topLeft.hashValue | (topRight.hashValue << 1) | (bottomLeft.hashValue << 2) | (bottomRight.hashValue << 3)
But that is a bad idea! It relies on the hash value of booleans having specific values:
false.hashValue == 0
true.hashValue == 1
which is nowhere guaranteed. (The only guarantee is that identical elements have the same hash value. One must not even assume that hash
values are equal across different executions of your program,
see Hashable).
A better solution would be
let value = (topLeft ? 1 : 0) + (topRight ? 2 : 0) + (bottomLeft ? 4 : 0) + (bottomRight ? 8 : 0)
Alternatively, use a switch-statement. Example:
switch (topLeft, topRight, bottomLeft, bottomRight) {
case (false, false, false, false):
// ... all false ...
case (false, true, true, false):
// ... topRight and bottomLeft are true ...
case (true, false, false, true):
// ... topLeft and bottomRight are true ...
default:
// ... all other cases ...
}
for example:
I have a binary look like this:
bin1 = "2\nok\n3\nbcd\n\n"
or
bin2 = "2\nok\n3\nbcd\n1\na\n\n"
and so on...
The format is
byte_size \n bytes \n byte_size \n bytes \n \n
I want parse binary get
["ok", "bcd"]
how to implement in Elixir or Erlang ?
Go version
a Go version parse this
func (c *Client) parse() []string {
resp := []string{}
buf := c.recv_buf.Bytes()
var idx, offset int
idx = 0
offset = 0
for {
idx = bytes.IndexByte(buf[offset:], '\n')
if idx == -1 {
break
}
p := buf[offset : offset+idx]
offset += idx + 1
//fmt.Printf("> [%s]\n", p);
if len(p) == 0 || (len(p) == 1 && p[0] == '\r') {
if len(resp) == 0 {
continue
} else {
c.recv_buf.Next(offset)
return resp
}
}
size, err := strconv.Atoi(string(p))
if err != nil || size < 0 {
return nil
}
if offset+size >= c.recv_buf.Len() {
break
}
v := buf[offset : offset+size]
resp = append(resp, string(v))
offset += size + 1
}
return []string{}
}
Thanks
A more flexible solution:
result = bin
|> String.split("\n")
|> Stream.chunk(2)
|> Stream.map(&parse_bytes/1)
|> Enum.filter(fn s -> s != "" end)
def parse_bytes(["", ""]), do: ""
def parse_bytes([byte_size, bytes]) do
byte_size_int = byte_size |> String.to_integer
<<parsed :: binary-size(byte_size_int)>> = bytes
parsed
end
I wrote a solution:
defp parse("\n") do
[]
end
defp parse(data) do
{offset, _} = :binary.match(data, "\n")
size = String.to_integer(binary_part(data, 0, offset))
value = binary_part(data, offset + 1, size)
len = offset + 1 + size + 1
[value] ++ parse(binary_part(data, len, byte_size(data) - len))
end
The Elixir mailing list provides another one:
defp parse_binary("\n"), do: []
defp parse_binary(binary) do
{size, "\n" <> rest} = Integer.parse(binary)
<<chunk :: [binary, size(size)], "\n", rest :: binary>> = rest
[chunk|parse_binary(rest)]
end
I can't seem to get my head around the rules that govern these two cases:
1. The end index may be one less than the start index, producing an empty array/string.
2. It's apparently legal to position the start index just behind the last element, if the end index is one less, as before.
[|0..2|].[3..2];; // [||]
"bar".[3..2];; // ""
A naive implementation of bound checks with consideration of case 1 wouldn't allow case 2:
let trySlice i j (a : string) =
let lastIdx = a.Length - 1
if i < 0 || i > lastIdx || j < i - 1 || j > lastIdx then None
else Some a.[i..j]
trySlice 3 2 "bar" // None
What's the rationale behind this behavior? How to proceed?
Edit
This is what I have now thanks to Tarmil's input
let trySlice i j (a : string) =
if i >= 0 && j >= i - 1 && j < a.Length then Some a.[i..j]
else None
which should be equivalent to
let trySlice' i j (s : string) =
try s.Substring(i, j - i + 1) |> Some
with _ -> None
I suppose the rationale is that a.[i..j] is a sequence of length (j - i + 1), so in a way it makes sense to allow i = j + 1 as a way to extract an empty sequence.
As for "how to proceed", if you want your trySlice to accept all cases that the built-in slicing accepts, then just remove the i > lastIdx clause. When i = lastIdx + 1, the only way for the other conditions to pass is if j = lastIdx, and when i > lastIdx + 1, there is no way for j to pass both its constraints.
As a side-note, the way you write:
if (failCondition || failCondition || ...) then None else Some x
feels counter-intuitive to me for some reason, I would have written it as:
if (successCondition && successCondition && ...) then Some x else None
I want to know if:
val1 = val2 = val3 ... = val6
I try this:
if (val1 == val2 == val3 == val4 == val5 == val6)
{
}
but it don't work, why?
The == operator only works between pairs of values. When you do this:
val1 == val2 == val3
What's really happening is this:
(val1 == val2) == val3
So if val1 and val2 are equal, the expression in the parenthesis evaluates to true:
true == val3
And then it checks whether true == val3, not whether val1 or val2 == val3. You have to do this instead:
val1 == val2 && val1 == val3
This is getting pretty unwieldy for six variables though. Do you really have six local variables that you have to compare? Perhaps you should store them in an array of some sort. Then you can do:
bool all_equal(int *vals, int length) {
if (length == 0) {
return true;
}
int first = vals[0];
for (int i=1; i < length; i++) {
if (vals[i] != first) {
return false;
}
}
return true;
}
So instead of:
int val1 = ..., val2 = ..., val3 = ..., val4 = ..., val5 = ..., val6 = ...;
if (val1 == val2 && val2 == val3 && val3 == val4 && val4 == val5 && val5 == val6) {
...
}
You would to:
int vals[6] = {..., ..., ..., ..., ..., ...};
if (all_equal(vals, 6)) {
...
}
You can't chain the == operator. Do this:
if (val1 == val2 && val2 == val3 && val3 == val4 && val4 == val5 && val5 == val6) {
// they are all equal
}
Error Issue is already ably explained by other users, I just wanted to share an another approach.
I written a C code using variable number of arguments: 9.9. Variable numbers of arguments I hope you find it interesting
#include<stdio.h>
#include<stdarg.h>
typedef enum {FALSE, TRUE} boolean;
boolean isAllEqual(int count, ...){
va_list ap; // vlist variable
int num = 0;
boolean flag = TRUE;
//Step2: To initialize `ap` using right-most argument that is `c`
va_start(ap, count);
//Step3: Now access vlist `ap` elements using va_arg()
num = va_arg(ap, int);
while(--count){
if (num != va_arg(ap, int)){
flag = FALSE;
break;
}
}
//Step4: Now work done, we should reset pointer to NULL
va_end(ap);
return flag? TRUE: FALSE;
}
int main(){
if(isAllEqual(5, 2, 2, 2, 2, 2))
printf(" Yes, All are equal\n");
else
printf(" No, All are NOT equal\n");
if(isAllEqual(4, 2, 4, 2, 5))
printf(" Yes, All are equal\n");
else
printf(" No, All are NOT equal\n");
return 0;
}
Output:
Yes, All are equal
No, All are NOT equal
Check codepade.
My boolean isAllEqual(int count, ...) function can check any number of integers, count = number of values you wants to compare. e.g. In isAllEqual(4, 2, 4, 2, 5) first 4 means you wants to compare next four values.
A short theory in four points will help you to understand my code.
I would suggest writing a macro or a function(if it is array with big size or if it is allocated at runtime) in this case.