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\$
  • 2
    \$\begingroup\$ Do we choose our own input method, or does it have to support all the mentioned? \$\endgroup\$ – anonymous2 Oct 3 '16 at 16:10
  • 1
    \$\begingroup\$ You may choose the input method \$\endgroup\$ – Shaun Wild Oct 3 '16 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 '16 at 16:19
  • 3
    \$\begingroup\$ Will midnight be given as 0 or 24? \$\endgroup\$ – xnor Oct 3 '16 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\$ – Mego Oct 3 '16 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\$
  • 3
    \$\begingroup\$ I think you don't need the a= part. \$\endgroup\$ – acrolith Oct 3 '16 at 16:50
  • \$\begingroup\$ @daHugLenny it need to be a full(usable) function \$\endgroup\$ – Rod Oct 3 '16 at 17:01
  • \$\begingroup\$ (y+24)%24 is just y \$\endgroup\$ – Vladimir Cravero Oct 3 '16 at 17:24
  • 1
    \$\begingroup\$ @Rod You don't need a=. It's allowed to be a pure lambda. \$\endgroup\$ – Yytsi Oct 4 '16 at 11:06
  • 1
    \$\begingroup\$ @VladimirCravero Of course not. It is the same as y%24. \$\endgroup\$ – Erik the Outgolfer Oct 4 '16 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\$
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\$
  • \$\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\$ – ETHproductions Oct 3 '16 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\$
  • \$\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 '16 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\$
  • \$\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\$ – Jörg Hülsermann Oct 4 '16 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 '16 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\$
  • \$\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\$ – 1Darco1 Oct 4 '16 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\$ – Kevin Cruijssen Oct 4 '16 at 8:55
  • \$\begingroup\$ Sorry. I wrote this approach from my mobile and couldn't test it. Fixed. :) \$\endgroup\$ – Roman Gräf Oct 5 '16 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\$
  • 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\$ – Jonathan Allan Oct 4 '16 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\$
  • \$\begingroup\$ This doesn't look as if it wraps around at midnight. \$\endgroup\$ – Neil Oct 4 '16 at 12:41
  • \$\begingroup\$ All test cases succeed \$\endgroup\$ – downrep_nation Oct 4 '16 at 12:57
  • \$\begingroup\$ I didn't ask that. \$\endgroup\$ – Neil Oct 4 '16 at 12:59
  • \$\begingroup\$ Then what test case of yours fails with my implementation? \$\endgroup\$ – downrep_nation Oct 4 '16 at 13:00
  • \$\begingroup\$ a=23 and b=0 seems to be the most obvious example. \$\endgroup\$ – Neil Oct 4 '16 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\$
  • \$\begingroup\$ @LuisMendo Thanks, it's fixed now \$\endgroup\$ – Sok Oct 5 '16 at 7:38
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
    \$\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\$ – ETHproductions Oct 29 '16 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\$
  • \$\begingroup\$ Shouldn't you output 12 when both starting and ending hour are zero? \$\endgroup\$ – Neil Oct 4 '16 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, privacy policy and cookie policy

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