I am trying to solve Leetcode 160. Intersection of Two Linked Lists:
Given the heads of two singly linked-lists headA and headB, return the node at which the two lists intersect. If the two linked lists have no intersection at all, return null.
For example, the following two linked lists begin to intersect at node c1:
The test cases are generated such that there are no cycles anywhere in the entire linked structure.
Note that the linked lists must retain their original structure after the function returns.
I wanted to use the two pointers to solve it, but the Leet Code site gives me a Time Limit Exceeded error.
My code is shown below:
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
ListNode *tempA = headA, *tempB = headB;
while (tempA != tempB) {
if (tempA->next != NULL) { tempA = tempA->next;}
else { tempA->next = headB;}
if (tempB->next != NULL) { tempB = tempB->next;}
else { tempB->next = headA; }
}
return tempA;
}
I then tried this existing solution and it works, but I cannot tell what's different:
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
ListNode *tempA = headA, *tempB = headB;
while (tempA != tempB) {
if (tempA != NULL) { tempA = tempA->next;}
else { tempA = headB;}
if (tempB != NULL) { tempB = tempB->next;}
else { tempB = headA;}
}
return tempA;
}
The algorithm should be a "read-only" algorithm, i.e. there should be no reason to modify the linked lists to determine the solution.
Yet, that is what the first version of the code does: it assigns a new reference to a node's next property. This should never happen: there is no good reason why a node's next property would need to get a new value when the only thing you want to do is "calculate" where a certain node is located and return it.
In this particular case tempA->next = headB; is linking the end of linked list A with the start of linked list B. To picture this, let's imagine the two lists are initially like this:
tempA
↓
┌────────────┐
headA:─► │ data: 2 │
│ next: ───────┐
└────────────┘ │ ┌────────────┐
└──► │ data: 3 │
┌──► │ next: NULL │
┌────────────┐ ┌────────────┐ │ └────────────┘
headB:─► │ data: 4 │ │ data: 5 │ │
│ next: ──────────► │ next: ───────┘
└────────────┘ └────────────┘
↑
tempB
The loop will in the first iterations always execute the if cases, and so after one iteration tempA and tempB will reference the next nodes:
┌────────────┐
headA:─► │ data: 2 │ tempA
│ next: ───────┐ ↓
└────────────┘ │ ┌────────────┐
└──► │ data: 3 │
┌──► │ next: NULL │
┌────────────┐ ┌────────────┐ │ └────────────┘
headB:─► │ data: 4 │ │ data: 5 │ │
│ next: ──────────► │ next: ───────┘
└────────────┘ └────────────┘
↑
tempB
And now, in the second iteration, the first else block will execute tempA->next = headB; which alters that tail node's next property, bringing about the following situation:
┌────────────┐
headA:─► │ data: 2 │ tempA
│ next: ───────┐ ↓
└────────────┘ │ ┌────────────┐
└──► │ data: 3 │
┌──► │ next: ────────┐
┌────────────┐ ┌────────────┐ │ └────────────┘ │
headB:─► │ data: 4 │ │ data: 5 │ │ │
┌─► │ next: ──────────► │ next: ───────┘ │
│ └────────────┘ └────────────┘ │
└───────────────────────────────────────────────────────────┘
↑
tempB
This is introducing a cycle in the linked list: there is now no more tail node -- there is no node anymore whose next property is NULL. As you can see that means the while condition will from now on always be true,... this has become an infinite loop. This explains why the platform that runs this code is signaling a "time limit exceeded" error.
I want to operate this expression with data.
But it gives the error that List(float64) type doesn't have the operation.
I guess the list type isn't implemented element-wise operations.
(col("vec").last() - col("vec")).abs().sum()
vec
---------
list[f64]
============================
0: [-0.000000, -1.11111, ..., ]
1: [-2.222222, 3.33333, ..., ]
...
n: [ 8.888888, -9.99999, ..., ]
Then if I want to subtract each row with the last row, what is the best way to do it?
The below is what i want to do:
0: sum(abs([ 8.888888, -9.99999, ..., ] - [-0.000000, -1.11111, ..., ]))
1: sum(abs([ 8.888888, -9.99999, ..., ] - [-2.222222, 3.33333, ..., ]))
...
n: sum(abs([ 8.888888, -9.99999, ..., ] - [ 8.888888, -9.99999, ..., ]))
I was able to finagle an answer by converting the lists to structs, unnesting said structs to get the equivalent data in a (vec, len(vec)) shaped DataFrame of floats, then doing standard operations from there and converting back to list:
>>> x = pl.DataFrame(data={'vec' : [[0., -1-1/9], [-2-2/9, 3+3/9], [8+8/9, -10.]]})
>>> (x
.select(dummy=pl.col('vec').arr.to_struct())
.unnest('dummy')
.select(vec=pl.concat_list(abs(pl.all().last() - pl.all()))
)
shape: (3, 1)
┌────────────────────────┐
│ vec │
│ --- │
│ list[f64] │
╞════════════════════════╡
│ [8.888889, 8.888889] │
│ [11.111111, 13.333333] │
│ [0.0, 0.0] │
└────────────────────────┘
This code was tested on Rust v1.67 for polars in v0.27.2.
Add these features in Cargo.toml:
[dependencies]
polars = { version = "*", features = [ "lazy", "lazy_regex", "list_eval" ] }
color-eyre = "*"
The main function:
use color_eyre::Result;
use polars::prelude::*;
use std::error::Error;
fn main() -> Result<(), Box<dyn Error>> {
let row1 = vec![0.0, -1.0 - 1.0 / 9.0, 1.77];
let row2 = vec![-2.0 - 2.0 / 9.0, 3.0 + 3.0 / 9.0, 2.93];
let row3 = vec![3.0 + 3.0 / 9.0, -4.0 - 1.0 / 9.0, 3.56];
let row4 = vec![8.0 + 8.0 / 9.0, -10.0, 7.26];
let series1: Series = Series::new("a", &row1);
let series2: Series = Series::new("b", &row2);
let series3: Series = Series::new("c", &row3);
let series4: Series = Series::new("d", &row4);
let list = Series::new("vec", &[series1, series2, series3, series4]);
let df: DataFrame = DataFrame::new(vec![list])?;
println!("df:\n{df}\n");
let mut lazyframe = df.lazy();
let mut new_columns: Vec<String> = Vec::new();
for i in 0..row1.len() {
let column_name: String = format!("vec_{i}");
let subtraction: String = format!("sub_{i}");
new_columns.extend([column_name.clone(), subtraction.clone()]);
lazyframe = lazyframe
.with_columns([
// split list into new intermediate columns
col("vec").arr().get(lit(i as i64)).alias(&column_name),
//col("vec").arr().eval(lit(2.0) * col(""), true)
//.alias("test multiplication by 2"),
])
.with_columns([
(col(&column_name).last() - col(&column_name))
.apply(absolute_value, GetOutput::from_type(DataType::Float64))
.alias(&subtraction)
]);
}
lazyframe = lazyframe
.select([
all(),
concat_lst([col("^sub_.*$")]).alias("Concat lists")
]);
lazyframe = lazyframe
.with_columns([
col("Concat lists").arr().sum().alias("Sum")
]);
// uncomment to discard intermediate columns
// lazyframe = lazyframe.drop_columns(new_columns);
println!("dataframe:\n{}\n", lazyframe.collect()?);
Ok(())
}
The absolute_value function is given below:
fn absolute_value(str_val: Series) -> Result<Option<Series>, PolarsError> {
let series: Series = str_val
.f64()
.expect("fn absolute_value: series was not an f64 dtype")
.into_iter()
.map(|opt_value: Option<f64>| opt_value.map(|value: f64| value.abs()))
.collect::<Float64Chunked>()
.into_series();
Ok(Some(series))
}
The initial DataFrame:
df:
shape: (4, 1)
┌─────────────────────────────┐
│ vec │
│ --- │
│ list[f64] │
╞═════════════════════════════╡
│ [0.0, -1.111111, 1.77] │
│ [-2.222222, 3.333333, 2.93] │
│ [3.333333, -4.111111, 3.56] │
│ [8.888889, -10.0, 7.26] │
└─────────────────────────────┘
The final result is:
dataframe:
shape: (4, 9)
┌─────────────────────────────┬───────────┬───────────┬───────────┬─────┬───────┬───────┬──────────────────────────────┬───────────┐
│ vec ┆ vec_0 ┆ sub_0 ┆ vec_1 ┆ ... ┆ vec_2 ┆ sub_2 ┆ Concat lists ┆ Sum │
│ --- ┆ --- ┆ --- ┆ --- ┆ ┆ --- ┆ --- ┆ --- ┆ --- │
│ list[f64] ┆ f64 ┆ f64 ┆ f64 ┆ ┆ f64 ┆ f64 ┆ list[f64] ┆ f64 │
╞═════════════════════════════╪═══════════╪═══════════╪═══════════╪═════╪═══════╪═══════╪══════════════════════════════╪═══════════╡
│ [0.0, -1.111111, 1.77] ┆ 0.0 ┆ 8.888889 ┆ -1.111111 ┆ ... ┆ 1.77 ┆ 5.49 ┆ [8.888889, 8.888889, 5.49] ┆ 23.267778 │
│ [-2.222222, 3.333333, 2.93] ┆ -2.222222 ┆ 11.111111 ┆ 3.333333 ┆ ... ┆ 2.93 ┆ 4.33 ┆ [11.111111, 13.333333, 4.33] ┆ 28.774444 │
│ [3.333333, -4.111111, 3.56] ┆ 3.333333 ┆ 5.555556 ┆ -4.111111 ┆ ... ┆ 3.56 ┆ 3.7 ┆ [5.555556, 5.888889, 3.7] ┆ 15.144444 │
│ [8.888889, -10.0, 7.26] ┆ 8.888889 ┆ 0.0 ┆ -10.0 ┆ ... ┆ 7.26 ┆ 0.0 ┆ [0.0, 0.0, 0.0] ┆ 0.0 │
└─────────────────────────────┴───────────┴───────────┴───────────┴─────┴───────┴───────┴──────────────────────────────┴───────────┘
I prepare some course notes for my students. They are about the solution of the ODE
with N(0)=25 (initial condition to calculate arbitrary constant) and N(1)=25 (to get k).
We have done it analytically; I want to present sympy's solution.
I use
k = sp.Symbol('k', positive = 'True')
t = sp.Symbol('t', positive = 'True')
N = sp.Function('N')
N0 = 25
N1 = 100
eqn = sp.Eq(sp.diff(N(t),t,1),k*N(t)*(1000-N(t))) # differential equation
sol_part = sp.dsolve(eqn, ics={N(0): N0}) # particular solution for N(0)=25
sol_part_k = sol_part.subs(t,1) # value of N(1)
sp.solveset(sol_part_k.rhs - N1,k) # determining k
It is here my issue because sympy does not take into account that k is a positive declared symbol.
Any suggestions? Thank you very much.
The solveset function does not directly look at assumptions on the unknown symbol but rather has a separate domain argument. The domain argument is the set from which solutions should be sought. By default the domain is assumed to be the complex numbers but you can specify any other set:
In [6]: solveset(sol_part_k.rhs - N1, k)
Out[6]:
⎧n⋅ⅈ⋅π log(13/3) │ ⎫ ⎧ⅈ⋅(2⋅n⋅π + π) log(39) │ ⎫
⎨───── + ───────── │ n ∊ ℤ⎬ \ ⎨───────────── + ─────── │ n ∊ ℤ⎬
⎩ 500 1000 │ ⎭ ⎩ 1000 1000 │ ⎭
In [7]: solveset(sol_part_k.rhs - N1, k, Complexes)
Out[7]:
⎧n⋅ⅈ⋅π log(13/3) │ ⎫ ⎧ⅈ⋅(2⋅n⋅π + π) log(39) │ ⎫
⎨───── + ───────── │ n ∊ ℤ⎬ \ ⎨───────────── + ─────── │ n ∊ ℤ⎬
⎩ 500 1000 │ ⎭ ⎩ 1000 1000 │ ⎭
In [8]: solveset(sol_part_k.rhs - N1, k, Reals)
Out[8]:
⎧-log(3/13) ⎫
⎨───────────⎬
⎩ 1000 ⎭
Try using something like this:
std::vector<Ort::Value> ort_inputs;
for (int i = 0; i < inputNames.size(); ++i) {
ort_inputs.emplace_back(Ort::Value::CreateTensor<float>(
memoryInfo, static_cast<float *>(inputs[i].data), inputs[i].get_size(),
inputShapes[i].data(), inputShapes[i].size()));
}
std::vector<Ort::Value> outputTensors =
session.Run(Ort::RunOptions{nullptr}, inputNames.data(),
ort_inputs.data(), 1, outputNames.data(), outputNames.size());
Now, my model is like this:
yolox_tiny_cpunms.onnx Detail
╭──────────────┬────────────────────────────────┬────────────────────────┬───────────────╮
│ Name │ Shape │ Input/Output │ Dtype │
├──────────────┼────────────────────────────────┼────────────────────────┼───────────────┤
│ input │ [1, 3, 416, 416] │ input │ float32 │
│ boxes │ [1, -1, -1] │ output │ float32 │
│ scores │ [1, -1] │ output │ float32 │
│ labels │ [1, -1] │ output │ int64 │
╰──────────────┴────────────────────────────────┴────────────────────────┴───────────────╯
As you can see, the output is dynamic, but C++ code output Tensor give me shape [1, 0, 4]
, [1, 0], [1,0]
How can I get the output shape in. C++?
I get the output shape in C++ like this
auto outputTensor = session.Run(runOptions, inputNames.data(), &inputTensor, 1, outputNames.data(), 1);
assert(outputTensor.size() == 1 && outpuTensor.front().IsTensor());
if (outputTensor[0].IsTensor())
{
auto outputInfo = outputTensor[0].GetTensorTypeAndShapeInfo();
std::cout << "GetElementType: " << outputInfo.GetElementType() << "\n";
std::cout << "Dimensions of the output: " << outputInfo.GetShape().size() << "\n";
std::cout << "Shape of the output: ";
for (unsigned int shapeI = 0; shapeI < outputInfo.GetShape().size(); shapeI++)
std::cout << outputInfo.GetShape()[shapeI] << ", ";
}
What I want to do is feed a list of key names to a module that will be used to generate many secrets with different random passwords in secrets manager.
I have tried many different things but have failed so far.
This is what I have currently:
module "secrets-manager-1" {
source = "lgallard/secrets-manager/aws"
for_each = var.list
secrets = {
"${each.value}" = {
description = each.value
recovery_window_in_days = 7
secret_string = random_password.special_password.result
}
}
tags = var.standard_tags
}
resource "random_password" "special_password" {
count = 2
length = 16
special = true
}
variable "list" {
type = list(string)
default = [
"secret_key_1",
"secret_key_2"
]
}
The Error:
│ Error: Invalid for_each argument
│
│ on ..\..\modules\jitsi\jitsi_secrets.tf line 54, in module "secrets-manager-1":
│ 54: for_each = var.list
│ ├────────────────
│ │ var.list is list of string with 2 elements
│
│ The given "for_each" argument value is unsuitable: the "for_each" argument must be a map, or set of strings, and you have provided a value of type list of string.
╵
Releasing state lock. This may take a few moments...
Unfortunately what you are providing is not even valid Terraform code. What I believe you would want to achieve the following:
// Create N random password. In this case N = 2
resource "random_password" "special_password" {
count = 2
length = 16
special = true
}
// Import a third party module
module "secrets-manager-1" {
source = "lgallard/secrets-manager/aws"
// Loop through the random_passowrd resouces and create the secrets
secrets = {
for index, pwd in random_password.special_password.*.result : "${element(var.list, index)}" => {
secret_string: "${pwd}",
recovery_window_in_days = 7
}
}
}
You may want to check out the splat expressions for being able to iterate over multiple resources. This is used for the for expression in the secrets-manager-1 module.