I've got this case statement which is giving an error 'variable constant1 is unused'. It seems to be ignoring the variables and returning the top line, so the variables obviously haven't got scope. If I replace the constant with a number 1 then it works. What is the best way of doing this in Elixir?
defmodule Main
do
def constant1, do: 1
def constant2, do: 1
def constant3, do: 1
x = 1
y = 0
z = 0
{a, b, c, d} =
case {x, y, z} do
{constant1, constant2, constant3} -> {1, 2, 3, 4}
{constant1, constant2, _} -> {5, 6, 7, 8}
{constant1, _, _} -> {9, 10, 11, 12}
{_, _, _} -> {13, 14, 15, 16}
end
IO.inspect {a, b, c, d}
end
Here is the output:
warning: variable constant1 is unused
Untitled 9:15
{1, 2, 3, 4}
Changing the constants to variables also doesn't work.
You have defined constant1 being a function. When you try to use it in pattern matching, Elixir expects the variable to be there and you’ve got an error. One can’t pattern match to functions.
What you’ve wanted is likely:
defmodule Main do
constant1 = 1
constant2 = 1
constant3 = 1
x = 1
y = 0
z = 0
{a, b, c, d} =
case {x, y, z} do
{^constant1, ^constant2, ^constant3} -> {1, 2, 3, 4}
{^constant1, ^constant2, _} -> {5, 6, 7, 8}
{^constant1, _, _} -> {9, 10, 11, 12}
{_, _, _} -> {13, 14, 15, 16}
end
IO.inspect {a, b, c, d}
end
#⇒ { 9, 10, 11, 12 }
Also, please remember that to pattern match to already defined value, one should use the pin operator ^ in front of matcher, otherwise the code
a = 42
case x do
a -> ...
end
will overwrite the value of a, setting it to the value of x (in the scope of case block, outside of case a will remain 42.) With ^, the code below will match if and only x == 42:
a = 42
case x do
^a -> ...
end
Answering the subsequent questions about “how to,” “can I use globals,” etc.
Elixir (as all known functional languages) has no notion of “global,” since everything is immutable from the outside point of view. True constants are being implemented as macros. Macros are compiled during the compilation stage to AST and therefore might be used as constants inside match:
defmodule Constants do
defmacro constant1 do
quote do: 1
end
defmacro constant2 do
quote do: 1
end
defmacro constant3 do
quote do: 1
end
end
defmodule Main do
require Constants
x = 1
y = 0
z = 0
{a, b, c, d} =·
case {x, y, z} do
{Constants.constant1, Constants.constant2, Constants.constant3} -> {1, 2, 3, 4}
{Constants.constant1, Constants.constant2, _} -> {5, 6, 7, 8}
{Constants.constant1, _, _} -> {9, 10, 11, 12}
{_, _, _} -> {13, 14, 15, 16}
end
IO.inspect {a, b, c, d}
end
The above works, because after compilation there is no Constants.constant1 anymore in Main code: there are real values: 1s and the code being run is:
case {x, y, z} do
{1, 1, 1} -> {1, 2, 3, 4}
{1, 1, _} -> {5, 6, 7, 8}
{1, _, _} -> {9, 10, 11, 12}
{_, _, _} -> {13, 14, 15, 16}
end
Hope it helps.
Related
There are list of numbers which represent size of blocks and I want to find out biggest Valley shape in the list.
Constraint is that unlike normal valley two end can be flat like in following example [5, 5] is still counts as valley end
Some examples;
[1, 5, 5, 2, 8] => [5, 5, 2, 8] widest valley [2, 6, 8, 5] => [2,6,8] widest valley [9, 8, 13, 13, 2, 2, 15, 17] => [13, 13, 2, 2, 15, 17] widest valley
It's not a homework or something but I am wondering how I can solve it in Erlang
I solved it in another language but Erlang is a bit recursive that's why I need some help
I'm no expert, but I'd solve the problem like this:
-record(valley, {from=1, to=1, deepest=1}).
widest_valley([]) ->
[];
widest_valley([H]) ->
[H];
widest_valley([H,T]) ->
[H,T];
widest_valley(L) ->
widest_valley(L, #valley{}, #valley{}, 1, 2).
widest_valley(L, _Curr, Widest, _FlatFrom, Pos) when Pos > length(L) ->
lists:sublist(L, Widest#valley.from, 1 + Widest#valley.to - Widest#valley.from);
widest_valley(L, Curr, Widest, FlatFrom, Pos) ->
Before = lists:nth(Pos - 1, L),
AtPos = lists:nth(Pos, L),
Deepest = lists:nth(Curr#valley.deepest, L),
Curr1 = if Before == Deepest ->
Curr#valley{deepest = if AtPos < Deepest ->
Pos;
true ->
Curr#valley.deepest
end};
AtPos < Before ->
#valley{from=FlatFrom, deepest=Pos};
true ->
Curr
end,
FlatFrom1 = if AtPos == Before ->
FlatFrom;
true ->
Pos
end,
Widest1 = if Pos - Curr1#valley.from > Widest#valley.to - Widest#valley.from ->
Curr1#valley{to=Pos};
true ->
Widest
end,
widest_valley(L, Curr1, Widest1, FlatFrom1, Pos + 1).
If I have a large struct that I want to create an array of (e.g. to later create a StructArray), how can I create an array of structs when I have keyword defaults.
E.g.
Base.#kwdef struct MyType
a = 0
b = 0
c = 0
d = 0
... # can be up to 10 or 20 fields
end
Base.#kwdef is nice because I can create objects with MyType(b=10,e=5) but sometimes I have arrays of the argument. I would like to be able to broadcast or succinctly construct an array of the structs.
That is I would like the following would create an array of three MyTypes: MyType.(c=[5,6,7],d = [1,2,3])
Instead, it creates a single MyType where c and d are arrays rather than scalar values.
What are ways to keep the convenience of both Base.#kwdef and easy array of struct construction?
Seems like a good use case for a comprehension:
julia> [MyType(c=cval, d=dval) for (cval, dval) in zip([5, 6, 7], [1, 2, 3])]
3-element Vector{MyType}:
MyType(0, 0, 5, 1)
MyType(0, 0, 6, 2)
MyType(0, 0, 7, 3)
Another possiblity (based on this answer ) is to explicitly do the broadcast call yourself:
julia> broadcast((cval, dval) -> MyType(c = cval, d = dval), [5, 6, 7], [1, 2, 3])
3-element Vector{MyType}:
MyType(0, 0, 5, 1)
MyType(0, 0, 6, 2)
MyType(0, 0, 7, 3)
or the equivalent ((cval, dval) -> MyType(c = cval, d = dval)).([5, 6, 7], [1, 2, 3]) as mentioned in the comment there.
Out of these, the array comprehension seems to me the clearest and most obvious way to go about it.
Following this post: https://github.com/JuliaLang/julia/issues/34737 there is no nice built-in syntax for your case.
One option is comprehension (see the other answer), second option (which I prefer here more) is building an anonymous function and vectoring over it such as:
julia> ((x,y)->MyType(;c=x,d=y)).([1,2],[3,5])
2-element Vector{MyType}:
MyType(0, 0, 1, 3)
MyType(0, 0, 2, 5)
It is also possible to call broadcast directly as:
julia> broadcast((x,y)->MyType(;c=x,d=y), [1,2],[3,5])
2-element Vector{MyType}:
MyType(0, 0, 1, 3)
MyType(0, 0, 2, 5)
Excuse me I am new to Wolfram. I have seen people asking questions about how to do convolution of a function with itself in Wolfram. However, I wonder how to do it multiple times in a loop. That is to say I want to do f20* i.e. f*f*f*f*....f totaling 20 f. How to implement it?
Here is my thinking. Of course do not work....
f[x_] := Piecewise[{{0.1`, x >= 0 && x <= 10}, {0, x < 0}, {0, x > 10}}];
g = f;
n = 19;
For[i = 1, i <= n, i++, g = Convolve[f[x], g, x, y]]; Plot[
g[x], {x, -10, n*10 + 10}, PlotRange -> All]
Could anybody help me?
My new code after revising agentp's code
f[x_] := Piecewise[{{0.1, x >= 0 && x <= 10}, {0, x < 0}, {0,x > 10}}];
n = 19;
res = NestList[Convolve[#, f[x], x, y] /. y -> x &, f[x], n];
Plot[res, {x, -10, (n + 1)*10 + 10}, PlotRange -> All,PlotPoints -> 1000]
My buggy image
maybe this?
Nest[ Convolve[#, f[x], x, y] /. y -> x &, f[x] , 3]
If that's not right maybe show what you get by hand for n=2 or 3.
res = NestList[ Convolve[#, f[x], x, y] /. y -> x &, f[x] , 10];
Plot[res, {x, 0, 100}, PlotRange -> All]
this gets very slow with n, I don't have the patience to run it out to 20.
Your approach is nearly working. You just have to
make sure to copy f by value before entering the loop, because otherwise you face infinite recursion.
Assign the result of Convolve to a function which takes a parameter.
This is the code with the mentioned changes:
f[x_] := Piecewise[{{0.1, x >= 0 && x <= 10}, {0, x < 0}, {0, x > 10}}];
g[x_] = f[x];
n = 20;
For[i = 1, i <= n, i++, g[y_] = Convolve[f[x], g[x], x, y]];
Plot[g[x], {x, -10, n*10 + 10}, PlotRange -> All]
Edit: While this works, agentp's answer is more consise and i suspect also faster.
I see that there's an update in the Dict module, but what about an update_all method that changes all values?
I tried doing this with Enum.map but the type changed:
iex(6)> Enum.map(%{:a => 2}, fn {k, v} -> {k, v + 1} end)
[a: 3]
You could pipe to Enum.into(%{}) or use a for comprehension, i.e.:
iex> for {k, v} <- %{a: 1, b: 2}, into: %{}, do: {k, v + 1}
%{a: 2, b: 3}
You can also do:
iex> Map.new(%{:a => 2}, fn {k, v} -> {k, v + 1} end)
%{:a => 3}
But feel like there should be something in the standard library to make this easier (Map.??(%{:a => 2}, &(&1 + 1))).
Here's one idea:
def update_map map, [head|tail], func do
update_map(
Dict.update(map, head, :unknown, func),
tail,
func
)
end
def update_map map, [], _ do
map
end
Then to call it:
iex(1)> d = %{:a => 1, :b => 2, :c => 3}
%{a: 1, b: 2, c: 3}
iex(2)> update_map(d, Dict.keys(d), fn v -> v + 1 end)
%{a: 2, b: 3, c: 4}
Let me add Enum.into into the mix
headers
|> Enum.group_by(fn {k, _v} -> k end, fn {_k, v} -> v end)
|> Enum.into(%{}, fn {k, v} -> {k, Enum.join(v, ", ")} end)
This turns:
[{"cookie", "a"}, {"cookie", "b"}] into %{"cookie", "a, b"}
I am writing a sudoku solver. It has been a long time since I have touched prolog, thus I don't remember everything regarding unification, backtracking, etc. I think that I cause the system to backtrack forever (but I don't get any stack exceptions - at least not immediately). This is what I have so far (the puzzle can be found at http://en.wikipedia.org/wiki/File:Sudoku-by-L2G-20050714.svg):
% representation of the example puzzle
puzzle([5, 3, _, _, 7, _, _, _, _],
[6, _, _, 1, 9, 5, _, _, _],
[_, 9, 8, _, _, _, _, 6, _],
[8, _, _, _, 6, _, _, _, 3],
[4, _, _, 8, _, 3, _, _, 1],
[7, _, _, _, 2, _, _, _, 6],
[_, 6, _, _, _, _, 2, 8, _],
[_, _, _, 4, 1, 9, _, _, 5],
[_, _, _, _, 8, _, _, 7, 9]).
% solve(S)
% the starting point of the program
% saves the solution in the variable S
solve(R1, R2, C1) :-
% save the rows into variables
puzzle(R1, R2, R3, R4, R5, R6, R7, R8, R9),
% solve for each row
allunique(R1), allunique(R2), allunique(R3),
allunique(R4), allunique(R5), allunique(R6),
allunique(R7), allunique(R8), allunique(R9),
% the columns must be created first
nelement(R1, 1, C11), nelement(R2, 1, C21), nelement(R3, 1, C31),
nelement(R4, 1, C41), nelement(R5, 1, C51), nelement(R6, 1, C61),
nelement(R7, 1, C71), nelement(R8, 1, C81), nelement(R9, 1, C91),
C1 = [C11, C21, C31, C41, C51, C61, C71, C81, C91],
allunique(C1).
% allunique(List)
% Succeeds if all the numbers of List are between 1-9
% and each number exists only once
allunique([]). % Recursion stops when the list is empty
% A member should be between 1-9 and not a member of the tail
allunique([H|T]) :-
allunique(T),
member(H, [1, 2, 3, 4, 5, 6, 7, 8, 9]),
not(member(H, T)).
% nelement(List, N-th, X)
% Saves the nth element of a list in variable X
nelement([H|_], 1, H). % The first element is the head
% All other elements will be found in the tail
nelement([_|T], N, X) :-
N > 1,
N1 is N-1,
nelement(T, N1, X).
The line allunique(C1) causes the problem. It seems that the system puts a 7 in the first empty box of the 1st column and never changes it (or at least not in the near future). An example C1 list is [5, 6, 7, 8, 4, 7, 9, 8, 6]. I am curious to find out why this is happening.
Your example list [5, 6, 7, 8, 4, 7, 9, 8, 6] doesn't satisfy allunique since it contains 8 twice.
solve/3 is incorrect since it checks all rows, but only one column and no "region" (the 3x3 squares).
The solve/1 predicate promised in the comments doesn't appear, so I can't test your code; allunique/1 and nelement/3 seem fine.
Even if you complete this program, I doubt it's ever going to return an answer. I've seen similar Prolog programs run for hours without finding the solution. Check out CLP(fd) if you want to do this fast (link is for SWI, but SICStus, GNU, and ECLiPSe have similar libraries.)