12
\$\begingroup\$

(Inspired by this challenge.)

Given six real values in three pairs: \$(x_1, x_2), (y_1, y_2),\$ and \$(x_0, y_0)\$, where \$x_1 < x_0 < x_2\$ and \$y_1 < y_0 < y_2\$, create a function which maps between \$(x_1, x_2)\$ and \$(y_1, y_2)\$ which also passes through \$(x_0,y_0)\$. In other words, make some function

$$f: \mathbb{R} \to \mathbb{R},\; f((x_1, x_2)) = (y_1, y_2),\; f(x_0) = y_0$$

Note that the image of the function has to be over the whole interval -- in other words, for every \$y \in (y_1,y_2)\$, there must be some \$x \in (x_1,x_2)\$, such that \$f(x)=y\$.

  • The function does not need to be bijective.
  • The value of the function cannot be outside of the given \$y\$ range.

For example, for \$(x_1, x_2) = (0, 10), (y_1, y_2) = (0, 10), x_0 = 4, y_0 = 2\$, a possible function is

$$\begin{cases} \frac12 x & 0 < x \leq 4 \\ -\frac43 x + \frac{46}{3} & 4 < x < 10 \end{cases}$$

Which looks like:

graph of function meeting description above

On the edge points (i.e. when \$x = x_1\$ or \$x = x_2\$) or outside of the interval, the function can have whatever value you want, or it can be undefined.


Note: You don't have to return a function -- you could also write your code so that it takes in \$x_1, x_2, y_1, y_2, x_0, y_0, x\$ and returns \$y = f(x)\$ following the constraints above.

Standard loopholes are forbidden. Since this is , the shortest function wins.

\$\endgroup\$
10
  • 2
    \$\begingroup\$ Is the second line in your example flipped? You say 10 should map to 10, and it would make more sense for 4+Δx to map to 2+Δy. \$\endgroup\$
    – Neil
    Mar 12, 2023 at 19:09
  • \$\begingroup\$ Is the image of \$f\$ required to be contained within \$(y_1,y_2)\$ over the interval \$x\in(x_1,x_2)\$, or can there be some value within the domain that maps to a value outside of \$(y_1,y_2)\$? \$\endgroup\$ Mar 13, 2023 at 15:33
  • \$\begingroup\$ @AndersKaseorg It does not need to be bijective. \$\endgroup\$ Mar 13, 2023 at 16:12
  • \$\begingroup\$ @Neil I don't think I understand your question. \$\endgroup\$ Mar 13, 2023 at 16:12
  • 1
    \$\begingroup\$ I didn't understand your formulae - what you're trying to say is that the function needs to map the open interval (x₁, x₂) to the open interval (y₁, y₂) and specifically the value x₀ needs to map to y₀. The confusion arises because (x₀, y₀) is a coordinate but the others are open intervals. \$\endgroup\$
    – Neil
    Mar 13, 2023 at 19:38

7 Answers 7

9
\$\begingroup\$

R, 6 bytes

approx

Try it online! or Try it with graphical output at rdrr.io

Input is x1,x2,x0, y1,y2,y0, x; output is x,y.

This seems like a fairly straightforward task for which built-in solution ought to exist in R, and indeed it does.


R, 48 38 bytes

\(a,b,c,x)(a+(x*(b+c-2*a)/c[1])%%b)[2]

Attempt This Online! or Try it with graphical output at rdrr.io

Input is x1,y1, x2,y2, x0,y0, x; output is y.

Non-builtin solution. Avoids any kind of curve-fitting tomfoolery by using a deliberately non-bijective function.

enter image description here

\$\endgroup\$
4
\$\begingroup\$

MATL, 4 bytes

&1Yn

The implemented mapping consists of two straight segments: the first from the point \$(x_1,y_1)\$ to \$(x_0,y_0)\$, and the second from \$(x_0,y_0)\$ to \$(x_2,y_2)\$.

The code inputs two numerical vectors and a number: [x1 x0 x2], [y1 y0 y2], x. Then it simply calls the interp1 function, which linearly interpolates the data defined by [x1 x0 x2] and [y1 y0 y2] at the abscissa x. The ouput is the value y corresponding to x.

Try it online! You can also see the graph of the mapping here.

\$\endgroup\$
3
\$\begingroup\$

JavaScript (ES6), 71 bytes

Expects \$(x_0,x_1,x_2,y_0,y_1,y_2,x)\$.

Just uses quadratic interpolation, which is most certainly not the shortest approach.

(a,b,c,d,e,f,x)=>(x-b)*((f-e)/(c-b)-(e-=d)/(b-=a))/(c-a)*(x-=a)+e/b*x+d

Try it online!

\$\endgroup\$
0
3
\$\begingroup\$

Charcoal, 31 bytes

NθNηNζF⊕›θη«NεNδ»I⁺ζ∕×⁻θη⁻δζ⁻εη

Try it online! Link is to verbose version of code. Takes input as seven numbers x, x₀, y₀, x₁, y₁, x₂ and y₂. Explanation: Performs linear interpolation between x₀ and y₀ and either x₁ and y₁ or x₂ and y₂ depending on whether x is greater than x₀ or not.

Nθ

Input x.

NηNζ

Input x₀ and y₀.

F⊕›θη«NεNδ»

Input x₁ and y₁ or x₂ and y₂ depending on whether x is greater than x₀.

I⁺ζ∕×⁻θη⁻δζ⁻εη

Perform linear interpolation.

\$\endgroup\$
3
\$\begingroup\$

Pyt, 33 bytes

Đ←=?ĉ←:←ŕŕ←←-Đ↔⇹ᵮ₄%⇹/4*←Đ←⇹-⇹↔*+;

Try it online!

Uses \$f(x)=\left\{\begin{array}{ c l }y_0 &\quad\textrm{if }x=x_0 \\y_1+(y_2-y_1)*{4\left(x\!\!\!\!\mod\!{x_2-x_1\over 4}\right)\over x_2-x_1}& \quad\textrm{otherwise}\end{array}\right. \$

Takes input as the following, each on a new line: x x0 y0 x2 x1 y1 y2

Code Stack Action
Đ \$x\ x\$ implicit input; Đuplicate
\$x\ x\ x_0\$ get \$x_0\$
=? \$x\ \{x\!=\!x_0\}\$ if \$x=x_0\$:
ĉ← \$y_0\$ ĉlear the stack and get \$y_0\$
:←ŕŕ \$x\$ otherwise, get \$y_0\$ and then ŕemove \$\{x\!=\!x_0\}\$ and \$y_0\$
←←- \$x\ z\$ get \$x_2\$ and \$x_1\$ and then subtract (call it \$z\$)
Đ \$x\ z\ z\$ Đuplicate
↔⇹ \$z\ x\ z\$ manipulate the stack
ᵮ₄ \$z\ x\ {z\over4}\$ cast to loat, then divide by 4
% \$z\ q\$ \$x\!\!\!\!\mod\!\! {z\over4}\$ (call it \$q\$)
\$q\ z\$ swap top two items on stack
/ \${q\over z}\$ divide
4* \${4q\over z}\$ multiply by 4
←Đ \${4q\over z}\ y_1\ y_1\$ get \$y_1\$ and Đuplicate
\${4q\over z}\ y_1\ y_1\ y_2\$ get \$y_2\$
⇹- \${4q\over z}\ y_1\ m\$ swap top two on stack and then subtract (call it \$m\$)
⇹↔ \$y_1\ m\ {4q\over z}\$ manipulate the stack
* \$y_1\ {4mq\over z}\$ multiply
+ \$y_1+{4mq\over z}\$ add
; either way, implicit print

The function is onto \$(y_1,y_2)\$ as follows:

It can be trivially shown that if the discontinuity at \$x_0\$ did not exist, then \$\forall y\in(y_1,y_2)\$, \$\exists\$ at least one \$x\in(x_1,x_2)\$ s.t. \$f(x)=y\$. In fact, there would be between two and four such points for all values.

Some of you may object here and say that \$\nexists x\in(x_1,x_2)\$ s.t. \$f(x)=y_2\$, and you'd be right. However, the problem lists the intervals as open, and so the endpoints are not necessary.

Since without the discontinuity, there would be at least two distinct \$x\in(x_1,x_2)\$ such that \$f(x)=y\$, with the discontinuity, every point must have at least one such \$x\$. Therefore, \$f(x)\$ is onto \$(y_1,y_2)\$.

\$\endgroup\$
2
\$\begingroup\$

Python, 81 bytes

lambda a,b,c,d,e,f,x:(x-b)*((f-e)/(c-b)-(e:=e-d)/(b:=b-a))/(c-a)*(x:=x-a)+e/b*x+d

Attempt This Online!

Port of Arnauld's JS answer.

\$\endgroup\$
0
\$\begingroup\$

JavaScript (Node.js), 55 bytes

f=(p,a,b,x,y,c,d)=>p>x?f(p,x,y,c,d):(y-b)/(x-a)*(p-a)+b

Try it online!

The linear map must be not shortest

Two segments

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.