[Question]
  [
Your task is to create a program that is to mimic [Big Ben (Twitter)](https://twitter.com/big_ben_clock).
### Task
Whenever a new hour has begun (according to your computer's local time or UTC), you have to output `BONG` repeated `hour` times (with a space between the words). For example, when it's 3 o' clock, you have to output `BONG BONG BONG`. The time format follows the 12-hour time format, ie after 12 o' clock, we have 1 and not 13. The program/function must run forever.
Example:
don't output stuff inside the brackets
```
(start: 00:34 for example)
BONG               (01:00)
BONG BONG          (02:00)
(...)
BONG BONG BONG BONG BONG BONG BONG BONG BONG BONG BONG BONG (12:00)
BONG               (01:00 again)
(...)
(it continues forever)
```
### Rules
* Each series of `BONG`s must be separated by a newline
* Leading/trailing newlines are allowed
* However leading/trailing **spaces** are **not** allowed
* The submission must run forever
* Your output may be printed ±3 seconds from the beginning of the hour
* You may **not** assume the program to be run at any specific hour
This is [code-golf](/questions/tagged/code-golf "show questions tagged 'code-golf'"), so the program with the shortest bytecount wins!
  
[Answer]
# Bash, ~~71~~, ~~70~~, 69 bytes
EDITS:
* Optimized the sleep interval computation a bit, -1 byte;
* Replaced backticks with xargs, -1 byte (Thanks @jrtc27 !).
**Golfed**
```
sleep `date +3600-%s%3600|bc`;yes BONG|sed $(date +%I)q|xargs;exec $0
```
**Explained**
```
#Compute the number of seconds left in the current hour and wait.
sleep `date +3600-%s%3600|bc`; 
#Print "hour" (1-12) worth of "BONG" strings, one per line,
#use xargs to merge them into a single space-separated string.
yes BONG|sed $(date +%I)q|xargs
#Re-execute itself (in the same process).
exec $0
```
**Test Version**
Works with minutes instead of hours
```
sleep `date +60-%s%60|bc`;yes BONG|sed $(date +%I)q|xargs;exec $0
```
[Answer]
## [\*><>](https://esolangs.org/wiki/Starfish), ~~48~~ ~~47~~ 44 bytes
```
>s?um?uhc%:?!c21.O
v$o" GNOB"oooo$1-:?!
\aofS
```
[Try it here!](https://starfish.000webhostapp.com/?script=HwZw-ArgtpAWDGBSAXGAhPATARgHQHkAoANwBIB7AIgAIBxAOXwCFLy3zTsBaVNQgHQCG5AGYBlIA) ([or this version which does it every minute for testing](https://starfish.000webhostapp.com/?script=HwZw-ArgDJAWDGBSAXGAhPATARgHQHkAoANwBIB7AIgAIBxAOXwCFLy3zTsBaVNQgHQCG5AGYBlIA))
This outputs a number of `BONG`s separated by spaces based on what hour it is (and 13 is 1, etc). There are no trailing space after the final `BONG`, and there is a trailing newline.
*Technically* this doesn't run *forever* (but it basically does). It leaks ~28 bytes per day (ignoring interpreter overhead ...). It would take ~105062 years for it to leak 1GiB.
Approximating for interpreter overhead, the stack is just a slice of `float64`s on the Golang interpreter. So I simply did `28*8` to come up with 224 bytes per day. I divided this number by the number of bytes in a gibibyte (1073741824) then 365 to approximate that it would take 13132.85 years to leak 1 GiB.
**Note about the interpreters**
The online interpreter is in Javascript. The page must be open and visible for it to check the time it currently is and output the BONGs. The [Golang interpreter](https://github.com/redstarcoder/go-starfish/releases) has no such limitation.
### Explanation
```
Main loop:
s?um?u          O     if seconds == 0 && minutes == 0:
      hc%               push hours % 12 (bongs) to the stack
         :?!c           if bongs is 0, push 12 to the stack
             21.        jump to "output bongs" coords (2, 1)
Output bongs:
Begins at `"` because of the jump.
   " GNOB"            push "BONG " to the stack
          oooo        output "BONG"
              $1-     subtract 1 from bongs
v                :?!  if bongs == 0, move to "newline and sleep"
 $o                   output " "
Newline and sleep:
\                     mirror the IP to the right
 ao                   output a newline
   fS                 sleep for 1.6s
\                     mirror to main loop
```
[Answer]
# JavaScript (ES6), ~~99~~ 93 bytes
```
f=_=>setTimeout('alert("BONG ".repeat(new Date/36e5%12|0||12).trim(f()))',36e5-new Date%36e5)
```
This uses UTC time (which lines up with the actual thing). Due to the untestable nature of the code, you can try the following which does the same thing, but every 60 seconds:
```
f=_=>setTimeout('alert("BONG ".repeat(new Date/36e5%12|0||12).trim(f()))',6e4-new Date%6e4)
f()
```
Here's a bonus 99-byte version which uses local time:
```
f=_=>setTimeout('alert("BONG ".repeat(new Date().getHours()%12||12).trim(f()))',36e5-new Date%36e5)
```
[Answer]
# JavaScript(ES6), ~~125~~ ~~123~~ ~~117~~ 115 bytes
*Thanks to @Flp.Tkc for saving 5 bytes!*
*Thanks to @BenAston for saving 2 more bytes!*
```
a=eval(b=`(new Date).getHours()`);setInterval(w=>eval(b)!=a?console.log(Array(++a%12+1).join`BONG `.trim()):"",1e3)
```
### Snack Snippet
```
a=eval(b=`(new Date).getHours()`);setInterval(w=>eval(b)!=a?console.log(Array(++a%12+1).join`BONG `.trim()):"",1e3)
```
[Answer]
## Batch, 142 bytes
```
@timeout/t>nul 1
@if not %time:~3,5%==00:00 %0
@set/ah=-%time:~0,2%%12
@set s=............
@call set s=%%s:~%h%%%
@echo %s:.=BONG %
@%0
```
Since the file runs as an infinite loop, I start with a 1s delay, as I need one anyway after the bongs, and this saves CPU cycles. The `>nul` is positioned carefully to save a byte (`1>nul` would cause the 1 to be eaten by the redirection). We then loop until both minutes and seconds are zero. The bongs are constructed by taking the negative hour modulo 12, and asking for the last `h` characters from a 12-character string. When `h` is zero this actually gives us the whole string, therefore 12 bongs. It then suffices to replace the characters with the word `BONG`. When run it looks something like this (note that the image does not loop, so you'll need to force-reload to see the animation again):
![Sample Output](https://i.stack.imgur.com/x00A9.gif)
[Answer]
# Bash + Linux crontab, 90
I was hoping this would be shorter than the other shell answers. Still, I think it's an interesting approach:
```
for i in {0..11};{
s+=\ BONG
echo "0 $i,$[i+12] * * * echo$s>/proc/$PPID/fd/1"
}|crontab -
```
The script runs once, populates the crontab, then exits. However, the output from the cronjobs is sent to the terminal from which the script was run. I think this satisfies the *submission must run forever* requirement.
**Warning** - this will clear out any existing crontab entries, so make sure you have existing ones backed up.
This works on Ubuntu 16.04, which is using [Vixie](https://en.wikipedia.org/wiki/Paul_Vixie) `cron` by default.
[Answer]
## Ruby, 112 99 Bytes
```
loop{sleep 2;n=Time.now;if(n.min==0);puts ('BONG '*n.strftime('%I').to_i).chop;sleep 60-n.sec end}
```
Old Version
```
loop{sleep(2);n=Time.now; if(n.min.zero?) then puts ('BONG ' * n.strftime('%I').to_i).chop;sleep(60-n.sec) end}
```
Thanks to QPaysTaxes for the tips
[Answer]
# Cheddar v1.0.5, 162 bytes
Cheddar has no built-in time reader/cmd output reader, so I had to improvise!
Golfed:
```
var f=->{IO.exec("time/t>c");(String::IO.read("c")).split(":")};var a=f()[0];for(;1;){var b=f();if(b[0]!=a){var c=Number::(a=b[0]);print("BONG "*c).head(5*c-1);}}
```
Ungolfed:
```
var f=->{
    IO.exec("time/t>c");
    (String::IO.read("c")).split(":")};
var a=f()[0];
for(;1;){
    var b=f();
    if(b[0]!=a){
        var c=Number::(a=b[0]);
        print("BONG "*c).head(5*c-1);
    }
}
```
Explanation:
Due to Cheddar's limited standard library, I had to use cmd to generate the time. I did this by saving the output of "time /t", which prints the time in 12-hour format, to a file named "c". IO.read returns a buffer which I casted to a string and split by ":" which ensured the hour is always in index zero. I saved that whole operation into a lambda expression which saved me 44 bytes. After that point it goes into the logic of "if stored hour doesn't equal current hour, set previous hour to current and print BONG n times, trim off the trailing space."
Cheddar may not be the least verbose language but it can be fun to find workarounds like this!
Sadly this is a Windows-only solution.
**Edit 1:** Saved two bytes by replacing "0<1" in the for-condition to "1" I didn't expect 1 to evaluate to true in this language!
[Answer]
# Ruby, ~~82~~ 81 bytes
```
loop{l=Time.new
puts ("BONG "*(l.hour%12+1)).chop if(l+1).hour!=l.hour
sleep 1}
```
Every second we check whether it's last second of the hour, and BONG accordingly. Could probably be golfed further with some dirty tricks, but I don't know too many. Also it works differently than the other Ruby answer.
One byte saved thanks to courtesy of QPaysTaxes.
[Answer]
# [Python 2](https://docs.python.org/2/), ~~105~~ 106 bytes
```
import time
h=0
while 1:
 l=time.localtime();c=l[3]%12
 if l[4:6]==(0,0)and h!=c:print('BONG '*c)[:-1];h=c
```
**Edit**
Added one byte by changing < to != after feedback from @pinkfloydx33. Good spot.
Tested as much as possible locally but doesn't work on TIO as it (obviously) exceeds the 60 second execution limit. Please feel free to test locally :-)
btw, losing that pesky trailing space cost me 7 bytes otherwise this would have been under 100.
In the absence of TIO here is output after waiting an hour. Prog was started at 15:27 with extra debug code to show the time of the print (12 hour format).
```
python bigben.py
time is 4:0:0
BONG BONG BONG BONG
time is 5:0:0
BONG BONG BONG BONG BONG
```
Pretty straightforward but here is an explanation for anyone who is interested.
```
import time                 #Import the time module
h=0                         #Create a variable to store the hour that has just been printed
while 1:                    #Loop forever
 l=time.localtime()         #Get the local time from the time module
 c=l[3]%12                  #Set a variable to the current hour in 12 hour format
 if l[4:6]==(0,0)and h!=c:   #If minutes=0 and hours=0 and the last hour that was printed is not the current hour
  print "time is "+`c`+":"+`l[4]`+":"+`l[5]`    #Debug code to show hour
  print('BONG '*c)[:-1]     #Print 'BONG '*number of hours and lose the space from the end 
  h=c                       #Update the last hour that was printed
```
[Answer]
# Python 3 - ~~100~~ ~~97~~ 92 bytes
```
from time import*
while 1:x=3600;sleep(x-time()%x);print(('BONG '*int(strftime("%I")))[:-1])[:-1])
```
Explanation:
```
import time;
while 1:
 t=time;x=3600;
 t.sleep(x-t.time()%x);#sleep for the remaining seconds until the next hour
 print(('BONG '*int(t.strftime("%I")))[:-1])#strftime("%")=nr of hours (1-12). Print the bongs and remove the last char
```
[Answer]
# [05AB1E](https://github.com/Adriandmen/05AB1E), 43 bytes
```
3600žcžb60*+->Lvw}["BONG "ža<12%>×,5°36*.W]
```
[Try it online!](https://tio.run/nexus/05ab1e#@29sZmBwdF/y0X1JZgZa2rp2PmXltdFKTv5@7gpKR/cl2hgaqdodnq5jemiDsZmWXnjs//9f8/J1kxOTM1IB "05AB1E – TIO Nexus") (lol this won't work, it will timeout in 60 seconds. Download the [05AB1E](https://github.com/Adriandmen/05AB1E) interpreter for this)
Explanation:
```
3600žcžb60*+->                          # Get amount of seconds (plus one) until next hour
              Lvw}                      # Wait said amount of seconds
                  [                     # Infinite loop start
                   "BONG "ža<12%>×,     # Print "BONG " multiplied by the amount of hours (12-hour clock)
                               5°36*.W  # Wait an hour (3600000 milliseconds)
                                      ] # Infinite loop end  
```
This took me a while to golf! I might be able to golf it a little more, but it beats `*><>`, so that's cool :)
Quick version:
```
1Uw["BONG "X<12%>×,wX>U]
```
Will wait one second on start, and one second between BONGs
[Answer]
# C, 238 bytes
```
#include<time.h>
#include<unistd.h>
i,j;f(){time_t t=time(0);struct tm l=*localtime(&t);for(;;){t=time(0),l=*localtime(&t),j=l.tm_hour;sleep(1);if(!(l.tm_min+l.tm_sec)){j=j%12?j<12?j:j-12:12;for(i=0;i<=j;i++)printf("BONG%c",i^j?32:10);}}}
```
I'm not sure if this works correctly, and I'm mobile, and my phone doesn't have a C compiler. (Only works on UNIX-like systems)
[Answer]
# sh, 66 bytes
```
yes 'echo `yes BONG|sed $(date +%I)q`'|sh -s|awk '$0!=a&&a;{a=$0}'
```
**Explained**
```
#Pipe a command into a subshell repeatedly
yes 'some command'|sh -s
#Print "hour" (1-12) worth of "BONG" strings, one per line,
#use backticks to merge them into a single space-separated string.
#(stolen from zeppelin's answer)
echo `yes BONG|sed $(date +%I)q`
#Print every time the output changes
awk '$0!=a&&a;{a=$0}
```
[Answer]
## PowerShell, 62
```
for(){if(0-eq(date -f mmss)){''+,'BONG'*(date -f hh)};sleep 1}
```
Infinite loop, gets the minutes and seconds with `-f`ormat string `mmss` and they're cast to ints when compared with `0-eq`euals. Gets the hour in 12 hour format with `-f`ormat string `hh`. Implicit spaces come from joining a `,'BONG'` array into a string with `''+`.
[Answer]
# C, 198 bytes
```
#import<time.h>
h,i;f(){time_t t=time(0);struct tm l=*localtime(&t);for(h=l.tm_hour;;t=time(0),l=*localtime(&t))if(h-l.tm_hour%12){h=l.tm_hour%12;for(i=h?h%12:12;--i;)printf("BONG ");puts("BONG");}}
```
[Answer]
# Javascript ES6 87 bytes
Edit: Shamelessly borrowed @ETHProductions' `new Date/36e5%12|0||12` code to save 6 bytes
```
setInterval('Date().match`:00:00`?alert("BONG ".repeat(new Date/36e5%12|0||12)):5',1e3)
```
[Answer]
# R, ~~104~~ 105 bytes
```
f=format;repeat{Sys.sleep(1);q=Sys.time();if(f(q,"%M%S")=="0000")print(rep("BONG",as.double(f(q,"%I"))))}
```
Each second, it will (should) test whether we are at the end of an hour, then print that amount of `BONG`s.
[Answer]
# JavaScript ES2015, ~~100~~ ~~99~~ ~~98~~ ~~96~~ ~~94~~ 88 bytes
```
h=_=>new Date/36e5%12|0,p=h();for(;;)h()!=p&&(p=h(),alert('BONG '.repeat(p||12).trim()))
```
Explanation:
`h` is a function that gets the 12-hour-based hour of the day using the remainder operator (`%12`). `36e5` is the number of milliseconds in one hour using the exponential syntax to save characters. The `new` operator does not require that parentheses are used with functions if there are no arguments, hence `new Date`. JavaScript only has floating point arithmetic, the `|` bitwise OR operator forces the number to be an integer because JS bitwise operators work with the integer subset of the numbers represented by IEEE 754 floating point.
The comma delineates sub-expressions. `p` is initialized to the current hour (`p=h()`).
`for(;;)` is used to check repeatedly whether any `BONG`s should be alerted. Checking is performed as rapidly as the runtime will allow.
If the hour has changed (`h()!=p`), then we update p and then alert the `BONG`s. The logical AND operator is used as a guard (it short-circuits if `h()===p`) to determine if the `BONG`s are output.
`String.prototype.repeat` is new in ES2015 and saves some characters over using something like ES5's `Array.prototype.join`.
`h` returns zero for exact multiples of 12 (i.e. 12pm, 12am), so we change it to 12 using the logical OR `p||12`.
With thanks to Kritixi Lithos and ETHProductions for ideas.
[Answer]
# Excel VBA, 97 Bytes
Code Outputs to the VBE Immediates Window
```
Do:DoEvents:n=Now:[A1]=(Hour(n)-1)Mod 12+1:?IIf(Minute(n),"",Trim([Rept("BONG ",A1)])+vbCr);:Loop
```
## Fun version, 147 Bytes (Non-Competing)
While it would be rather difficult to get excel to go BONG, it is pretty straight forward to get excel to go `Beep`. The `Beep` call produces a beeping sound, and the code below uses this to produce beeps indicating the hour, on the hour, separated by 1 second pauses.
```
Sub b:Set a=Application:Do:n=Now
```
If Minute(n)=0 Then:For i=1To(Hour(n)-1)Mod 12+1:Beep:a.Wait(Now+#0:0:1#):Next:a.Wait(n+#0:1#):End If:Loop:End Sub
## Ungolfed Version
```
Public Sub BigBen()
    Dim i As Byte
    Dim n As Date
    Dim w As Worksheet
    Dim a As Excel.Application
    Set a = Application
    Set w = a.ThisWorkbook.Sheets(1)
    Let w.Name = "Big Ben"
    Let w.[A1] = Now
    w.Columns("A:A").AutoFit
    Do
        DoEvents
        Let n = Now
        If Minute(n) = 0 Then
            ''  Print BONG
            Let s = ""
            For i = 1 To Hour(n) Mod 12 Step 1
                Let s = s & "BONG "
            Next i
            Debug.Print Trim(s)
            ''  Go Beep
            For i = 1 To Hour(n) Mod 12 Step 1
                Beep
                a.Wait (Now + #12:00:01 AM#) ''  <- #0:0:1# resolves to #12:00:01 AM#
            Next i
            ''  Keep Ticking After Going BONG
            While Now < n + #12:01:00 AM#    ''  <- #0:1# resolves to #12:01:00 AM#
                Let w.[A1] = Now
                Let a.StatusBar = IIf(Second(Now) Mod 2, "Tick", "Tock")
                DoEvents
            Wend
        End If
        ''  Tick Tock until its time to Go BONG again
        Let a.StatusBar = IIf(Second(n) Mod 2, "Tick", "Tock")
        Let w.[A1] = Now
    Loop
End Sub
```
[Answer]
**C# 234 Bytes**
I'm not planning on winning any prizes here, but a C# implementation is compulsory.
```
using System;
using System.Linq;namespace B{class P{static void Main(){Func<int> h=()=>DateTime.Now.Hour % 12;var p=h();while (true){var t=h();if (t!=p)Console.WriteLine(string.Concat(Enumerable.Repeat("BONG",t== 0?12:t)));p=t;}}}}
```
Ungolfed with comments:
```
using System;
using System.Linq;
namespace B
{
    class P
    {
        static void Main()
        {
            Func<int> h = () => DateTime.Now.Hour % 12; // h(): the hour in the range [0, 11], making this a lambda saves a few chars
            var p = h(); // p: Previous time
            while (true)
            {
                var t = h(); // t: Current time
                if (t != p) // If current hour is different to previous hour
                    Console.WriteLine(string.Concat(Enumerable.Repeat("BONG", t == 0 ? 12 : t))); // Print "BONG" t times (also correcting t = 0 to 12)
                p = t; // Current time is now previous time
            } // Repeat ad nauseum
        }
    }
}
```
[Answer]
# Groovy, 72 bytes
```
{x={new Date().getHours()};y=x();while(1){if(y!=(y==x()){print "BONG "*y}}​}​​​
```
How?
Store a method to get current hours.
```
x={new Date().getHours()};
```
Store initial hours.
```
y=x();
```
While true, if current hour not equal previous hour, output current hour multiplied by "BONG " to output current hour of bongs.
```
while(1){if(y!=(y==x()){print "BONG "*y}}
```
+3 bytes `%12` for non-military bongs.
[Answer]
## perl, 60 bytes
**Update**
Replaced  `" "` with `$"`, removed `CORE::`, corrected count.
**Golf**
```
say join$",(BONG)x(time/3600%12||12)while sleep -time%3600+1
```
This needs to be run with `perl -E`.
**Remarks**
* In perl, `x while y` is equivalent to `while(y){x}` (where `x` is a single statement) but does not need the brackets. `sleep` is executed the first time before anything is printed.
* `time` uses UTC. The original Big Ben is on summer time (British Summer Time, BST) from the end of March until the end of October.
* One second is added to the wait time in order to ensure that the program waits for at least one second. This means that the BONGs will always be printed one second late, which is legal according to the rules. Let's say you're standing on Westminster Bridge, ca. 300 m away from Big Ben. On the plus side, this also means that the program will print the correct amount of BONGs if it is started at exactly the beginning of an hour (instead of waiting 3600 seconds).
* `sleep` returns the number of seconds waited. This will always be true.
[Answer]
## [QBIC](https://drive.google.com/drive/folders/0B0R1Jgqp8Gg4cVJCZkRkdEthZDQ), 82 bytes
```
X=$left$|(_d,2){Y=left$$|(_d,2)~Y<>X|x=!Y!%12~x=0|x=12]B=C[x|B=B+@BONG |]?_tB|]X=Y
```
Really need to change the token for code literals (`$`) and implement a substring feature (`left$(x,y)` can be shorter).
The inner workings:
```
In the first part, we want to set X$ to the hour-component
of our system's time. The DATE is implemented in QBIC, but
Substring (LEFT$, RIGHT$ and MID$ in QBasic) is not (yet).
We need to use the QBasic LEFT$ function, and QBIC can do 
that using a 'code literal': everything from '$' to '|'
is not parsed by QBIC but passed on to QBasic.
X=               Set X$ to
$left$|(         the leftmost (note the '$' and '|' for the code literal)
_d,2)            2 characters of TIME$ (hh:mm format)
{                DO - infinite loop
Y=left$$|(_d,2)  Set Y$ in the same way
~Y<>X            If Y$ is not equal to X$ the hour has changed
|x=!Y!%12        THEN set x to the modulo 12 of Y$ cast to number
~x=0|x=12]       If Y% happens to be divisible by 12, set x to 12
B=C              Clear B$ (c$ never gets assiged a value)
[x|B=B+@BONG |]  For the given number of hours, add "BONG " to B$
?_tB|            Print B$, trim the trailing space
]                end if
X=Y              Update X$
<DO LOOP is implicitly closed>
```
Update (NC): The `$` is no longer used in QBICs instruction set, so it can now be used freely as code for QBasic without the need for code literals. In this case, it saves 4 bytes, bringing QBIC to 78 bytes:
```
X=left$(_d,2){Y=left$(_d,2)~Y<>X|x=!Y!%12~x=0|x=12]B=C[x|B=B+@BONG `]?_tB|]X=Y
```
[Answer]
# SmileBASIC, ~~74~~ 67 bytes
```
WAIT 61TMREAD OUT H,M,S?("BONG"+" BONG"*((H+11)MOD 12))*!(M+S)EXEC.
```
Outputs large amounts of "trailing" line breaks ;)
Edit: saved 7 bytes with a better 24->12 hour algorithm.
[Answer]
# PHP, 63 bytes
I could save two more bytes with extended ASCII. But I am currently too lazy for that.
```
for(;;sleep(1))+date(is)?:print str_pad("
",5*date(h),"BONG ");
```
prints the BONGs with a leading linebreak precisely at the full hour. Run with `-nr`.
[Answer]
# C, 152
```
int a=0,i,L=25;main(){char s[9];for(i=-1;++i<48;){sprintf(s,"%02i:00:00",i);if(!strcmp(s,__TIME__)&&i!=L)a=L=i,i=-1;printf(a-->0?"BONG ":"\n");}main();}
```
---
Readable:
```
int a=0,i,L=25;
main(){
    char s[9];
    for(i=-1;++i<48;){
        sprintf(s,"%02i:00:00",i);
        if(!strcmp(s,__TIME__)&&i!=L)
            a=L=i,i=-1;
        printf(a-->0?"BONG ":"\n");
    }
    main();
}
```
[Answer]
# x86-16 machine code, IBM PC DOS, ~~62~~ 61 bytes
Binary:
```
00000000: ba0b 01b8 1c25 cd21 f4eb fdb8 092c cd21  .....%.!.....,.!
00000010: 3834 741f 8834 86ca 85d2 7517 86c5 d40c  84t..4....u.....
00000020: 7502 b00c 91b5 00ba 3401 cd21 e2fc ba3a  u.......4..!...:
00000030: 01cd 21cf 424f 4e47 2024 0d0a 24         ..!.BONG $..$
```
Listing:
```
BA 010B     MOV  DX, OFFSET INT_BONG    ; interrupt vector of bong proc 
B8 251C     MOV  AX, 0251CH             ; AL = 1CH (timer tick), AH = 25H (set vector)
CD 21       INT  21H                    ; set new interrupt vector 
0108    INF_LOOP: 
F4          HLT                         ; wait for interrupt 
EB FD       JMP  INF_LOOP               ; loop forever 
        INT_BONG:                       ; interrupt handler for BONG program 
B8 092C     MOV  AX, 2C09H              ; AH = get system time, AL = DOS write string 
CD 21       INT  21H                    ; CH = hour, CL = min, DH = sec
38 34       CMP  BYTE PTR[SI], DH       ; compare to previous second 
74 21       JZ   DONE                   ; if same second, do nothing 
88 34       MOV  BYTE PTR[SI], DH       ; otherwise save new second 
        DO_BONG: 
86 CA       XCHG CL, DL                 ; DL = min, DH = sec 
85 D2       TEST DX, DX                 ; are min and sec 0? 
75 19       JNZ  DONE                   ; if so, do nothing 
86 C5       XCHG AL, CH                 ; AL = hour, CH = DOS write string
D4 0C       AAM  12                     ; AL = AL % 12, ZF if 0 
75 02       JNZ  NOT_MID                ; if not midnight or noon, skip 
B0 0C       MOV  AL, 12                 ; if 0, set to 12 
        NOT_MID: 
91          XCHG AX, CX                 ; CL = hour counter, AH = DOS write string
B5 00       MOV  CH, 0                  ; clear high byte of CX 
BA 0139     MOV  DX, OFFSET BONG        ; pointer to BONG string 
        BONG_LOOP: 
CD 21       INT  21H                    ; write BONG 
E2 FC       LOOP BONG_LOOP              ; keep looping 
BA 013F     MOV  DX, OFFSET CRLF        ; display CRLF 
CD 21       INT  21H                    ; write to stdout 
        DONE: 
CF          IRET                        ; return from interrupt
        BONG:
            DB   'BONG $'
        CRLF:
            DB   0DH, 0AH,'$'
```
Standalone PC DOS executable COM program. This program "hooks" the [`INT 1CH` Timer Tick](http://vitaly_filatov.tripod.com/ng/asm/asm_001.14.html) interrupt which is called every 18.2 times per second (oh really?) by the hardware timer, and then runs our new program in memory. Typically you'd be considerate and set this back to original handler when done but since we don't really care about the system once we start the program, we're not really worrying about that.
Yes, this is more bytes than just a big loop, but hopefully a little bit more "interesting"!
Runtime:
[![enter image description here](https://i.stack.imgur.com/cFLhA.png)](https://i.stack.imgur.com/cFLhA.png)
[![enter image description here](https://i.stack.imgur.com/ZB2gD.png)](https://i.stack.imgur.com/ZB2gD.png)
*The next day...*
[![enter image description here](https://i.stack.imgur.com/UxBhh.png)](https://i.stack.imgur.com/UxBhh.png)
]