Розрахунок БПМ за допомогою входів


30

Програмуйте найкоротший код, який обчислює середній показник BPM (ударів за хвилину), використовуючи 8 пропущених даних часу. Це моя перша публікація, і я не бачив подібного до цього питання. Оскільки я шанувальник ритм-ігор, було б непогано мати невеликий зручний інструмент для обчислення BPM за допомогою власної клавіатури та власного почуття ритму (якщо у вас є такий ...)

Виклик

  • Усі входи повинні бути єдиними. (тобто лише натискання "enter" як "input")
  • Ваша програма повинна взяти щонайменше 9 входів. (Для створення 8 точок даних пройшов час.)
  • Ваша програма повинна виводити BPM натискань клавіш, округлених у 2 знаки після коми. (тобто 178,35)
  • Час починається з першого введення. Не запуск програми

Це , тому найкоротша відповідь виграє.

Приклад введення та виводу

Надайте принаймні один приклад вводу та виводу. Переконайтесь, що вони відповідають вашим власним описам того, як повинен виглядати вхід.

Вхід:

> [Enter-Key]
# User waits 1 second
...  7 more inputs
> [Enter-Key] 

Вихід:

> 60

Поточний переможець - КарлКастор у 22 байтах із використанням Pyth

Незважаючи на те, що переможець використовував Pyth, відповідь Matlab була помітною відповіддю.


5
Га! Цікаво, ласкаво просимо до PPCG; для подальшої довідки у нас також є пісочниця, де ви можете отримати зворотній зв'язок щодо своїх проблем, перш ніж публікувати їх. Це дуже добре зроблено, хоча.
Чарівна восьминога урна

Як ми обчислюємо BPM? Почнемо проводити синхронізацію під час першого натискання клавіші або коли код почне працювати? Чи поділимо ми на 7 або 8 перед екстраполяцією?
xnor

Хм .. Тож час слід починати з першого натискання клавіші. Що стосується поділу, я зміню його на 9 входів (так що ви розділите на 8)
xNinjaKittyx

Класне питання! Удачі
Ной Крістіно,

Відповіді:


1

Піт , 22 байти

 wJ.d0 mw8.Rc480-.d0J2

(так, провідний простір)

Введення - натискання "enter".

Якщо дозволено додатковий вихід, я можу видалити пробіли та отримати 20 байт.

Приклад виконання

пояснення

 wJ.d0 mw8.Rc480-.d0J2
 w                      # take the first input
                        # (space) throw the result away
  J.d0                  # store the current system time in J
       mw8              # take 8 inputs and throw the result away
                 -.d0J  # difference of current time and J
             c480       # divide 480 by this
           .R         2 # round to 2 decimal places 

9

MATLAB / Octave, 58 56 55 байт

Дякую @LuisMendo за -1 байт!

input('');tic;for k=1:7;input('');end;fix(48e3/toc)/100

Ви повинні натиснути клавішу Enter 9 разів. (Також працює в Octave.)

Тут ви бачите його в дії, зліва MATLAB, праворуч Octave:


D'oh! але це round(.,2)не працює, чи це в нових версіях?
недолік

О, це працює лише в Матлабі
Луїс Мендо

7

JavaScript (ES6), 77 74 байт

(i=8,n=Date.now,t)=>onclick=_=>(t=t||n(),i--||alert((48e6/(n()-t)|0)/100))

Створює onclickподію на глобальному windowоб’єкті. Надішліть удари, клацнувши будь-де у вікні.

Тест-фрагмент


632,41! досить хороший вимір :) +1
V. Courtois



5

Javascript, 100 , 84 завдяки Powelles , 82 байти завдяки Justin Mariner

z=>{(a=alert)();i=0;s=(n=Date.now)();while(i++<8)a();a((48e4/(n()-s)).toFixed(2))}


1
Ви повинні мати можливість використовувати Date.now()замість new Date().getTime()і 48e4замість 480000.
Powelles

Також ви можете попередити результат, замість того, щоб повертати його та призначити попередження для такої змінної, як (a=alert)()для першого використання, а потім для подальшого використання a().
Powelles

Ах спасибі, я ніколи не думав 48e4, і виклик і створення екземпляра alertразом: (a=alert)().
Серж К.

1
Ви також можете переключитися sна використання Date.now()та .getTime()пізніше скасувати. І тоді ви можете псевдонімом Date.nowдо коротшого імені. І початковий z=не потрібен, оскільки ви не викликаєте функцію рекурсивно. Тут до 69 байт
Джастін Марінер

О, і ваше рішення не округлює до двох знаків після коми, як це вимагає завдання.
Джастін Марінер

4

Java 1.5 +, 345 339 361 337 байт

-34 байти, завдяки Майклу за те, що він забув виправити свій імпорт

import java.awt.event.*;class B{public static void main(String[]a){new java.awt.Frame(){{addKeyListener(new KeyAdapter(){long x=System.currentTimeMillis();int b=0;public void keyPressed(KeyEvent e){if(e.getKeyChar()==' '&&b++==9){System.out.println(Math.round(6000000.0*b/(System.currentTimeMillis()-x))/100.0);}}});setVisible(1>0);}};}}

Слухає користувача, коли він натискає пробіл. Потім, коли користувач натиснув його 9 разів, друкує для користувача поточну BPM:

введіть тут опис зображення

Зображення містить повідомлення про налагодження, відсутні у коді для гольфу.


Безголовки:

import java.awt.event.*;

class B {
    public static void main(String[] a) {
        new java.awt.Frame() {
            {
                addKeyListener(new KeyAdapter() {
                    long x = System.currentTimeMillis();
                    int b = 0;

                    public void keyPressed(KeyEvent e) {
                        if (e.getKeyChar() == ' ' && b++ == 9) {
                            System.out
                                    .println(Math.round(6000000.0 * b
                                            / (System.currentTimeMillis() - x)) / 100.0);
                        }
                    }
                });
                setVisible(1 > 0);
            }
        };
    }
}

Якесь задоволення спробувати і отримати високий рейтинг ...

KEY PRESS0 AT 250ms.
KEY PRESS1 AT 343ms.
KEY PRESS2 AT 468ms.
KEY PRESS3 AT 563ms.
KEY PRESS4 AT 672ms.
KEY PRESS5 AT 781ms.
KEY PRESS6 AT 880ms.
KEY PRESS7 AT 989ms.
485

Я вніс незначну зміну і хотів 9 входів, щоб у вас було 8 точок даних для введення замість 7. (має бути лише невелика зміна.)
xNinjaKittyx

Пропущено пробіл:String[]a) {new java
Стівен

Інша справа, я поставив вимогу, яка говорить "Це повинно виводити BPM натискань клавіш, округлених у 2 десяткові крапки". Чи відповідає цей раунд до 2 знаків після коми?
xNinjaKittyx

1
@xNinjaKittyx робить зараз.
Magic Octopus Urn

1
запис 2027.03BPM xD трохи змінив код для кращого бенчмаркінгу
XtremeBaumer

3

C # (.NET Core), 193 206 189 186 155 143 137 байт

-47 байт завдяки TheLethalCoder
-4 байти завдяки Nazar554
-16 байт завдяки Luc
-2 байти завдяки Камілу Дракарі

_=>{var x=new long[9];for(int i=0;i<9;){Console.ReadKey();x[i++]=DateTime.Now.Ticks;}return Math.Round(48e8/(x[8]-x[0]),2);}

Також додано до кількості байтів:

using System;

Ціла програма:

namespace System
{
    class A
    {
        static void Main()
        {
            Func<int, double> f = _ =>
            {
                var x = new long[9];
                for (int i = 0; i < 9; )
                {
                    Console.ReadKey();
                    x[i++] = DateTime.Now.Ticks;
                }
                return Math.Round(48e8 / (x[8] - x[0]), 2);
            };
            Console.WriteLine(f(0));
        }
    }
}

1
Було б коротше, щоб дві змінні мали одну поза циклу після першого натискання клавіші на час запуску, а потім перезаписали іншу в циклі. Я не думаю, що вам потрібно відформатувати вихідне значення, щоб просто +""або навіть повернути подвійне було б добре. namespace System.Diagnostics{}Ймовірно , коротше , але ви використовуєте тільки Diagnosticsна wнастільки повно кваліфікації , що, ймовірно , коротше теж. Зауважте, що ви повинні включити using System;у свій рахунок байт для Consoleдзвінка.
TheLethalCoder

2
замінити 540000.0з5.4e5
Nazar554

1
Ну ви могли б зробити що - щось на зразок (end-start).Millisecondsі набір endі startдо DateTime.Now.
TheLethalCoder

1
Думаю, у вашому розрахунку помилка. Якщо ви заміните ReadKey на Thread.Sleep (100), ви повинні отримати трохи менше 600 БПМ, але ваш код дає більше (приблизно 670 БПМ). Формула повинна бути "60 сек * 1000 мс / (дельтаМс / 8 балів)", що означає "48e8 / deltaMs". Також ви можете повернути $ "{48e8 / (d [8] -d [0]). Тички: n2}" fo -20 ;-)
Люк

1
Я думаю, ви повинні бути в змозі зберегти деякі байти, роблячи 8/TimeSpan.TotalMinutesзамість цього 54e4/TimeSpan.TotalMilliseconds. Крім того, шляхом швидкої перевірки за допомогою "Math.Round (значення, 2)" замість того, value.ToString("n2")щоб зберегти кілька символів, частково тому, що йому потрібно менше дужок
Каміль Дракарі

2

C ++, 150 байт

#include<iostream>
#include<ctime>
#define G getchar()
void f(){G;auto s=clock();G;G;G;G;G;G;G;G;std::cout<<round(6000/(double(clock()-s)/8000))/100;}

Ви можете зберегти 5 байт, якщо ви видалите #defineта замість цього зробитеvoid f(){for(int i=0,auto s=clock();i++<9;){getchar();}std::cout<<round(6000/(double(clock()-s)/8000))/100;}
DJMcMayhem

Ні, тому що якщо я це зробити, томінг розпочнеться до першого введення, тоді як, як кажуть, Час починається з першого введення. Не початок програми
HatsuPointerKun

Чи можна було б змінити рядок 3 на, #define G;getchar()а потім змінити clock();Gна clock()G?
Zacharý

@ Zacharý Я отримую синтаксичні помилки
HatsuPointerKun

Чомусь мій укладач скаржиться round.
Zacharý

2

Пітон + прокльони, 122 байти

import curses as C,time as T
s=C.initscr()
C.cbreak()
t=0
exec's.getch();t=t or T.time()'*9
print'%.2f'%(540/(T.time()-t))

Потрібен cursesмодуль для завантаження.

-9 байт завдяки Феліпе Нарді Батісті


Що робить модуль прокльонів? Проклинаєте вас?
Чарівна восьминога урна

@MagicOctopusUrn Звичайно, це, безумовно, це робить.
HyperNeutrino

час () потрібно починати з першого введення, а не з виконання програми.
xNinjaKittyx

@xNinjaKittyx виправлено; дякую
HyperNeutrino

@MagicOctopusUrn Жартує вбік, це бібліотека графічного інтерфейсу на основі терміналу.
Кролтан

2

vba, 57

msgbox"":x=timer:for i=1to 8:msgbox"":next:?480/(timer-x)

натисніть клавішу Enter або натисніть кнопку ОК у вікні повідомлень.


2

Python 3 , 74 байти

from timeit import*;print('%.2f'%(480/timeit('input()',input(),number=8)))

Спробуйте в Інтернеті!

Це дасть вам нерозумні цифри в TIO, оскільки він працює всі входи відразу, але це працює. timeit()повертає час виконання оператора 'input()'в секундах, виключаючи параметр настройки input(). TIO із затримкою 1с на вхід для перевірки.


1

Java 8, 180 135 байт

-45 байт завдяки @SocratPhoenix пропонує використовувати System.inбезпосередньо.

x->{System.in.read();long t=System.nanoTime(),i=0;for(;i++<8;System.in.read());System.out.printf("%.2f",4.8e11/(System.nanoTime()-t));}

Анонімна лямбда-функція з невикористаним аргументом, який повинен бути призначений методу функціонального інтерфейсу, який видає Exception(приклад нижче). Читає з консолі; удари надсилаються натисканням enter.

Невикольований w / оточуючий тестовий код

public class A {
    interface F{void f(Object x) throws Exception;}

    public static void main(String[]a) throws Exception {
        F f =

        x->{
            System.in.read();
            long t=System.nanoTime(),i=0;
            for(;i++<8;System.in.read());
            System.out.printf("%.2f",4.8e11/(System.nanoTime()-t));
        }

        ;
        f.f(null);
    }
}

1
Чи буде коротше просто читати безпосередньо з System.in?
Сократичний Фенікс

@SocratPhoenix Я ніколи насправді не пробував цього, але, здається, працює; просто використовуючи System.in.read()для блокування, поки не буде отримано вхід. Спасибі! Буде оновлено відповідь.
Джастін Марінер

25559105.43 bpm з цим lol
V. Courtois

1

C #, 117 байт

Відповідь на C # (.NET Core) вже існує . Додано інтерпольовану рядок (такої .NET Core, здається, не вистачає) для виведення та поголений деякі байти, використовуючи довгий масив замість DateTime.

_=>{var d=new long[9];for(var i=0;i<9;){Console.ReadKey();d[i++]=DateTime.Now.Ticks;}return$"{48e8/(d[8]-d[0]):n2}";}

Гуманна версія

class Program
{
    static void Main()
    {
        Func<int, string> f = _ =>
        {
            var d = new long[9];
            for (var i = 0; i < 9;)
            {
                Console.ReadKey();   // Switch these two to "automate" key presses.
                //Thread.Sleep(100); 

                d[i++] = DateTime.Now.Ticks;
            }
            return $"{48e8 / (d[8] - d[0]):n2}";
        };

        var result = f(1);
        Console.WriteLine();
        Console.WriteLine(result);
        Console.ReadKey(true);
    }
}

1

R, 79 84 байт

scan();s=Sys.time;x=s();replicate(8,scan());cat(round(60/as.numeric((s()-x)/8),d=2))

Працює лише під час використання enter, оскільки сканування негайно закінчиться. Явно використовує printдля свого digitsаргументу обробку округлення.

> scan();s=Sys.time;x=s();replicate(8,scan());cat(round(60/as.numeric((s()-x)/8),d=2))
1: 
Read 0 items
numeric(0)
1: 
Read 0 items
1: 
Read 0 items
1: 
Read 0 items
1: 
Read 0 items
1: 
Read 0 items
1: 
Read 0 items
1: 
Read 0 items
1: 
Read 0 items
[[1]]
numeric(0)

[[2]]
numeric(0)

[[3]]
numeric(0)

[[4]]
numeric(0)

[[5]]
numeric(0)

[[6]]
numeric(0)

[[7]]
numeric(0)

[[8]]
numeric(0)

[1] 439.47

Чи також це правильний результат із CPM, що перевищує 1000?
Роман Ґраф

@ RomanGräf витає, ні. Відредаговано.
JAD

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