Apa sudut itu?

12

Tujuan dari tantangan ini adalah untuk menentukan sudut garis dalam gambar.

Aturan pada gambar:

  • Latar belakang gambar akan menjadi putih ( #FFFFFF)
  • Garis garis akan menjadi hitam ( #000000)
  • Baris ini TIDAK akan anti-alias
  • Gambar akan berukuran 100x100 piksel
  • Garis akan mulai di tengah gambar
  • Garis akan mulai menunjuk ke bawah (6-OClock)
  • Panjangnya 50 piksel
  • Sudut garis akan diukur berlawanan arah jarum jam dari posisi awal
  • Codec gambar akan berupa .jpgatau.png

Format input akan menjadi nama file yang dilewatkan oleh baris perintah, input skrip, atau fungsi. Format output sederhana - cukup output jumlah derajat (misalnya 90).

Jawaban bisa ± 1 derajat dari ukuran yang dinyatakan. Berikut adalah beberapa contoh gambar:

1

Gambar referensi pada 45 derajat dengan latar belakang abu-abu

1

0 derajat

2

45 derajat

3

50 derajat

4

130 derajat

6

230 derajat

7

324 derajat

Berikut adalah kode yang digunakan untuk membuat gambar (ini diberi kode Memproses ):

int deg = 45;

int centX = width/2, centY = height/2;

background(255);
noSmooth();
line(centX,
     centY,
     centX + sin(radians(deg))*50,
     centY + cos(radians(deg))*50);

saveFrame("line-"+deg+".png");// image codec can be changed here. use '.png' or '.jpg'
J Atkin
sumber
1
Apakah saya mendapat downvote? Jika demikian, dapatkah pemilih menjelaskan mengapa?
J Atkin
Bisakah kita hanya menampilkannya, bukan menyimpannya ke file?
ev3commander
Tentu, begitulah semua jawaban lain melakukannya. Cukup cetak ke konsol jawaban yang dihasilkan program Anda.
J Atkin
1
@JAtkin Saya tidak akan khawatir tentang downvotes pada postingan yang umumnya terbalik. c: Kita semua mengerti itu.
Addison Crump
Oh begitu. Saya heran mengapa saya dapat satu ...
J Atkin

Jawaban:

7

Pyth - 28 26 byte

Menggunakan strategi brute force yang sama dengan jawaban js.

f!@F+]'zm+50s*48.t.tT7d_U2

Mengambil input sebagai nama file dari stdin.

f                     Filters from 1 till predicate is matched
 !                    Boolean not so that only pixel with zero value matched
  @F+]                Folds by indexing to get pixel value  
   'z                 Reads image filename input
   m         _U2      Maps over both trig ratios
    +50               Adds 50 to pixel value
     *48              Multiplies pixel value by 48
      .t    d         Takes trig ratio with appropriate option
        .t 7          Degrees to radians
          T           Filter var
Maltysen
sumber
Wow, ini keren tapi saya tidak bisa bicara. Maukah Anda menambahkan penjelasan?
J Atkin
1
Saya berharap JavaScript memiliki jumlah byte yang sama di sisi lain.
masukkan nama pengguna di sini
@insertusernamehere Saya berharap groovy atau scala bisa melakukan golf semacam ini juga.
J Atkin
Penjelasan @JAtkin ditambahkan. Jangan ragu untuk mengirim saya pesan melalui obrolan jika Anda memiliki pertanyaan.
Maltysen
9

JavaScript (ES6), 225 227 244 byte

Mari kita mulai menggulirkan bola:

f=s=>{(i=new Image).src=s;c=document.createElement`canvas`.getContext`2d`;c.drawImage(i,0,0,100,100);for(a=360;a--,r=a/180*(m=Math).PI;)if(!c.getImageData(50+48*m.cos(r),50+48*m.sin(r),1,1).data[1]){alert((450-a)%360);break}}

Cukup berikan URL gambar ke fungsi:

f('90deg.png');

Memperingatkan derajat dalam kisaran ± 1. Lulus semua kasus uji.

Tidak disatukan

f=s=>{
    // create new image and set source
    (i=new Image).src=s;
    // create canvas and get context
    c=document.createElement`canvas`.getContext`2d`;
    // set width/height to 100px and draw image on canvas
    c.drawImage(i,0,0,100,100);
    // check whether for any degree on the theoretical circle a black pixel is found
    for(a=360;a--,r=a/180*(m=Math).PI;)
        if(!c.getImageData(50+48*m.cos(r),50+48*m.sin(r),1,1).data[1]){
            // wait, it should be ccw and the board is rotated 90 degrees
            alert((450-a)%360);
            break
        }
}

Suntingan

  • Disimpan 17 byte - pikir saya tidak perlu mengatur lebar dan tinggi elemen kanvas.
  • Disimpan 2 byte dengan meniadakan kondisi.
masukkan nama pengguna di sini
sumber
Saya pikir ini harus berhasil (belum mengujinya). 206 byte:s=>{(i=new Image).src=s;with(Math)with(document.createElement`canvas`.getContext`2d`)for(drawImage(i,0,0,100,100),a=360;r=--a/180*PI;)getImageData(50+48*cos(r),50+48*sin(r),1,1).data[1]||alert((450-a)%360)}
user81655
1
Kode ini berfungsi karena Anda beruntung. Kanvas akan ternoda hampir setiap saat. Khusus dengan file://. Anda perlu mengatur crossOriginproperti. Juga, itu tidak akan berfungsi jika pemuatan gambar membutuhkan waktu 0,00001 detik lebih banyak daripada membuat kanvas. Juga, Anda tidak perlu f=, memotong 2 byte. Tapi itu memang solusi yang bagus !!! Suara positif saya untuk itu.
Ismael Miguel
@IsmaelMiguel Terima kasih atas umpan balik terperinci Anda. Anda benar tentang kanvas. Pada awalnya saya mencoba untuk memutar dan mencerminkan gambar, sehingga sudutnya tidak perlu diubah. Anda bisa mengucapkan selamat tinggal pada hal itu! Menjadi buram, tidak dapat menemukan piksel yang tepat. Saya telah melewatkan onloadbagian karena saya dilemahkan dalam tantangan lain karena itu. Jadi saya pikir tidak apa-apa untuk menganggap bahwa itu memuat cukup cepat. Mengenai fungsi anonim, saya tidak yakin bagaimana cara menghitungnya. Jika saya memotong f=dan saya ingin memohonnya saya harus membungkusnya ()seperti (s=>{})('arg');. Bisakah saya mengabaikan ini dalam hitungan byte?
masukkan nama pengguna di sini
@insertusernamehere Ya, Anda dapat mengabaikan jumlah byte. Tetapi Anda harus menentukan bahwa itu adalah fungsi anonim
Ismael Miguel
5

Matlab, 118 104 byte

Saya menghasilkan matriks dengan ukuran yang sama dengan gambar dengan bilangan kompleks (0 di tengah) dan mengecualikan dari matriks nilai-nilai yang ada di baris. Argumen rata-rata tersebut kemudian ditampilkan.

Terima kasih kepada @ThomasKwa yang menyarankan peningkatan akurasi yang juga menghasilkan kode yang lebih pendek !!!

I=imread(input('','s'));
[y,x]=ndgrid(-50:49);
c=y+i*x;
disp(mod(angle(mean(c(~I(:,:,1))))*180/pi+360,360))
cacat
sumber
1
Apakah akan lebih pendek untuk menemukan argumen dari rata-rata semua poin di telepon?
lirtosiast
Wow, ini jauh lebih pendek daripada yang saya harapkan, pekerjaan yang bagus!
J Atkin
@ThomasKwa Tentu saja, tetapi tidak akan seakurat, karena piksel yang dekat dengan pusat benar-benar tidak akurat. Jika Anda ingin mencoba, Anda dapat menjalankan kode ini dalam Oktaf juga, saya pikir!
flawr
Argumen mean (yang seharusnya memberikan argumen pusat garis ke akurasi yang cukup baik), bukan berarti argumen. Saya tidak tahu apakah akurasinya dapat diterima.
lirtosiast
1
@ThomasKwa Ide bagus, terima kasih! Keakuratannya bahkan lebih baik sekarang dan kodenya lebih pendek beberapa byte =)
flawr
5

Matlab, 86 77 byte

Berikut cara lain menggunakan Matlab:

[I,J]=find(~im2bw(imread(input('','s'))));mode(mod(round(atan2d(J-51,I-51)),360))

Ini membaca file (dicuri dari flawr ), dan menemukan indeks piksel hitam. Kemudian, ia bekerja pada vektor yang menunjuk dari pusat gambar ke setiap piksel hitam, dan menggunakan atan2duntuk menemukan sudut, membulatkan untuk mendapatkan sudut bilangan bulat, dan melakukan mod(...,360)untuk mendapatkan hasil dalam kisaran yang tepat. Untuk mendapatkan sudut yang benar (ada sedikit kesalahan untuk piksel dekat dengan pusat), ambil sudut yang paling sering dihitung.

Terima kasih kepada slvrbld untuk im2bwsarannya!

David
sumber
1
Kode Anda dapat dikurangi menjadi 77 byte dengan mengganti bagian sebelum mode (...) dengan [I, J] = find (~ im2bw (imread (input ('')))));
slvrbld
Yang bagus! Terima kasih, saya yakin ada cara untuk melakukan itu dengan lebih mudah tetapi tidak dapat mengingatnya.
David
3

Labview, 10098 Bytes

Mari kita taruh kode labview lain di luar sana.

Karena tidak ada cara resmi untuk menghitung byte di labview saya menggunakan ukuran file saat disimpan. Atau menghitung setiap kawat dan fungsi sebagai 1 dan kasing 2 maka akan menjadi 71.

1

Muat gambar, ratakan ke 1D, pindai 0s dari kedua sisi dan ambil yang pertama, kembalikan ke titik dan gunakan geometri untuk mendapatkan sudut.

Eumel
sumber
1
Bagus, ini menarik. Anda mungkin ingin bertanya pada meta bagaimana cara mencetak program labview.
J Atkin
sudah ada utas tentang cara mencetak gol tetapi sayangnya belum ada jawaban
Eumel
Oh begitu. Saya baru saja mengedit posting Anda untuk membuat jumlah byte lebih dapat dimengerti oleh kami di AS A.
J Atkin
@JAtkin Sebagai orang Eropa, itu membuat saya menggaruk-garuk kepala, bertanya-tanya bagaimana dia mendapatkan pecahan byte itu. Tidakkah menggunakan ruang tolong semua sisi?
Aaron
Hehehe, aku lupa kalian punya ,tempat desimal.
J Atkin