Elixir map_reduce referencing last element - recursion

How can I loop (recursively or with reduce) a List of Maps while comparing to the last element in the list?
For example, let's say I have a List of maps like this:
datetime = Timex.beginning_of_day(Timex.now)
data = [
%{a: 0, cluster: 0, time: datetime},
%{a: 1, cluster: 0, time: Timex.shift(datetime, minutes: 3)},
%{a: 2, cluster: 0, time: Timex.shift(datetime, minutes: 6)},
%{a: 3, cluster: 0, time: Timex.shift(datetime, minutes: 9)},
%{a: 4, cluster: 1, time: Timex.shift(datetime, minutes: 12)},
%{a: 5, cluster: 1, time: Timex.shift(datetime, minutes: 15)},
%{a: 6, cluster: 0, time: Timex.shift(datetime, minutes: 18)},
%{a: 7, cluster: 0, time: Timex.shift(datetime, minutes: 21)},
%{a: 8, cluster: 0, time: Timex.shift(datetime, minutes: 23)},
%{a: 9, cluster: 2, time: Timex.shift(datetime, minutes: 26)},
%{a: 10, cluster: 2, time: Timex.shift(datetime, minutes: 29)},
%{a: 11, cluster: 2, time: Timex.shift(datetime, minutes: 32)},
%{a: 12, cluster: 1, time: Timex.shift(datetime, minutes: 35)},
%{a: 13, cluster: 1, time: Timex.shift(datetime, minutes: 38)},
]
I want to modify the cluster attribute of each map to represent the group that it is in with respect to the order that it is in.
Using the group_by is great if the cluster ids were not repeating.
I want to group them as they change group, resulting in something like this:
[
%{a: 0, cluster: 0, time: datetime},
%{a: 1, cluster: 0, time: Timex.shift(datetime, minutes: 3)},
%{a: 2, cluster: 0, time: Timex.shift(datetime, minutes: 6)},
%{a: 3, cluster: 0, time: Timex.shift(datetime, minutes: 9)},
%{a: 4, cluster: 1, time: Timex.shift(datetime, minutes: 12)},
%{a: 5, cluster: 1, time: Timex.shift(datetime, minutes: 15)},
%{a: 6, cluster: 2, time: Timex.shift(datetime, minutes: 18)},
%{a: 7, cluster: 2, time: Timex.shift(datetime, minutes: 21)},
%{a: 8, cluster: 2, time: Timex.shift(datetime, minutes: 23)},
%{a: 9, cluster: 3, time: Timex.shift(datetime, minutes: 26)},
%{a: 10, cluster: 3, time: Timex.shift(datetime, minutes: 29)},
%{a: 11, cluster: 3, time: Timex.shift(datetime, minutes: 32)},
%{a: 12, cluster: 4, time: Timex.shift(datetime, minutes: 35)},
%{a: 13, cluster: 4, time: Timex.shift(datetime, minutes: 38)},
]
To do this, I need to compare the current item in the list to the previous one. I had started with something like this (below) and stopped because I know it will not reference the previous item to compare the current item to the previous one:
Enum.map_reduce(data, 0, fn(x, acc) -> cluster_grouping(x, acc) end)
def cluster_grouping(x, acc) do
cond do
x.cluster == acc -> {Map.put(x, :cluster, acc), acc}
x.cluster > acc -> {Map.put(x, :cluster, acc), acc + 1}
end
end

You'll need to keep two integers in the accumulator: the current resulting cluster (which will increment by 1 on every change) and the last raw value of cluster.
datetime = Timex.beginning_of_day(Timex.now)
data = [
%{a: 0, cluster: 0, time: datetime},
%{a: 1, cluster: 0, time: Timex.shift(datetime, minutes: 3)},
%{a: 2, cluster: 0, time: Timex.shift(datetime, minutes: 6)},
%{a: 3, cluster: 0, time: Timex.shift(datetime, minutes: 9)},
%{a: 4, cluster: 1, time: Timex.shift(datetime, minutes: 12)},
%{a: 5, cluster: 1, time: Timex.shift(datetime, minutes: 15)},
%{a: 6, cluster: 0, time: Timex.shift(datetime, minutes: 18)},
%{a: 7, cluster: 0, time: Timex.shift(datetime, minutes: 21)},
%{a: 8, cluster: 0, time: Timex.shift(datetime, minutes: 23)},
%{a: 9, cluster: 2, time: Timex.shift(datetime, minutes: 26)},
%{a: 10, cluster: 2, time: Timex.shift(datetime, minutes: 29)},
%{a: 11, cluster: 2, time: Timex.shift(datetime, minutes: 32)},
%{a: 12, cluster: 1, time: Timex.shift(datetime, minutes: 35)},
%{a: 13, cluster: 1, time: Timex.shift(datetime, minutes: 38)},
]
Enum.map_reduce(data, {0, 0}, fn x, {i, last} ->
i = if x.cluster == last, do: i, else: i + 1
{Map.put(x, :cluster, i), {i, x.cluster}}
end)
|> elem(0)
|> IO.inspect
Output:
[
%{a: 0, cluster: 0, time: #DateTime<2018-02-18 00:00:00Z>},
%{a: 1, cluster: 0, time: #DateTime<2018-02-18 00:03:00Z>},
%{a: 2, cluster: 0, time: #DateTime<2018-02-18 00:06:00Z>},
%{a: 3, cluster: 0, time: #DateTime<2018-02-18 00:09:00Z>},
%{a: 4, cluster: 1, time: #DateTime<2018-02-18 00:12:00Z>},
%{a: 5, cluster: 1, time: #DateTime<2018-02-18 00:15:00Z>},
%{a: 6, cluster: 2, time: #DateTime<2018-02-18 00:18:00Z>},
%{a: 7, cluster: 2, time: #DateTime<2018-02-18 00:21:00Z>},
%{a: 8, cluster: 2, time: #DateTime<2018-02-18 00:23:00Z>},
%{a: 9, cluster: 3, time: #DateTime<2018-02-18 00:26:00Z>},
%{a: 10, cluster: 3, time: #DateTime<2018-02-18 00:29:00Z>},
%{a: 11, cluster: 3, time: #DateTime<2018-02-18 00:32:00Z>},
%{a: 12, cluster: 4, time: #DateTime<2018-02-18 00:35:00Z>},
%{a: 13, cluster: 4, time: #DateTime<2018-02-18 00:38:00Z>}
]

The more elixirish approach would be to use pattern matching on function clauses inside map-reducer:
Enum.map_reduce(data, {0, 0}, fn
%{cluster: last} = x, {i, last} ->
{%{x | cluster: i}, {i, last}}
%{cluster: last} = x, {i, _} ->
{%{x | cluster: i + 1}, {i + 1, last}}
end)

Related

Getting unknown error in SudokuSolver Backtracking problem

I was trying a Backtracking problem (SudokuSolver) I am getting an error which no-one could resolve or even understand. Hence I am seeking help here.
The problem is as follows:
And the main function/part of my code is:
Here my removerow, removecol and removebox functions are removing the numbers which have already occurred in that row, column and sub-box of 3x3 respectively.
The error I am getting is very long that is:
Can someone please help me with this? I'm stuck at it since 2 days. Ready to provide further clarification if needed.
Please find the entire code here: link
I have created a test class, to try understand what your functions are doing - or rather, to make sure they do what I think they do...
import unittest
from Otter.Help_Parth.entire_code import tellbox
from Otter.Help_Parth.entire_code import removerow
from Otter.Help_Parth.entire_code import removecol
from Otter.Help_Parth.entire_code import removebox
class MyTestCase(unittest.TestCase):
def test_tellbox(self):
""" Put each of the 81 x,y combination to tellbox
and retrieve the 81 corresponding box-numbers
assert that the numbers are as expected. """
lst_results = list()
for i in range(9):
for j in range(9):
lst_results.append(tellbox(i, j))
self.assertEqual(lst_results, [0, 0, 0, 3, 3, 3, 6, 6, 6, 0, 0, 0, 3, 3, 3, 6, 6, 6, 0, 0, 0, 3, 3, 3, 6, 6, 6, 1, 1, 1, 4, 4, 4, 7, 7, 7, 1, 1, 1, 4, 4, 4, 7, 7, 7, 1, 1, 1, 4, 4, 4, 7, 7, 7, 2, 2, 2, 5, 5, 5, 8, 8, 8, 2, 2, 2, 5, 5, 5, 8, 8, 8, 2, 2, 2, 5, 5, 5, 8, 8, 8])
def test_removerow(self):
""" Given a partly filled board, a list and an x,y coordinate
try call removerow() and assert that the returned list are as expected. """
board = [[1, 2, 3, 4, 5, 6, 7, 8, 9],
[4, 5, 6, 7, 8, 9, 1, 2, 3],
[7, 8, 9, 1, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0]]
l = [1, 2, 3, 4, 5, 6, 7, 8, 9]
x, y = 2, 4
res = removerow(l, board, x, y)
self.assertEqual([2, 3, 4, 5, 6], res)
def test_removecol(self):
""" Given a partly filled board, a list and an x,y coordinate
try call removecol() and assert that the returned list are as expected. """
board = [[1, 2, 3, 4, 5, 6, 7, 8, 9],
[4, 5, 6, 7, 8, 9, 1, 2, 3],
[7, 8, 9, 1, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0]]
l = [1, 2, 3, 4, 5, 6, 7, 8, 9]
x, y = 2, 4
res = removecol(l, board, x, y)
self.assertEqual([1, 2, 3, 4, 6, 7, 9], res)
def test_removebox(self):
""" Given a partly filled board, a list and an x,y coordinate
try call removebox() and assert that the returned list are as expected. """
board = [[1, 2, 3, 4, 5, 6, 7, 8, 9],
[4, 5, 6, 7, 8, 9, 1, 2, 3],
[7, 8, 9, 1, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0]]
l = [1, 2, 3, 4, 5, 6, 7, 8, 9]
x, y = 2, 4
bno = tellbox(x, y)
res = removebox(l, board, x, y, bno)
self.assertEqual([2, 3], res)
if __name__ == '__main__':
unittest.main()
It all goes quite well, until removebox().
If you can read and understand my test_removebox(self) Are you kind to confirm that, under the given circumstances, it should in fact return [2, 3]?
Otherwise, please tell what it should return, and why?
When I run the test class, it returns the following:
NB: To be able to run the test class against your code, you need to change it like this:
if __name__ == '__main__':
board = [[ int(ele) for ele in input().split() ] for i in range(9)]
ans=solveSudoku(board,0,0)
if ans:
print('true')
else:
print('false')
Both your code-sample and the output seems incomplete.
We don't know your variables, so I assume 'board' is a list of 81 integers, but what is the mysterious (and newer used) boxl?
And why would you set board[x][y] = 0 (in the line with the comment), when you have just gone through the trouble of setting it = ele?
We would be able to help you better, if you provided the entire code, in a run-able form.
Sorry! I just realized that I answered to the wrong post!

Sets and set operations in Sage

How am I able to input this into Sage?
A = {x ∈ ℕ | x ≤ 10}
B = {a, b}
I've looked at the docs and they are not clear. I am trying to find the union and distinction between them afterwards.
This might be what you want.
sage: A = set(0 .. 10)
sage: B = {4, 12}
sage: A.union(B)
{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12}
sage: A.intersection(B)
{4}
sage: A.difference(B)
{0, 1, 2, 3, 5, 6, 7, 8, 9, 10}
sage: A.symmetric_difference(B)
{0, 1, 2, 3, 5, 6, 7, 8, 9, 10, 12}

Complicated filtering of data frame without loops

I have big data frame with positions, time stamps, trip ids etc.
I would like to in a simple way, to avoid double loops, filter out and save only some of the rows.
So for all the rows that have the same combination of trip_id and stop_id, I want to save the row where the speed was first equal to zero. Either by take the minimum timestamp where the speed is zero or simple just the first time the speed is zero since the frame is ordered by the timestamp.
So in the example below, I would like to find the three top rows (in the real data frame a lot more rows) and just save the second row where the speed first was zero.
Is there a way to do this without any loops?
trip_id.x stop_id latitude.x longitude.x bearing speed timestamp vehicle id
55700000048910944 9022005000050006 58.416879999999999 15.624510000000001 30 0.2 1541399400 9031005990005424
55700000048910944 9022005000050006 58.416879999999999 15.624510000000001 0 0 1541399401 9031005990005424
55700000048910944 9022005000050006 58.416879999999999 15.624510000000001 0 0 1541399402 9031005990005424
55700000048910300 9022005000050006 58.416879999999999 15.624510000000001 30 0.5 1541400000 9031005990005424
Edit:
Here is the dput() of a longer exampel with a simpler format of the data I have:
structure(list(trip_id = c(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3,
3, 3, 3), stop_id = c(1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 1,
1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3,
3, 3), speed = c(5, 0, 0, 5, 2, 0, 0, 2, 4, 0, 0, 4, 5, 0, 0,
5, 2, 0, 0, 2, 4, 0, 0, 4, 5, 0, 0, 5, 2, 0, 0, 2, 4, 0, 0, 4
), timestamp = c(1, 2, 3, 4, 101, 102, 103, 104, 201, 202, 203,
204, 301, 302, 303, 304, 401, 402, 403, 404, 501, 502, 503, 504,
601, 602, 603, 604, 701, 702, 703, 704, 801, 802, 803, 804)), row.names = c(NA,
-36L), class = c("tbl_df", "tbl", "data.frame"))
And the wanted output:
structure(list(trip_id = c(1, 1, 2, 2, 2, 3, 3, 3), stop_id = c(1,
3, 1, 2, 3, 1, 2, 3), speed = c(0, 0, 0, 0, 0, 0, 0, 0), timestamp = c(2,
202, 302, 402, 502, 602, 702, 802)), row.names = c(NA, -8L), class = c("tbl_df",
"tbl", "data.frame"))
Edit: Trying to change to code to have conditions in it. Tried with case_when and if but can't get it to work:
df_arrival_z <- df %>%
group_by(trip_id, stop_id) %>%
filter(speed == 0)
# Check if there is any rows where speed is zero
if (nrow(filter(speed == 0)) > 0){
# Take the first row if there is rows with zero
filter(speed == 0) %>% slice(1)
}
if (nrow(filter(speed == 0)) == 0){
# Take the middle point if there is no rows with speed = 0
slice(nrow%/%2)
}
Without desired output I can't be sure what you expect, but try this and let me know:
library(dplyr)
df %>%
group_by(trip_id, stop_id) %>%
filter(speed == 0) %>%
slice(1)

Computing iterations in R to calculate the rate of population increase

I´ve tried to calculate the rate of population increase, denoted as r, which is obtained from:
sum(e^(r*x)*lx*mx) = 1
I know the values of x, lx, and mx, but r value should be iteratively obtained to get a sum of one.
This is the code I wrote (or tried to), which it´s not correct as it returns values for the sum but not for r.
I don´t know what´s wrong. I´ll appreciate any clue to solve this.
Thanks.
lx <- c(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0)
mx <- c(1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0)
x <- c(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
18, 19, 20, 21, 22)
radj = sum((exp(-r*x))*lx*mx)
for (radj in 0:1) {
repeat { radj <- sum((exp(-r*x))*lx*mx)
print(radj)
if (radj < 1) break ()} }
Try this:
root <- uniroot( f = function(r) sum(exp(r*x)*lx*mx) - 1, interval = c(-1, 0))
root$root
> [1] -0.8340894

How can you find the polynomial for a decimated LFSR?

I know that it if you decimate the series generated by a linear feedback shift register, you get a new series and a new polynomial. For example, if you sample every fifth element in the series generated by a LFSR with polynomial x4+x+1, you get the series generated by x2+x+1. I can find the second polynomial (x2+x+1) by brute force, which is fine for low-order polynomials. However, for higher-order polynomials, the time required to brute force it gets unreasonable.
So the question is: is it possible to find the decimated polynomial analytically?
Recently read this article and thought of it when seeing your question, hope it helps.. :oÞ
Given a primitive polynomial over GF(q), one can obtain another primitive polynomial by decimating an LFSR sequence obtained from the initial polynomial. This is demonstrated in the code below.
K := GF(7);
C := PrimitivePolynomial(K, 2);
C;
D^2 + 6*D + 3
In order to generate an LFSR sequence, we must first multiply this polynomial by a suitable constant so that the trailing coefficient becomes 1.
C := C * Coefficient(C,0)^-1;
C;
5*D^2 + 2*D + 1
We are now able to generate an LFSR sequence of length 72 - 1. The initial state can be anything other than [0, 0].
t := LFSRSequence (C, [K| 1,1], 48);
t;
[ 1, 1, 0, 2, 3, 5, 3, 4, 5, 5, 0, 3, 1, 4, 1, 6, 4, 4, 0, 1, 5, 6, 5, 2, 6, 6,
0, 5, 4, 2, 4, 3, 2, 2, 0, 4, 6, 3, 6, 1, 3, 3, 0, 6, 2, 1, 2, 5 ]
We decimate the sequence by a value d having the property gcd(d, 48)=1.
t := Decimation(t, 1, 5);
t;
[ 1, 5, 0, 6, 5, 6, 4, 4, 3, 1, 0, 4, 1, 4, 5, 5, 2, 3, 0, 5, 3, 5, 1, 1, 6, 2,
0, 1, 2, 1, 3, 3, 4, 6, 0, 3, 6, 3, 2, 2, 5, 4, 0, 2, 4, 2, 6, 6 ]
B := BerlekampMassey(t);
B;
3*D^2 + 5*D + 1
To get the corresponding primitive polynomial, we multiply by a constant to make it monic.
B := B * Coefficient(B, 2)^-1;
B;
D^2 + 4*D + 5
IsPrimitive(B);
true
from these notes: "The decimation by n>0 of a m-sequence c , denoted as c[ n],
has a period equal to N/gcd(N,n), if it is not the all-zero
sequence, its generator polynomial gˆ( x ) has roots that are nth
powers of the roots of g(x)"

Resources