Problem:
Score : 200 points

Problem Statement

There is a square in the xy-plane. The coordinates of its four vertices are (x_1,y_1),(x_2,y_2),(x_3,y_3) and (x_4,y_4) in counter-clockwise order.
(Assume that the positive x-axis points right, and the positive y-axis points up.)

Takahashi remembers (x_1,y_1) and (x_2,y_2), but he has forgot (x_3,y_3) and (x_4,y_4).

Given x_1,x_2,y_1,y_2, restore x_3,y_3,x_4,y_4. It can be shown that x_3,y_3,x_4 and y_4 uniquely exist and have integer values.

Constraints

|x_1|,|y_1|,|x_2|,|y_2| \leq 100

(x_1,y_1) ≠ (x_2,y_2)

All values in input are integers.

Input

Input is given from Standard Input in the following format:

x_1 y_1 x_2 y_2

Output

Print x_3,y_3,x_4 and y_4 as integers, in this order.

Sample Input 1

0 0 0 1

Sample Output 1

-1 1 -1 0

(0,0),(0,1),(-1,1),(-1,0) is the four vertices of a square in counter-clockwise order.
Note that (x_3,y_3)=(1,1),(x_4,y_4)=(1,0) is not accepted, as the vertices are in clockwise order.

Sample Input 2

2 3 6 6

Sample Output 2

3 10 -1 7

Sample Input 3

31 -41 -59 26

Sample Output 3

-126 -64 -36 -131

Solution in Rust (1.15.1) (judge verdict: Accepted)

// ternary operation
#[allow(unused_macros)]
macro_rules! _if {
  ($_test:expr, $_then:expr, $_else:expr) => {
    if $_test { $_then } else { $_else }
  };
  ($_test:expr, $_pat:pat, $_then:expr, $_else:expr) => {
    match $_test {
      $_pat => $_then,
      _     => $_else
    }
  };
}

use std::io::{ stdin, stdout, Write };
use my::WriteWith;

#[inline(always)]
fn abc108_b() {
  let stdin  = stdin();
  let stdout = stdout();
  let mut scanner = my::Scanner::with_capacity(12, stdin.lock());
  let mut writer  = stdout.lock();
  let mut itoa    = my::ItoA::with_capacity(10);

  let x1 = my::atoi::<i32>(scanner.read_until(my::SP));
  let y1 = my::atoi::<i32>(scanner.read_until(my::SP));
  let x2 = my::atoi::<i32>(scanner.read_until(my::SP));
  let y2 = my::atoi::<i32>(scanner.read_until(my::LF));

  let x = x2 - x1;
  let y = y2 - y1;

  let x3 = x2 - y;
  let y3 = y2 + x;

  let x4 = x1 - y;
  let y4 = y1 + x;

  writer.write_with(itoa.from_i32(x3), b" ").unwrap();
  writer.write_with(itoa.from_i32(y3), b" ").unwrap();
  writer.write_with(itoa.from_i32(x4), b" ").unwrap();
  writer.write_with(itoa.from_i32(y4), b"\n").unwrap();
  writer.flush().unwrap();
}

fn main() {
  abc108_b();
}

//------------------------------------------------------------------------
mod my {
  use std::hash::Hasher;
  use std::hash::BuildHasher;

  pub struct MyHasher(u64);

  impl Default for MyHasher {
    #[inline(always)]
    fn default() -> Self {
      MyHasher(0x00)
    }
  }

  impl BuildHasher for MyHasher {
    type Hasher = MyHasher;

    #[inline(always)]
    fn build_hasher(&self) -> Self::Hasher {
      Self::Hasher::default()
    }
  }

  impl Hasher for MyHasher {
    #[inline(always)]
    fn finish(&self) -> u64 {
      self.0
    }

    #[inline(always)]
    fn write(&mut self, bytes: &[u8]) {
      self.0 = 0;
      for i in 0..bytes.len() {
        self.0 ^= (bytes[i] as u64) << (8 * (i % 8));
      }
    }
  }

  //----------------------------------------------------------------------
  use std::io::{ self, Write };
  use std::fmt::Debug;
  use std::ops::{ Add, Sub, Mul, Rem, Neg };
  use std::mem;

  #[allow(dead_code)]
  pub const SP    : u8 = b' ';
  #[allow(dead_code)]
  pub const LF    : u8 = b'\n';

  //----------------------------------------------------------------------
  #[allow(dead_code)]
  #[inline(always)]
  pub fn rotate_right<T>(ary: &mut [T])
    where T: Copy +
             Debug
  {
    if ary.len() <= 1 {
      return;
    }

    let len = ary.len() - 1;
    let tmp = ary[len];
    for i in 0..len {
      ary[len - i] = ary[len - i - 1];
    }
    ary[0] = tmp;
  }

  #[allow(dead_code)]
  #[inline(always)]
  pub fn rotate_left<T>(ary: &mut [T])
    where T: Copy +
             Debug
  {
    if ary.len() <= 1 {
      return;
    }

    let len = ary.len() - 1;
    let tmp = ary[0];
    for i in 0..len {
      ary[i] = ary[i + 1];
    }
    ary[len] = tmp;
  }

  //----------------------------------------------------------------------
  #[allow(dead_code)]
  #[inline(always)]
  pub fn gcd<T>(mut x: T, mut y: T) -> T
    where T: Rem<Output=T> +
             Default +
             PartialEq +
             Copy +
             Debug
  {
    let zero = T::default();

    if x == zero { return y; }
    if y == zero { return x; }

    while y != zero {
      let tmp = x % y;
      x = y;
      y = tmp;
    }

    x
  }

  //----------------------------------------------------------------------
  #[allow(dead_code)]
  #[inline(always)]
  pub fn intersection<T>(mut x: (T, T), mut y: (T, T)) -> Option<(T, T)>
    where T: PartialOrd +
             Copy +
             Debug
  {
    if x.0 > x.1 {
      mem::swap(&mut x.0, &mut x.1);
    }
    if y.0 > y.1 {
      mem::swap(&mut y.0, &mut y.1);
    }

    if x.0 >= y.1 || x.1 <= y.0 {
      return None;
    }

    if x.0 < y.0 {
      x.0 = y.0;
    }
    if x.1 > y.1 {
      x.1 = y.1;
    }

    Some(x)
  }

  //----------------------------------------------------------------------
  #[allow(dead_code)]
  #[inline(always)]
  pub fn is_ascii_digit(b: u8) -> bool {
    _if!(b >= b'0' && b <= b'9',
      true,
      false)
  }

  #[allow(dead_code)]
  #[inline(always)]
  pub fn is_ascii_uppercase(b: u8) -> bool {
    _if!(b >= b'A' && b <= b'Z',
      true,
      false)
  }

  #[allow(dead_code)]
  #[inline(always)]
  pub fn is_ascii_lowercase(b: u8) -> bool {
    _if!(b >= b'a' && b <= b'z',
      true,
      false)
  }

  #[allow(dead_code)]
  #[inline(always)]
  pub fn is_ascii_alphabetic(b: u8) -> bool {
    _if!(is_ascii_uppercase(b) || is_ascii_lowercase(b),
      true,
      false)
  }

  #[allow(dead_code)]
  #[inline(always)]
  pub fn to_ascii_lowercase(b: u8) -> u8 {
    _if!(is_ascii_uppercase(b),
      b + 0x20,
      b)
  }

  #[allow(dead_code)]
  #[inline(always)]
  pub fn to_ascii_uppercase(b: u8) -> u8 {
    _if!(is_ascii_lowercase(b),
      b - 0x20,
      b)
  }

  //----------------------------------------------------------------------
  #[allow(dead_code)]
  #[inline(always)]
  pub fn atoui<T>(s: &[u8]) -> T
    where T: Add<Output=T> +
             Sub<Output=T> +
             Mul<Output=T> +
             Default +
             From<u8> +
             Debug
  {
    let mut n = T::default();
    if s.len() == 0 {
      return n;
    }

    let mut i = 0;
    if s[i] == b'+' {
      i += 1;
    }

    for b in &s[i..] {
      n = (n * T::from(10)) + T::from(b - b'0');
    }

    n
  }

  #[allow(dead_code)]
  #[inline(always)]
  pub fn atoi<T>(s: &[u8]) -> T
    where T: Add<Output=T> +
             Sub<Output=T> +
             Mul<Output=T> +
             Neg<Output=T> +
             Default +
             From<u8> +
             Debug
  {
    let mut n = T::default();
    if s.len() == 0 {
      return n;
    }

    let mut i = 0;
    let mut negative = false;
    if s[i] == b'-' {
      negative = true;
      i += 1;
    } else if s[i] == b'+' {
      i += 1;
    }

    for b in &s[i..] {
      n = (n * T::from(10)) + T::from(b - b'0');
    }

    _if!(negative,
      n.neg(),
      n)
  }

  //----------------------------------------------------------------------
  #[allow(dead_code)]
  #[inline(always)]
  pub fn rw<R, W>(cap: usize, r: R, w: W) -> (Scanner<io::BufReader<R>>, io::BufWriter<W>)
    where R: io::BufRead,
          W: io::Write
  {
    (
      Scanner::with_capacity(cap, io::BufReader::new(r)),
      io::BufWriter::new(w)
    )
  }

  //----------------------------------------------------------------------
  pub trait WriteWith {
    fn write_with(&mut self, buf: &[u8], delim: &[u8]) -> io::Result<usize>;
  }

  macro_rules! fn_write_with {
    () => {
      #[inline(always)]
      fn write_with(&mut self, buf: &[u8], delim: &[u8]) -> io::Result<usize> {
        Ok(self.write(buf)? + self.write(delim)?)
      }
    };
  }

  impl WriteWith for Vec<u8> {
    fn_write_with!();
  }
  impl<W> WriteWith for io::BufWriter<W>
    where W: io::Write
  {
    fn_write_with!();
  }
  impl<'a> WriteWith for io::StdoutLock<'a> {
    fn_write_with!();
  }

  //----------------------------------------------------------------------
  macro_rules! pub_fn_ItoA_from_ty {
    (uint, $($name:ident => $_type:ty),*) => {$(
      #[allow(dead_code)]
      #[inline(always)]
      pub fn $name(&mut self, mut n: $_type) -> &[u8] {
        self.buf.clear();
        if n == 0 {
          self.buf.push(b'0');
          return self.buf.as_slice();
        }

        while n > 0 {
          self.buf.push((n % 10) as u8 + b'0');
          n /= 10;
        }
        self.buf.reverse();
        self.buf.as_slice()
      }
    )*};

    (int, $($name:ident => $_type:ty),*) => {$(
      #[allow(dead_code)]
      #[inline(always)]
      pub fn $name(&mut self, mut n: $_type) -> &[u8] {
        self.buf.clear();
        if n == 0 {
          self.buf.push(b'0');
          return self.buf.as_slice();
        }

        let mut negative = false;
        if n.is_negative() {
          negative = true;
          n = n.abs();
        }

        while n > 0 {
          self.buf.push((n % 10) as u8 + b'0');
          n /= 10;
        }
        if negative {
          self.buf.push(b'-');
        }
        self.buf.reverse();
        self.buf.as_slice()
      }
    )*};
  }

  #[derive(Debug)]
  pub struct ItoA {
    buf: Vec<u8>,
  }

  impl ItoA {
    #[allow(dead_code)]
    #[inline(always)]
    pub fn with_capacity(cap: usize) -> Self {
      ItoA {
        buf: Vec::with_capacity(cap),
      }
    }

    pub_fn_ItoA_from_ty!(
      uint,
      from_usize => usize,
      from_u8    => u8,
      from_u16   => u16,
      from_u32   => u32,
      from_u64   => u64
    );

    pub_fn_ItoA_from_ty!(
      int,
      from_isize => isize,
      from_i8    => i8,
      from_i16   => i16,
      from_i32   => i32,
      from_i64   => i64
    );
  } // impl ItoA

  //----------------------------------------------------------------------
  #[derive(Debug)]
  pub struct Scanner<R> {
    reader: R,
    buf   : Vec<u8>,
  }

  impl<R> Scanner<R>
    where R: io::BufRead
  {
    #[allow(dead_code)]
    #[inline(always)]
    pub fn with_capacity(cap: usize, reader: R) -> Self {
      Scanner {
        reader: reader,
        buf   : Vec::with_capacity(cap),
      }
    }

    //--------------------------------------------------------------------
    #[allow(dead_code)]
    #[inline(always)]
    pub fn into_inner(self) -> R {
      self.reader
    }

    #[allow(dead_code)]
    #[inline(always)]
    pub fn resize(&mut self, len: usize, val: u8) {
      self.buf.resize(len, val);
    }

    //--------------------------------------------------------------------
    #[allow(dead_code)]
    #[inline(always)]
    pub fn read_until(&mut self, delim: u8) -> &[u8] {
      self.buf.clear();
      let mut len = self.reader.read_until(delim, &mut self.buf).unwrap();
      if len == 0 {
        return self.buf.as_slice();
      }

      len -= 1;
      if self.buf[len] == delim {
        self.buf.truncate(len);
      }
      self.buf.as_slice()
    }

    //--------------------------------------------------------------------
    #[allow(dead_code)]
    #[inline(always)]
    pub fn for_each<F>(&mut self, n: usize, delim: u8, mut func: F)
      where F: FnMut(&[u8])
    {
      for _ in 0..n - 1 {
        func(self.read_until(delim));
      }
      func(self.read_until(LF))
    }

    #[allow(dead_code)]
    #[inline(always)]
    pub fn fold<B, F>(&mut self, n: usize, delim: u8, mut init: B, mut func: F) -> B
      where F: FnMut(B, &[u8]) -> B
    {
      for _ in 0..n - 1 {
        init = func(init, self.read_until(delim));
      }
      func(init, self.read_until(LF))
    }
  } // impl<R> Scanner<R>

} // mod my