24
\$\begingroup\$

Introduction

A bell tower will ring its bells every hour, n times, with n being the the current hour on a 12 hour clock.

For example, a bell will ring 5 times at 5pm, and 10 times at 10am.

Task

Given two times in a suitable format, output the number of times the bell will ring, inclusive of the start and end times

Examples

"10am-12pm"
10+11+12= 33

[01:00, 05:00]
1+2+3+4+5 = 15

[11, 15]
11+12+1+2+3 = 29

[10:00pm, 10:00am]
10+11+12+1+2+3+4+5+6+7+8+9+10 = 88

If the start is the same as the end then the you simply just ouput the number of chimes for that hour:

[5pm, 5pm]
5 = 5

As you can see, you may choose an input method but the output must be an integer on its own (or an acceptable alternative) trailing/ leading newlines and spaces are allowed.

Note:

  • inputs may span from the afternoon of one day to the morning of the next.
  • the difference between the two times will never be more than 24 hours.
  • input is flexible so long as you clearly state what format your input is.
  • your input must have a clear distinction between AM and PM.
\$\endgroup\$
13
  • 2
    \$\begingroup\$ Do we choose our own input method, or does it have to support all the mentioned? \$\endgroup\$
    – anonymous2
    Oct 3, 2016 at 16:10
  • 1
    \$\begingroup\$ You may choose the input method \$\endgroup\$
    – Shaun Wild
    Oct 3, 2016 at 16:13
  • 1
    \$\begingroup\$ You should make it more clear that the inputs can go from pm to am, thus crossing to a 2nd day. \$\endgroup\$
    – mbomb007
    Oct 3, 2016 at 16:19
  • 3
    \$\begingroup\$ Will midnight be given as 0 or 24? \$\endgroup\$
    – xnor
    Oct 3, 2016 at 17:21
  • 4
    \$\begingroup\$ We encourage the use of the Sandbox to work out any issues with challenges before they are posted to the main site. \$\endgroup\$
    – user45941
    Oct 3, 2016 at 17:44

23 Answers 23

12
\$\begingroup\$

JavaScript (ES6), 38 35 bytes

f=(x,y)=>~-x%12-~(x-y&&f(x%24+1,y))

Recursively adds the current number of bell rings to the total. Called like f(11,15); midnight is represented as 24. I got part of the ~- trick from @xnor's Python answer.

Test snippet

f=(x,y)=>~-x%12-~(x-y&&f(x%24+1,y))
g=(x,y)=>console.log("x:",x,"y:",y,"result:",f(x,y))

g(10,12)
g(1,5)
g(11,15)
g(22,10)
<input id=A type="number" min=1 max=24 value=9>
<input id=B type="number" min=1 max=24 value=17>
<button onclick="g(A.value,B.value)">Run</button>

Non-recursive version (Firefox 30+), 56 bytes

(x,y,t=0)=>[for(_ of Array((y-x+25)%24))t+=x++%12||12]|t

Equivalent to the following ES6 function:

(x,y,t=0)=>[...Array((y-x+25)%24))].map(_=>t+=x++%12||12)|t
\$\endgroup\$
7
\$\begingroup\$

Python 2, 46 bytes

f=lambda x,y:(x%12or 12)+(x-y and f(-~x%24,y))

Based on my JS answer. The recursive formula f for the solution is defined as so:

  1. Start with two integers x and y.
  2. Take x mod 12; if this is 0, take 12 instead.
  3. If x != y, add the result of f(x+1 mod 24, y).
\$\endgroup\$
6
\$\begingroup\$

Python 2, 59 54 bytes

a=lambda x,y:sum(1+i%12for i in range(x-1,y+24*(x>y)))
Equivalent to
summ=0
if start > end:
    end+=24
for hour in range(start-1,end):
    summ +=1+hour%12
print summ
\$\endgroup\$
8
  • 3
    \$\begingroup\$ I think you don't need the a= part. \$\endgroup\$
    – acrolith
    Oct 3, 2016 at 16:50
  • \$\begingroup\$ @daHugLenny it need to be a full(usable) function \$\endgroup\$
    – Rod
    Oct 3, 2016 at 17:01
  • \$\begingroup\$ (y+24)%24 is just y \$\endgroup\$ Oct 3, 2016 at 17:24
  • 1
    \$\begingroup\$ @Rod You don't need a=. It's allowed to be a pure lambda. \$\endgroup\$
    – Yytsi
    Oct 4, 2016 at 11:06
  • 1
    \$\begingroup\$ @VladimirCravero Of course not. It is the same as y%24. \$\endgroup\$ Oct 4, 2016 at 11:11
3
\$\begingroup\$

05AB1E, 13 bytes

With a lot of help from Emigna.

-24%ݹ+<12%>O

Uses the CP-1252 encoding. Try it online!

\$\endgroup\$
0
3
\$\begingroup\$

Python, 42 bytes

f=lambda a,b:~-a%12-~(b-a and f(-~a%24,b))

A recursive function that takes two numbers from 0 to 23. Expanding the ~x's to -x-1 gives

f=lambda a,b:(a-1)%12+1+(b-a and f((a+1)%24,b))

The expression (a+1)%12+1 converts a time to the number of rings 1 to 12. Then, the lower bound is incremented modulo 24 and the function for the recursive result is added. That is, unless the current hour is the end hour, in which case we stop.

I've been trying to write a purely arithmetical solution instead, but so far I've only found long and messy expressions.

\$\endgroup\$
1
  • \$\begingroup\$ Ah, I get it: it's basically the same technique as my Python answer, but with a really clever way of getting around the or. Nice one! \$\endgroup\$ Oct 3, 2016 at 17:30
3
\$\begingroup\$

Haskell, 48 43 bytes

s%e=sum[mod x 12+1|x<-[s-1..e+23],x<e||s>e]

Usage is startHour % endHour, with both inputs given in 24-hr format.

edit: added @xnor's improvement, saving 5 bytes

\$\endgroup\$
1
  • \$\begingroup\$ Instead of changing e when e<s, you could filter the range s%e=sum[mod(x-1)12+1|x<-[s..e+24],x<=e||s>e]. It then saves a byte to shift x down by 1: s%e=sum[mod x 12+1|x<-[s-1..e+23],x<e||s>e]. \$\endgroup\$
    – xnor
    Oct 3, 2016 at 21:58
3
\$\begingroup\$

C#, 73 bytes

a=>b=>{int x=0;for(;;){x+=(a%=24)>12?a-12:a<1?12:a;if(a++==b)return x;}};

Acceptable input: integers in range [0,23].

This solution does not use LINQ.


Full program with test cases:

using System;

namespace HowManyTimesABellTowerRings
{
    class Program
    {
        static void Main(string[] args)
        {
            Func<int,Func<int,int>>f= a=>b=>{int x=0;for(;;){x+=(a%=24)>12?a-12:a<1?12:a;if(a++==b)return x;}};
            
            Console.WriteLine(f(10)(12));   //33
            Console.WriteLine(f(1)(5));     //15
            Console.WriteLine(f(11)(15));   //29
            Console.WriteLine(f(22)(10));   //88
            Console.WriteLine(f(10)(10));   //10
            Console.WriteLine(f(11)(10));   //156
            Console.WriteLine(f(0)(23));    //156
            Console.WriteLine(f(22)(1));    //34
        }
    }
}
\$\endgroup\$
3
\$\begingroup\$

Jelly, 17 16 15 14 bytes

>×24+⁹⁸r’%12‘S

TryItOnline

How?

>×24+⁹⁸r’%12‘S - Main link: a, b (24 hr integers, midnight may be 0 or 24)
>              - a>b? (1 if true, 0 if false)
 ×24           - times 24 (24 if a>b, else 0)
    +⁹         - add to b (b+24 if a>b, else b)
      ⁸        - a
       r       - range(a, b+24 or b) ([a,a+1,...,b+24 or b])
        ’      - decrement (vectorises) ([a-1,a,...,b+23 or b-1])
         %12   - mod 12 (vectorises) (number of tolls at each occurrence - 1)
            ‘  - increment (vectorises) (number of tolls at each occurrence)
             S - sum
\$\endgroup\$
2
\$\begingroup\$

MATL, 14 bytes

yy>24*+&:12X\s

Input format is as in the third example in the challenge, that is, two numbers in 24-hour format.

Try it online!

Explanation

Take inputs 22, 10 as an example.

yy      % Take two inputs implicitly. Duplicate both
        %   STACK: 22, 10, 22, 10
>       % Is the first greater than the second?
        %   STACK: 22, 10, 1
24*     % Multiply by 24
        %   STACK: 22, 10, 24
+       % Add
        %   STACK: 22, 34
&:      % Binary range
        %   STACK: [22 23 24 25 26 27 28 29 30 31 32 33 34]
12X\    % Modulo 12, 1-based
        %   STACK: [10 11 12 1 2 3 4 5 6 7 8 9 10]
s       % Sum of array
        %   STACK: 88
        % Implicitly display
\$\endgroup\$
2
\$\begingroup\$

PHP, 90 Bytes

Input format '[1,24]' between 1 and 24

In this challenge that I am hate why PHP loose against other languages. I prefer to show all my ideas. Maybe an other PHP Crack finds a shorter solution.

<?list($f,$g)=$_GET[b];for($i=$f;$i-1!=$g|$f>$g&!$c;$s+=$i++%12?:12)$i<25?:$c=$i=1;echo$s;

99 Bytes

<?for($i=($b=$_GET[b])[0],$c=($d=$b[1]-$b[0])<0?25+$d:$d+1;$c--;$s+=$i++%12?:12)$i<25?:$i=1;echo$s;

113 Bytes a way with min and max

<?for($i=min($b=$_GET[b]);$i<=$m=max($b);)$s+=$i++%12?:12;echo($b[0]>$b[1])?156-$s+($m%12?:12)+($b[1]%12?:12):$s;

okay this crazy idea works with an array 149 Bytes fills the array $y[0] and $y[1] if $_GET["b"][0]<=$_GET["b"][1] if $y[1] is null we can sum this array array_diff_key($y[0],array_slice($y[0],$b[1],$b[0]-$b[1]-1,1))

<?for(;++$i<25;)$y[$i>=($b=$_GET[b])[0]&$i<=$b[1]][$i]=$i%12?:12;echo array_sum($y[1]??array_diff_key($y[0],array_slice($y[0],$b[1],$b[0]-$b[1]-1,1)));

This could be golfed down 124 Bytes

<?for(;++$i<25;)$x[($v=($b=$_GET[b])[0]>$b[1])?$i<$b[0]&$i>$b[1]:$i>=$b[0]&$i<=$b[1]][$i]=$i%12?:12;echo array_sum($x[!$v]);

Now at this point we can reduce the array with only two ints 101 Bytes Make 2 sums $x[0] and $x[1]

list($f,$g)=$_GET[b];

if $v=($f>$g then add value to $x[$i<$f&$i>$g] else add value to $x[$i>=$f&$i<=$g] the output will be find by case echo$x[!$v];

<?list($f,$g)=$_GET[b];for(;++$i<25;)$x[($v=$f>$g)?$i<$f&$i>$g:$i>=$f&$i<=$g]+=$i%12?:12;echo$x[!$v];

After that i found a way to calculate the result directly 112 Bytes

<?list($x,$y)=$_GET[t];echo(($b=$x>$y)+(($x-($s=$x%12?:12)^$y-($t=$y%12?:12))xor$b))*78-($s*($s-1)-$t*($t+1))/2;

recursive 103 Bytes

<?list($x,$y)=$_GET[t];function f($x,$y){return($x%12?:12)+($x-$y?f(++$x<25?$x:1,$y):0);}echo f($x,$y);
\$\endgroup\$
2
\$\begingroup\$

PHP, 69 bytes

list(,$i,$a)=$argv;for($a+=$i>$a?24:0;$i<=$a;)$n+=$i++%12?:12;echo$n;

The list extraction was inspired by Jörg Hülsermann's answer but the rest of the similarities are a result of convergent evolution and because it's quite a lot shorter and the conditionals in the loop are different enough I'm posting it as a separate answer.

Takes input as 24 hour times (fine with either 0 or 24). Run like:

php -r "list(,$i,$a)=$argv;for($a+=$i>$a?24:0;$i<=$a;)$n+=$i++%12?:12;echo$n;" 9 18
\$\endgroup\$
2
  • \$\begingroup\$ $i>$a?24:0 has the same length as ($i>$a)*24 wiki.php.net/rfc/short_list_syntax Maybe you want to use the short list syntax which is new in 7.1 [$x,$i,$a]=$argv; -2 Bytes Before I have not tested that I would not use it. NIce way now I'am hate me more that I found not this way. \$\endgroup\$ Oct 4, 2016 at 16:00
  • \$\begingroup\$ thanks, I knew about the upcoming short list syntax but as php 7.1 hasn't been properly released yet (still on release candidate 3 at time of writing) I assumed it wasn't yet permitted in PPCG answers. \$\endgroup\$
    – user59178
    Oct 5, 2016 at 8:22
2
\$\begingroup\$

Java, 72 71 78 76 bytes

Usage: 
    pm:    true if first time is past 11am
    time:  first time%12
    pm2:   true if second time is past 11am
    time2: second time%12

Edit:

  • -1 byte off. Thanks to @1Darco1
  • Fixed function head. +7 bytes on.
  • -2 bytes off. Thanks to @Kevin Cruijssen
  • +2 bytes on. Now e/clock is initialized.

(a,b,c,d)->{int e=0;b+=a?12:0;d+=c?12:0;for(;b!=d;e+=b%12,b=++b%24);return e;}

Ungolfed:

public static int clock(boolean pm, int time, boolean pm2, int time2){
  int clock=0;
  time+=pm?12:0;
  time2+=pm2?12:0;
  while(time!=time2){
    clock+=time%12;
    time=++time%24;
  }
  return clock;
}
\$\endgroup\$
3
  • \$\begingroup\$ Where do you define a, and d, and b ? The full method makes sense, but unless I'm severely missing something, I think you need to look at your golfed lambda again and actually try to execute it. For further golfing: (time+1) can become ++time. \$\endgroup\$
    – Marco
    Oct 4, 2016 at 5:49
  • \$\begingroup\$ There is an error in the golfed part: a+=a? should be b+=a?. Also, you can golf it by 2 bytes by changing the while into a bodyless for like this: (a,b,c,d)->{int e;b+=a?12:0;d+=c?12:0;for(;b!=d;e+=b%12,b=++b%24);return e;} \$\endgroup\$ Oct 4, 2016 at 8:55
  • \$\begingroup\$ Sorry. I wrote this approach from my mobile and couldn't test it. Fixed. :) \$\endgroup\$ Oct 5, 2016 at 9:07
1
\$\begingroup\$

QBIC, 90 47 bytes

So, here's the answer printing only the total number of bell-rings:

::{c=a~c>12|c=c-12]d=d+c~a=b|_Xd]a=a+1~a>24|a=1

Input is in range 1-24; a and b are the inputs (:: in the code), c keeps track of am/pm, d is the total number of rings. When we've counted down all the hours, _Xd terminates the program, printing d in the process.


OK, I misunderstood the question and thought the 1+2+3...= text was part of the output, so I wrote that:

::{c=a~c>12|c=c-12]X=!c$Z=Z+X+@+| d=d+c~a=b|?left$$|(Z,len(Z)-1)+@ =|+!d$_X]a=a+1~a>24|a=1

Now, I'll go code the proper answer...

\$\endgroup\$
1
\$\begingroup\$

Pyth - 11 bytes

s|R12%R12}F

Test Suite.

\$\endgroup\$
1
  • 2
    \$\begingroup\$ This does not count around midnight, for example 23, 1 outputs 144 when it should output 24. (Such a case should, of course, be in the tests!) \$\endgroup\$ Oct 4, 2016 at 8:50
1
\$\begingroup\$

C#, 76 bytes

(a,b)=>Enumerable.Range(a,Math.Abs(b-a)+1).Select(n=>n%12==0?12:n%12).Sum();
\$\endgroup\$
5
  • \$\begingroup\$ This doesn't look as if it wraps around at midnight. \$\endgroup\$
    – Neil
    Oct 4, 2016 at 12:41
  • \$\begingroup\$ All test cases succeed \$\endgroup\$ Oct 4, 2016 at 12:57
  • \$\begingroup\$ I didn't ask that. \$\endgroup\$
    – Neil
    Oct 4, 2016 at 12:59
  • \$\begingroup\$ Then what test case of yours fails with my implementation? \$\endgroup\$ Oct 4, 2016 at 13:00
  • \$\begingroup\$ a=23 and b=0 seems to be the most obvious example. \$\endgroup\$
    – Neil
    Oct 4, 2016 at 13:20
1
\$\begingroup\$

Perl, 36 bytes

Includes +1 for -p

Give start and end time in 24-hour format on a line each on STDIN:

toll.pl
11
15
^D

toll.pl:

#!/usr/bin/perl -p
$\+=$_%12||12for$_..$_+(<>-$_)%24}{
\$\endgroup\$
1
\$\begingroup\$

Java 7, 64 bytes

int c(int x,int y){return(x%12<1?12:x%12)+(x!=y?c(-~x%24,y):0);}

Recursive method based on @ETHproductions's Python 2 answer. Uses a 24-hour clock input.

Ungolfed & test code:

Try it here.

class M{
  static int c(int x, int y){
    return (x%12 < 1
             ? 12
             : x%12)
         + (x != y
             ? c(-~x % 24, y)
             : 0);
  }

  public static void main(String[] a){
    System.out.println(c(10, 12));
    System.out.println(c(1, 5));
    System.out.println(c(11, 15));
    System.out.println(c(10, 22));
    System.out.println(c(5, 5));
  }
}

Output:

33
15
29
88
5
\$\endgroup\$
1
\$\begingroup\$

Batch, 168 91 bytes

@cmd/cset/ax=(%1+23)%%24,y=x+(%2+24-%1)%%24,z=y%%12+1,(y/12-x/12)*78+z*-~z/2-(x%%=12)*-~x/2

Edit: Saved 77 byte by switching to a closed form for the answer.

  • %1 and %2 are the two command-line parameters
  • @ Disable Batch's default which is to echo the command
  • cmd/c Fool Batch into immediately printing the result of the calculation
  • set/a Perform a numeric calculation
  • x=(%1+23)%%24, Normalise the starting hour to be the number of hours since 1AM (1PM would also work, but 11 is no shorter than 23)
  • y=x+(%2+24-%1)%%24, Normalise the ending hour to be ahead of the starting hour, advancing to the next day if necessary
  • z=y%%12+1, Number of bells struck at the ending hour
  • (y/12-x/12)*78+ Number of bells due to extra half days
  • z*~-z/2- Number of bells from 1 o'clock to the ending hour inclusive
  • (x%%=12) One less than the number of bells struck at the starting hour
  • *-~x/2 Number of bells that would have been struck from 1 o'clock to the starting hour, but not including the starting hour
\$\endgroup\$
1
\$\begingroup\$

C, 56 Bytes

f(a,b,c=0){while(b-->a){c+=b>12?b-12:b;}printf("%d",c);}
\$\endgroup\$
1
\$\begingroup\$

><>, 48 + 2 = 50 bytes

<v$&%$-&:$+}:*2c
{>:?!v1-}:1+
v?=1l<++1%c+b$
>n;

Input is expected to be present on the stack at program start, so +2 bytes for the -v flag. Input is two integers specifying the hour on the 24 hour clock, so 10am - 10pm would be given as 10 22.

Try it online!

\$\endgroup\$
0
1
\$\begingroup\$

Cubix, 45 44 bytes

Saved 1 byte, thanks to @ETHproductions

My first foray into Cubix...

)$424tU4OI0Iuq;;-!^;^%&21u+rr;ss!;sqU>&%r$@;

Or, cubified:

      ) $ 4
      2 4 t
      U 4 O
I 0 I u q ; ; - ! ^ ; ^
% & 2 1 u + r r ; s s !
; s q U > & % r $ @ ; .
      . . .
      . . .
      . . .

You can try it out at the online interpreter. Input is in 24 hour format, with the end time first. For example, from 5pm to 1am the input should be 1 17.


Previous version, 45 bytes:

)$442t\/OI0Iuq;;-!^;^%&21u+rr;ss!;sqU>&%r$@.;
\$\endgroup\$
1
  • 1
    \$\begingroup\$ Thank you for using my language, and great job :-) I see one small byte you can save by rearranging slightly and dropping the no-op: )$424tU4OI0Iuq;;-!^;^%&21u+rr;ss!;sqU>&%r$@; \$\endgroup\$ Oct 29, 2016 at 2:07
0
\$\begingroup\$

Qbasic, 112 bytes

input "",a
input "",b
do
if a=25 then a=1
if a<=12 then
c=c+a
else
c=c+a-12
endif
a=a+1
loop until a=b+1
print c
\$\endgroup\$
1
  • \$\begingroup\$ Shouldn't you output 12 when both starting and ending hour are zero? \$\endgroup\$
    – Neil
    Oct 4, 2016 at 12:42
0
\$\begingroup\$

Python, 73 bytes

It would be so much shorter if we didn't have to support pm to am. I use recursion to support it.

f=lambda a,b:sum([~-i%12+1for i in range(a,b+1)]*(a<b)or[f(a,24),f(1,b)])

Try it online

Without supporting pm to am (45 bytes):

lambda a,b:sum(~-i%12+1for i in range(a,b+1))
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.