Який це кут?


12

Мета цього завдання - визначити кут лінії на зображенні.

Правила щодо зображення:

  • Фон зображення буде білим ( #FFFFFF)
  • Обведення лінії буде чорним ( #000000)
  • Рядок НЕ буде антисексуальним
  • Зображення буде розміром 100x100 пікселів
  • Рядок розпочнеться в центрі зображення
  • Лінія почне вказувати вниз (6-OClock)
  • Лінія буде довжиною 50 пікселів
  • Кут лінії буде вимірюватися, рухаючись проти годинникової стрілки від вихідного положення
  • Кодек зображень буде .jpgабо.png

Формат введення буде ім'ям файлу, переданим аргументом командного рядка, введенням скрипту або функцією arg. Формат виводу простий - просто виведіть кількість градусів (наприклад,90 ).

Відповіді можуть бути ± 1 ступінь зазначеної міри. Ось кілька прикладів зображень:

1

Еталонне зображення при 45 градусах із сірим фоном

1

0 градусів

2

45 градусів

3

50 градусів

4

130 градусів

6

230 градусів

7

324 градуси

Ось код, який використовується для створення зображень (це закодовано за допомогою Processing ):

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'

1
Я отримав протизаконний запис? Якщо так, чи міг би виборець пояснити, чому?
J Atkin

Чи можемо ми просто відобразити його, а не зберегти його у файл?
ev3commander

Звичайно, саме так роблять і всі інші відповіді. Просто надрукуйте на консолі відповідь, яку створює ваша програма.
J Atkin

1
@JAtkin Я б не хвилювався з приводу загальнодоступних повідомлень на загальнодоступній посаді. c: Ми всі це отримуємо.
Аддісон Кримп

О Я бачу. Цікаво, чому я все-таки отримав такий ...
J Atkin

Відповіді:


7

Pyth - 28 26 байт

Використовується така ж стратегія грубої сили, що і відповідь js.

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

Вводиться як ім'я файлу від 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

Нічого собі, це круто, але я не розмовляю пітом. Ви б не хотіли додати пояснення?
Дж. Аткін

1
Я б хотів, щоб JavaScript мав такий самий підрахунок байтів, з іншого боку.
вставитикористувач туди

@insertusernameту Я б хотів, щоб groovy або scala міг би робити і цей вид гольфу.
Дж. Аткін

@JAtkin додано пояснення. Якщо у вас виникли запитання, не соромтеся надіслати мені повідомлення в чаті.
Мальтісен

9

JavaScript (ES6), 225 227 244 байт

Давайте згорнемо кульку:

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}}

Просто передайте URL-адресу зображення у функцію:

f('90deg.png');

Попередження градусів в межах ± 1. Пройшов усі тестові справи.

Безумовно

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
        }
}

Правки

  • Збережено 17 байт - зрозуміло, що мені не потрібно встановлювати ширину та висоту елемента полотна.
  • Збережено 2 байти , відкинувши умову.

Я думаю, що це має спрацювати (не перевіряли). 206 байт: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)}
користувач81655

1
Цей код працює, тому що вам пощастило. Полотно буде заплямоване майже кожного разу. Спеціально с file://. Потрібно встановити crossOriginвластивість. Крім того, воно не працюватиме, якщо завантаження зображення займе 0,00001 секунди більше, ніж створює полотно. Крім того, вам не потрібно f=, відрізаючи 2 байти. Але це приємне рішення справді !!! Моя підтримка за це.
Ісмаїл Мігель

@IsmaelMiguel Дякую за детальний відгук. Ти маєш рацію щодо полотна. На початку я намагався обертати зображення та дзеркально, щоб кут не потребував перетворення. Ви можете попрощатися з цим! Вийшов розмитим, не вдалося знайти потрібний піксель. Я пропустив onloadчастину, тому що був недорізаний в іншому виклику через це. Тому я подумав, що гарно вважати, що він завантажується досить швидко. Щодо анонімної функції, я не знаю, як її порахувати. Якщо я відрізаю f=і хочу викликати це, я мушу обернути його на ()зразок (s=>{})('arg');. Чи можу я проігнорувати це в кількості байтів?
insertusernamehere

@insertusernamehere Так, ви можете ігнорувати кількість байтів. Але ви повинні вказати, що це анонімна функція
Ісмаель Мігель

5

Матлаб, 118 104 байт

Я генерую матрицю такого ж розміру, що і зображення зі складними числами (0 в центрі) і витягую з цієї матриці значення, які знаходяться на лінії. Потім відображається аргумент середнього значення цих.

Дякуємо @ThomasKwa за пропозицію покращити точність, що також призвело до скорочення коду !!!

I=imread(input('','s'));
[y,x]=ndgrid(-50:49);
c=y+i*x;
disp(mod(angle(mean(c(~I(:,:,1))))*180/pi+360,360))

1
Чи буде коротше знайти аргумент середнього значення всіх точок на лінії?
lirtosiast

Ого, це набагато коротше, ніж я очікував на відповіді, приємна робота!
J Atkin

@ThomasKwa Абсолютно, але тоді це було б не так точно, оскільки пікселі, близькі до центру, абсолютно неточні. Якщо ви хочете спробувати, ви можете запустити цей код і в Octave, я думаю!
flawr

Аргумент середнього значення (який повинен надати аргумент центру рядка з досить хорошою точністю), а не означає аргументи. Я не знаю, чи була б точність прийнятною.
lirtosiast

1
@ThomasKwa Чудова ідея, дякую! Точність зараз навіть краща, і код на кілька байт коротший =)
недолік

5

Матлаб, 86 77 байт

Ось ще один спосіб використання Matlab:

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

Це зчитує файл (викрадений з flawr ) та знаходить індекси чорних пікселів. Потім він опрацьовує вектор, який вказує від центру зображення до кожного чорного пікселя, і використовує atan2dдля пошуку кута, округлення, щоб отримати цілі кути, і робить mod(...,360)для отримання результатів у потрібному діапазоні. Щоб отримати правильний кут (є трохи помилок для пікселів, близьких до центру), візьміть найчастіше обчислений кут.

Дякую slvrbld за im2bwпропозицію!


1
Ваш код можна зменшити до 77 байт , замінивши частину перед режимом (...) на [I, J] = find (~ im2bw (imread (input (''))))));
slvrbld

Хороший! Дякую, я був впевнений, що існує спосіб зробити це простіше, але не міг його запам'ятати.
Девід

3

Labview, 10098 байт

Давайте поставимо ще один код лабораторного перегляду.

Оскільки немає офіційного способу підрахунку байтів у лабораторії, я використовую розмір файлу при збереженні. В якості альтернативи, рахуючи кожен провід і функціонуючи як 1, а випадок - 2, він вийде до 71.

1

Завантажте зображення, розрівняйте до 1D, скануйте на 0s з обох сторін і візьміть перший, обчислений назад до точки та використовуйте геометрію, щоб отримати кут.


1
Приємно, це цікаво. Ви можете запитати в мета, як оцінювати програми лабораторного перегляду.
J Atkin

там вже є нитка про те, як забити, але, на жаль, відповіді ще немає
Eumel

О Я бачу. Я щойно відредагував вашу публікацію, щоб зробити кількість байтів більш зрозумілою для нас у США.
J Atkin

@JAtkin Як європейський хлопець змусив мене почухати голову, цікавившись, як він отримав ці частки байта. Не використовуйте пробіл усіх сторін?
Аарон

Хе-хе, я забув, хлопці, ,десяткові знаки .
J Atkin
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.