Avoiding explicit record typing - record

Suppose I have the following functions for operating over an idealized stream:
fun Stream s = { pos = 0, row = 1, col = 0, str = s }
fun len { str, pos = _, row = _, col = _ } = String.size str
fun poke off { str, pos, row: int, col: int } =
let val n = pos + off in
if n >= 0 andalso n <= (String.size str) then SOME (String.sub(str, n)) else NONE
end
This works/compiles, but it's unfortunate to have to litter my function definitions with information I don't care about. row/col are ignored poke and len. However, while the wildcard can be used with len, it can't be with poke. Is there a way to restructure these functions so that less explicit typing needs to be put in, while still being able to pattern match/destructure?

If you give your type a name (such as stream), you can refer to it more briefly:
type stream = { pos : int, row : int, col : int, str : string }
fun Stream s = { pos = 0, row = 1, col = 0, str = s }
fun len ({ str, ... } : stream) = String.size str
fun poke off ({ str, pos, ... } : stream) =
let val n = pos + off in
if n >= 0 andalso n <= String.size str
then SOME (String.sub (str, n))
else NONE
end
Or, more-or-less equivalently:
datatype stream = STREAM of { pos : int, row : int, col : int, str : string }
fun Stream s = STREAM { pos = 0, row = 1, col = 0, str = s }
fun len (STREAM { str, ... }) = String.size str
fun poke off (STREAM { str, pos, ... }) =
let val n = pos + off in
if n >= 0 andalso n <= String.size str
then SOME (String.sub (str, n))
else NONE
end

Related

Two sum in kotlin

Given an array of integers nums and an integer target, return indices of the two numbers such that they add up to target.
Example 1:
Input: nums = [2,7,11,15], target = 9
Output: [0,1]
Explanation: Because nums[0] + nums[1] == 9, we return [0, 1].
Example 2:
Input: nums = [3,2,4], target = 6
Output: [1,2]
Example 3:
Input: nums = [3,3], target = 6
Output: [0,1]
I am adding piece of code.
fun main() {
// val nums = intArrayOf(2, 7, 11, 15)
// val target = 9
val nums = intArrayOf(3, 2, 4)
val target = 6
// val nums = intArrayOf(3, 3)
// val target = 6
twoSum(nums, target).forEach {
print(" $it")
}
}
fun twoSum(nums: IntArray, target: Int): IntArray {
val map = mutableMapOf<Int, Int>()
nums.forEachIndexed { index, i ->
map[i]?.let {
return intArrayOf(it, index)
}
map[target - i] = index
}
return intArrayOf()
}
My youtube link is described that I am debugging the code. My question is how
map[i]?.let {
return intArrayOf(it, index)
}
is going inside the 1st and 2nd iteration of return statment and it not going in 3rd iteration. Can anyone help me on this. Thanks

Kotlin Calculating with BigDecimal vs Double

I have 2 Functions. One uses BigInteger and BigDecimal. I want to calculate sin(z) using the Taylor series:
Here is my code:
fun sinus(z: BigDecimal, upperBound: Int = 100): BigDecimal = calcSin(z, upperBound)
fun cosinus(z: BigDecimal, upperBound: Int = 100): BigDecimal = calcSin(z, upperBound, false)
fun calcSin(z: BigDecimal, upperBound: Int = 100, isSin: Boolean = true): BigDecimal {
var erg: BigDecimal = BigDecimal.ZERO
for (n in 0..upperBound) {
// val zaehler = (-1.0).pow(n).toBigDecimal() * z.pow(2 * n + (if (isSin) 1 else 0))
// val nenner = fac(2 * n + (if (isSin) 1 else 0)).toBigDecimal()
val zaehler = (-1.0).pow(n).toBigDecimal() * z.pow(2 * n + 1)
val nenner = fac(2 * n + 1).toBigDecimal()
erg += (zaehler / nenner)
}
return erg
}
fun calcSin(z: Double, upperBound: Int = 100): Double {
var res = 0.0
for (n in 0..upperBound) {
val zaehler = (-1.0).pow(n) * z.pow(2 * n + 1)
val nenner = fac(2 * n + 1, true)
res += (zaehler / nenner)
}
return res
}
fun fac(n: Int): BigInteger = if (n == 0 || n == 1) BigInteger.ONE else n.toBigInteger() * fac(n - 1)
fun fac(n: Int, dummy: Boolean): Double = if (n == 0 || n == 1) 1.0 else n.toDouble() * fac(n - 1, dummy)
According to Google, Sin(1) is
0.8414709848
The Output of the following is however:
println("Sinus 1: ${sinus(1.0.toBigDecimal())}")
println("Sinus 1: ${sinus(1.0.toBigDecimal()).toDouble()}")
println("Sinus 1: ${sinus(1.0.toBigDecimal(), 1000)}")
println("Sinus 1: ${calcSin(1.0)}")
Output:
Sinus 1: 0.8414373208078281027995610599000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
Sinus 1: 0.8414373208078281
Sinus 1: 0.8414373208078281027995610599000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
Sinus 1: 0.8414709848078965
Wha am I missing? Why does the Double-Variant gives the correct value, while The BigDecimal doesn't? Even with 1000 Iterations.
The commented out code was meant for calculation Cos as well, but wanted to figure out that Problem first, so i made both Functions look the same
In the BigDecimal variant, try replacing erg += (zaehler / nenner) with erg += (zaehler.divide(nenner, 20, RoundingMode.HALF_EVEN))
I suspect that the defaults for scaling the division results (as described here https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/math/BigDecimal.html) are not what you want.
BTW - I assume that performance is not part of the exercise, otherwise your implementation of factorial is a low hanging fruit.

Bankers' rounding for BigQuery

Simple question what is the way to use bankers' rounding in BigQuery.
The only thing which I can find is:
BAD WAY to do it but still works:
CREATE TEMP FUNCTION test(num FLOAT64, decimalPlaces INT64)
RETURNS FLOAT64
LANGUAGE js AS """
var d = decimalPlaces || 0;
var m = Math.pow(10, d);
var n = +(d ? num * m : num).toFixed(8); // Avoid rounding errors
var i = Math.floor(n), f = n - i;
var e = 1e-8; // Allow for rounding errors in f
var r = (f > 0.5 - e && f < 0.5 + e) ?
((i % 2 == 0) ? i : i + 1) : Math.round(n);
return d ? r / m : r;
""";
SELECT ROUND(1.525,2)
There is a simpler way of calculating it:
CREATE TEMP FUNCTION bankersRound(num FLOAT64, decimals INT64)
RETURNS FLOAT64
LANGUAGE js AS """
var scale = Math.pow(10, decimals);
var result = value = (Math.round((num * scale) / 2) * 2) / scale;
return result;
""";
Bad way, but still works:
CREATE TEMP FUNCTION test(num FLOAT64, decimalPlaces INT64)
RETURNS FLOAT64
LANGUAGE js AS """
var d = decimalPlaces || 0;
var m = Math.pow(10, d);
var n = +(d ? num * m : num).toFixed(8); // Avoid rounding errors
var i = Math.floor(n), f = n - i;
var e = 1e-8; // Allow for rounding errors in f
var r = (f > 0.5 - e && f < 0.5 + e) ?
((i % 2 == 0) ? i : i + 1) : Math.round(n);
return d ? r / m : r;
""";
SELECT ROUND(1.525,2)

How to Base64 encode an IntArray in Kotlin

How to base64 encode a buff of intArrayOf using Kotlin.
val vec = intArrayOf(1,2,3,4,5)
val data =?!
val base64Encoded = Base64.encodeToString(data, Base64.DEFAULT);
The 'ByteArray" representation of an IntArray can be calculated like this:
fun IntArray.toByteArray(): ByteArray {
val result = ByteArray(this.size * 4)
for ((idx, value) in this.withIndex()) {
result[idx + 3] = (value and 0xFF).toByte()
result[idx + 2] = ((value ushr 8) and 0xFF).toByte()
result[idx + 1] = ((value ushr 16) and 0xFF).toByte()
result[idx] = ((value ushr 24) and 0xFF).toByte()
}
return result
}
This result can then be Base64 encoded like mentioned in the question:
val vec = intArrayOf(1,2,3,4,5)
val data = vec.toByteArray()
val base64Encoded = Base64.encodeToString(data, Base64.DEFAULT);

How to implement the MapReduce example in Erlang efficiently?

I am trying to compare the performance of concurrent programming languages, such as Haskell, Go and Erlang. The following Go code calculates the sum of squares, ( repeat calculate the sum of squares for R times):
1^2+2^2+3^2....1024^2
package main
import "fmt"
func mapper(in chan int, out chan int) {
for v := range in {out <- v*v}
}
func reducer(in1, in2 chan int, out chan int) {
for i1 := range in1 {i2 := <- in2; out <- i1 + i2}
}
func main() {
const N = 1024 // calculate sum of squares up to N; N must be power of 2
const R = 10 // number of repetitions to fill the "pipe"
var r [N*2]chan int
for i := range r {r[i] = make(chan int)}
var m [N]chan int
for i := range m {m[i] = make(chan int)}
for i := 0; i < N; i++ {go mapper(m[i], r[i + N])}
for i := 1; i < N; i++ {go reducer(r[i * 2], r[i *2 + 1], r[i])}
go func () {
for j := 0; j < R; j++ {
for i := 0; i < N; i++ {m[i] <- i + 1}
}
} ()
for j := 0; j < R; j++ {
<- r[1]
}
}
The following code is the MapReduce solution in Erlang. I am a newbie to Erlang. I would like to compare performance among Go, Haskell and Erlang. My question is how to optimize this Erlang code. I compile this code by using erlc -W mr.erl and run the code by using erl -noshell -s mr start -s init stop -extra 1024 1024. Are there any special compile and execution options available for optimizations? I really appreciate any help you can provide.
-module(mr).
-export([start/0, create/2, doreduce/2, domap/1, repeat/3]).
start()->
[Num_arg|Repeat] = init:get_plain_arguments(),
N = list_to_integer(Num_arg),
[R_arg|_] = Repeat,
R = list_to_integer(R_arg),
create(R, N).
create(R, Num) when is_integer(Num), Num > 0 ->
Reducers = [spawn(?MODULE, doreduce, [Index, self()]) || Index <- lists:seq(1, 2*Num - 1)],
Mappers = [spawn(?MODULE, domap, [In]) || In <- lists:seq(1, Num)],
reducer_connect(Num-1, Reducers, self()),
mapper_connect(Num, Num, Reducers, Mappers),
repeat(R, Num, Mappers).
repeat(0, Num, Mappers)->
send_message(Num, Mappers),
receive
{result, V}->
%io:format("Repeat: ~p ~p ~n", [0, V])
true
end;
repeat(R, Num, Mappers)->
send_message(Num, Mappers),
receive
{result, V}->
%io:format("Got: ~p ~p ~n", [R, V])
true
end,
repeat(R-1, Num, Mappers).
send_message(1, Mappers)->
D = lists:nth (1, Mappers),
D ! {mapper, 1};
send_message(Num, Mappers)->
D = lists:nth (Num, Mappers),
D ! {mapper, Num},
send_message(Num-1, Mappers).
reducer_connect(1, RList, Root)->
Parent = lists:nth(1, RList),
Child1 = lists:nth(2, RList),
Child2 = lists:nth(3, RList),
Child1 ! {connect, Parent},
Child2 ! {connect, Parent},
Parent !{connect, Root};
reducer_connect(Index, RList, Root)->
Parent = lists:nth(Index, RList),
Child1 = lists:nth(Index*2, RList),
Child2 = lists:nth(Index*2+1, RList),
Child1 ! {connect, Parent},
Child2 ! {connect, Parent},
reducer_connect(Index-1, RList, Root).
mapper_connect(1, Num, RList, MList)->
R = lists:nth(Num, RList),
M = lists:nth(1, MList),
M ! {connect, R};
mapper_connect(Index, Num, RList, MList) when is_integer(Index), Index > 0 ->
R = lists:nth(Num + (Index-1), RList),
M = lists:nth(Index, MList),
M ! {connect, R},
mapper_connect(Index-1, Num, RList, MList).
doreduce(Index, CurId)->
receive
{connect, Parent}->
doreduce(Index, Parent, 0, 0, CurId)
end.
doreduce(Index, To, Val1, Val2, Root)->
receive
{map, Val} ->
if Index rem 2 == 0 ->
To ! {reduce1, Val},
doreduce(Index, To, 0, 0, Root);
true->
To ! {reduce2, Val},
doreduce(Index, To, 0, 0, Root)
end;
{reduce1, V1} when Val2 > 0, Val1 == 0 ->
if Index == 1 ->% root node
Root !{result, Val2 + V1},
doreduce(Index, To, 0, 0, Root);
Index rem 2 == 0 ->
To ! {reduce1, V1+Val2},
doreduce(Index, To, 0, 0, Root);
true->
To ! {reduce2, V1+Val2},
doreduce(Index, To, 0, 0, Root)
end;
{reduce2, V2} when Val1 > 0, Val2 == 0 ->
if Index == 1 ->% root node
Root !{result, Val1 + V2},
doreduce(Index, To, 0, 0, Root);
Index rem 2 == 0 ->
To ! {reduce1, V2+Val1},
doreduce(Index, To, 0, 0, Root);
true->
To ! {reduce2, V2+Val1},
doreduce(Index, To, 0, 0, Root)
end;
{reduce1, V1} when Val1 == 0, Val2 == 0 ->
doreduce(Index, To, V1, 0, Root);
{reduce2, V2} when Val1 == 0, Val2 == 0 ->
doreduce(Index, To, 0, V2, Root);
true->
true
end.
domap(Index)->
receive
{connect, ReduceId}->
domap(Index, ReduceId)
end.
domap(Index, To)->
receive
{mapper, V}->
To !{map, V*V},
domap(Index, To);
true->
true
end.
Despite it is not a good task for Erlang at all, there is a quite simple solution:
-module(mr).
-export([start/1, start/2]).
start([R, N]) ->
Result = start(list_to_integer(R), list_to_integer(N)),
io:format("~B x ~B~n", [length(Result), hd(Result)]).
start(R, N) ->
Self = self(),
Reducer = start(Self, R, 1, N),
[ receive {Reducer, Result} -> Result end || _ <- lists:seq(1, R) ].
start(Parent, R, N, N) ->
spawn_link(fun() -> mapper(Parent, R, N) end);
start(Parent, R, From, To) ->
spawn_link(fun() -> reducer(Parent, R, From, To) end).
mapper(Parent, R, N) ->
[ Parent ! {self(), N*N} || _ <- lists:seq(1, R) ].
reducer(Parent, R, From, To) ->
Self = self(),
Middle = ( From + To ) div 2,
A = start(Self, R, From, Middle),
B = start(Self, R, Middle + 1, To),
[ Parent ! {Self, receive {A, X} -> receive {B, Y} -> X+Y end end}
|| _ <- lists:seq(1, R) ].
You can run it using
$ erlc -W mr.erl
$ time erl -noshell -run mr start 1024 1024 -s init stop
1024 x 358438400
real 0m2.162s
user 0m4.177s
sys 0m0.151s
But most of the time is VM start and gracefull stop overhead
$ time erl -noshell -run mr start 1024 1024 -s erlang halt
1024 x 358438400
real 0m1.172s
user 0m4.110s
sys 0m0.150s
$ erl
1> timer:tc(fun() -> mr:start(1024,1024) end).
{978453,
[358438400,358438400,358438400,358438400,358438400,
358438400,358438400,358438400,358438400,358438400,358438400,
358438400,358438400,358438400,358438400,358438400,358438400,
358438400,358438400,358438400,358438400,358438400,358438400,
358438400,358438400,358438400,358438400|...]}
Keep in mind it is more like an elegant solution than an efficient one. An efficient solution should balance reduction tree branching with communication overhead.