Elixir zero hour time as 24 - erlang

I need to convert an erlang time stamp to NaiveDateTime in elixir.
NaiveDateTime.from_erl {{2019, 4, 24}, {24, 0, 0}}
{:error, :invalid_time}
The docs for NaiveDateTime (and all other time modules in elixir) do not support 24 as the zero time even through it is ISO8601 compatible.
Any ideas on how to deal with this? I could pattern match on the tuple and then just change it to 0, but I feel that is a pretty ugly solution. Any ideas?
Thanks
Update
My solution: Thanks to #Aleksei Matiushkin with a tweak.
defmodule Helpers do
def naive_date_time({{y, m, d}, {24, 0, 0}}) do
case NaiveDateTime.from_erl({{y, m, d}, {0, 0, 0}}) do
{:ok, naive_dt} -> {:ok, NaiveDateTime.add(naive_dt, 24 * 3_600)}
{:error, reason} -> {:error, reason}
end
end
def naive_date_time(dt), do: NaiveDateTime.from_erl(dt)
end

The documentation clearly states this format is not supported:
while ISO 8601 allows datetimes to specify 24:00:00 as the zero hour of the next day, this notation is not supported by Elixir
That said, one should not expect this to be handled even in the future. I would go with an explicit helper function:
defmodule Helpers do
def naive_date_time({{y, m, d}, {24, 0, 0}}),
do: NaiveDateTime.add({{y, m, d}, {0, 0, 0}}, 24 * 3_600)
def naive_date_time(dt), do: NaiveDateTime.from_erl(dt)
end
I do not see any ugliness here. Please note, one should add a day when converting {24, 0, 0} → {0, 0, 0}.
NB! the solution above raises on malformed input. See the update in the original question for the fix, or below:
defmodule Helpers do
def naive_date_time({{y, m, d}, {24, 0, 0}}) do
{{y, m, d}, {0, 0, 0}}
|> NaiveDateTime.from_erl()
|> naive_date_time_add()
end
def naive_date_time(dt), do: NaiveDateTime.from_erl(dt)
defp naive_date_time_add({:ok, dt}),
do: {:ok, NaiveDateTime.add(dt, 24 * 3_600)}
defp naive_date_time_add(err), do: err
end

Related

Elixir: Split list into odd and even elements as two items in tuple

I am quiet new to Elixir programming and stuck badly at splitting into two elements tuple.
Given a list of integers, return a two element tuple. The first element is a list of the even numbers from the list. The second is a list of the odd numbers.
Input : [ 1, 2, 3, 4, 5 ]
Output { [ 2, 4], [ 1, 3, 5 ] }
I have reached to identify the odd or even but not sure how do I proceed.
defmodule OddOrEven do
import Integer
def task(list) do
Enum.reduce(list, [], fn(x, acc) ->
case Integer.is_odd(x) do
:true -> # how do I get this odd value listed as a tuple element
:false -> # how do I get this even value listed as a tuple element
end
#IO.puts(x)
end
)
end
You can use Enum.partition/2:
iex(1)> require Integer
iex(2)> [1, 2, 3, 4, 5] |> Enum.partition(&Integer.is_even/1)
{[2, 4], [1, 3, 5]}
If you really want to use Enum.reduce/2, you can do this:
iex(3)> {evens, odds} = [1, 2, 3, 4, 5] |> Enum.reduce({[], []}, fn n, {evens, odds} ->
...(3)> if Integer.is_even(n), do: {[n | evens], odds}, else: {evens, [n | odds]}
...(3)> end)
{[4, 2], [5, 3, 1]}
iex(4)> {Enum.reverse(evens), Enum.reverse(odds)}
{[2, 4], [1, 3, 5]}
Or you can use the Erlang :lists module:
iex> :lists.partition(fn (n) -> rem(n, 2) == 1 end, [1,2,3,4,5])
{[1,3,5],[2,4]}

How to smooth a histogram3D in mathematica using moving average?

I am trying to smooth a 3D histogram using moving average in mathematica. I know there is a function called smoothhistogram3D, which is close to what I want, however, it seems to only have the option of using distribution functions to smooth the curve. I was able to create a function for smoothing a 2D histogram by modifying this stackoverflow answer to include an interpolationOrder and the moving average feature.
MovAvgHistoPlot[MovAvg_, dx_] := Module[{histList, transposedHistList, histListAvg},
histList = HistogramList[data, {dx}];
transposedHistList = Transpose[{histList[[1]],ArrayPad[histList[[2]], {0, 1},
"Fixed"]}];
histListAvg = MovingAverage[transposedHistList, MovAvg];
histPlot = ListPlot[histListAvg, InterpolationOrder -> 3, Joined -> True,
AxesOrigin -> {histListAvg[[1, 1]], 0}, PlotRange -> All, InterpolationOrder -> 3,
PlotStyle -> Black, FrameLabel -> {"kTh", "Ion Intensity"},Frame -> {{True, False},
{True, False}}, Axes -> False, ImageSize -> Large]
]
Manipulate[MovAvgHistoPlot[MovAvg, dx], {{MovAvg, 1, "Moving Average"}, 1, 500, 1},
ContinuousAction -> False]
I tried to extend it to the 3rd dimension using the code below, but didn't have success.
MovAvgHistPlot3D[MovAvg_] := Module[{HistList3D, XAndZGroupedValues, XValues, ZValues,
XAndZValues, YValues, ListPlot3DPoints},
HistList3D = HistogramList[data];
XAndZValues = Flatten[Partition[Table[Riffle[HistList3D[[1, 2]],
HistList3D[[1, 1, i]], {1, -1, 2}], {i,Length[HistList3D[[1, 1]]]}], {1, 2}]];
YValues = Flatten[ArrayPad[Map[ArrayPad[##, {0, 1}, "Fixed"] &, HistList3D[[2]]],
{0, 1}, "Fixed"]];
ListPlot3DPoints = Partition[Riffle[XAndZValues, YValues, {3, -1, 3}], 3];
ListPlot3DPointsAvg = MovingAverage[ListPlot3DPoints, MovAvg];
ListPlot3D[ListPlot3DPointsAvg, InterpolationOrder -> 3, Joined -> True]
]
Manipulate[MovAvgHistPlot3D[MovAvg], {{MovAvg, 1, "Moving Average"}, 1, 1000, 1},
ContinuousAction -> False]
However, the 3D function outputs this image using my data set: http://imgur.com/MJeBbwW
I tried using a method similar to this first, except with an option to smooth it using the moving average:
ListPlot3D[HistogramList[filteredData1]]
However, it outputted an image like this:
http://imgur.com/Bkj0R9W
(Sorry, can't post more than two links due to lack of reputation points)
I want a data set that closely resembles the output of smoothhistogram3D, but with the option of smoothing with the moving average.
http://imgur.com/NRj6V2R
Any suggestions? Is there a simpler way I'm not realizing?
Sorry I realize the code, especially the second piece, is barely readable. I'm new to mathematica and was just trying to get it to work.
This is also my first time posting on stack overflow so please excuse any formatting or guideline mistakes.

How to convert datetime() to timestamp() in erlang

I need to convert {{2012, 9, 21}, {13, 21, 11}} into timestamp(). How can I do that?
Thank you.
Corrected version:
Seconds = calendar:datetime_to_gregorian_seconds(DateTime) - 62167219200,
%% 62167219200 == calendar:datetime_to_gregorian_seconds({{1970, 1, 1}, {0, 0, 0}})
{Seconds div 1000000, Seconds rem 1000000, 0}.
You might use this
to_timestamp({{Year,Month,Day},{Hours,Minutes,Seconds}}) ->
(calendar:datetime_to_gregorian_seconds(
{{Year,Month,Day},{Hours,Minutes,Seconds}}
) - 62167219200)*1000000;
This is part of module from this
Github/Arboreus

prolog all binary numbers

i need a predicate that will produce all the binary number of N digits .
For instance the predicate binary(2,L)
will return L = [[0, 0], [0, 1], [1, 0], [1, 1]].
please do not use findall ....
Once you have a list representing all the numbers with N bits, generating all the numbers of N+1 bits is just a matter of unfolding every N-number [a,b,c,...] into two N+1-numbers: [0,a,b,c,...] and [1,a,b,c,...].
Update:
unfold([], []).
unfold([H|T], [[0|H], [1|H]|L]) :-
unfold(T, L).
bn(N, L) :-
( N = 0
-> L = [[]]
; N1 is N - 1,
bn(N1, L1),
unfold(L1, L)
).
If you need to avoid findall/3, then you need an aggregator to collect the binary numbers:
binary(N, L) :-
collect_binaries(N, [], L).
You then generate one binary at a time and check whether it's already present in the aggregated list:
collect_binaries(N, R, L) :-
length(B, N),
make_binary(B), % make binary of length N
\+ memberchk(B, R),
!,
collect_binaries(N, [B|R], L).
If generating another binary fails, you are done:
collect_binaries(_, L, L).
Generating binaries is simple (I'm using the format you gave in your question: a list of 0/1 values). You iterate over all positions in the list and use either 1 or 0:
make_binary([]).
make_binary([H|T]) :-
member(H, [1,0]),
make_binary(T).
Result:
?- binary(2, L).
L = [[0, 0], [0, 1], [1, 0], [1, 1]]
Yes (0.00s cpu)

sudoku solver infinite recursion

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.)

Resources