Obliczanie BPM z danymi wejściowymi


30

Zaprogramuj najkrótszy kod, który obliczy średni BPM (liczbę uderzeń na minutę) przy użyciu 8 punktów danych czasu, który upłynął. To jest mój pierwszy post i nie widziałem podobnego pytania. Ponieważ jestem fanem gier rytmicznych, fajnie byłoby mieć małe, poręczne narzędzie do obliczania BPM przy użyciu własnej klawiatury i własnego wyczucia rytmu (jeśli masz taki ...)

Wyzwanie

  • Wszystkie dane wejściowe muszą być pojedyncze. (tzn. naciskając tylko „enter” jako „input”)
  • Twój program musi mieć co najmniej 9 danych wejściowych. (Aby utworzyć 8 punktów danych czasu minionego.)
  • Twój program powinien wypisywać BPM naciśnięć klawiszy zaokrąglonych do 2 miejsc po przecinku. (tj. 178,35)
  • Czas zaczyna się od pierwszego wejścia. Nie uruchamia się programu

To jest , więc wygrywa najkrótsza odpowiedź.

Przykład wejścia i wyjścia

Podaj co najmniej jedno przykładowe wejście i wyjście. Upewnij się, że pasują one do twojego opisu tego, jak powinny wyglądać dane wejściowe.

Wkład:

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

Wydajność:

> 60

Obecny zwycięzca to KarlKastor w 22 bajtach przy użyciu Pyth

Mimo że zwycięzca używał Pytha, odpowiedź Matlaba była znaczącą odpowiedzią.


5
Ha! Ciekawe, witamy w PPCG; do wykorzystania w przyszłości mamy również piaskownicę, w której możesz uzyskać informacje zwrotne na temat swoich wyzwań przed ich opublikowaniem. Jest to jednak całkiem dobrze zrobione.
Magic Octopus Urn

Jak obliczamy BPM? Czy zaczynamy mierzyć czas po pierwszym naciśnięciu klawisza, czy kiedy kod zaczyna działać? Czy dzielimy przez 7 lub 8 przed ekstrapolacją?
xnor

Hmm .. Więc czas powinien zacząć się przy pierwszym naciśnięciu klawisza. Jeśli chodzi o podział, zmienię go na 9 wejść (więc dzielicie przez 8)
xNinjaKittyx

Fajne pytanie! Powodzenia
Noah Cristino,

Odpowiedzi:


1

Pyth , 22 bajty

 wJ.d0 mw8.Rc480-.d0J2

(tak, jest wiodąca przestrzeń)

Wejście to prasy „enter”.

Jeśli dozwolone są dodatkowe dane wyjściowe, mogę usunąć spacje i uzyskać wynik 20 bajtów.

example execution

wyjaśnienie

 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 bajtów

Dzięki @LuisMendo za -1 bajt!

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

Musisz nacisnąć enter 9 razy. (Działa również w Octave.)

Tutaj widzisz to w akcji, lewy MATLAB, prawy oktawowy:


Nie! ale round(.,2)czy nie działa, czy też w nowszych wersjach?
flawr

Och, to działa tylko w Matlabie
Luis Mendo

7

JavaScript (ES6), 77 74 bajtów

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

Tworzy onclickzdarzenie w windowobiekcie globalnym . Wysyłaj rytmy, klikając dowolne miejsce w oknie.

Test Snippet


632,41! całkiem niezłe obliczenia :) +1
V. Courtois


5

Bash + typowe narzędzia Linux, 58

script -tt -c'sed -n 9q'
sed '1c2k0
s/ 2/+/;$a480r/p' t|dc

5

JavaScript, 100 , 84 dzięki Powelles , 82 bajty dzięki Justin Mariner

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


1
Powinieneś być w stanie używać Date.now()zamiast new Date().getTime()i 48e4zamiast 480000.
powelles,

Możesz także zaalarmować wynik zamiast go zwracać i przypisać alert do zmiennej, takiej jak (a=alert)()przy pierwszym użyciu, a następnie później a().
powelles,

Ach dziękuję, nigdy myśli 48e4i instanciate i nazywają alertsiebie: (a=alert)().
Serge K.

1
Możesz także przełączyć sna używanie Date.now()i upuścić .getTime()później. Następnie możesz użyć aliasu Date.nowna krótszą nazwę. Inicjał z=nie jest potrzebny, ponieważ funkcja nie jest wywoływana rekurencyjnie. Do 69 bajtów tutaj
Justin Mariner

Aha, a twoje rozwiązanie nie zaokrągla do 2 miejsc po przecinku, o jakie prosi wyzwanie.
Justin Mariner

4

Java 1.5+, 345 339 361 337 bajtów

-34 bajty dzięki Michaelowi za wskazanie, że zapomniałem naprawić import

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

Słucha użytkownika, gdy naciska klawisz spacji. Następnie, gdy użytkownik naciśnie go 9 razy, drukuje z powrotem bieżący BPM:

enter image description here

Obraz ma komunikaty debugowania nieobecne w kodzie golfowym.


Nie golfowany:

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

Trochę zabawy, aby spróbować uzyskać najlepszy wynik ...

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


Brakowało spacji:String[]a) {new java
Stephen

Inną sprawą jest, że stawiam wymóg, który mówi: „Powinien generować BPM naciśnięć klawiszy zaokrąglonych z dokładnością do 2 miejsc po przecinku”. Czy ta runda do 2 miejsc po przecinku?
xNinjaKittyx

1
@xNinjaKittyx robi teraz.
Magic Octopus Urn

1
rekord to 2027.03BPM xD nieznacznie zmodyfikował kod w celu lepszego testowania
XtremeBaumer

3

C # (.NET Core), 193 206 189 186 155 143 137 137 bajtów

-47 bajtów dzięki TheLethalCoder
-4 bajtów dzięki Nazar554
-16 bajtów dzięki Lucowi
-2 bajty dzięki Kamilowi ​​Drakari

_=>{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);}

Dodano również do liczby bajtów:

using System;

Cały program:

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
Byłoby krócej, gdyby dwie zmienne miały jedną poza pętlą po pierwszym naciśnięciu klawisza dla czasu rozpoczęcia, a następnie nadpisały inną w pętli. Nie sądzę, że musisz sformatować wartość wyjściową, więc po prostu +""lub nawet zwrócenie podwójnej wartości byłoby w porządku. namespace System.Diagnostics{}jest prawdopodobnie krótszy, ale używasz go tylko Diagnosticsprzy wtak pełnych kwalifikacjach, że prawdopodobnie też jest krótszy. Pamiętaj, że należy uwzględnić using System;w liczbie bajtów Consolepołączenia.
TheLethalCoder

2
wymienić 540000.0z5.4e5
Nazar554

1
Cóż, zrobiłbyś coś takiego, (end-start).Millisecondsustawiłeś endi startwykonałeś DateTime.Now.
TheLethalCoder

1
Myślę, że masz błąd w obliczeniach. Jeśli zamienisz ReadKey na Thread.Sleep (100), powinieneś otrzymać nieco mniej niż 600 BPM, ale twój kod daje więcej (około 670 BPM). Formuła powinna mieć postać „60 s * 1000 ms / (deltaMs / 8 punktów)”, co przekłada się na „48e8 / deltaMs”. Możesz także zwrócić $ "{48e8 / (d [8] -d [0]). Ticks: n2}" fo -20 ;-)
Luc

1
Myślę, że powinieneś być w stanie zaoszczędzić trochę bajtów, wykonując 8/TimeSpan.TotalMinuteszamiast 54e4/TimeSpan.TotalMilliseconds. Ponadto poprzez szybkie sprawdzenie za pomocą „Math.Round (wartość, 2)” zamiast value.ToString("n2")wydawało się, że uratował kilka znaków, częściowo dlatego, że potrzebował mniejszej liczby nawiasów
Kamil Drakari

2

C ++, 150 bajtów

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

Możesz zapisać 5 bajtów, jeśli usuniesz #definei zamiast tegovoid f(){for(int i=0,auto s=clock();i++<9;){getchar();}std::cout<<round(6000/(double(clock()-s)/8000))/100;}
DJMcMayhem

Nie, ponieważ jeśli to zrobię, czas rozpocznie się przed pierwszym wejściem, podczas gdy mówi się, że czas zaczyna się od pierwszego wejścia. Nie uruchamia się programu
HatsuPointerKun

Czy można zmienić linię 3 na, #define G;getchar()a następnie zmienićclock();G na clock()G?
Zacharý

@ Zacharý Dostaję błędy składniowe
HatsuPointerKun

Z jakiegoś powodu mój kompilator narzeka round.
Zacharý

2

Python + przekleństwa, 122 bajty

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

Wymaga curseszaładowania modułu.

-9 bajtów dzięki Felipe Nardi Batista


Co robi moduł przekleństw? Przekląć cię?
Magic Octopus Urn

@MagicOctopusUrn Oczywiście, że tak właśnie działa.
HyperNeutrino

time () musi zaczynać się od pierwszego wejścia, a nie od wykonania programu.
xNinjaKittyx

@xNinjaKittyx naprawiony; dzięki
HyperNeutrino,

@MagicOctopusUrn Żarty na bok, to biblioteka GUI oparta na terminalach.
Kroltan

2

vba, 57

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

naciśnij enter lub kliknij OK w oknie komunikatu.


2

Python 3 , 74 bajty

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

Wypróbuj online!

To da ci głupie liczby w TIO, ponieważ obsługuje wszystkie wejścia naraz, ale działa. timeit()zwraca czas wykonania instrukcji 'input()'w sekundach z wyłączeniem parametru setup input(). TIO z opóźnieniem 1 s na wejście do weryfikacji.


1

Java 8, 180 135 bajtów

-45 bajtów dzięki @SocraticPhoenix sugerującym użycie System.inbezpośrednio.

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

Anonimowa funkcja lambda z nieużywanym argumentem, który musi być przypisany do funkcjonalnej metody interfejsu, która wyrzuca an Exception (przykład poniżej). Odczytuje z konsoli; uderzenia są wysyłane przez naciśnięcie enter.

Ungolfed z otaczającym kodem testowym

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
Czy krótsze byłoby czytanie bezpośrednio z System.in?
Socratic Phoenix,

@SocraticPhoenix Tak naprawdę nigdy tego nie próbowałem, ale wydaje się, że działa; po prostu używaj System.in.read()do blokowania, aż do otrzymania danych wejściowych. Dzięki! Zaktualizuje odpowiedź.
Justin Mariner,

25.559.105,43 bpm z tym LOL
V. Courtois

1

C #, 117 bajtów

Istnieje już odpowiedź w języku C # (.NET Core), na której opiera się ta. Dodano interpolowany ciąg (którego brakuje .NET Core) dla danych wyjściowych i ogolono niektóre bajty za pomocą długiej tablicy zamiast 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}";}

Wersja humanitarna

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 bajtów

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

Działa tylko przy użyciu enter, ponieważ natychmiast zakończy skanowanie. Jawnie używa printswojego digitsargumentu do obsługi zaokrąglania.

> 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

Czy to również zaokrągla poprawnie przy CPM większym niż 1000?
Roman Gräf

@ RomanGräf woops, nie. Edytowane.
JAD

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.