How many times will a bell tower ring?

24

3

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.

Shaun Wild

Posted 2016-10-03T16:06:53.440

Reputation: 2 329

2Do we choose our own input method, or does it have to support all the mentioned? – anonymous2 – 2016-10-03T16:10:09.010

1You may choose the input method – Shaun Wild – 2016-10-03T16:13:57.897

1You should make it more clear that the inputs can go from pm to am, thus crossing to a 2nd day. – mbomb007 – 2016-10-03T16:19:32.600

3Will midnight be given as 0 or 24? – xnor – 2016-10-03T17:21:20.600

Does being able to choose the input method go as far as allowing us to take the two times in reverse (i.e. 11pm to 1am as 1, 23)? – Jonathan Allan – 2016-10-03T17:43:19.653

4

We encourage the use of the Sandbox to work out any issues with challenges before they are posted to the main site.

– Mego – 2016-10-03T17:44:13.780

1@xnor : All bell towers I've seen rung 12 times at midnight. – vsz – 2016-10-04T06:08:29.340

To make it more challenging, some bell towers ring once at every quarter hour. And as almost all bell towers are attached to churches, they also ring Sundays at the beginning and end of church service. (they also ring when there is a marriage or funeral, but that would be too difficult to predict...) – vsz – 2016-10-04T06:13:59.827

1I think the first example in the "Examples" section is incorrect - 12am is 00:00, or midnight. Therefore 10am-12am = 10:00 to 00:00, or 10+11+12+1+2+3+4+5+6+7+8+9+10+11+12 = 111 – Sok – 2016-10-04T08:38:27.900

1Can I use 13-23 for 1pm-11pm and 0 instead of 12am? – Erik the Outgolfer – 2016-10-04T10:44:21.807

1This challenge still has several issues with clarity, and should not have been reopened. – Mego – 2016-10-04T11:35:25.633

@BasicallyAlanTuring Shouting doesn't solve anything. As mentioned in the comments above, the first example is incorrect, and it's not clear whether midnight in 24-hour time should be 0 or 24. – Mego – 2016-10-04T12:50:27.897

@Mego It is your choice just make sure you specify – Shaun Wild – 2016-10-04T13:25:15.617

Answers

12

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

ETHproductions

Posted 2016-10-03T16:06:53.440

Reputation: 47 880

7

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).

ETHproductions

Posted 2016-10-03T16:06:53.440

Reputation: 47 880

6

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

Rod

Posted 2016-10-03T16:06:53.440

Reputation: 17 588

3I think you don't need the a= part. – acrolith – 2016-10-03T16:50:31.553

@daHugLenny it need to be a full(usable) function – Rod – 2016-10-03T17:01:26.653

(y+24)%24 is just y – Vladimir Cravero – 2016-10-03T17:24:45.440

1@Rod You don't need a=. It's allowed to be a pure lambda. – Yytsi – 2016-10-04T11:06:55.387

@Rod You don't need a named function

– Erik the Outgolfer – 2016-10-04T11:10:22.463

1@VladimirCravero Of course not. It is the same as y%24. – Erik the Outgolfer – 2016-10-04T11:11:58.257

Yep @EriktheGolfer you are right, in my mind y < 24 which is true in this particular case. – Vladimir Cravero – 2016-10-04T11:14:30.660

Guys, I know that the a= isn't necessary, but all the python answers in this question have it. It's better for score comparison to keep this pattern across the answers. All or None c: – Rod – 2016-10-04T11:22:23.783

3

05AB1E, 13 bytes

With a lot of help from Emigna.

-24%ݹ+<12%>O

Uses the CP-1252 encoding. Try it online!

Adnan

Posted 2016-10-03T16:06:53.440

Reputation: 41 965

3

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

Jonathan Allan

Posted 2016-10-03T16:06:53.440

Reputation: 67 804

3

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.

xnor

Posted 2016-10-03T16:06:53.440

Reputation: 115 687

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! – ETHproductions – 2016-10-03T17:30:12.660

3

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

Nick Hansen

Posted 2016-10-03T16:06:53.440

Reputation: 71

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]. – xnor – 2016-10-03T21:58:29.207

3

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
        }
    }
}

adrianmp

Posted 2016-10-03T16:06:53.440

Reputation: 1 592

2

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);

Jörg Hülsermann

Posted 2016-10-03T16:06:53.440

Reputation: 13 026

2

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;
}

Roman Gräf

Posted 2016-10-03T16:06:53.440

Reputation: 2 915

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. – 1Darco1 – 2016-10-04T05:49:36.237

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;} – Kevin Cruijssen – 2016-10-04T08:55:13.453

Sorry. I wrote this approach from my mobile and couldn't test it. Fixed. :) – Roman Gräf – 2016-10-05T09:07:05.503

2

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

Luis Mendo

Posted 2016-10-03T16:06:53.440

Reputation: 87 464

2

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

user59178

Posted 2016-10-03T16:06:53.440

Reputation: 1 007

$i>$a?24:0 has the same length as ($i>$a)*24 https://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. – Jörg Hülsermann – 2016-10-04T16:00:58.263

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. – user59178 – 2016-10-05T08:22:37.157

1

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...

steenbergh

Posted 2016-10-03T16:06:53.440

Reputation: 7 772

1

Pyth - 11 bytes

s|R12%R12}F

Test Suite.

Maltysen

Posted 2016-10-03T16:06:53.440

Reputation: 25 023

2This 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!) – Jonathan Allan – 2016-10-04T08:50:34.787

1

C#, 76 bytes

(a,b)=>Enumerable.Range(a,Math.Abs(b-a)+1).Select(n=>n%12==0?12:n%12).Sum();

downrep_nation

Posted 2016-10-03T16:06:53.440

Reputation: 1 152

This doesn't look as if it wraps around at midnight. – Neil – 2016-10-04T12:41:38.853

All test cases succeed – downrep_nation – 2016-10-04T12:57:24.997

I didn't ask that. – Neil – 2016-10-04T12:59:29.073

Then what test case of yours fails with my implementation? – downrep_nation – 2016-10-04T13:00:43.713

a=23 and b=0 seems to be the most obvious example. – Neil – 2016-10-04T13:20:12.860

1

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}{

Ton Hospel

Posted 2016-10-03T16:06:53.440

Reputation: 14 114

1

><>, 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!

Sok

Posted 2016-10-03T16:06:53.440

Reputation: 5 592

@LuisMendo Thanks, it's fixed now – Sok – 2016-10-05T07:38:14.017

1

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

Neil

Posted 2016-10-03T16:06:53.440

Reputation: 95 035

1

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

Kevin Cruijssen

Posted 2016-10-03T16:06:53.440

Reputation: 67 575

1

C, 56 Bytes

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

user60119

Posted 2016-10-03T16:06:53.440

Reputation:

1

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$@.;

Sok

Posted 2016-10-03T16:06:53.440

Reputation: 5 592

1Thank 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$@; – ETHproductions – 2016-10-29T02:07:54.940

0

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

anonymous2

Posted 2016-10-03T16:06:53.440

Reputation: 421

Shouldn't you output 12 when both starting and ending hour are zero? – Neil – 2016-10-04T12:42:44.277

0

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))

mbomb007

Posted 2016-10-03T16:06:53.440

Reputation: 21 944