multiplication of two list using list -erlang - erlang

how to multiple two numbers represented in a list for example 123 * 12 = 1476
I want to do this operation using list in this example it should be like this
mul([1,2,3],[1,2]) result will be [1,4,7,6] without converting list to number by using list_to_integer function. I did this so far but its just working if the length of one of the list is equal to one
mul([],A) ->[];
mul(A,[]) ->[];
mul([H|T],B) ->
if
(length([H|T]) ==1) or (length(B)== 1)
->
[X*Y||X<-[H],Y<-B]++mul(T,B);
(length([H|T]) >1) or (length(B) > 1)
->
[X*Y||X<-[H],Y<-B]++mul(T,B)
end.

For example, so:
multi(List, N) when is_number(N) ->
element(1,
lists:foldr(
fun(X, {Sum, Index}) -> {Sum + X * N * pow10(Index), Index + 1} end,
{0, 0}, List));
multi(L1, L2) when is_list(L2) ->
List = [fun() -> multi(L1, X) end() || X <- L2],
element(1,
lists:foldr(
fun(X, {Sum, Index}) -> {Sum + X * pow10(Index), Index + 1} end,
{0, 0}, List)).
pow10(N) when N =:= 0 -> 1;
pow10(N) -> 10 * pow10(N - 1).
If a notice that foldr expressions similar , it is possible to simplify the code:
multi(List, N) when is_number(N) ->
element(1,
lists:foldr(
fun(X, {Sum, Index}) -> {Sum + X * N * pow10(Index), Index + 1} end,
{0, 0}, List));
multi(L1, L2) when is_list(L2) ->
multi([fun() -> multi(L1, X) end() || X <- L2], 1).
pow10(N) when N =:= 0 -> 1;
pow10(N) -> 10 * pow10(N - 1).
for getting list, use integer_to_list:
...
multi(L1, L2) when is_list(L2) ->
create_list(multi([fun() -> multi(L1, X) end() || X <- L2],1)).
create_list(Number)->
[X-48 || X<-integer_to_list(Number)].
...

Here is solution that doesn't use list_to_integer or integer_to_list. Algorithm is called long multiplication and is usually used when language does not support multiplication/sum of big (larger than INT.MAX) numbers. Below is basic implementation that can be optimized in various ways, but will work just fine for education purposes.
Keep in mind that Erlang supports long multiplication and long sum out of the box (as opposed to, say, C), so implementing multiplication is useless in real life applications.
sum(A, B) when is_list(A) andalso is_list(B) ->
lists:reverse(sum_impl(lists:reverse(A), lists:reverse(B), {[], 0})).
mult(A, B) when is_list(A) andalso is_list(B) ->
lists:reverse(mult_impl(lists:reverse(A), lists:reverse(B), {[], []})).
sum_impl([], [], {Res, 0}) -> Res;
sum_impl([], [], {Res, C}) -> sum_impl([C], [0], {Res, 0});
sum_impl(A, [], Acc) -> sum_impl(A, [0], Acc);
sum_impl([], B, Acc) -> sum_impl([0], B, Acc);
sum_impl([HA | TA], [HB | TB], {Res, C}) ->
sum_impl(TA, TB, {Res ++ [(HA + HB + C) rem 10], (HA + HB + C) div 10}).
mult_impl(_A, [], {Res, _C}) -> Res;
mult_impl(A, [HB | TB], {Res, C}) ->
mult_impl(A, TB, {sum_impl(Res, C ++ [X * HB || X <- A], {[], 0}), [0 | C]}).

Here's a version that allows you to specify a base (2-10):
In the shell:
167> c(my).
{ok,my}
168> Base10 = 10.
10
169> Base2 = 2.
2
170> my:list_mult([1,1], [1,1,1], Base10).
[1,2,2,1]
171> 11 * 111.
1221
172> my:list_mult([1,1], [1,1,1], Base2).
[1,0,1,0,1]
173> io:format("~.2B~n", [2#11 * 2#111]).
10101
ok
-module(my).
%%-compile(export_all).
-export([list_mult/3]).
-include_lib("eunit/include/eunit.hrl").
list_mult(List1, List2, Base) ->
Number = digits_to_int(List1, Base) * digits_to_int(List2, Base),
list_of_digits(Number, Base).
list_mult_test() ->
Base10 = 10,
?assertEqual(
list_of_digits(123 * 12, Base10),
list_mult([1,2,3], [1,2], Base10)
),
?assertEqual(
list_of_digits(2 * 5, Base10),
list_mult([2], [5], Base10)
),
?assertEqual(
list_of_digits(0 * 0, Base10),
list_mult([], [], Base10)
),
?assertEqual(
list_of_digits(0 * 23, Base10),
list_mult([], [2,3], Base10)
),
?assertEqual(
list_of_digits(30 * 4, Base10),
list_mult([0,3,0], [0,4], Base10)
),
?assertEqual(
list_of_digits(1 * 3, Base10),
list_mult([0,0,1], [0,3], Base10)
),
Base2 = 2,
?assertEqual(
list_of_digits(2#11 * 2#1000, Base2),
list_mult([1,1], [1,0,0,0], Base2)
),
?assertEqual(
list_of_digits(2#1001 * 2#10, Base2),
list_mult([1,0,0,1], [1,0], Base2)
),
%%Errors:
?assertThrow(
"illegal_number: Some elements are >= to Base",
list_mult([1,3], [1,0,0,0,0], Base2)
),
?assertThrow(
"illegal_number: Some elements are >= to Base",
list_mult([a, 3], [f,1], Base10) %%hex notation
).
%--------------
digits_to_int_test() ->
Base10 = 10,
?assertEqual(
123,
digits_to_int([1,2,3], Base10)
),
?assertEqual(
10,
digits_to_int([1,0], Base10)
),
?assertEqual(
3,
digits_to_int([3], Base10)
),
?assertEqual(
0,
digits_to_int([0], Base10)
),
?assertEqual(
0,
digits_to_int([], Base10)
),
Base2 = 2,
?assertEqual(
2#11,
digits_to_int([1,1], Base2)
),
?assertEqual(
2#1101,
digits_to_int([1,1,0,1], Base2)
),
?assertEqual(
2#11110000,
digits_to_int([1,1,1,1, 0,0,0,0], Base2)
),
?assertEqual(
2#1,
digits_to_int([1], Base2)
),
?assertEqual(
0,
digits_to_int([0], Base2)
),
?assertEqual(
0,
digits_to_int([], Base2)
),
%%Errors:
?assertThrow(
"illegal_number: Some elements are >= to Base",
digits_to_int([1,2,3], Base2)
),
?assertThrow(
"illegal_number: Some elements are >= to Base",
list_mult([a, 3], [f,1], Base10) %%hex notation
).
digits_to_int(List, Base) ->
HighestPower = length(List) - 1,
digits_to_int(List, Base, HighestPower, 0).
digits_to_int([], _, _, Sum) ->
Sum;
digits_to_int([X|Xs], Base, Power, Sum) when X<Base ->
Term = round( math:pow(Base, Power) * X ), %%round() converts float to integer.
digits_to_int(Xs, Base, Power-1, Sum+Term);
digits_to_int(_, _, _, _) ->
throw("illegal_number: Some elements are >= to Base").
%--------------
list_of_digits_test() ->
Base10 = 10,
?assertEqual(
[1,1],
list_of_digits(11, Base10)
),
?assertEqual(
[1,0,0],
list_of_digits(100, Base10)
),
?assertEqual(
[1],
list_of_digits(1, Base10)
),
?assertEqual(
[],
list_of_digits(0, Base10)
),
Base2 = 2,
?assertEqual(
[1,0,1,1],
list_of_digits(2#1011, Base2)
),
?assertEqual(
[1,1,1],
list_of_digits(2#111, Base2)
),
?assertEqual(
[1],
list_of_digits(1, Base2)
).
list_of_digits(0, _Base) ->
[];
list_of_digits(Number, Base) -> %% 193
HighestPower = get_highest_power(Number, Base),
list_of_digits(Number, Base, HighestPower, []).
list_of_digits(Number, _, 0, Digits) ->
lists:reverse([Number|Digits]);
list_of_digits(Number, Base, Power, Digits) ->
X = round(math:pow(Base, Power) ),
Digit = Number div X,
Remainder = Number rem X,
list_of_digits(Remainder, Base, Power-1, [Digit|Digits]).
%---------------
get_highest_power_test() ->
Base10 = 10,
?assertEqual(
2,
get_highest_power(199, Base10)
),
?assertEqual(
3,
get_highest_power(1999, Base10)
),
?assertEqual(
3,
get_highest_power(1000, Base10)
),
?assertEqual(
1,
get_highest_power(19, Base10)
),
?assertEqual(
0,
get_highest_power(5, Base10)
).
get_highest_power(Number, Base) ->
Power = 0,
KeepGoing = (Number div round(math:pow(Base,Power)) ) > 0,
get_highest_power(Number, Base, Power, KeepGoing).
get_highest_power(Number, Base, Power, KeepGoing) when KeepGoing =:= true ->
NewPower = Power+1,
StillKeepGoing = (Number div round(math:pow(Base, NewPower)) ) > 0,
get_highest_power(Number, Base, NewPower, StillKeepGoing);
get_highest_power(_, _, Power, KeepGoing) when KeepGoing =:= false ->
max(0, Power - 1).

Related

java 8 streams reduce method returns same result

Having java code like this:
public static void main(String... aa) {
Stream<Integer> stream = Arrays.asList(1, 2, 3, 4, 5, 6).stream();
List<Integer> numbers = stream.reduce(
new ArrayList<Integer>(),
(List<Integer> l, Integer e) -> {
l.add(e);
return l;
},
(List<Integer> l1, List<Integer> l2) -> {
l1.addAll(l2);
return l1;
});
System.out.println("numbers" + numbers);
stream = Arrays.asList(1, 2, 3, 4, 5, 6).stream();
numbers = stream.reduce(new ArrayList<Integer>(),
(List<Integer> l, Integer e) -> {
l.add(e);
return l;
},
(List<Integer> l1, List<Integer> l2) -> {
return l1;
});
System.out.println("numbers" + numbers);
stream = Arrays.asList(1, 2, 3, 4, 5, 6).stream();
numbers = stream.reduce(new ArrayList<Integer>(),
(List<Integer> l, Integer e) -> {
l.add(e);
return l;
},
(List<Integer> l1, List<Integer> l2) -> {
return null;
});
System.out.println("numbers" + numbers);
}
gives result as this:
numbers[1, 2, 3, 4, 5, 6]
numbers[1, 2, 3, 4, 5, 6]
numbers[1, 2, 3, 4, 5, 6]
why the result it is same ?
I think the aswer is:
When a stream executes in parallel, the Java runtime splits the stream into multiple substreams. In such cases, we need to use a function to combine the results of the substreams into a single one. This is the role of the combiner — in the above snippet, it's the Integer::sum method reference.
so the proper implementation is the first one.

Is there a way in Dart using the list map method to build a list containing two (or more) items for each source list item?

In Python, this code realizes the objective:
intLst = [1, 2, 3]
f1 = lambda x: x
f2 = lambda x: x * 10
newLst = [f(x) for x in intLst for f in [f1, f2]]
print(newLst) # [1, 10, 2, 20, 3, 30]
but in Dart I was not able to do the same using an anonymous function passed to the map() List method.
You can achieve the same thing using collection for, which allows you to do the same type of things you can do with a list comprehension in python.
void main() {
List<int> intLst = [1, 2, 3];
int Function(int) f1 = (x) => x;
int Function(int) f2 = (x) => x * 10;
List<int> newLst = [
for (var x in intLst)
for (var f in [f1, f2]) f(x),
];
print(newLst); // [1, 10, 2, 20, 3, 30]
}
The alternative would be to use expand rather than map. expand is the same as what some other languages call flatMap.
void main() {
List<int> intLst = [1, 2, 3];
int Function(int) f1 = (x) => x;
int Function(int) f2 = (x) => x * 10;
List<int> newLst = intLst.expand((v) => [f1(v), f2(v)]).toList();
print(newLst); // [1, 10, 2, 20, 3, 30]
}
Here's another way to obtain the same result without using functions:
void main() {
List<int> intList = [1, 2, 3];
List<int> newList = [
for (var x in intList) ...[x, x * 10, x * x],
];
print(newList); // [1, 10, 1, 2, 20, 4, 3, 30, 9]
}

Find minimum sum

Find the minimum sum of elements with one element from each row. I think the answer is
-214, but z3py returns unsat. What is wrong?
from z3 import Solver, Int, ForAll, Or
ARR = [
[36, 12, 90, 88, 82],
[-92, 50, 40, 31, 43],
[81, 28, -26, 8, -59],
[18, -99, -70, -33, 58],
[44, -33, 24, -92, -68],
]
s = Solver()
xs = [Int(f"x_{i}") for i, row in enumerate(ARR)]
ys = [Int(f"y_{i}") for i, row in enumerate(ARR)]
for x, y, row in zip(xs, ys, ARR):
s.add(Or(*[x == val for val in row]))
s.add(Or(*[y == val for val in row]))
s.add(ForAll(ys, sum(xs) <= sum(ys)))
print(s.check()) # unsat
Your encoding isn't quite correct. If you stick the following line in your program:
print(s.sexpr())
You'll see that it prints, amongst other things:
(assert (forall ((y_0 Int) (y_1 Int) (y_2 Int) (y_3 Int) (y_4 Int))
(<= (+ 0 x_0 x_1 x_2 x_3 x_4) (+ 0 y_0 y_1 y_2 y_3 y_4))))
And this is the reason why it is unsat. This is a quantified formula, and thus it says it is only satisfiable if the formula is true for all values y_0 .. y_4. This is obviously not true, and hence the unsat result.
Instead of this formulation, you should use z3's optimization engine. Pick one variable from each row, add them, and minimize that result. Something like this:
from z3 import *
ARR = [
[36, 12, 90, 88, 82],
[-92, 50, 40, 31, 43],
[81, 28, -26, 8, -59],
[18, -99, -70, -33, 58],
[44, -33, 24, -92, -68],
]
o = Optimize()
es = [Int(f"e_{i}") for i, row in enumerate(ARR)]
for e, row in zip (es, ARR):
o.add(Or(*[e == val for val in row]))
minTotal = Int("minTotal")
o.add(minTotal == sum(es))
o.minimize(minTotal)
print(o.check())
print(o.model())
When I run this, I get:
sat
[e_0 = 12,
e_3 = -99,
e_2 = -59,
e_1 = -92,
e_4 = -92,
minTotal = -330]
That is, solver picks 12 from the first row, -92 from the second, -59 from the third, -99 from the fourth, and -92 from the last row; for a minimum sum of -330.
It's easy to see that this is the correct solution since the solver picks minimum element from each row, and thus their sum will be minimal as well. (I'm not sure why you were expecting -214 to be the answer.)

Newer versions of Z3 no longer keep/print all function instances

Notice in the new versions of Z3, the model only prints the arguments to the function that have a value other than the default. Is there a way to return to the old method of receiving all instances, including those that map to the default value?
Code:
import z3
config_init = z3.Function('config_init', z3.IntSort(), z3.IntSort(), z3.IntSort(), z3.IntSort())
def fooY(W, X, Y, Z):
return config_init(W, X, Y) == Z
s = z3.Solver()
s.add(fooY(1, 2, 3, 4))
s.add(fooY(2, 3, 4, 5))
s.add(fooY(1, 2, 8, 4))
s.add(fooY(2, 3, 9, 5))
print("Z3 Version", z3.get_version())
if s.check() == z3.sat:
mod = s.model()
print(mod)
else:
print('failed')
print(s.unsat_core())
Old Z3 Output
('Z3 Version', (4L, 5L, 1L, 0L))
[config_init = [(1, 2, 3) -> 4,
(2, 3, 4) -> 5,
(1, 2, 8) -> 4,
(2, 3, 9) -> 5,
else -> 4]]
New Z3 Output
Z3 Version (4, 8, 7, 0)
[config_init = [(2, 3, 4) -> 5, (2, 3, 9) -> 5, else -> 4]]

How to convert binary code to a number in Dart

Given an array of ones and zeroes, convert the equivalent binary value to an integer.
Eg: [0, 0, 0, 1] is treated as 0001 which is the binary representation of 1.
Testing: [0, 0, 0, 1] ==> 1
Testing: [0, 0, 1, 0] ==> 2
Testing: [0, 1, 0, 1] ==> 5
Testing: [1, 0, 0, 1] ==> 9
Testing: [0, 0, 1, 0] ==> 2
Testing: [0, 1, 1, 0] ==> 6
Testing: [1, 1, 1, 1] ==> 15
Testing: [1, 0, 1, 1] ==> 11
With Prime numbers I solved everything code from below
int binaryArrayToNumber(List<int> arr) {
return
(arr[0] * 8) +
(arr[1] * 4) +
(arr[2] * 2) +
(arr[3] * 1);
}
How do I make this automatic for larger numbers
A traditional approach would be to iterate over the binary digits and to perform bitshifts and ORs:
int binaryArrayToNumber(List<int> digits) {
var result = 0;
for (var digit in digits) {
result <<= 1;
result |= digit;
}
return result;
}
A more concise, less error-prone (but less efficient) approach would be to convert the list of digits to a String and then parse it:
int binaryArrayToNumber(List<int> digits) =>
int.parse(digits.join(""), radix: 2);
It's good to learn the protocols for the core data types, like List.fold.
int binaryArrayToNumber(List<int> digits) =>
digits.fold(0,(prev, cur) => 2*prev + cur);

Resources