Construindo um metrônomo

36

Introdução

Alguns dias atrás eu precisava de um metrônomo para alguma coisa. Como não havia nenhum disponível, baixei um aplicativo da App Store. O aplicativo tinha um tamanho de 71 MB !!!
71 MB para criar tic-toc ...?!
Então o código-golfe veio à minha mente e eu estava pensando se alguns de vocês poderiam melhorar isso.

Desafio

Golf algum código que emita algum som. É muito irrelevante que tipo de som. Se necessário, crie algum arquivo de som ... mas um bipe do sistema também fará o trabalho. ( Aqui está um som que eu criei ... nada de especial. )

Entrada : as batidas por minuto que o metrônomo emite.

Exemplo

Esta é uma versão Java sem golfe! É apenas para mostrar a tarefa.

public class Metronome {
  public static void main(String[] args) throws InterruptedException {
    int bpm = Integer.valueOf(args[0]);
    int interval = 60000 / bpm;

    while(true) {
        java.awt.Toolkit.getDefaultToolkit().beep();
        // or start playing the sound
        Thread.sleep(interval);
        System.out.println("Beep!");

    }
  }
}

Regras

Você não pode usar bibliotecas externas, apenas ferramentas da própria linguagem são permitidas.
Apenas os bytes do código fonte contam ... não o arquivo de som.

Isso é , então a submissão com a menor quantidade de bytes ganha!

EDITAR:

Exemplo de saída: Então, algo assim seria a saída para 120 bps : link

PERA
fonte
1
Você pode adicionar alguns exemplos de E / S (gravar algum som e enviá-lo, postar os links aqui)?
Addison Crump
2
Pergunta: quando você diz "bibliotecas externas", isso inclui as bibliotecas sugeridas com o idioma? (I não vai usar este, mas é um exemplo em Vitsy em que I pode aceder concha ou JS (JS mas é incorporado))
Addison Crump
3
Você pode adicionar um snippet de cabeçalho ?
Addison Crump
1
Eu suspeito que a maioria do aplicativo que você baixou é bastante gráfica e efeitos sonoros. É como aqueles apps de lanterna que não fazem nada, mas virar a tela toda branca, mas ainda conseguem usar de alguma forma até dezenas de MB ...
Darrel Hoffman
1
Qual é o requisito de precisão? Em sua amostra, tanto beep()e saída do console não são exatamente IIRC instante. Nenhum dos dois sleep()é conhecido por ser preciso.
Num Lock

Respostas:

19

Mathematica, 26 bytes

Pause[Beep[];60/#]~Do~∞&

Doé normalmente usado como um loop "for" no sentido mais restrito: repita esse trecho de código para cada um ide xpara y... ou mesmo apenas repita esse trecho de código n. Em vez de um número n, podemos dar-lhe infinito para criar um loop infinito. O corpo do loop é Pause[Beep[];60/#]que é apenas uma maneira de escrever golfe, Beep[];Pause[60/#]onde #está o argumento da função.

Se for admissível que a solução exploda eventualmente a pilha de chamadas, podemos salvar um byte com uma solução recursiva:

#0[Beep[];Pause[60/#];#]&
Martin Ender
fonte
Eu não sabia que isso ~Do~∞era possível. Um Forloop me atingiu apenas 29 bytes. (Além disso, eu pessoalmente acredito que a versão 26-byte é o único válido.)
LegionMammal978
@ LegionMammal978 Infelizmente, ~Do~∞parece não funcionar quando se trata de uma variável. (Eu tentei usar que quando golfe sua máquina verdade.)
Martin Ender
1
Attributes[Do]inclui HoldAll, então meu palpite é que _~Do~∞tem um padrão de avaliação especial.
LegionMammal978 23/01
@ LegionMammal978 Parece mais o que as variáveis ​​fazem, porque a mensagem de erro para Do[...,a]onde afica o infinito mostra realmente a chamada como Do[...,{a}].
Martin Ender
14

Pitão, 11 10 9 bytes

Agradeço a Adnan por me lembrar #.

#C7.dc60Q

Para sempre ( #), imprima o Ccódigo har 7. Em seguida, durma ( .d) 60segundos dividido por ( c) input ( Q).

PurkkaKoodari
fonte
@ Adnan Esqueceu sobre isso. Obrigado.
PurkkaKoodari 23/01
Você precisa do espaço?
precisa saber é o seguinte
@ThomasKwa Sim. O IIRC 7.seria analisado como um número.
Conor O'Brien
5
Oh. #pythnoob
Conor O'Brien
2
Eu não conseguia dormir quando tentei. Ele manteve a impressão hora Unix
busukxuan
8

JavaScript, 36 45 42 41 34 bytes

Guardado 1 byte graças a @RikerW

Guardado 1 byte graças a @ETHproductions

n=>{for(;;sleep(60/n))print("\7")}

Esta é uma função.

Se eu usar `\7`, o SpiderMonkey reclama que os literais octais estão obsoletos.

Alternativa, 31 bytes

n=>{for(;;sleep(60/n))print``}

O problema é que os não imprimíveis são removidos, mas isso deve funcionar.

Downgoat
fonte
Droga, eu estava prestes a postar algo assim. Ainda vou publicá-lo (porque ele usa o nó e tudo) porque uso uma abordagem diferente.
Addison Crump
Se você olhar da maneira que fiz a pergunta, a solução recursiva não seria possível. Metrônomos são feitos para trabalhar e trabalhar ... não para travar após algum tempo.
PEAR 23/01
@PEAR, isso não deve travar porque nenhuma variável está sendo incrementada. A única coisa que pode causar o travamento é o buffer do terminal, exceto em computadores modernos que podem levar> 50-100 anos, eu acho
Downgoat
Em que ambiente isso funciona? Eu tentei o chrome e o Node.js, mas não consigo fazê-lo funcionar.
Starbeamrainbowlabs
@starbeamrainbowlabs Isto usa o shell JavaScript (SpiderMonkey)
Downgoat
8

Bash, 53 55 41 bytes

Graças a @Dennis por raspar 14 bytes 1

Ok, hora da verdade: sou péssimo em jogar basquete. Qualquer ajuda seria muito apreciada.

echo " ";sleep `bc -l<<<60/$1`;exec $0 $1
      ^ That's ASCII char 7

1 Caramba. Não é de admirar que ninguém possa superar Dennis.

Addison Crump
fonte
É while 1 possível?
PEAR 23/01
@ PEAR Nupe - já tentei isso.
Addison Crump
while printf \\a possivelmente?
Neil
Isso não funciona, pois o bash usa divisão inteira. Você precisará usar bc.
a spaghetto
1. O caractere BEL não é especial para o Bash, então você não precisa das aspas. 2. Se você ler a entrada como um CLA, não precisará read. 3. echoexiste com o código 0, então você pode usar essa instrução em vez de true.
Dennis
7

JavaScript ES6 (navegador), 43 bytes

Isso pode estar estendendo as regras:

x=>setInterval('new Audio(1).play()',6e4/x)

Dê um nome a esta função (por exemplo F=x=>...) e digite-a no console do navegador nesta página . Em seguida, chame a função com seus bps, por exemplo F(60), e aguarde a mágica acontecer. :-)

Por que isso funciona? Bem, b.htmlestá na mesma pasta que um arquivo chamado1 , que é o arquivo de som de amostra do OP. Não tenho certeza se isso está dentro das regras (acho que é como a versão do shell; ele precisa ser executado em um ambiente específico), mas valeu a pena tentar.

Versão mais segura, 57 bytes

Se o código acima não for permitido por algum motivo, tente o seguinte:

x=>setInterval('new Audio("//ow.ly/Xrnl1").play()',6e4/x)

Funciona em qualquer página!

ETHproductions
fonte
Esta é uma solução interessante. É ainda mais curto quando você baixa e renomeia o arquivo, não é?
PEAR 23/01
@PEAR Isso seria mais curto, mas seria necessário sua própria página da Web com o arquivo de som na mesma pasta para ser executado.
ETHproductions
Ah, é JavaScript xD ... você está certo
PEAR
@ PEAR Lá, eu fiz. Esta nova solução está dentro das regras?
ETHproductions
Hã. Você pode especificar que é JS com a determinada página da web. É um intérprete preexistente, portanto é uma linguagem válida.
Addison Crump
6

05AB1E , 31 bytes

Código:

I60s/[7ç?D.etime.sleep(#.pop())

Se eu tivesse um built-in esperando N segundos, isso poderia ter sido 11 bytes. Infelizmente, esse não é o caso. Aqui está a explicação:

I                               # Push input
 60                             # Push 60
   s                            # Swap the top 2 items
    /                           # Divide the top 2 items
     [                          # Infinite loop
      7ç                        # Push the character \x07
        ?                       # Output it, which give a sound
         .e                     # Evaluate the following as Python code
           time.sleep(       )  # Wait for N seconds
                      #         # Short for stack
                       .pop()   # Pop the last item

Usa a codificação ISO 8859-1.

Adnan
fonte
Essa deve ser uma das primeiras respostas 05AB1E o.Ô Parece muito estranho ver o time.sleepe .pop()no meio do código dessa maneira. ;)
Kevin Cruijssen 20/08
6

osascript, 39 bytes

on run a
repeat
beep
delay 60/a
end
end

Existe literalmente um comando chamado beep? Sweeeet!

Executável apenas no Mac OS X devido a licença restrita, mas para executar, faça:

osascript -e "on run a
repeat
beep
delay 60/a
end
end" bpm
Addison Crump
fonte
6

Python, 68 67 57 bytes

Guardado 1 byte graças a @FlagAsSpam

Guardado 9 bytes graças a @Adnan

import time
a=input()
while 1:print"\7";time.sleep(60./a)

Também demorou 2 bytes a menos depois de converter as terminações de linha no formato UNIX.

Versão mais antiga, que na verdade leva bpm como argumento de linha de comando (66 bytes):

import sys,time
while 1:print"\7";time.sleep(60./int(sys.argv[1]))
webwarrior
fonte
4
Você não pode fazer print"\7";? Não tenho certeza, mas tenho certeza que funciona.
Addison Crump
@Andan Não, input () solicita entrada do usuário. Não sei se isso é considerado uma entrada válida. Também a conversão para número é necessária de qualquer maneira.
Webwarrior
1
Como substituir a=input()e ? Eu sempre pensei que o Python 2 avalia automaticamente a entrada e, portanto, não precisa da conversão int, mas posso estar errado. aint(sys.argv[1])
Adnan
@Andan input()realmente avalia automaticamente. Eu esqueci esse recurso. É bastante antitônico - provavelmente um legado dos velhos tempos.
Webwarrior
Pode time.sleep(60./a)ser substituído por time.sleep(60./input()), enquanto remove completamente a=input()?
clap
4

AutoIt , 56 bytes

Func _($0)
While Sleep(6e4/$0)
Beep(900,99)
WEnd
EndFunc
mınxomaτ
fonte
4

Vitsy, 14 bytes

a6*r/V1m
<wVO7

Modo detalhado (intérprete em breve):

0:                              // a6*r/V1m
push a; // 10
push 6;
multiply top two; // 60
reverse stack; // bpm on top
divide top two; // bpm/60
save/push permanent variable; 
push 1;
goto top method; // goes to 1
1:                              // <wVO7
go backward; // infinite loop, from the bottom of 1
wait top seconds;
save/push permanent variable; // pushes the bpm in terms of seconds of delay
output top as character;
push 7;

Basicamente, eu uso o woperador para aguardar um determinado número de segundos, conforme especificado por bpm/60, envolvido em um loop infinito. Então, faço ruído com a saída do terminal do caractere ASCII 7 ( BEL).

Addison Crump
fonte
Parece bom, mas como posso testar isso? :)
PEAR
@PEAR Você precisará baixar o intérprete (esqueceu de vinculá-lo no título). Salve-o em um arquivo e execute-o com java -jar Vitsy.jar <filename>.
Addison Crump
4

C #, 118 bytes

class A{static int Main(string[]a){for(;;System.Threading.Thread.Sleep(60000/int.Parse(a[0])))System.Console.Beep();}}

Solução básica.

LegionMammal978
fonte
Por que não imprimir ASCII char 7?
Addison Crump
@FlagAsSpam É mais longo: o bipe do sistema é usado System.Console.Beep();e a impressão do personagem é usada System.Console.Write('<\a character>');.
LegionMammal978
Woah. Isso é muito para escrever um personagem.
Addison Crump
4

Java, 103 82 bytes

Obrigado a Justin por cortar 21 bytes!

Oh puxa.

void x(int b)throws Exception{for(;;Thread.sleep(60000/b))System.out.print('\7');}

Método e versão em golf do programa de amostra.

Addison Crump
fonte
Por que não em System.out.print('\7');vez do java.awt.Toolkit.getDefaultToolkit().beep();?
Justin
@ Justin \ é apenas para escapar caracteres regex.
precisa saber é o seguinte
1
não, a barra invertida é uma sequência de escape. '\7'é o personagem sino, que faz um som quando ele é impresso
Justin
@Justin Huh. Eu sempre joguei erros nisso (ao usar aspas duplas). Meu erro. Obrigado! : D
Addison Crump
3

Código de máquina GMC-4 , 21,5 bytes

O GMC-4 é um computador de 4 bits de uma empresa chamada Gakken para ensinar os princípios da linguagem assembly em um conjunto de instruções e computador simplificados. Essa rotina leva a entrada nos endereços da memória de dados 0x5Dpor meio 0x5Fde decimal big-endian (ou seja, um dígito por mordidela).

O algoritmo está basicamente adicionando a entrada à memória e aguardando 0,1s, até que seja pelo menos 600, e subtraindo 600 e emitindo um sinal sonoro, em um loop infinito. Como o GMC-4 possui várias funções de troca de registro, mas nenhuma cópia de registro função de , isso é feito da maneira mais difícil.

Em hexadecimal (a segunda linha está na posição na memória):

A24A14A04 80EC AF5A2EF AE5A1EF AD5A0EF 8A6 F2AF09 86ADEEE9F09
012345678 9ABC DEF0123 4567890 ABCDEF0 123 456789 ABCDEF01234

Na montagem:

    tiy 2     ;ld y, 0x2
    AM        ;ld a, [0x50 + y]
    tiy 1
    AM
    tiy 0
    AM
start:
    tia 0     ;ld a, 0x0
    cal timr  ;pause for (a+1)*0.1 seconds
    tiy F
    MA        ;ld [0x50 + y], a
    tiy 2
    cal DEM+  ;add a to [0x50 + y]; convert to decimal and carry.
    tiy E     ;do the same for the second digit
    MA
    tiy 1
    cal DEM+
    tiy D     ;and the third.
    MA
    tiy 0
    cal DEM+
    tia A
    M+
    jump beep
    jump start
beep:
    tia 6
    tiy D
    cal DEM-
    cal SHTS  ;'play short sound'
    jump start

Aviso Legal:

Na verdade, eu não tenho um GMC-4. Verifiquei meticulosamente este programa com documentação on-line, mas posso ter cometido um erro. Eu também não sei o endianness. Parece que o GMC-4 é big endian, mas não tenho certeza. Se alguém é dono de um GMC-4 e pode verificar isso / me dizer o endianness do GMC-4, eu agradeceria muito.

lirtosiast
fonte
3

C, 48 bytes

void f(int b){while(printf(""))Sleep(60000/b);}
                            ^ literal 0x07 here

Uma solução apenas para Windows (função Sleep (), para ser específico).

Eu também (ab) usei o fato de printf () retornar o número de caracteres impressos para usá-lo como condição de loop infinito.

Há um caractere entre aspas duplas na chamada printf (), mas ele não é exibido aqui por algum motivo. Em caso de dúvida, copie e cole no Sublime Text 2 ou Notepad ++, o caractere será exibido comoBEL .

Isso começou como uma solução C ++, mas meio que caiu no subconjunto C do C ++ (porque, você sabe, Sleep()é um pouco menor que std::this_thread::sleep_for(std::chrono::milliseconds())) eprintf() é menor que std::cout<<).

Alexander Revo
fonte
3

AppleScript 94 bytes

Eu sei que estou muito atrasado, e este é o meu primeiro post aqui, mas tanto faz.

caixa de diálogo "" resposta padrão ""
defina x como 60000 / o texto do resultado retornado
repetir
bip
atraso x
fim

Ungolfed:

caixa de diálogo "" resposta padrão ""
defina x como 60000 / (o texto do resultado retornado)
repetir
    bip
    atraso x
repetição final
Vocês
fonte
Hey, novas respostas :) Infelizmente eu sou incapaz de tentar a sua pós a menos que eu não tenho Mac;) - mas muito obrigado
PERA
@PEAR De nada. :)
Você
Bem-vindo à programação de quebra-cabeças e código de golfe. Esta é uma boa resposta, +1. Por favor, continue respondendo!
Wizzwizz4
2

VBScript, 113 66 bytes

a=InputBox("")
Do
WScript.Echo(Chr(7))
WScript.Sleep(60000/a)
Loop

Este programa é bastante simples; recebe entrada, ecoa o caractere BEL e aguarda. Agradecemos a Niel por cortar quase metade do programa!

Conor O'Brien
fonte
O que há de errado WScript.Echo CHR(7)? Além disso, você quis dizer 60000?
Neil
@ Neil Ah, sim. esqueceu sobre aqueles .;
Conor O'Brien
2

Ruby, 37 33 bytes

m=->b{loop{puts"\7"
sleep 6e1/b}}

Bem direto.

Esta é uma função lambda. Se você queria 60 bpm, você faria: m[60].

Justin
fonte
Teoricamente $><<?\a, também deve funcionar para o sinal sonoro. E não há necessidade de dar um nome para o proc (todas as soluções de JavaScript com função seta gordura também deixá-lo não atribuído), você pode chamá-lo anonimamente também: ->b{loop{$><<?\a;sleep 6e1/b}}[60].
manatwork
@ manatwork Eu só tenho Ruby 2.x, então não pude testar o ?\a; você tem o Ruby 1.x? Se sim, você pode testar se isso funciona?
Justin Justin
Bem, eu tenho um Ruby 1.9.3 e o código não gera nenhum erro com ele. Mas tenho outro problema com o teste: nenhum sinal sonoro na minha máquina. Nem Ruby nem mais nada. Defina algo uma vez, não faço ideia do que.
manatwork
2

Japonês, 30 bytes

6e4/U i`?w Au¹o('../1').play()

O ?deve ser o byte literal 9A. Teste online! (Desculpe pelo pop-up que adia as primeiras batidas; isso será removido em breve.)

Como funciona

6e4/U i"new Audio('../1').play()  // Implicit: U = input bps
6e4/U                             // Calculate 60000 / U.
      i                           // Set a timed event every that many milliseconds,
       "new Audio('../1').play()  // running this code every time.
                                  // ../1 is the path to the file used in my JS entry.
ETHproductions
fonte
2

Caxumba, 18 bytes

R I F  H 60/I W *7

Leia o BPM na variável I, então F {com dois espaços depois} é um loop infinito. Pare por 60 segundos / BPM, depois escreva $ CHR (7) {Ascii: BEL} na saída padrão, fornecendo a saída de áudio necessária e, em seguida, reinicie no loop infinito.

zmerch
fonte
2

Java, 321 caracteres

Parece muito bom. Funciona apenas em sistemas com suporte a MIDI.

import javax.sound.midi.*;import java.util.*;class A{public static void main(String[] a) throws Exception{int d=new Scanner(System.in).nextInt();Synthesizer b=MidiSystem.getSynthesizer();b.open();MidiChannel c=b.getChannels()[0];c.programChange(116);while(true){c.noteOn(0,100);Thread.sleep((int)(d/.06));c.noteOff(0);}}}

.

nomedeusuario.ak
fonte
Parece bom, mas isso não funciona para mim: pastebin.com/0CbGYkU0
PEAR
@PEAR corrigido. Eu esqueci um elenco.
username.ak
@PEAR e uma importação
username.ak
@ PEAR, eu troquei algumas operações por não ter som
username.ak
2

ChucK , 90 bytes

Ruído branco que é ligado e desligado a cada dois tiques.

60./Std.atoi(me.arg(0))*1000=>float s;while(1){Noise b=>dac;s::ms=>now;b=<dac;s::ms=>now;}

Explicação

60./Std.atoi(me.arg(0)) //Convert the input to an int and divide 60 by it
*1000                   //Multiply by 1000 (in order to avoid s::second)
=>float s;              //Store it as a float in variable s
while(1)                //Forever,
{Noise b=>dac;          //Connect a noise generator b to the audio output
s::ms=>now;             //Wait for s milliseconds
b=<dac;                 //Disconnect b from the audio output
s::ms=>now;}            //Wait for s milliseconds

Isso é feito para ativar o som em uma batida e depois desligá-lo depois.

98 versão de 93 bytes (mais sofisticada)

O ruído branco é reproduzido por 10 milissegundos por tick.

60./Std.atoi(me.arg(0))*1000-9=>float s;while(1){Noise b=>dac;10::ms=>now;b=<dac;s::ms=>now;}

Isso é feito para ser um clique, em vez de ativar e desativar o ruído constante.

The_Basset_Hound
fonte
2

Perl 5, 36 bytes

{{$|=print"\a";sleep 60/$_[0];redo}}

Uma sub-rotina; use-o como

sub{{$|=print"\a";sleep 60/$_[0];redo}}->(21)
msh210
fonte
sleepestá em segundos, então você não pode ter mais de 60 sinais sonoros por minuto, não tenho certeza se isso é um requisito. Além disso, você provavelmente pode manter a mesma contagem de bytes, mas ter um programa completo fazendo algo como: $|=<>;{print"\a";sleep 60/$|;redo}(não pode testá-lo agora).
precisa saber é o seguinte
@ChatterOne, de acordo com a documentação, você está certo sleep. Mas funcionou para mim.
Msh210
1

Jolf, 7 bytes, não-competitivo

Eu adicionei sons depois que esse excelente desafio foi feito.

TΑa/Αaj
T       set an interval
 Αa      that plays a short beep (Α is Alpha)
   /Αaj  every 60000 / j (the input) seconds. (Αa returns 60000)

Se você deseja limpar este som, anote a saída. Diga que esse número é x. Execute outro comando Jolf ~CP"x", e o intervalo será limpo.

Conor O'Brien
fonte
1

Zsh , 32 bytes

<<<$'\a'
sleep $[60./$1]
. $0 $1

Com base na resposta principal do bash, mas sources em vez de execs. O TIO vincula as fontes $0:adevido à forma como o arquivo original é executado, mas funcionará sem ele.

Experimente online!

GammaFunction
fonte
Você está atrasado para a festa, mas isso parece uma solução muito boa!
PEAR
Sei que estou atrasado, mas estava com vontade de jogar golfe hoje. Decidiu verificar a etiqueta da música por diversão e encontrou este desafio. Bom, btw!
GammaFunction
0

Bash + bc + > <> , 44 bytes

Brincando com o fato de que o intérprete> <> permite definir um tempo de verificação:

python fish.py -t $(bc -l<<<"2/$1/60") -c 7o

O código> <> é 7oe deve BELgerar o caractere, produzindo um sinal sonoro do sistema. Ele fará um loop até ser interrompido.
O -tvalor é definido como (2 / RPM) / 60 para que todo o código seja reproduzido em RPM * 60 vezes por segundo.

Aaron
fonte
Muito obrigado por uma nova resposta após algum tempo após a publicação. Não funciona para mim :( Não tenho certeza se há algum problema no meu sistema ou algo mais. Fiz o download do fish.py no GitHub e executei seu commad (openSUSE). Consegui este erro: (standard_in) 1: uso de erro de sintaxe: fish py [-h] (<arquivo de script> | -c <code>) [<options>] fish.py: erro: argumento -t / - carrapato: espera um argumento
PERA
Você foi bcinstalado? Parece que o $(bc -l<<<"2/$1/60")não produziu nenhuma saída. Vou adicioná-lo à lista de idiomas da resposta. Ainda não consegui testar completamente minha resposta, por isso também pode haver algum tipo de erro.
Aaron
0

SmileBASIC, 26 bytes

INPUT B$BGMPLAY@8T+B$+"[C]

Ele pode tocar qualquer instrumento midi geral, embora qualquer coisa acima de 9 use mais bytes.

12Me21
fonte
0

Stax, 17 bytes

ü7»♥O╚⌂╥☻≈OyM╜Δ∩`

ou desembalado:

4|A48*x/W2|A]pc{| }*

O programa gera bytes que, quando alimentados pela ferramenta de linha de comando, são exibidos com a configuração padrão, produzem um ruído do metrônomo. A entrada é usada como bpm

exemplo:

example-stax-interpreter metronome.stax -i "60" | aplay

Você deve ouvir um bip horrível nas bpm desejadas

user89655
fonte