99 erros no código

47

99 erros no código

A adaptação de "99 garrafas de cerveja na parede" para a ciência da computação, onde os bugs aumentam em vez de diminuir as garrafas, é frequentemente publicada na Internet. Exemplo de camiseta aqui .

Eu acho que será interessante ver uma possível recursão e geração aleatória de números em uma enorme variedade de idiomas e encontrar as maneiras mais eficientes de fazer isso.

Existem alguns outros desafios a serem enfrentados com 99 garrafas de cerveja, mas nenhuma parece ter um número crescente e decrescente!

Desafio

Seu programa ou função não deve receber nenhuma entrada e depois imprimir

99 erros no código

99 erros no código

Pegue um e remova-o

X erros no código

(linha em branco)

Onde X é o número inteiro anterior menos 1 mais um número inteiro aleatório no intervalo [-15,5].
Você pode mesclar o menos 1 no número inteiro aleatório, permitindo o intervalo [-16,4].
As faixas podem ser exclusivas, portanto menos um mais (-16,6) ou (-17,5).

Os números inteiros aleatórios não precisam ser distribuídos uniformemente, apenas precisam ser possíveis.

O programa sempre começa com 99 bugs.

Você pode ignorar o erro gramatical de "1 erro".

O programa deve parar quando o número de bugs for 0 ou negativo e imprimir

0 erros no código

Nunca deve haver um número negativo de bugs. O final deve parecer

Y erros no código

Y erros no código

Pegue um e remova-o

0 erros no código

(linha em branco)

0 erros no código

Uma nova linha à direita é aceitável.

  • Seu código pode ser um programa completo ou uma função.
  • Não há entrada.
  • A saída deve ser stdout ou retornada.
  • Avisos / erros nos logs / STDERR são válidos desde que STDOUT possua o texto necessário. Veja aqui para mais informações.

Isso é código-golfe, portanto o código mais curto em bytes vence.

Saída de exemplo

Saída de exemplo de caixa de colagem criada para -11 erros cada vez

Sam Dean
fonte
1
Relacionado: 1 2 (diferença: nesse desafio a saída pode ser arbitrariamente longa).
User202729
16
Um cenário mais realista seria se o sinal do número aleatório fosse invertido!
Stewie Griffin
9
Estou desapontado por os requisitos não incluírem que o programa deva ter um bug assim que um número negativo for encontrado, como travar, transbordar para max int ou similar;).
allo
3
"Os números inteiros aleatórios não precisam ser distribuídos uniformemente, apenas precisam ser possíveis". lembrou-me de xkcd.com/221
Ivo Beckers
2
É uma pena que o 99 não tenha geração de números aleatórios.
Jonathan Allan

Respostas:

18

R , 182 140 138 135 bytes

n=99;while(n)cat(n,b<-" bugs in the code
",n,b,"take one down and patch it around
",n<-max(0,n-sample(21,1)+5),b,"
",c(n,b)[!n],sep="")

Experimente online!

embora seja razoavelmente bom na geração aleatória de números, R é péssimo em strings e impressão. JayCe encontrou cerca de um bilhão de bytes e continua a encontrar novas maneiras de jogar isso!

Giuseppe
fonte
1
Onde JayCe encontrou todos esses bytes? Foi apenas um acaso ou JayCe estava procurando ativamente por eles?
Stewie Griffin
Não está lhe +5custando mais 2 bytes? por que não apenas sample(26,6))?
Theforestecologist
2
@theforestecologist Bem-vindo ao PPCG! Eu sugiro que você dê uma olhada mais de perto a questão ... há um sinal de menos na frentesample
Jayce
11

Java 8, 161 160 bytes

v->{String s="",t=" bugs in the code\n";for(int i=99;i>0;s+=i+t+i+t+"Take one down and patch it around\n"+((i-=Math.random()*21+4)<0?0:i)+t+"\n");return s+0+t;}

-1 byte graças a @ JonathanAllan .

Experimente online.

Explicação:

v->{                   // Method with empty unused parameter and String return-type
  String s="",         //  Result-String, starting empty
         t=" bugs in the code\n";
                       //  Temp-String we use multiple times
  for(int i=99;i>0;    //  Start `i` at 99, and loop as long as it's larger than 0
    s+=                //   Append to the result-String:
       i+t             //    The first line of the verse
       +i+t            //    The second (duplicated) line of the verse
       +"Take one down and patch it around\n"
                       //    The third line of the verse
       +((i-=Math.random()*21-4)
                       //    Decrease `i` by a random integer in the range [-16, 4]
         <0?0:i)       //    If `i` is now negative, set it to 0
        +t+"\n");      //    And append the fourth line of the verse
  return s             //  Return the result,
         +0+t;}        //  appended with an additional line for 0 at the very end
Kevin Cruijssen
fonte
Parece que você não está usando rnada?
OOBalance
1
A remoção ,rparece ainda funcionar: Experimente online!
Kamil Drakari
@OOBalance Opa .. Não sei por que cheguei lá ..>.> Obrigado por perceber.
Kevin Cruijssen
1
i - = ... + 5 salva um (embora eu acho que a faixa deve ser [-16 4] não [-15,5])
Jonathan Allan
1
@OOBalance sim r não é usado, porque ele é usando java ;-)
Anand Rockzz
10

PowerShell , 137 135 133 131 bytes

$b=' bugs in the code';for($a=99;$a){,"$a$b"*2;"Take one down and patch it around";$a+=-16..4|Random;if($a-lt0){$a=0}"$a$b`n"}"0$b"

Experimente online!

A seção "bugs no código" é salva $bpara uso posterior. Define $acomo 99, entra em um forloop $a. Primeiro, criamos uma matriz de duas cadeias ," "*2, com a cadeia sendo a "X bugs in the code".

Em seguida é apenas a corda "Take one down and patch it around". Em seguida, incrementamos $aselecionando um Randomnúmero inteiro no intervalo [-16,4]. Depois disso, fixamos $apara estar no mínimo zero usando um if if($a-lt0){$a=0}. Então a corda "Y bugs in the code".

Finalmente, depois que o loop termina, colocamos a corda "0 bugs in the code"no pipeline. Todas essas strings são coletadas do pipeline, e um implícito Write-Outputnos fornece novas linhas entre elas de graça.

Salva dois bytes usando um forloop em vez de um whileloop.
Salva dois bytes movendo $b- se para sua própria seção.
Economizou dois bytes graças a Adrian Blackburn.

AdmBorkBork
fonte
Você pode substituir $ a = (0, $ a) [$ a-gt0]; com If ($ a-lt0) {$ a = 0} por alguns bytes
Adrian
@AdrianBlackburn Thanks!
AdmBorkBork
9

JavaScript (Node.js) , 127 bytes

f=(i=99,t=` bugs in the code
`)=>i>0?i+t+`Take one down and patch it around
`+((i+=0|Math.random()*21-15)<0?0:i)+t+`
`+f(i):0+t

Experimente online!


Explicação:

f = (                                          // start of our recursive function
    i=99,t=` bugs in the code                 // parameters, 1. num bugs , 2. text
`)                                           // using string literal end text with \n
=>                                          // start function
    i > 0 ?                                // if i is greater than 0
        i + t +                           // return value of i, value of t and  
    `Take one down and patch it around   // and this text 
    `                                   // + new line
    + (( i +=                          // and add 
        0|Math.random()*21-15) < 0 ?  // remove decimal from value obtained by multiplying
                                     // random number (between 0 and 1) multiplied by 21 
                                    // and then subtracting 15 from it
                                   // if that value is less than 0
        0 :                       // add 0 to i
        i                        // otherwise add value of i  
        )                       // end the parenthesis 
    + t                        // add value of t to that
    + `\n`                    // along with a new line 
    + f(i)                   // and repeat the process (this is recursive)
    :                       // if i > 0 condition not met then
        0 + t              // return 0 + t. Zero is there so the last line can be 
                          // repeated

Obrigado a @tsh pela idéia de recursão e implementação (salvou alguns bytes)

Todas as sugestões de golfe ainda são bem-vindas.

Muhammad Salman
fonte
1
Por que foi 0+removido? Parece ser uma saída necessária.
tsh
@tsh: É? Eu não li essa parte.
Muhammad Salman
7

05AB1E , 59 bytes

99[Ð16(4ŸΩ+¾‚{θ©3F“ÿ±À€†€€ƒË“Š}“ƒ¶€µ„‹€ƒš¡€•…¡“ªsõ®>#®]sDŠ»

Experimente online!

Emigna
fonte
6

Python 2 , 151 bytes

Bom truque j=i+max(-i,randint(-16,4))de Jo King, explorando a distribuição desigual permitida

Salvou alguns bytes graças ao Mnemonic

from random import*
i,s=99,'bugs in the code\n'
while i:j=max(0,i+randint(-16,4));print i,s,i,s,'Take one down and patch it around\n',j,s;i=j
print i,s

Experimente online!

Gambá morto
fonte
1
Você pode salvar um byte usando j=max(0,i+randint(-16,4)).
Mnemonic
Além disso, é 'bugs no do código'.
Mnemonic
Usando 0 para comparar o wiil, nem todos os números são possíveis. Obrigado por nada 'the': D
Dead Possum
O mesmo truque que a minha resposta, 151 bytes
Jo King
Eles não são possíveis de qualquer maneira. Você não está autorizado a ir abaixo de 0.
Mnemonic
6

Carvão vegetal , 81 bytes

≔⁹⁹θ≔”⧴"pWº⁴tSn/{yBⅈ⁺”ζW›θ⁰«×²﹪ζθ”↶0⪫\`3+¤⸿Zν(z¬hLÀTj'ZXεPraF”≧⁺⁻⁴‽²¹θ﹪ζ×θ›θ⁰¶»﹪ζ⁰

Experimente online! Link é a versão detalhada do código. Explicação:

≔⁹⁹θ

Comece com 99 erros no código.

≔”⧴"pWº⁴tSn/{yBⅈ⁺”ζ

Salve a sequência compactada "% d erros no código \ n".

W›θ⁰«

Repita enquanto houver um número positivo de erros restantes.

ײ﹪ζθ

Imprima o número de bugs no código duas vezes.

”↶0⪫\`3+¤⸿Zν(z¬hLÀTj'ZXεPraF”

Imprima "Pegue uma e remova-a".

≧⁺⁻⁴‽²¹θ

Adicione um número aleatório de bugs entre -17 (exclusivo) e 4 (inclusive).

﹪ζ×θ›θ⁰

Imprima o número de bugs restantes ou 0 se negativo.

Deixe uma linha em branco entre os versículos.

»﹪ζ⁰

Após o último verso, imprima 0 erros no código novamente.

Neil
fonte
Precisa desse final repetido "0 bugs no código"!
Sam Dean
1
@ SamDean Desculpe, eu tinha esquecido isso, corrigido.
305 Neil
6

JavaScript, 189 176 168 162 bytes

f=(x=99)=>{c=console.log;m=Math;a=` bugs in the code
`;c(x+a+x+a+"Take one down and patch it around"+(x=m.max(x+m.ceil(m.random()*21-15),0))+a)
x?f(x):c(`
`+x+a)}

Experimente online!

Obrigado por Muhammad Salman pela falta de console.logsubstituição e por Oliver pela melhoria do teste x

Obrigado por l4m2 por jogar este por 8 bytes

O cara aleatório
fonte
Não sou especialista em nós, mas acredito que "o programa deve parar quando o número de bugs for 0 ou negativo" significa que você precisa x<=0?console.log("\n"+0+a):f(x)no final.
NoOneIsHere
1
Ok desculpe. Só mais uma coisa: se você precisa recurse em uma função anônima, você precisa nomear explicitamente que (+2 bytes)
NoOneIsHere
1
esse último "console.log" não pode ser substituído por "c"?
Sam Dean
1
Também @NoOneIsHere está certo. Você precisa dessa fdeclaração. Votado até atualizado para corrigir isso. (Também o meu link precisa de uma atualização também)
Muhammad Salman
2
O ponto que estou tentando enfatizar aqui é que seu código não funcionará se a função não for chamada f, o que você não pode assumir.
NoOneIsHere
6

Python 3 , 156 138 bytes

Graças à resposta de Jonathan Python 2 para o idtruque

r=n=99
z='%d bugs in the code\n'
while n:x=n;r+=id(r);n-=min(n,r%21-4);print((z%x)*2+'Take one down and patch it around\n'+z%n)
print(z%n)

Experimente online!

Explicação:

r=n=99       #Initialise r and n to 99
z='%d bugs in the code\n'  #Save n
while n:     #Loop while n is not 0
    x=n      #Save value of n
    r+=id(r) #Modify value of r, which changes the hash value
    n-=min(n,r%21-4)  #Change n's value by a random number between 4 and -16
    print((z%x)*2+'Take one down and patch it around\n'+z%n)   #Print the message
print(z%n)  #And print the final line
Brincadeira
fonte
5

Oitava , 149 148 bytes

Salvou um byte alterando randi(21)e %ipara 21*rande %.f. %.fgarante que a saída seja flutuante com zero decimal (ou seja, inteiro).

Inserido um monte de quebras de linha em vez de vírgulas e ponto e vírgula para facilitar a legibilidade. Parece errado, mas não é mais do que o one-liner.

x=99;do(p=@(i)printf('%.f bugs in the code\n',i))(x)
p(x)
disp('Take one down and patch it around')
p(max([0,x+=21*rand-17]))
disp('')until x<1
p(0)

Experimente online!

Explicação:

x=99;               % Initialize the number of bugs to 99
do ...  until x<1   % Loop until the number of bugs is less than 1
 (p=@(i)printf('%.f bugs in the code\n',i))(x)  % Create a function handle p that takes
                                                % the number of bugs as input and outputs
                                                % the string x bugs ... \n
 p(x)                % Call that function with the same number of bugs to get two lines
 ,disp('Take on down and patch it around')       % Outputs that line, including a newline
 ,p(max([0,x+=21*rand-17]))                    % Call p again, while updating the number
                                                 % of bugs. The number of bugs will be 
                                                 % the old one plus the random number, or 0
                                                 % if it would have turned negative
 ,disp('')        % A newline
p(0)              % Finally, the last single line.

Usar em p((x+=21*rand-17)*(x>0)vez de maxsalva um byte, mas a última linha é exibida em -0 bugs ...vez de 0 bugs. Funciona com randi(21)-17, mas tem o mesmo comprimento que o acima. Experimente online!

Stewie Griffin
fonte
5

COBOL (GnuCOBOL), 317 294 279 270 bytes

data division.working-storage section. 1 i pic S99 value 99.procedure division.perform until i=0 perform a 2 times display"Take one down and patch it around"compute i=i-(random*21- 4)if i<0 compute i=0 end-if perform a display""end-perform.a.display i" bugs in the code"

Experimente online!

Ungolfed

data division.                     <-- Define the variables we want to use
working-storage section.           <-- Define global variables used in this
                                       program

1 i pic S99 value 99.              <-- Define variable i with datatype signed
                                       numeric and with two digits

procedure division.                <-- Define our program

perform until i = 0                <-- Perform the following code until i = 0
    perform a 2 times              <-- Execute the procedure called 'a' twice,
                                       see below

    display "Take one down and patch it around"   <-- Display this sentence
    compute i = i -                <-- Subtract from i some random value
        (random * 21 - 4)

    if i < 0                       <-- if i < 0
        compute i=0                <-- then assign 0 to i
    end-if
    perform a                      <-- Execute the procedure 'a'
    display ""                     <-- Display an empty string; needed because
                                       of the blank line
end-perform.

a.                                 <-- Define procedure called 'a'.
    display i " bugs in the code"  <-- Display the value of i and then the
                                       given string literal

Nota: a última frase ainda é impressa, porque o COBOL executa todo o programa e após o perform until loop, "passa" pelo rótulo a , executando suas instruções. Esse comportamento é semelhante a um switch casesem break.

PS: Os números não são exatamente exibidos conforme necessário, mas o COBOL não é tão bom na conversão automática de números em uma representação bastante textual.

MC Emperor
fonte
1
Oi. Bem-vindo ao PPCG.
Muhammad Salman
Eu acho que menos 4 deve ser mais 4. Acho que você optou por (i- (rand-4) == (i-rand + 4). Mas como não há colchetes, o sinal precisa mudar. dos números ser removido ou isso é uma característica da linguagem mas bom trabalho com uma linguagem amigável non ouro?!
Sam Dean
1
@SamDean Thanks! Eu consertei esse erro. Eu tenho que admitir que o aleatório real calculado foi inspirado na resposta de Kevin Cruijssen . Mas ele usa um operador de atribuição composto ( -=in i-=Math.random()*21-4), que implica parênteses em torno de todo o operando do lado direito. Eu esqueci de explicitar, mas agora está corrigido, eu acho.
MC Emperor
@MCEmperor parece bom para mim agora!
Sam Dean
Você não pode usar +4 e salvar os colchetes?
raznagul #
4

VBA: 212 163 bytes

Esta solução é baseada na que Chronocidal postou ontem. Este é o meu primeiro post e não tenho reputação suficiente para comentar sobre o post dele.

Esta revisão contém dois aprimoramentos.

  1. Usar em While/Wendvez de For/Nextsalva alguns caracteres.
  2. Chamar um Sub nomeado com um único caractere é mais curto que GoSube as linhas Exit Sube Returnnecessárias para suportá-lo.

Edit:
3. Removido o espaço em branco e os caracteres que o editor do VBA adicionará automaticamente de volta. Consulte Dicas para jogar golfe no VBA
. espaço em branco. Uma alteração de chave era anexada vbLFà sequência de saída, portanto Debug.Print, não precisava ser chamada com tanta frequência. Muitos elogios para EricF .


Sub b()
s=" bugs in the code"&vbLf
c=99
While c
Debug.? c &s &c &s &"Take one down and patch it around
c=c+5-Int(Rnd()*20)
c=IIf(c<0,0,c)
Debug.? c &s
Wend
End Sub

Este foi um desafio divertido. Se você conhece um intérprete on-line como o TIO for VB6 / VBScript / VBA, deixe um comentário.

Se você deseja testar esse código e ter o Microsoft Excel, Word, Access ou Outlook instalado (apenas Windows), pressione Alt + F11 para abrir o IDE do VBA. Insira um novo módulo de código (Alt + I, M) e limpe Option Explicit. Em seguida, cole o código e pressione F5 para executá-lo. Os resultados devem aparecer na janela Imediata (pressione Ctrl + G se você não a vir).

Ben
fonte
4
Bem vindo ao site!
Wheat Wizard
1
Você pode obtê-lo para baixo a 197 caracteres se você combinar cordas, use cem vez de c>0como sua condição Enquanto, e usar c=Iif(c<0,0,c), em vez de If c<0 [...]: pastebin.com/nFGtGqdE
ErikF
4

LaTeX , 368 304 293 287 245 240 bytes

Embora não seja realmente competitivo comparado aos outros programas em termos de bytes, eu só queria ver como fazer isso no LaTeX.

\documentclass{proc}\newcount\b\b99\usepackage[first=-16,last=5]{lcg}\def~{\the\b\ bugs in the code\\}\def\|{\loop~~Take one down and patch it around\\\rand\advance\b\value{rand}\ifnum\b>0 ~\\\repeat\b0 ~\\~}\begin{document}\|\end{document}

Mais legível:

\documentclass{proc}               %shortest document class
\newcount\b                        %short variable name
\b 99                              %set the value to 99
\usepackage[first=-16,last=5]{lcg} %random number generator
%\the prints the value of the variable behind it
%\def is shorter than \newcommand and can redefine commands
\def~{\the\b\ bugs in the code\\}
\def\|{                            %the function
    \loop
        ~
        ~
        Take one down and patch it around\\
        %\rand creates a counter named rand and                                        
        %stores the random value in it
        \rand \advance\b\value{rand} 
        %if the counter is smaller than 0, it becomes 0
        \ifnum\b>0 
            ~ \\                  %extra newline as required
    \repeat
    %if b is equal or smaller than 0, set it to 0
    \b 0 
    ~ \\                          %then print like normal
    %extra print at the end
    ~
}
\begin{document}
    \|                             %calling the function
\end{document}

Melhorias (por edição):

  1. "x bugs no código" agora é uma função em vez de 4 linhas
  2. Reescreveu a \ifcláusula para o\repeat as\else
  3. Aparentemente, \value{b}=xfunciona para inicialização, mas não no loop (em vez de\setcounter{b}{x} )
  4. Aparentemente, \relaxdeve ser usado para o ponto 3, mas isso também pode ser alcançado através da inserção de um espaço. Removidos os \elsecomandos TeX usados ​​em vez do LaTeX, pois são mais curtos e substituídos \'por~ .
  5. Algum código não precisou ser relaxado por algum motivo.
Simon Klaver
fonte
1
Bem-vindo ao PPCG.
Muhammad Salman
Bem-vindo ao PPCG! Eu não executar seu código, mas não deveria ser \ifnum\value{b}<1, em vez de <0?
Jayce
@ JayCe: Realmente não importa, uma vez que b é 0, ele escapa do loop de qualquer maneira. Pode ser menos intuitivo que, quando b é 0, o caso else seja impresso, mas efetivamente não há diferença, eu acho.
Simon Klaver
@JayCe encurtou o código, agora não importa mais;)
Simon Klaver
4

C,  169  165 bytes

Obrigado a @ceilingcat por salvar quatro bytes!

*s=" bugs in the code";f(i,j){for(i=99;i>0;i=j)printf("%d%s\n%d%s\nTake one down and patch it around\n%d%s\n\n",i,s,i,s,(j=i+rand()%19-15)<0?0:j,s);printf("0%s",s);}

Experimente online!

Steadybox
fonte
3

SAS, 210 bytes

%macro t;%let b=bugs in the code;%let a=99;%do%until(&a<=0);%put&a &b;%put&a &b;%put Take one down, pass it around;%let a=%eval(&a-%sysfunc(ranbin(0,20,.3))+4);%if &a<0%then%let a=0;%put&a &b;%put;%end;%mend;%t

Ungolfed:

%macro t;
%let b=bugs in the code;
%let a=99;
%do%until(&a<=0);
  %put &a &b;
  %put &a &b;
  %put Take one down, pass it around;    
  %let a=%eval(&a-%sysfunc(ranbin(0,20,.3))+4);
  %if &a<0%then%let a=0;
  %put &a &b; 
  %put;
%end;
%mend;
%t

Pode economizar alguns bytes, se são permitidos avisos no log (coloque o &ana &bvariável de macro, mas que gera um aviso inicial).

Joe
fonte
Alguns outros têm avisos, então eu vou com eles são permitidos.
Sam Dean
3

PHP, 126 bytes

Execute na linha de comando, usando php -r 'code here':

$b=" bugs in the code
";for($x=99;print$x.$b,$x;)echo"$x{$b}Take one down and patch it around
",$x-=min($x,rand(-4,16)),"$b
";
PleaseStand
fonte
3

ABAP , 295 bytes

... porque por que diabos não!

REPORT z.DATA:a(16),c TYPE qfranint.a = 'bugs in the code'.data(b) = 99.WRITE:/ b,a.WHILE b > 0.WRITE:/ b,a,/'Take one down and patch it around'.CALL FUNCTION
'QF05_RANDOM_INTEGER' EXPORTING ran_int_max = 21 IMPORTING ran_int = c.b = b + c - 17.IF b < 1.b = 0.ENDIF.WRITE:/ b,a,/,/ b,a.ENDWHILE.

Certamente não é competitivo em comparação com outros idiomas, mas eu consegui reduzi-lo dos 330 bytes que escrevi inicialmente, então conto como uma vitória pessoal.

Como o ABAP não permite linhas com mais de 255 caracteres, tive que substituir um espaço por uma quebra de linha. No Windows, isso inicialmente aumentou o tamanho para 296 bytes devido ao CRLF, mas funciona bem apenas com o LF existente. A ABAP com certeza exige muitos espaços, portanto, isso não é grande coisa.

WRITE simplesmente despeja o texto da GUI, então acho que é como stdout? Provavelmente eu poderia salvar alguns bytes aqui usando uma estrutura ou tabela, mas devido à maneira como o SAP lida com estruturas mistas (contendo caracteres e números), a abordagem que imaginei funcionaria apenas em sistemas não Unicode ... Que eu pessoalmente considero um vá, apesar de ter acesso a ambos.

O módulo de função para números aleatórios é o único que eu poderia encontrar em nosso sistema, suponho que poderia haver um com um nome ou parâmetros mais curtos. Nenhuma idéia!

Código mais ou menos legível, comentários incluídos:

REPORT z.
  "Define a (text) and c (random)
  DATA: a(16),
        c TYPE qfranint. "A stupid data type for a random INT

  "This is shorter than using VALUE (saves 3 bytes)
  a = 'bugs in the code'.
  "This is slightly shorter than doing ',b TYPE i' and 'b = 99'. (saves 2 bytes)
  data(b) = 99.

  "first line has to be outside of loop due to our exit condition (saved me ~5 bytes)
  WRITE: / b,a. "\n xx bugs in the code

  WHILE b > 0.
    WRITE: / b,a, "\n xx bugs in the code
    /'Take one down and patch it around'.

    "This ridiculous function for random numbers...
    "To save some bytes, I leave ran_int_min at it's default
    "of 1, and set the max to 21 instead, from which I remove
    "17 later on, resulting in a range of [-16,4]
    "Compare:
    "   ' - 17'              =  5 bytes
    "   ' ran_int_min = -16' = 18 bytes
    "(saves 13 bytes)

    CALL FUNCTION 'QF05_RANDOM_INTEGER'
        EXPORTING ran_int_max = 21
        IMPORTING ran_int = c.

    "Maximum number of bugs added:     4 = 21 - 17
    "Maximum number of bugs removed: -16 =  1 - 17
    b = b + c - 17.

    IF b <= 0.
        b = 0.
    ENDIF.

    WRITE: / b,a,/,/ b,a. "\nxx bugs in the code\n\nxx bugs in the code
  ENDWHILE.

Obrigado pelo desafio!
Para o meu chefe: Por favor, não me demitir, estou apenas me educando!

Maz
fonte
3

Limpo , 245 234 bytes

import StdEnv,Math.Random,System.Time,System._Unsafe,Text
f[n,v:l]b|n>0=n<+b<+n<+b+"Take one down and patch it around\n"<+max 0v<+b+"\n"+f[v:l]b=0<+b

f(scan(+)99[n rem 20-16\\n<-genRandInt(toInt(accUnsafe time))])" bugs in the code\n"

Experimente online!

Furioso
fonte
Alguma chance de remover as aspas no início e no final?
Sam Dean
1
@ SamDean Oh, isso é apenas uma opção do compilador que eu esqueci. Eu vou fazer isso em.
Οurous
3

C #, 184 181 bytes

Minha primeira resposta do Code Golf!

(Baseado na resposta Java de @Kevin Cruijssen)

Func<String>c=()=>{String s="",t=" bugs in the code\n";for(int i=99;i>0;s+=i+t+i+t+"Take one down and patch it around\n"+((i-=new Random().Next(21)-4)<0?0:i)+t+"\n");return s+0+t;};

Experimente online!

Ben Noble
fonte
1
Bem-vindo ao PPCG :)
Shaggy
2

T-SQL, 188 bytes

DECLARE @ INT=99,@b CHAR(18)=' bugs in the code
'a:PRINT CONCAT(@,@b,@,@b,'Take one down and patch it around
')SET @+=5-22*RAND()IF @<0SET @=0PRINT CONCAT(@,@b,'
')IF @>0GOTO a;PRINT '0'+@b

O SQL permite retornos dentro de literais de string, o que ajuda.

CONCAT()faz uma conversão implícita em texto para que eu não precise me preocupar com CASTou CONVERT.

BradC
fonte
2

JavaScript, 138 bytes

_=>(I=i=>`Take one down and patch it around
${l=(i>0?i:0)+` bugs in the code
`}
`+l+l+(i>0&&I(i+Math.random()*21-15|0)))(99).slice(55,-25)

darrylyeo
fonte
2

QB64 , 134 bytes

Do meu irmão.

S$="bugs in the code":I=99:WHILE I>0:?I;S$:?I;S$:?"Take one down and patch it around":I=I+INT(RND*21)-15:I=-(I>0)*I:?I;S$:?:WEND:?I;S$
ErikF
fonte
2

Pitão , 94 92 bytes

J99WJ%jb[K"%d bugs in the code"K"Take one down and patch it around"Kk)[JJ=JeS,Z+J-O21 16;%KZ

Experimente online


Versão anterior: 94 bytes

J99WJp%jb[K"%d bugs in the code"K"Take one down and patch it around"K)[JJ=JeS,Z+J-O21 16)b;%KZ
Sok
fonte
2

Geléia , 61 bytes

;“,Ȥm46Ṛṛ⁽eɼḞF»
ÇȮ“"ḃḲɠ⁼ċTṪʠ/Ạ⁺ṗḍ^ẸƘⱮṖ8»20X+_«¥©17Ç⁷®ßÇ®?
99Ç

Um link niládico que também funciona como um programa completo.

Experimente online!(a saída é liberada após a conclusão da execução, mas imprime parágrafo por parágrafo)

Quão?

;“,Ȥm46Ṛṛ⁽eɼḞF» - Link 1, helper to construct count-text: number
 “,Ȥm46Ṛṛ⁽eɼḞF» - compressed string (list of characters) = " bugs in the code\n"
;               - concatenate the number with that list of characters

ÇȮ“"ḃḲɠ⁼ċTṪʠ/Ạ⁺ṗḍ^ẸƘⱮṖ8»20X+_«¥©17Ç⁷®ßÇ®? - Link 2, print stuff: number
Ç                                         - call the last Link (1) as a monad
 Ȯ                                        - print and yield that
                                          - ...at this point that is then printed again
                                          -    implicitly due to the start of a new leading
                                          -    constant chain below
  “"ḃḲɠ⁼ċTṪʠ/Ạ⁺ṗḍ^ẸƘⱮṖ8»                  - compressed string (list of characters)
                                          -     = "Take one down and patch it around\n"
                                          - ...once again an implicit print, same reason
                        20                - twenty
                          X               - random int from [1,20] 
                           +              - add the left argument, the number
                                17        - seventeen
                              ¥           - last two links as a dyad:
                             «            -   minimum (of rand[1,20]+n and 17) 
                            _             -   subtract
                               ©          - copy this newNumber to the register
                                  Ç       - call last Link (1) as a monad = f(newNumber)
                                          - here we get another implicit print, same reason
                                   ⁷      - a new line character
                                          - yet another implicit print, same reason
                                    ®     - recall newNumber from the register
                                        ? - if... 
                                       ®  - ...condition: recall from register again
                                          -               (i.e. if non-zero)
                                     ß    - ...then: call this Link (2) as a monad
                                          -          = Link 2(newNumber)
                                      Ç   - ...else: call the last Link (1) as a monad
                                          -          = Link 1(0) (since newNumber=0)

99Ç - Main Link: no arguments
99  - yep, you guessed it, ninety nine
  Ç - call the last Link (2) as a monad
Jonathan Allan
fonte
2

Perl, 132 bytes

$c=" bugs in the code
";for($i=99;$i>0;$i+=~~rand(21)-16){print$t.$/,($t=$i.$c)x2,"Take one down and patch it around
"}print"0$c
"x2
Trenton Trama
fonte
2

VBA: 225 233 bytes

Sub b()
For c = 99 To 0 Step -1
GoSub d
GoSub d
Debug.Print "Take one down and patch it around"
c = c + 5 - Int(rnd() * 20)
If c < 0 Then c = 0
GoSub d
Debug.Print
Next c
Exit Sub
d:
Debug.Print c & " bugs in the code"
Return
End Sub

{EDIT} adicionada a faltarnd()*

Notas:
Usada GoSubpara imprimir a linha em triplicado, porque é um pouco menor do que atribuir a linha a uma variável e Debug.Printinseri-la.
Debug.Printsem nenhum argumento, imprime uma linha vazia (sem necessidade de uma cadeia nula ou vazia). Uma WorksheetFunction.Maxlinha seria muito longa; portanto, usei um "se menor que" para evitar negativos.

 

Com recuo e comentários

Sub b()
    For c = 99 To 0 Step -1
        GoSub d '"# bugs in the code"
        GoSub d '"# bugs in the code"
        Debug.Print "Take one down and patch it around"
        c = c + 5 - Int(rnd() * 20)
        If c < 0 Then c = 0 'Non-negative
        GoSub d '"# bugs in the code"
        Debug.Print
    Next c
    Exit Sub
d: 'This is our GoSub bit
    Debug.Print c & " bugs in the code"
    Return
End Sub
Cronocida
fonte
1
Essa é uma maneira muito eficiente de fazer números aleatórios!
Sam Dean
@SamDean Não tenho certeza de como eu esqueci de incluir o item rnd() * - acho que estava ocupado fazendo uma contagem se houvesse menos caracteres Dim c%(ou seja, "c é um número inteiro") e solte oInt()
Cronocida
haha não se preocupe! É bom ver uma resposta do VBA, pois eu não a uso há anos!
Sam Dean
2

Python 2 ,  138 134 133 131  127 bytes

-1 Obrigado a Jo King (reorganize para usar a lógica em bugs-=min(bugs,randomNumber)vez de bugs=max(0,bugs-randomNumber)). Isso permitiu a saída forçada usando um erro de divisão por zero, economizando mais 6 bytes!

r=n=99
t="bugs in the code\n"
while 1:r+=id(r);b=n;n-=min(n,r%21-4);print b,t,1/b|b,t,"Take one down and patch it around\n",n,t

Experimente online!

Jonathan Allan
fonte
Acontece que eu não preciso criar tuplas.
Jonathan Allan
133 bytes
Jo King
@JoKing Thanks! (Eu realmente deveria ter visto que desde que é mais parecido com o que eu faço na minha resposta Jelly.)
Jonathan Allan
2
@JoKing ... o que significa que pode forçar o encerramento com uma divisão por zero erro para salvar --two-- seis mais :)
Jonathan Allan
2

Ruby: 149 bytes

n=99;f=" bugs in the code\n";loop{puts"#{n}#{f}"*2+"Take one down and patch it around\n";(n+=rand -16..4)>0?puts("#{n}#{f}\n"):break};puts"0#{f}\n"*2

Deve funcionar em praticamente qualquer versão do Ruby> = 1.8

Eu acho que pode ser possível otimizar um pouco mais as strings, mas em geral estou bastante satisfeito com isso - em particular a atribuição de combinação / comparação / declaração de interrupção e o abuso de colchetes opcionais.

Nota: a saída tecnicamente possui duas novas linhas finais; se isso precisar ser contabilizado, ele aumentará 4 caracteres.

DaveMongoose
fonte
Olá, e bem-vindo ao PPCG! Contamos novas linhas à direita, mas se funcionar no Linux, você pode apenas contar \n(não \r).
NoOneIsHere
@NoOneIsHere Obrigado :) Atualizei minha resposta para esclarecer - eu estava me referindo a novas linhas na saída porque a pergunta especifica que ter um é aceitável, mas não tinha certeza de dois.
214188 DaveMongoose #
Eu vejo. Eu acho que está tudo bem
NoOneIsHere
2

Zsh , 133 bytes

b="%d bugs in the code
";for ((n=99;n;)){printf $b$b"Take one down and patch it around
$b
" n n n-=RANDOM%21-4,n=n\>0\?n:0};printf $b

Experimente online!


Isso tira proveito de alguns recursos do zsh.

  • a forma alternativa de loop : while list; do list; donepode ser escrita comowhile list {list}
  • Se um especificador de formato em printf for numérico, o argumento correspondente será avaliado como uma expressão aritmética. Assim:
    • obtemos o valor de ngraça sem usar um$
    • n -= RANDOM % 21 - 4, n = n > 0 ? n : 0é novamente avaliada sem a necessidade de utilização $((...)), $[...]ou semelhante. O >e? teve que ser escapado.
    • O printf $bno final avalia um argumento vazio como 0 para %d.
  • A divisão de palavras na expansão de parâmetros está desativada por padrão, portanto, não preciso citar em $bnenhum lugar.
    • Isso permite que eu escreva em $b$b"Take..."vez de "$b${b}Take...".

  • Salvou alguns bytes usando novas linhas reais em vez de \ne em for((n=99;n;))vez de n=99;while ((n)).
muru
fonte
Eu acho que deveria ser -4. "- =" se parece com seu composto, então ele primeiro +4 subtrai tudo.
Sam Dean
@SamDean oops, corrigido.
Muru