Sisi persegi menunjukkan dengan tepat

13

Selamat datang di tantangan kode-golf pertama saya! :) Ayo langsung saja ke dalamnya.

Tantangan:

Diberi dua vektor floating point, O (asal) dan T (target), Anda harus membuat program untuk mencetak nilai L dan R ke STDOUT.

  1. O adalah salah satu sudut alun-alun
  2. T adalah salah satu sudut alun-alun yang terletak berhadapan dengan O
  3. L adalah titik 2D (sudut) yang menandai titik lain dari kuadrat tidak lengkap
  4. R adalah titik 2D (sudut) yang berlawanan dengan L

Aturan

  1. Nilai O dan T harus dibaca dari STDIN (lihat contoh input).
  2. Sekali lagi, nilai L dan R harus dicetak ke STDOUT.

Penilaian dan bonus

  1. Hitung byte dari program Anda.
  2. Jika program Anda menggambar garis yang menghubungkan antara O ke L ke T ke R , kurangi 15 byte dari jumlah byte.

Contohnya

Baris pertama mencakup input (kurung kuadrat pertama untuk O dan kurung berikutnya untuk T ) dan jalur lain mewakili output yang diharapkan.

  • [0, 0] [3, 3] Diharapkan: [0, 3] [3, 0]
  • [0, 0] [-2, -2] Diharapkan: [-2, 0] [0, -2]
  • [1, -1] [4, 2] Diharapkan: [1, 2] [4, -1]
  • [0, -1] [0, 1] Diharapkan: [-1, 0] [1, 0]

PEMBERITAHUAN : input dan output bisa menjadi titik mengambang!

Informasi penting!

  • Nilai O dan T dapat diambil dalam format apa pun, asalkan berasal dari STDIN (mis. Di dalam [] atau () ...), gunakan format apa pun yang Anda inginkan.
  • L dan R dapat dicetak dalam urutan apa pun.
  • Ingat: ketika (O-> L-> T-> R-> O) terhubung, masing-masing pihak harus memiliki panjang yang sama!

Kemenangan

  • Ini adalah kode-golf sehingga jawaban byte paling sedikit menang!
  • Jawaban pemenang akan diterima pada hari Minggu 15.11.2015 20: 00-22: 00 (waktu Finlandia) (Jika saya tidak salah, tanggal tersebut ditulis seperti 11.15.2015 di AS, jangan bingung).

Selamat bermain golf!

Yytsi
sumber
3
Jika Anda tidak menyadarinya, izinkan saya merekomendasikan kotak pasir untuk tantangan di masa depan, di mana Anda bisa mendapatkan umpan balik dan memoles tantangan Anda sebelum ditayangkan (dan sebelum perubahan mungkin membatalkan jawaban yang ada).
Martin Ender
Bisakah kita mengambil input sebagai daftar dua bilangan kompleks?
lirtosiast
@ThomasKwa yakin Anda bisa menganggapnya sebagai daftar. Bukankah input bilangan kompleks ketika diberikan ...? Maksud saya Anda tidak perlu secara pribadi mengetahui nilai diri Anda untuk komputer untuk menghitungnya, bukan?
Yytsi
Ketika Anda mengatakan "point of the square", sepertinya maksud Anda sudut? Ada banyak poin lain dalam sebuah kotak.
Reto Koradi
@RetoKoradi Anda benar. Maksud saya sudut dengan itu.
Yytsi

Jawaban:

8

Serius , 11 byte

Port jawaban TI-BASIC saya. Menghitung mean(X)+i*(X-mean(X)).

,;Σ½;)±+ï*+

Penjelasan:

,           Read input
;           Duplicate
Σ½          Half the sum (the mean) of the top copy
;           Copy the mean
)           Rotate stack to the left
            Now there's a copy of the mean on the bottom
±+          Negate mean and add to input list
ï*          Multiply by i
+           Add to mean

Masukan sebagai daftar dua bilangan kompleks: [1-1j,4+2j], dan output dalam format yang sama: [(4-1j), (1+2j)].

lirtosiast
sumber
3
Saya sangat bangga ...
Mego
Setelah jawaban ini diposting, Mego menambahkan ædaftar mean, dan menyebabkan î(multiply-by-i) untuk membuat vektor, memungkinkan solusi 9-byte yang tidak bersaing. Serius mulai menjadi bahasa yang sangat baik.
lirtosiast
Bahasa yang baik "Serius". @ThomasKwa
Addison Crump
Bukankah Σ2 byte?
Ash Burlaczenko
@AshBurlaczenko Serius tampaknya menggunakan pengkodean CP437 , di mana Σmemiliki titik kode 0xF4.
Dennis
6

Serius , 25 byte

,i││-++½)+-+½)++-½)±+++½)

Mengambil input sebagai daftar: [x1,y1,x2,y2]

Strategi yang sama dengan jawaban Python saya, tetapi dalam Serius!

Penjelasan:

,      get input
i      flatten list
││     duplicate stack twice, so that we have 4 copies of the input total
-++½)  calculate the first x-value using the formula (x1-y1+x2+y2)/2, and shove it to the end of the stack
+-+½)  calculate the first y-value using (x1+y1-x2+y2)/2, and shove it to the end of the stack
++-½)  calculate the second x-value using (x1+y2+x2-y2)/2, and shove it to the end of the stack
±+++½) calculate the second y-value using (-x1+y1+x2+y2)/2, and shove it to the end of the stack

Cobalah online

Mego
sumber
3
Ini sungguh keren! (
Maksud
5

TI-BASIC, 16 byte

Untuk kalkulator TI-83+ atau 84+ seri.

Input X
i∟X+.5sum(∟X-i∟X

Kecuali saya salah paham, OP mengatakan mereka baik-baik saja dengan mengambil input dan output sebagai angka yang kompleks. Di isini adalah unit imajiner, bukan variabel statistik.

TI-BASIC memiliki mean(fungsi, tetapi mengganggu itu tidak bekerja dengan daftar yang kompleks, melempar ERR:DATA TYPE.

Masukkan formulir {1-i,4+2i}untuk [[1,-1],[4,2]]. Output dalam bentuk {4-i 1+2i}untuk [[1,2][4,-1]].

lirtosiast
sumber
Ini mengingatkan saya bagaimana TI-BASIC tidak mendukung daftar string. Itu mungkin akan menjadi satu hal yang akan saya tambahkan ke TI-BASIC: P
Conor O'Brien
4

Matlab, 51 45 46 45 42 byte

Sekarang inputnya diharapkan dalam satu vektor kolom: [x0;y0;x1;y1](ouput dalam format yang sama) Saya baru saja memodifikasinya menjadi program lengkap.

z=eye(4);disp((.5-z([2:4,1],:))*input(''))

Atau sebagai alternatif

z=[1,1;-1,1];disp([z',z;z,z']*input('')/2)

Solusi lama:

Input mengharapkan vektor kolom, mis f([0;0],[3;3])

@(a,b)[0,1;-1,0]*(b-a)*[.5,-.5]+(b+a)*[.5,.5]

Ini juga mengembalikan dua vektor kolom (sebagai matriks 2x2).

cacat
sumber
3

Japt, 29 28 byte

Japt adalah versi singkat dari Ja vaScri pt . Penerjemah

1o5 mZ=>$eval$(Uq'+)/2-UgZ%4

Perhatikan bahwa fungsi panah memerlukan browser yang sesuai dengan ES6, seperti versi Firefox yang lebih baru. Input masuk sebagai array 4-item, mis [1,-1,4,2].

Bagaimana itu bekerja

         // Implicit: U = input array
1o5      // Create a range of integers from 1 to 5. Returns [1,2,3,4]
mZ=>     // Map each item Z in this range to:
$eval$(  //  evaluate:
 Uq'+    //   U joined with "+" (equivalent to summing U)
)/2      //  divided by 2,
-UgZ%4   //  minus the item at Z%4 in the input. This translates to [y₁,x₂,y₂,x₁],
         //  which in turn tranlsates to:
         //   [(x₁-y₁+x₂+y₂)/2, (x₁+y₁-x₂+y₂)/2, (x₁+y₁+x₂-y₂)/2, (-x₁+y₁+x₂+y₂)/2]
         //  which is [Lx,Ly,Rx,Ry], or [Rx,Ry,Lx,Ly], depending on the situation.
         // Implicit: Output last expression

Bagaimana itu golf

Saya pertama kali mencoba menyalin pendekatan Python @ Mego. Ini meninggalkan saya dengan monster 48 byte ini:
(Catatan: input saat ini tidak boleh dibungkus dalam array.)

[U-V+W+X /2,(U+V-W+X /2,(U+V+W-X /2,(V+W+X-U /2]

Karena masing-masing item ini perlu dibagi 2, lebih pendek untuk memetakan seluruh larik dengan mY=>Y/2:

[U-V+W+X,U+V-W+X,U+V+W-X,V+W+X-U]mY=>Y/2

Sekarang apa? Nah, array sekarang hanya menambahkan tiga input dan mengurangi yang keempat, mengikuti pola 1,2,3,0. Jadi, kita bisa mengemas input ke dalam array, kemudian menambahkannya bersama-sama, bagi dengan 2, dan kurangi item yang diperlukan:

[1,2,3,0]mZ=>(Ug0 +Ug1 +Ug2 +Ug3)/2-UgZ

Bagus, menyimpan satu byte! Tetapi apakah mungkin untuk mengecilkan array di awal? Mari kita coba mengemasnya menjadi string, kemudian membaginya kembali menjadi array dengan a:

"1230"a mZ=>(Ug0 +Ug1 +Ug2 +Ug3)/2-UgZ

Lihat itu, byte lain disimpan. Tetapi apakah ada cara yang lebih baik? Kita bisa menggunakan fakta bahwa [1,2,3,0] ≡ [1,2,3,4] mod 4:

1o5 mZ=>(Ug0 +Ug1 +Ug2 +Ug3)/2-UgZ%4

Dua byte lagi! Sekarang kita pergi ke suatu tempat. Tapi itu Ug0 +Ug1 +Ug2 +Ug3memonopoli banyak ruang. Bagaimana jika kita mengurangi array dengan tambahan?

1o5 mZ=>Ur(X,Y =>X+Y /2-UgZ%4

Wow, itu sangat membantu! Sekarang kita turun ke 29 byte. Dan terima kasih kepada @ ן nɟuɐɯɹɐ ן oɯ, saya bahkan bisa melakukan pengurangan byte lain. Tetapi jika kita bisa menggunakan built-in untuk menjumlahkan array, itu akan jauh lebih pendek:

1o5 mZ=>Uu /2-UgZ%4

19 byte! Luar biasa! Sayangnya, Japt belum memiliki built-in seperti itu. Saya akan menambahkan ini ketika saya mendapat kesempatan. Saran diterima, baik untuk program atau bahasa!


Nah, pada v1.4.4, saya telah mengimplementasikan beberapa fitur ke dalam Japt daripada yang saya rencanakan sebelumnya. Dimulai dengan paket asli untuk versi yang lebih pendek:

1o5 mZ=>Uu /2-UgZ%4

Pertama kita perlu mengubah beberapa hal: Fungsi didefinisikan dengan {, dan fungsi penjumlahannya adalah x. Versi ini berfungsi apa adanya:

1o5 mZ{Ux /2-UgZ%4

Sekarang, @adalah singkatan untuk XYZ{, memungkinkan kita untuk menyimpan byte dengan beralih dari Zke X. Juga, £merupakan jalan pintas untuk m@, menyimpan byte lain:

1o5 £Ux /2-UgX%4

Baru-baru ini saya mengimplementasikan fitur di mana Upada awal program biasanya dapat ditinggalkan. Namun, karena kesalahan implementasi, ini juga berfungsi dengan fungsi:

1o5 £x /2-UgX%4

Akhirnya, gfungsi sekarang membungkus jika indeks melewati akhir string, memungkinkan kita untuk menghapus %4total 13 byte :

1o5 £x /2-UgX

Dan saya pikir 19 luar biasa ;-) Uji secara online!

Produksi ETH
sumber
Anda mungkin dapat menyimpan beberapa byte dengan menggunakan setara Japt dari eval(U.join`+`).
Mama Fun Roll
Saya suka bahasa ini: D
phase
@ ן nɟuɐɯɹɐ ן oɯ Terima kasih, meskipun saya belum menambahkan yang evalsetara, itu sebenarnya menghemat satu byte!
ETHproduksi
2

Javascript (Node.js / ES6), 154 byte

process.stdin.on('data',s=>(s=s.toString().split(','),a=s[0]-0,b=s[1]-0,x=s[2]-0,y=s[3]-0,console.log([a+(c=(a+x)/2-a)+(d=(b+y)/2-b),b+d-c,a+c-d,b+d+c])))

Mendapatkan stdin adalah bagian kode yang lebih panjang. Input harus dipisahkan dengan koma:

echo "0,0,3,3" | node square.js
Naouak
sumber
Apakah ini program lengkap ...? Yang menampilkan poin ke STDOUT ...? Tidak seperti itu.
Yytsi
Kamu benar. Sial, ini akan menambah banyak byte,
Naouak
Voa, diperbaiki. hampir 3 kali lebih lama sekarang :(
Naouak
Hmm: / Saya masih berpikir bahwa intinya adalah membuat seni kode yang indah yang berfungsi dengan baik. Dan kode yang Anda berikan terlihat sangat rumit & seni yang tampan. :) terima kasih telah berpartisipasi!
Yytsi
2

ngn APL, 21 byte

⎕←F.5 0J.5×(F←+/,-/)⎕

Ini mengambil input sebagai pasangan bilangan kompleks (misalnya, 1J¯1 4J2) dan mencetak output dengan cara yang sama (misalnya, 4J¯1 1J2). Cobalah online di demo ngn / apl .

Dennis
sumber
Bekerja untuk semua input positif, namun, itu tidak menghasilkan apa-apa ketika saya memasukkan angka negatif. Apakah saya memasukkannya dalam format yang salah? 1J1 3J3 berfungsi. 0J-1 0J1 tidak. Saya juga mencoba menggunakan simbol minus atas untuk menyatakan angka negatif.
Yytsi
@ TuukkaX minus tinggi di jalan untuk pergi. Saya mendapatkan output 1 ¯1untuk input 0J¯1 0J1, yang merupakan jawaban yang benar. Apa yang kamu dapatkan
Dennis
1
Oh, sekarang aku berhasil. Saya hanya harus menghapus spasi putih sebelum tanda minus tinggi. Ia bekerja dan memenuhi syarat.
Yytsi
2

Pyth, 12 byte

.jL.OQ-R.OQQ

Ini mengambil input sebagai pasangan bilangan kompleks (misalnya, 1-1j, 4+2j) dan mencetak output sebagai array (misalnya, [(4-1j), (1+2j)]). Cobalah online.

Dennis
sumber
1

CJam, 30 byte

q~_:.+\:.-(W*+_2$.+@@.-].5ff*`

Cobalah online

Ini mengambil input sebagai daftar daftar, misalnya untuk contoh terakhir:

[[0 -1] [0 1]]

Penjelasan:

q~      Get and interpret input.
_       Make a copy.
:.+     Reduce the list of two points with vector sum operator.
\       Swap copy of input to top.
:.-     Reduce the list of two points with vector difference operator.
(W*+    Turn (x, y) into orthogonal (y, -x) by popping off first element, inverting
        its sign, and concatenating again. We now have center and offset vector.
_2$     Create a copy of both...
.+      ... and add them.
@@      Rotate original values to top...
.-      ... and subtract them.
]       Wrap the two results...
.5ff*   ... and multiply all values by 0.5.
`       Convert list to string.
Reto Koradi
sumber
1

Prolog, 118 byte

p([A,B],[C,D]):-read([E,F,G,H]),I is(E+G)/2,J is(F+H)/2,K is(G-E)/2,L is(H-F)/2,A is I-L,B is J+K, C is I+L, D is J-K.

Sedikit lebih mudah dibaca:

p([A,B],[C,D]):-read([E,F,G,H]),
                        I is(E+G)/2,
                        J is(F+H)/2,
                        K is(G-E)/2,
                        L is(H-F)/2,
                        A is I-L,
                        B is J+K, 
                        C is I+L, 
                        D is J-K.

Untuk memulai program:

p(X,Y).

Input contoh ketika sudut yang diketahui adalah [1, -1] [4, 2]:
[1, -1,4,2]

Contoh output, di mana X dan Y akan berisi sudut yang tidak diketahui:
X = [1.0, 2.0],
Y = [4.0, -1.0]

Cobalah secara online di sini

Edit: Diubah untuk membaca input dari STDIN

Emigna
sumber
Apakah ini dibaca dari STDIN dan dicetak ke STDOUT ...?
Yytsi
@ TuukkaX: Mungkin tidak. Dibutuhkan input dalam bentuk kueri. Saya membaca bagian yang mengatakan bahwa input dapat berupa format apa pun yang kita inginkan. Saya melewatkan bagian tentang STDIN. Bahkan tidak yakin apa itu STDIN di Prolog. Apakah membaca input dari pengguna boleh?
Emigna
STDIN adalah singkatan dari input standar. Jadi membaca dari pengguna adalah cara untuk pergi :) dan dengan format yang saya maksud adalah cara pengguna memasukkan nilai. Mis [x, y] [x, y] atau {x, y} ...
Yytsi
0

Python 3, 102 byte

g=lambda a,b,c,d:((a-b+c+d)/2,(a+b-c+d)/2,(a+b+c-d)/2,(d+b-a+c)/2)
print(g(*map(float,input().split())))

Masukan diambil dalam bentuk x1 y1 x2 y2 , pada satu baris.

Cobalah online

Mego
sumber
Anda melakukan sesuatu yang salah, jumlah byte Anda pergi dengan setiap mengedit, tapi saya mencoba untuk membawa bytecount yang turun dengan masing-masing edit = P
flawr
8
@ flawr Akulah yang anti-Dennis
Mego
Saya percaya semua jawaban harus berupa program lengkap, mengambil masukan dari STDIN (atau alternatif terdekat). Apakah ini memenuhi syarat?
ETHproduksi
0

Python 2, 56 byte

i=input()
s=sum(i)/2.0
print s-i[1],s-i[2],s-i[3],s-i[0]

Input bisa x1,y1,x2,y2atau(x1,y1,x2,y2)

TFeld
sumber