Сколько раз будет звонить колокольня?


24

Введение

Колокольня будет звонить в колокола каждый час, nвремя от времени, с nтекущим часом на 12-часовых часах.

Например, колокол будет звонить 5 раз в 17:00 и 10 раз в 10:00.

задача

Задав два раза в подходящем формате, выведите количество звонков, включая время начала и окончания

Примеры

"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

Если начало совпадает с концом, то вы просто выводите количество звонков за этот час:

[5pm, 5pm]
5 = 5

Как вы можете видеть, вы можете выбрать метод ввода, но выходные данные должны быть целыми числами (или приемлемой альтернативой), допускаются завершающие / ведущие символы новой строки и пробелы.

Заметка:

  • входные данные могут охватывать от полудня одного дня до утра следующего.
  • Разница между этими двумя значениями никогда не будет превышать 24 часа.
  • Ввод гибкий, если вы четко указали, в каком формате он находится.
  • Ваш вклад должен иметь четкое различие между AM и PM.

2
Мы выбираем наш собственный метод ввода или он должен поддерживать все перечисленное?
anonymous2

1
Вы можете выбрать метод ввода
Shaun Wild

1
Вы должны прояснить, что входные данные могут идти от pmк am, таким образом, переходя на 2-й день.
mbomb007

3
Будет ли полночь дана как 0 или 24?
xnor

4
Мы рекомендуем использовать Песочницу для решения любых проблем с проблемами до того, как они будут опубликованы на основном сайте.
Mego

Ответы:


12

JavaScript (ES6), 38 35 байт

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

Рекурсивно добавляет текущее количество звонков к общему количеству. Называется как f(11,15); полночь представляется как 24. Я получил часть ~-уловки из ответа @ xnor's Python .

Тестовый фрагмент

Нерекурсивная версия (Firefox 30+), 56 байт

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

Эквивалент следующей функции ES6:

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

7

Python 2, 46 байт

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

На основании моего ответа JS. Рекурсивная формула f для решения определяется так:

  1. Начните с двух целых чисел x и y .
  2. Возьми х мод 12 ; если это 0, возьмите 12 вместо.
  3. Если x! = Y , добавить результат f (x + 1 mod 24, y) .

6

Python 2, 59 54 байта

a=lambda x,y:sum(1+i%12for i in range(x-1,y+24*(x>y)))
Эквивалентно
summ=0
if start > end:
    end+=24
for hour in range(start-1,end):
    summ +=1+hour%12
print summ

3
Я думаю, что вам не нужна a=часть.
Акролит

@daHugLenny это должна быть полная (пригодная для использования) функция
Rod

(y + 24)% 24 - это просто y
Владимир Краверо

1
@ Род Вам не нужен a=. Это разрешено быть чистой лямбдой.
Yytsi

1
@VladimirCravero Конечно нет. Это так же, как y%24.
Эрик Outgolfer


3

Python, 42 байта

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

Рекурсивная функция , которая принимает два числа от 0 до 23. Расширение ~x«с до -x-1дает

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

Выражение (a+1)%12+1преобразует время в число колец 1в 12. Затем нижняя граница увеличивается по модулю 24 и добавляется функция для рекурсивного результата. То есть, если текущий час не является последним часом, в этом случае мы останавливаемся.

Вместо этого я пытался написать чисто арифметическое решение, но пока что нашел только длинные и грязные выражения.


Ах, я понял: это в основном та же техника, что и в моем ответе на Python, но с действительно умным способом обойти or. Хороший!
ETHproductions

3

Haskell, 48 43 байта

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

Использование startHour % endHourс обоими входами, представленными в 24-часовом формате.

edit: добавлено улучшение @ xnor, экономия 5 байт


Вместо того чтобы менять eвремя e<s, вы можете отфильтровать диапазон s%e=sum[mod(x-1)12+1|x<-[s..e+24],x<=e||s>e]. Затем он сохраняет байт для смещения х вниз 1: s%e=sum[mod x 12+1|x<-[s-1..e+23],x<e||s>e].
xnor

3

C #, 73 байта

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

Допустимый ввод: целые числа в диапазоне [0,23].

Это решение не использует LINQ.


Полная программа с тестовыми примерами:

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

3

Желе , 17 16 15 14 байт

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

TryItOnline

Как?

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

2

MATL , 14 байтов

yy>24*+&:12X\s

Формат ввода такой же, как в третьем примере в задании, то есть два числа в 24-часовом формате.

Попробуйте онлайн!

объяснение

Возьмем входные данные 22, 10как пример.

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

2

PHP, 90 байт

Формат ввода '[1,24]' от 1 до 24

В этом вызове я ненавижу, почему PHP проигрывает против других языков. Я предпочитаю показывать все свои идеи. Может быть, другой PHP Crack найдет более короткое решение.

<?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 байт

<?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 байт путь с мин и макс

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

хорошо, эта сумасшедшая идея работает с массивом 149 байт заполняет массив, $y[0]и $y[1]если, $_GET["b"][0]<=$_GET["b"][1] если $y[1]это, nullмы можем суммировать этот массив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)));

Это может быть гольф до 124 байт

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

Теперь на этом этапе мы можем уменьшить массив всего двумя целыми числами. 101 байт. Сделать 2 суммы $x[0]и$x[1]

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

если $v=($f>$g затем добавить значение к $x[$i<$f&$i>$g] другому добавить значение к $x[$i>=$f&$i<=$g] выходу будет найден в каждом конкретном случае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];

После этого я нашел способ рассчитать результат прямо 112 байтов

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

рекурсивный 103 байта

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

2

PHP, 69 байт

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

Извлечение списка было вдохновлено ответом Йорга Хюльсермана, но все остальное сходство является результатом конвергентной эволюции, и потому что он намного короче и условия в цикле достаточно разные, я публикую его как отдельный ответ.

Принимает ввод как 24-часовой (хорошо с 0 или 24). Беги как:

php -r "list(,$i,$a)=$argv;for($a+=$i>$a?24:0;$i<=$a;)$n+=$i++%12?:12;echo$n;" 9 18

$i>$a?24:0имеет ту же длину, что и ($i>$a)*24 wiki.php.net/rfc/short_list_syntax. Возможно, вы захотите использовать синтаксис короткого списка, новый в 7,1 [$x,$i,$a]=$argv;-2 байта, прежде чем я не проверил, что я не буду его использовать. Теперь я ненавижу меня больше, что нашел не таким.
Йорг Хюльсерманн

спасибо, я знал о предстоящем синтаксисе короткого списка, но так как php 7.1 еще не был выпущен должным образом (все еще в версии 3 кандидата на момент написания), я предположил, что это еще не разрешено в ответах PPCG.
user59178

2

Java, 72 71 78 76 байт

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

Редактировать :

  • -1 байт выключен. Благодаря @ 1Darco1
  • Исправлена ​​функция головы. +7 байт вкл.
  • -2 байта выкл. Спасибо @Kevin Cruijssen
  • +2 байта вкл. Сейчас e/ clockинициализирован.

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

Где вы определяете a, и d, и b? Полный метод имеет смысл, но если я что-то сильно упускаю, думаю, вам нужно еще раз взглянуть на свою лямбду в гольфе и попытаться ее выполнить. Для дальнейшего игры в гольф: (time+1)может стать ++time.
Darco1

В гольфовой части есть ошибка: a+=a?должно быть b+=a?. Кроме того, вы можете whileсыграть в гольф на 2 байта, превратив его в тело без тела for:(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;}
Кевин Круйссен

Сожалею. Я написал этот подход со своего мобильного телефона и не смог проверить его. Исправлена. :)
Роман Грэф

1

QBIC , 90 47 байтов

Итак, вот ответ, печатающий только общее количество звонков:

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

Вход находится в диапазоне 1-24; aи bявляются входами ( ::в коде), cотслеживает am / pm, dявляется общим количеством звонков. Когда мы отсчитали все часы, _Xdпрограмма завершает работу, печатая dв процессе.


Хорошо, я неправильно понял вопрос и подумал, что 1+2+3...=текст является частью вывода, поэтому я написал это:

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

Теперь я пойду код правильный ответ ...



1

C #, 76 байт

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

Это не похоже на то, как будто это происходит в полночь.
Нил

Все тесты успешно
пройдены

Я этого не спрашивал.
Нил

Тогда какой твой контрольный пример терпит неудачу с моей реализацией?
downrep_nation

a=23и, b=0кажется, самый очевидный пример.
Нил

1

Perl, 36 байт

Включает +1 для -p

Укажите время начала и окончания в 24-часовом формате в строке на STDIN:

toll.pl
11
15
^D

toll.pl:

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

1

Java 7, 64 байта

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

Рекурсивный метод, основанный на ответе @ETHproductions на Python 2 . Использует 24-часовой вход часов.

Ungolfed & тестовый код:

Попробуй это здесь.

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

Выход:

33
15
29
88
5

1

Пакет, 168 91 байт

@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

Изменить: 77 байт, переключившись на закрытую форму для ответа.

  • %1и %2два параметра командной строки
  • @ Отключить пакетный режим по умолчанию, который должен повторить команду
  • cmd/c Дурак Пакетный в печать сразу результат расчета
  • set/a Выполнить числовой расчет
  • x=(%1+23)%%24, Нормализовать начальный час, указав количество часов с 1 утра (1 вечера также будет работать, но 11 не короче 23)
  • y=x+(%2+24-%1)%%24, Нормализуйте конечный час так, чтобы он опережал начальный час, при необходимости переходя на следующий день
  • z=y%%12+1, Количество колоколов, выпущенных в последний час
  • (y/12-x/12)*78+ Количество звонков из-за дополнительных полдня
  • z*~-z/2- Количество звонков от 1 часа до часа окончания включительно
  • (x%%=12) На один меньше количества колоколов, выпущенных в начальный час
  • *-~x/2 Количество звонков, которые были бы сбиты с 1 часа до начального часа, но не включая начальный час

1

C, 56 байт

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

1

> <> , 48 + 2 = 50 байтов

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

Ожидается, что вход будет присутствовать в стеке при запуске программы, поэтому +2 байта для -vфлага. Входные данные представляют собой два целых числа, указывающие час на 24-часовых часах, поэтому 10am - 10pmбудут заданы как 10 22.

Попробуйте онлайн!


@LuisMendo Спасибо, сейчас все исправлено
Sok

1

Cubix , 45 44 байта

Сохранено 1 байт благодаря @ETHproductions

Мой первый набег в Cubix ...

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

Или в кубе:

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

Вы можете попробовать это в онлайн переводчике . Ввод в 24-часовом формате, с первым временем окончания. Например, с 5 вечера до 1 утра вход должен быть 1 17.


Предыдущая версия, 45 байт:

)$442t\/OI0Iuq;;-!^;^%&21u+rr;ss!;sqU>&%r$@.;

1
Спасибо за использование моего языка и отличную работу :-) Я вижу один маленький байт, который вы можете сохранить, слегка переставив и опустив no-op:)$424tU4OI0Iuq;;-!^;^%&21u+rr;ss!;sqU>&%r$@;
ETHproductions

0

Qbasic, 112 байт

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

Не следует ли вывести 12, когда начальный и конечный час равны нулю?
Нил

0

Python, 73 байта

Было бы гораздо короче , если бы мы не должны поддерживать pmв am. Я использую рекурсию, чтобы поддержать это.

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

Попробуйте онлайн

Без поддержки pmдо am(45 байт):

lambda a,b:sum(~-i%12+1for i in range(a,b+1))
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.