Find all "pairing sets", such that all elements have a pair, and no pairs contain common elements - language-agnostic

I am currently trying to solve the following problem.
I must find all pairs of a set (with even number of elements) such that:
No two pairs have common elements
All elements are in a pair
As an example:
pairingsSet({0, 1, 2, 3})
should return something like
{
{{0, 1}, {2, 3}},
{{0, 2}, {1, 3}},
{{0, 3}, {1, 2}},
}
And a more verbose example:
pairingsSet({0, 1, 2, 3, 4, 5})
should return something like
{
{{0, 1}, {2, 3}, {4, 5}},
{{0, 1}, {2, 4}, {3, 5}},
{{0, 1}, {2, 5}, {3, 4}},
{{0, 2}, {1, 3}, {4, 5}},
{{0, 2}, {1, 4}, {3, 5}},
...
{{0, 5}, {1, 3}, {2, 4}},
{{0, 5}, {1, 4}, {2, 3}},
}
I can tell that the easiest way to solve this problem is with recursion, but I can't quite get my finger on how to do it.
I ordered the sets above because it helped me think of a solution, but the order does not matter. I still can't quite put my finger on a solution. I will likely be figuring out the answer soon, I made this question in case anyone else encountered a similar problem. If anyone figures out an alternative answer though, I would love to see it!
(I am currently working on a solution in Go although solutions in other languages are very much welcome)

Here is my solution in Go:
func allPairingSetsForAlphabet(alphabet []int) [][][2]int {
if len(alphabet) == 2 {
return [][][2]int{{{alphabet[0], alphabet[1]}}}
}
first := alphabet[0]
rest := alphabet[1:]
var pairingsSet [][][2]int
for i, v := range rest {
pair := [2]int{first, v}
withoutV := make([]int, len(rest)-1)
copy(withoutV[:i], rest[:i])
copy(withoutV[i:], rest[i+1:])
// recursive call
otherPairingsSet := allPairingSetsForAlphabet(withoutV)
for _, otherPairings := range otherPairingsSet {
thisPairing := make([][2]int, len(otherPairings)+1)
thisPairing[0] = pair
copy(thisPairing[1:], otherPairings)
pairingsSet = append(pairingsSet, thisPairing)
}
}
return pairingsSet
}
Essentially it performs the following steps:
If there are only two remaining things in the alphabet, we return a pairing set containing only those two pairs (ie {{{0, 1}}})
Pick an element (we will call it first)
Makes a new set which contains all elements of the alphabet, without first (we will call this rest)
For each element (v) in rest, we:
Make a pair of {first, v} (we will call this pair)
Create a subset of rest which contains all elements in rest except v (we will call this withoutV)
We make a recursive call, allPairingsForAlphabet(withoutV)
For each pairing (pairing) that this call returns, we add {pair} U pairing to the result.

Related

How to read JSON file in Prolog

I found a few SO posts on related issues which were unhelpful. I finally figured it out and here's how to read the contents of a .json file. Say the path is /home/xxx/dnns/test/params.json, I want to turn the dictionary in the .json into a Prolog dictionary:
{
"type": "lenet_1d",
"input_channel": 1,
"output_size": 130,
"batch_norm": 1,
"use_pooling": 1,
"pooling_method": "max",
"conv1_kernel_size": 17,
"conv1_num_kernels": 45,
"conv1_stride": 1,
"conv1_dropout": 0.0,
"pool1_kernel_size": 2,
"pool1_stride": 2,
"conv2_kernel_size": 12,
"conv2_num_kernels": 35,
"conv2_stride": 1,
"conv2_dropout": 0.514948804688646,
"pool2_kernel_size": 2,
"pool2_stride": 2,
"fcs_hidden_size": 109,
"fcs_num_hidden_layers": 2,
"fcs_dropout": 0.8559119274655482,
"cost_function": "SmoothL1",
"optimizer": "Adam",
"learning_rate": 0.0001802763794651928,
"momentum": null,
"data_is_target": 0,
"data_train": "/home/xxx/data/20180402_L74_70mm/train_2.h5",
"data_val": "/home/xxx/data/20180402_L74_70mm/val_2.h5",
"batch_size": 32,
"data_noise_gaussian": 1,
"weight_decay": 0,
"patience": 20,
"cuda": 1,
"save_initial": 0,
"k": 4,
"save_dir": "DNNs/20181203090415_11_created/k_4"
}
To read a JSON file with SWI-Prolog, query
?- use_module(library(http/json)). % to enable json_read_dict/2
?- FPath = '/home/xxx/dnns/test/params.json', open(FPath, read, Stream), json_read_dict(Stream, Dicty).
You'll get
FPath = 'DNNs/test/k_4/model_params.json',
Stream = <stream>(0x7fa664401750),
Dicty = _12796{batch_norm:1, batch_size:32, conv1_dropout:0.
0, conv1_kernel_size:17, conv1_num_kernels:45, conv1_stride:
1, conv2_dropout:0.514948804688646, conv2_kernel_size:12, co
nv2_num_kernels:35, conv2_stride:1, cost_function:"SmoothL1"
, cuda:1, data_is_target:0, data_noise_gaussian:1, data_trai
n:"/home/xxx/Downloads/20180402_L74_70mm/train_2.h5", data
_val:"/home/xxx/Downloads/20180402_L74_70mm/val_2.h5", fcs
_dropout:0.8559119274655482, fcs_hidden_size:109, fcs_num_hi
dden_layers:2, input_channel:1, k:4, learning_rate:0.0001802
763794651928, momentum:null, optimizer:"Adam", output_size:1
30, patience:20, pool1_kernel_size:2, pool1_stride:2, pool2_
kernel_size:2, pool2_stride:2, pooling_method:"max", save_di
r:"DNNs/20181203090415_11_created/k_4", save_initial:0, type
:"lenet_1d", use_pooling:1, weight_decay:0}.
where Dicty is the desired dictionary.
If you want to define this as a predicate, you could do:
:- use_module(library(http/json)).
get_dict_from_json_file(FPath, Dicty) :-
open(FPath, read, Stream), json_read_dict(Stream, Dicty), close(Stream).
Even DEC10 Prolog released 40 years ago could handle JSON just as a normal term . There should be no need for a specialized library or parser for JSON because Prolog can just parse it directly .
?- X={"a":3,"b":"hello","c":undefined,"d":null} .
X = {"a":3, "b":"hello", "c":undefined, "d":null}.
?-

(Ecto.Query.CompileError) Tuples can only be used in comparisons with literal tuples of the same size. - Elixir

Where I'm at
For this example, consider Friends.repo
Table Person has fields :id, :name, :age
Example Ecto query:
iex> from(x in Friends.Person, where: {x.id, x.age} in [{1,10}, {2, 20}, {1, 30}], select: [:name])
When I run this, I get relevant results. Something like:
[
%{name: "abc"},
%{name: "xyz"}
]
But when I try to interpolate the query it throws the error
iex> list = [{1,10}, {2, 20}, {1, 30}]
iex> from(x in Friends.Person, where: {x.id, x.age} in ^list, select: [:name])
** (Ecto.Query.CompileError) Tuples can only be used in comparisons with literal tuples of the same size
I'm assuming I need to do some sort of type casting on the list variable. It is mentioned in the docs here : "When interpolating values, you may want to explicitly tell Ecto what is the expected type of the value being interpolated"
What I need
How do I achieve this for a complex type like this? How do I type cast for a "list of tuples, each of size 2"? Something like [{:integer, :integer}] doesn't seem to work.
If not the above, any alternatives for running a WHERE (col1, col2) in ((val1, val2), (val3, val4), ...) type of query using Ecto Query?
Unfortunately, the error should be treated as it is stated in the error message: only literal tuples are supported.
I was unable to come up with some more elegant and less fragile solution, but we always have a sledgehammer as the last resort. The idea would be to generate and execute the raw query.
list = [{1,10}, {2, 20}, {1, 30}]
#⇒ [{1, 10}, {2, 20}, {1, 30}]
values =
Enum.join(for({id, age} <- list, do: "(#{id}, #{age})"), ", ")
#⇒ "(1, 10), (2, 20), (1, 30)"
Repo.query(~s"""
SELECT name FROM persons
JOIN (VALUES #{values}) AS j(v_id, v_age)
ON id = v_id AND age = v_age
""")
The above should return the {:ok, %Postgrex.Result{}} tuple on success.
You can do it with a separate array for each field and unnest, which zips the arrays into rows with a column for each array:
ids =[ 1, 2, 1]
ages=[10, 20, 30]
from x in Friends.Person,
inner_join: j in fragment("SELECT distinct * from unnest(?::int[],?::int[]) AS j(id,age)", ^ids, ^ages),
on: x.id==j.id and x.age==j.age,
select: [:name]
another way of doing it is using json:
list = [%{id: 1, age: 10},
%{id: 2, age: 20},
%{id: 1, age: 30}]
from x in Friends.Person,
inner_join: j in fragment("SELECT distinct * from jsonb_to_recordset(?) AS j(id int,age int)", ^list),
on: x.id==j.id and x.age==j.age,
select: [:name]
Update: I now saw the tag mysql, the above was written for postgres, but maybe it can be used as a base for a mySql version.

Pretty-print using the new Ruby syntax for hashes

There's a ton of questions about Ruby pretty-printing of recursive structures à la JSON (i.e, just scalars, arrays and hashes), and the answers refer to the json, pp, awesome_printer, etc. However, I have not seen a way to pretty-print a hash in Ruby syntax, that in addition would please classical Ruby linters. Something like
> pretty({a: [1, 2, {b: 3, c: 4}], d: {e: {'f g': 42}}})
=> "{a: [1, 2, {b: 3, c: 4}], d: {e: {'f g': 42}}}"
awesome_print comes close:
> ({a: [1, 2, {b: 3, c: 4}], d: {e: {'f g': 42}}}).
ai(plain: true, multiline: false, ruby19_syntax: true)
=> "{ a: [ 1, 2, { b: 3, c: 4 } ], d: { e: { \"f g\": 42 } } }"
but I didn't find a means to get rid of the inner spaces for braces and brackets, and it chose to use double-quotes for a constant string, which is disliked by Rubocop.
I can write my pretty-printer myself, but I'm surprised there's no COTS^h^h^h^hgem that does that. Did I miss something?

How to append an integer to an existing binary

Suppose I have a binary like this <<1,2,3,4>> and I want to modify it to <<1,2,3,4,5>>. How can I do it?
Also, I am trying to convert a list into a binary [1,2,3,4,5] => <<1,2,3,4,5>> but I'm not sure how to do that.
In Elixir, you can use the <> operator:
iex(1)> <<1, 2, 3, 4>> <> <<5>>
<<1, 2, 3, 4, 5>>
or the binary syntax:
iex(1)> a = <<1, 2, 3, 4>>
<<1, 2, 3, 4>>
iex(2)> <<a::binary, 5>>
<<1, 2, 3, 4, 5>>
In Erlang, use the binary syntax with /binary:
1> A = <<1, 2, 3, 4>>.
<<1,2,3,4>>
2> <<A/binary, 5>>.
<<1,2,3,4,5>>
Edit: to convert a list of bytes to a binary, use :erlang.list_to_binary/1:
iex(1)> :erlang.list_to_binary [1, 2, 3, 4, 5]
<<1, 2, 3, 4, 5>>
It heavily depends on what you want to append.
The most generic (although probably the most verbose) solution would be to go through the charlist:
<<1, 2, 3, 4>>
|> to_charlist()
|> Kernel.++([5])
|> to_string
#⇒ <<1, 2, 3, 4, 5>>
One might use Kernel.SpecialForms.for/1 comprehension:
for i <- [1, 2, 3, 4, 5], do: <<i>>, into: <<>>
#⇒ <<1, 2, 3, 4, 5>>
Also since it’s a charlist, one might use Kernel.to_string/1:
to_string [1, 2, 3, 4, 5]
#⇒ <<1, 2, 3, 4, 5>>
Here's what I found:
1> list_to_binary([<<"existing binary - ">>, integer_to_binary(1234, 10)]).
<<"existing binary - 1234">>
I was noticing that if the list contains values greater than 255 I am
getting an argument error(if erlang function) or changed values cause
default size of the binary elements is 1 byte I guess. How can I
overcome this ? Is this even possible ?
You can't represent the integer 257 in one byte, and its representation in two bytes is <<1, 1>>. Do you know why that is?
The string "257" and the integer 257 are two very different things. You aren't ever going to see: <<1, 2, 3, 257>> in elixir(or erlang) because each number between the commas is an integer that can fit in one byte. In addition, although an elixir string is a binary, a binary isn't necessarily an elixir string. Do you know how that is possible?
You seem to think that the binary <<1, 2, 3>> represents the characters "1", "2", and "3". That is incorrect. The binary <<1, 2, 3>> actually represents the characters named, Start of Heading, Start of Text, and End of Text. The character "1" is actually represented by the binary <<49>>:
iex(20)> <<49>>
"1"
Similarly, the character "2" is represented by the binary <<50>>, and the character "3" is represented by the binary <<51>>. There is no such thing as the character "257"--that is three characters "2", and "5", and "7".

Plotting a function as a function of another function in Mathematica

I wasn't entirely sure what to search for, so if this question has been asked before, I apologize in advance:
I have two functions
R := Rref*mx(mx^(4/3) - C0)^(-1)
M := Mref*(mx + C1*mx^(-1)*((1 - C0*mx^(-4/3))^(-3) - 1))
where Rref, Mref, C0 and C1 are constants and mx is the variable. I need to plot R as a function of M. Surely there must be something available in Mathematica to do such a plot - I just can't seem to find it.
The comment is correct, in that what you have is a set of two "parametric equations". You would use the ParametricPlot command. However, the syntax of functions with parameters is sometimes tricky, so let me give you my best recommendation:
R[Rref_, C0_, C1_][mx_] = Rref*mx (mx^(4/3) - C0)^(-1);
M[Mref_, C0_, C1_][mx_] = Mref*(mx + C1*mx^(-1)*((1 - C0*mx^(-4/3))^(-3) - 1));
I like that notation better because you can do things like derivatives:
R[Rref,C0,C1]'[mx]
(* Output: -((4 mx^(4/3) Rref)/(3 (-C0 + mx^(4/3))^2)) + Rref/(-C0 + mx^(4/3)) *)
Then you just plot the functions parametrically:
ParametricPlot[
{R[0.6, 0.3, 0.25][mx], M[0.2, 0.3, 0.25][mx]},
{mx, -10, 10},
PlotRange -> {{-10, 10}, {-10, 10}}
]
You can box this up in a Manipulate command to play with the parameters:
Manipulate[
ParametricPlot[
{R[Rref, C0, C1][mx], M[Mref, C0, C1][mx]},
{mx, -mmax, mmax},
PlotRange -> {{-10, 10}, {-10, 10}}
],
{Rref, 0, 1},
{Mref, 0, 1},
{C0, 0, 1},
{C1, 0, 1},
{mmax, 1, 10}
]
That should do it, I think.