expression 'a' is of type 'int' and has to be used (or discarded) - nim-lang

I'm trying to rewrite the cryptomath code from here and I'm getting this when I try to compile to JS;
Hint: used config file '/home/*******/.choosenim/toolchains/nim-1.6.8/config/nim.cfg' [Conf]
Hint: used config file '/home/*******/.choosenim/toolchains/nim-1.6.8/config/config.nims' [Conf]
...........................................................
/home/*******/nim/cryptomath.nim(6, 9) Error: expression 'a' is of type 'int' and has to be used (or discarded)
This is my code:
import std/random
import std/math
randomize()
proc gcd*(a: int, b: int): int =
while a != 0:
a, b = floorMod(b,a), a # fails here apparently
return (b+a)-a
proc find_mod_inverse*(a: int, m: int): int =
if gcd(a,m) != 1:
return -1
var
u1 = 1
u2 = 0
u3 = a
v1 = 0
v2 = 1
v3 = m
q = -1
while v3 != 0:
q = floorDiv(u3,v3)
v1 = (u1 - q * v1)
v2 = (u2 - q * v2)
v3 = (u3 - q * v3)
u1 = v1
u2 = v2
u3 = v3
return floorMod(u1,m)
I tried adding this, but it did nothing
discard a
before the end of the function

Your code has two issues:
Function arguments in Nim are immutable by default, so if you want to overwrite them locally, you need to shadow them or use var
Nim syntax for multiple variable assignment is different from Python and is done with tuple-like syntax
Fixed code would look like this:
import std/random
import std/math
randomize()
proc gcd*(a: int, b: int): int =
var (a, b) = (a, b)
while a != 0:
(a, b) = (floorMod(b,a), a)
return (b+a)-a
proc find_mod_inverse*(a: int, m: int): int =
if gcd(a,m) != 1:
return -1
var
u1 = 1
u2 = 0
u3 = a
v1 = 0
v2 = 1
v3 = m
q = -1
while v3 != 0:
q = floorDiv(u3,v3)
v1 = (u1 - q * v1)
v2 = (u2 - q * v2)
v3 = (u3 - q * v3)
u1 = v1
u2 = v2
u3 = v3
return floorMod(u1,m)
The compiler error is unclear, I agree.
Also, just a tip - keep in mind that standard Nim integers are limited by the architecture's native integer size, so if you want to operate on big numbers, you need to use a separate library.

Related

Scala string interpolation with a pass-by-name string

I'd like to pass a default string to a function and have "string interpolation" done on it in the function rather than at the call site.
For example,
def isBetween(a:Int, b:Int,
msg: String = s"${v} is not between ${a} and ${b}."
)(v:Int):Either[String, Boolean] = {
if (a <= v && v <= b) Right(true) else Left(msg)
}
This doesn't compile because none of a, b, and for sure not v are in scope when the compiler wants to do the interpolation.
The goal is to provide a default error string but allow the user to change it, if necessary. For example:
val normalBetween = isBetween(0, 100)
val customBetween = isBetween(0, 100, s"Doofus! it's gotta be ${a} <= v <= ${b} but v is ${v}!")
val result1 = normalBetween(101) // Left("101 is not between 0 and 100.")
val result2 = customBetween(101) // Left("Doofus! it's gotta be 0 <= v <= 100 but v is 101!")
I tried making msg pass-by-name; no luck.
I suppose I want something like this from the Python world:
name = 'world'
program ='python'
print('Hello {name}!This is{program}.'.format(name=name, program=program))
Any suggestions?
As #LuisMiguelMejíaSuárez suggested in the comment, you can just use java's string formatting:
def isBetween(a: Int, b: Int, msg: String = "%%d is not between %d and %d.")(v: Int): Either[String, Boolean] = {
if (a <= v && v <= b) Right(true) else Left(msg.format(a, b).format(v))
}
def normalBetween: Int => Either[String, Boolean] = isBetween(0, 100)
def customBetween: Int => Either[String, Boolean] = isBetween(0, 100, "Doofus! it's gotta be %d <= v <= %d but v is %%d!")
val result1 = normalBetween(101) // Left("101 is not between 0 and 100.")
val result2 = customBetween(101) // Left("Doofus! it's gotta be 0 <= v <= 100 but v is 101!")
println(result1)
println(result2)
The result will be as expected. Code run at Scastie. If you are taking this approach, and your scenario inn reality is more complex than the given example, you can use named parameters in this string. More can be read about it at Named placeholders in string formatting, How to format message with argument names instead of numbers?, and many more articles.
It's not possible to refer to a variable declared in the same (or a future) parameter list, however you can refer to a variable declared in a previous parameter list, like so:
def isBetween(
a:Int, b:Int
)(v: Int)(
msg: String = s"${v} is not between ${a} and ${b}."
): Either[String, Boolean] = {
if (a <= v && v <= b) Right(true) else Left(msg)
}
If you'd like to be able to offer callers the ability to provide a custom template string, you can do so as follows:
def isBetween(
a:Int, b:Int
)(v: Int)(
msg: (Int, Int, Int) => String =
(pA, pB, pV) => s"${pV} is not between ${pA} and ${pB}."
): Either[String, Boolean] = {
if (a <= v && v <= b) Right(true) else Left(msg(a, b, v)
}
Example usage:
val customMsg = (a: Int, b: Int, v: Int) => s"Sorry but $v is not between $a and $b!"
isBetween(5, 7)(6)(customMsg)
If you'd like to offer callers a completely "custom" isBetween, then you can do so by putting the message in the first parameter group:
def isBetween(
msg: (Int, Int, Int) => String =
(pA, pB, pV) => s"${pV} is not between ${pA} and ${pB}."
)(
a:Int, b:Int
)(v: Int): Either[String, Boolean] = {
if (a <= v && v <= b) Right(true) else Left(msg(a, b, v))
}
val customMsg = (a: Int, b: Int, v: Int) => s"Sorry but $v is not between $a and $b!"
val customMsgIsBetween = isBetween(customMsg) _
customMsgIsBetween(5, 7)(6)
It's worth remembering that we can use sentinel values for this. While null is discouraged in Scala for passing data around, it is still allowed, and for a temporary local use, it's fairly harmless as long as we don't let it escape scope.
def isBetween(a: Int, b: Int, msgArg: String = null)(v: Int): Either[String, Boolean] = {
val msg = if (msgArg == null) {
s"${v} is not between ${a} and ${b}.";
} else {
msgArg
}
if (a <= v && v <= b) {
Right(true)
} else {
Left(msg)
}
}

Ocaml - Check, given a list of transitions, the word is recognized

I created a function that returns a list of transitions. Transitions are of type int * char * int.
for example (0 'E' 1); (1 'A' 2). The valid alphabet for the transitions are A, C, G and T and the char 'E' represents epsilon.
type transition = int * char * int;;
let get_start (a,_,_) = a;;
let get_char (_,a,_) = a;;
let get_end (_,_,a) = a;;
The initial state and the final state are stored in the following variables.
...
let i_strt = ref !state_initial;;
let i_end = ref !state_end;;
exception Out_of_loop;;
let seq = read_line();;(* string to be tested *)
let len_seq = String.length seq -1;;
let lst_trs_length = List.length !aux_transitions -1;; (* aux_transitions -> all transitions*)
let i = ref 0;;
let f = ref 0;;
while !i <= len_seq do
let c_r = seq.[i]in (* c_r = 'A' seq = ACGT*)
try
while !j <= lst_trs_length do
let aux_trs = List.nth !aux_transitions !j in (* 0 'E' 1 -> 1 'A' 2 ....*)
if (get_start aux_trs) = !i_strt then (* *)
let aux_chr = get_char aux_trs in (* 'A' *)
if aux_chr = c_r then(
i_strt := get_end aux_trs; (* i_strt = 1*)
raise Out_of_loop
)
else if aux_chr = 'E' then(
i_strt := get_end aux_trs;
j := -1
);
j := !j+1
done;
with Out_of_loop ->();
i := !i +1
done;
I am trying to use these two cycles to check whether the string "seq" can be recognized or not by the list of transitions taking into account the initial state. I am having trouble writing this function ... I want a function that, given a list of transitions and a string, returns 'true' in case it is recognized or false in the negative case.

NodeJS Zlib support for LZW ("compress") algorithm?

I've got a Node/ExpressJS server whose client software only has access to the "compress" (LZW) algorithm for de/compression.
As far as I can tell the Node 12.X zlib library does not support LZW. There also don't appear to be any modules in npm that handle LZW in a fast, general way on content larger than a few hundred bytes.
Does anyone know of a way to efficiently and, ideally, natively use LZW on a Node server? Is something in Zlib compatible with LZW? My use case is for data up to a few tens of kilobytes.
Everything is in Docker, so I could install ncompress on the host and use child_process to call it directly, or something, but that seems convoluted.
You could do this without any external library.
These are two LZW encode and decode functions.
function en(c) { var x = "charCodeAt", b, e = {}, f = c.split(""), d
= [], a = f[0], g = 256; for (b = 1; b < f.length; b++) c = f[b], null != e[a + c] ? a += c :(d.push(1 < a.length ? e[a] :ax),
e[a + c] = g, g++, a = c); d.push(1 < a.length ? e[a] :ax);
for (b = 0; b < d.length; b++) d[b] = String.fromCharCode(d[b]);
return d.join(""); }
function de(b) { var a, e = {}, d = b.split(""), c = f = d[0], g = [
c ], h = o = 256; for (b = 1; b < d.length; b++) a =
d[b].charCodeAt(0), a = h > a ? d[b] :e[a] ? e[a] :f + c,
g.push(a), c = a.charAt(0), e[o] = f + c, o++, f = a; return
g.join(""); }
Please note: These functions are for strings only.
Source: https://gist.github.com/JavaScript-Packer/bbf68a4dc0e1fd102221

Problem with spec block in literate haskell file

I have this block of code on my literate haskell file
\end{code}
\paragraph{Valorização}
Codigo em C
\begin{spec}
double co(double x, int n){
double a = 1;
double b = -1 * x * x / 2;
double c = 12;
double d = 18;
for(; n > 0; n--){
a = a + b;
b = b * (-1 * x * x) / c;
c = c + d;
d = 8 + d;
}
return a;
}
\end{spec}
\subsection*{Problema 4}
What's happening is, when using lhs2tex and the pdflatex, what's inside the spec block is being completely ignored, and everything after it is forward, like it has a tab before it... Maybe this is something common? I'm not used to this... First time using it
By the way, if I remove the spec block everything else is formatted correctly
The following answer is based on speculation. If you would provide an MCVE—a short .lhs file that clearly demonstrates the issue—perhaps a better answer could emerge.
I think the issue is that lhs2TeX is not meant for C code. It gets confused by the spec block, thinks that it is Haskell code, and outputs problematic TeX commands. In fact, I can't even get your posted code past pdflatex—the .tex is that broken. You can use a different mechanism to output C code. The minted package should do.
\documentclass{article}
%include lhs2TeX.fmt
\usepackage{minted}
\setlength{\parindent}{0pt}
\begin{document}
Some C code:
\begin{minted}{c}
double co(double x, int n){
double a = 1;
double b = -1 * x * x / 2;
double c = 12;
double d = 18;
for(; n > 0; n--){
a = a + b;
b = b * (-1 * x * x) / c;
c = c + d;
d = 8 + d;
}
return a;
}
\end{minted}
It can be directly translated into Haskell:
\begin{code}
co :: Double -> Int -> Double
co x = worker 1 (-1 * x * x / 2) 12 18
where worker a _ _ _ 0 = a
worker a b c d n = worker (a + b) (b * (-1 * x * x) / c) (c + d) (8 + d) (n - 1)
\end{code}
As you can see, \textit{Haskell} code passes through just fine.
\end{document}
PS: The weird for-loop can be written while(n-- > 0) { ... }, no?

Iterate every row of a spark dataframe without using collect

I want to iterate every row of a dataframe without using collect. Here is my current implementation:
val df = spark.read.csv("/tmp/s0v00fc/test_dir")
import scala.collection.mutable.Map
var m1 = Map[Int, Int]()
var m4 = Map[Int, Int]()
var j = 1
def Test(m:Int, n:Int):Unit = {
if (!m1.contains(m)) {
m1 += (m -> j)
m4 += (j -> m)
j += 1
}
if (!m1.contains(n)) {
m1 += (n -> j)
m4 += (j -> n)
j += 1
}
df.foreach { row => Test(row(0).toString.toInt, row(1).toString.toInt) }
This does not give any error but m1 and m4 are still empty. I can get the result I am expecting if I do a df.collect as shown below -
df.collect.foreach { row => Test(row(0).toString.toInt, row(1).toString.toInt) }
How do I execute the custom function "Test" on every row of the dataframe without using collect
According to the Spark documentation for foreach:
"Note: modifying variables other than Accumulators outside of the foreach()may result in undefined behavior. See Understanding closures for more details."
https://spark.apache.org/docs/latest/rdd-programming-guide.html#actions

Resources