ASCII часы с точками и запятыми

39

Введение

код гольф объяснение

Представьте, что на самом деле линия символов состоит из двух рядов. Верхний ряд - точки - представляет часы (24-часовая система), а нижний - запятые - минуты . Один символ может представлять час, минуту или оба - когда это возможно.

Сначала, вероятно, вам придется конвертировать минуты с полуночи в часы и минуты .

Результатом является строка, показывающая текущее время в «точечном формате». Счетчик точек ( апостроф считается здесь как точка и будет называться так! ) - счетчик часов с полуночи, а счетчик запятых - счетчик минут. Я покажу несколько примеров, чтобы прояснить это.

  • (Примечание) чч: мм - result
  • (Только часы) 05:00 - '''''
  • (Только минуты) 00:08 - ,,,,,,,,
  • (часы <минуты) 03:07 - ;;;,,,,
  • (часы> минуты) 08:02 - ;;''''''
  • (часы = минуты) 07:07 - ;;;;;;;
  • (начало дня) 00:00 - ( пустой результат )

Заметить, что «оба» символа могут использоваться максимум 23 раза - для 23: xx, где xx равно 23 или более.

Символы

Если символ должен (см. Правило 5) экранироваться на вашем языке, вы можете изменить его на одну из альтернатив. Если упомянутых альтернатив недостаточно, вы можете использовать другие символы - но оставляйте их разумными. Я просто не хочу, чтобы побег был барьером.

  • ; (точка с запятой) - маркер для часов и минут (alt: : )
  • ' (апостроф) - маркер для часов (alt: '``° )
  • , (запятая) - маркер для минут (alt: . )

Дополнительные правила

  1. Код с наименьшим количеством байтов выигрывает!
  2. Вы должны использовать оба символа, когда это возможно. Для 02:04 результат не может быть '',,,,, ни ;',,,. Должно быть;;,,
  3. Ввод - может быть параметром скрипта / приложения, пользовательским вводом (например, readline) или переменной внутри кода
    3.1. Если используется переменная внутри кода, ее длина должна быть максимально возможной. Это 1439(23:59), так это будет выглядетьt=1439
  4. Общая часть, которая обозначается символом «оба» (12 в 12:05, 3 в 03:10), должна располагаться в начале строки
  5. Символы могут быть заменены альтернативами, только если они должны быть экранированы в вашем коде.
  6. Ввод дан в минутах после 00:00 . Вы можете предположить, что это неотрицательное целое число.

Контрольные примеры

Input: 300
Output: '''''

Input: 8
Output: ,,,,,,,,

Input: 187
Output: ;;;,,,,

Input: 482
Output: ;;''''''

Input: 427
Output: ;;;;;;;

Input: 0
Output:  (empty)
Krzysiu
источник
Спасибо, Аднан, за редактирование моего поста! Так я научусь сравнивать мой новый гольф с твоим :)
Кшишуу
3
Нет проблем! Это очень хороший первый пост и хороший вызов :)
Аднан
1
это выглядит так хорошо только с точками с запятой и запятыми, но апострофы все испортили :(
Спарр
На самом деле 1439есть 23:59и нет 1339. (23 х 60 + 59).
insertusername здесь
Спасибо всем за добрые слова! :) @Sparr, да, это плохой момент :( Ты представляешь, как его можно заменить? Имя_пользователя здесь, конечно, верно! Исправлено :)
Krzysiu

Ответы:

10

Pyth, 19 байт

:.iF*V.DQ60J"',"J\;

Тестирование

:.iF*V.DQ60J"',"J\;
      .DQ60            Divmod the input by 60, giving [hours, minutes].
           J"',"       Set J equal to the string "',".
    *V                 Perform vectorized multiplication, giving H "'" and M ','.
 .iF                   Interleave the two lists into a single string.
:               J\;    Perform a substitution, replacing J with ';'.
isaacg
источник
8

CJam, 22 20 19 байтов

Принимает участие от STDIN:

ri60md]',`.*:.{;K+}

Проверьте это здесь.

объяснение

ri     e# Read input and convert to integer.
60md   e# Divmod 60, pushes hours H and minutes M on the stack.
]      e# Wrap in an array.
',`    e# Push the string representation of the comma character which is "',".
.*     e# Repeat apostrophe H times and comma M times.
:.{    e# Apply this block between every pair of characters. This will only applied to
       e# first N characters where N = min(hours,minutes). The others will remain
       e# untouched. So we want the block to turn that pair into a semicolon...
  ;    e#   Discard the comma.
  K+   e#   Add 20 to the apostrophe to turn it into a semicolon.
}

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

Это единственный 3-байтовый блок, который я нашел до сих пор. Было множество 4-символьных решений:

{;;';}
{';\?}
{^'0+}
{^'F-}
{-'@+}
{-'6-}
...
Мартин Эндер
источник
6

GNU Sed, 37

Оценка включает в себя +1 для -Eопции для sed.

Я не был особенно впечатлен игривостью моего ответа bash , поэтому я подумал, что попробую с sed для удовольствия.

Ввод в унарном, согласно этому мета-ответу .

y/1/,/          # Convert unary 1's to commas (minutes)
s/,{60}/'/g     # divmod by 60.  "'" are hours
:               # unnamed label
s/(.*)',/;\1/   # replace an apostrophe and comma with a semicolon
t               # jump back to unnamed label until no more replacements

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

Цифровая травма
источник
безымянный ярлык ??
mikeserv
@ Manatwork - я думаю, что это ошибка GNU.
mikeserv
@mikeserv - но с ошибками тоже можно, верно? Я не прошу насмехаться над тобой, я просто не знаю :)
Krzysiu
@Krzysiu - хорошо? хмм. на этом сайте я думаю, что это будет знак отличия. иначе почти точно нет. когда программисты отклоняются от API и используют детали реализации, программы становятся зависимыми от версии / реализации - что плохо.
mikeserv
6

Python 2, 56 байт

def g(t):d=t%60-t/60;print(t/60*";")[:t%60]+","*d+"'"*-d

Функция, которая печатает (один символ короче, чем t=input();).

Метод похож на метод Ловжо . Число ,разное между минутами и часами, с неявным минимальным значением 0. Так 'как это отрицание. Ибо ;вычисляетmin неявно , беря целых ;несколько часов, а затем обрезая до количества минут.

Это экономит символы, чтобы сэкономить d, но не количество часов и минут здесь. Аналог с лямбдой был на два символа длиннее (58), поэтому присваивание переменных того стоит.

lambda t:(t%60*";")[:t/60]+","*(t%60-t/60)+"'"*(t/60-t%60)

Непосредственная обработка ввода также не спасла символы (58):

h,m=divmod(input(),60);d=m-h;print(";"*m)[:h]+","*d+"'"*-d

Еще одна стратегия с нарезкой, гораздо дольше (64):

def g(t):m=t%60;h=t/60;return(";"*m)[:h]+(","*m)[h:]+("'"*h)[m:]
XNOR
источник
3

Pure Bash (без внешних утилит), 103

p()(printf -vt %$2s;printf "${t// /$1}")
p \; $[h=$1/60,m=$1%60,m>h?c=m-h,h:m]
p , $c
p \' $[m<h?h-m:0]

Спасибо @ F.Hauri за сохранение 2 байта.

Цифровая травма
источник
Ницца! Но вы могли бы сэкономить 2 символов путем замены $1и $2в p()и написать p , $cв строке 3.
F. Hauri
Да, но так как он используется только в a printf "%s", cпустой будет хорошо работать (хотя и не будет использоваться повторно)
Ф. Хаури
@ F.Hauri Теперь я понял - спасибо!
Цифровая травма
3

C 119 байтов

#define p(a,b) while(a--)putchar(b);
main(h,m,n){scanf("%d",&m);h=m/60;m%=60;n=h<m?h:m;h-=n;m-=n;p(n,59)p(h,39)p(m,44)}

Детальнее

// macro: print b, a times
#define p(a,b) while(a--)putchar(b)

int main(void)
{
    int h,m,n;
    scanf("%d",&m);  // read input

    h=m/60;m%=60;    // get hours:minutes
    n=h<m?h:m;       // get common count
    h-=n;m-=n;       // get remaining hours:minutes

    p(n,59);        // print common
    p(h,39);        // print remaining hours
    p(m,44);        // print remaining minutes

    return 0;
}
Khaled.K
источник
1
Использование putchar& целочисленных литералов в качестве символов сохраняет один байт, вытягивание точек с запятой внутри макроса сохраняет еще два :)
Квентин,
@Quentin записка сделана, сохранено 5 байтов
Khaled.K
Вы можете потерять пространство перед вашим whileв #define макросе. -1 байт
Альберт Реншоу
1
Вы также можете сохранить еще несколько байтов, просто сделав p (a, b) функцией вместо макроса. (И добавляя еще несколько
Альберт Реншоу
3

Haskell, 68 66 Bytes

g(h,m)=id=<<zipWith replicate[min h m,h-m,m-h]";',"
g.(`divMod`60)

Пример использования:

(g.(`divMod`60)) 482

Умная часть здесь в том, что replicate вернет пустую строку, если заданная длина будет отрицательной или нулевой, так что я могу применить ее к обеим различиям, и будет отображаться только положительная. Первая часть проста, так как количество точек с запятой - это минимум двух. Затем zipWithприменяет функцию к соответствующим элементам.

РЕДАКТИРОВАТЬ: понял, что я использовал неправильный символ в течение нескольких минут

РЕДАКТИРОВАТЬ 2: Сохранено 2 байта благодаря @Laikoni

user1472751
источник
Вы можете сохранить два байта, заменив concat$на id=<<.
Лайкони
2

JavaScript (ES6) 69

m=>";".repeat((h=m/60|0)>(m%=60)?m:h)+",'"[h>m|0].repeat(h>m?h-m:m-h)
edc65
источник
2

Powershell, 99 85 байт

param($n)";"*(($m=$n%60),($h=$n/60))[($b=$m-gt$h)]+"'"*(($h-$m)*!$b)+","*(($m-$h)*$b)

Используя метод Loovjo , это моя реализация powershell.

ungolfed

param($n) 
# set the number of minutes and hours, and a boolean which one is bigger
# and also output the correct number of ;s
";"*(($m=$n%60),($h=$n/60))[($b=$m-gt$h)]+ 
# add the difference between h and m as 's but only if h > m
"'"*(($h-$m)*!$b)+
# add the difference between m and h as ,s but only if m > h
","*(($m-$h)*$b)

Сохранено 14 байт благодаря AdmBorkBork

Бьорн Моленмейкер
источник
Вы можете сэкономить, используя псевдо-тройной для первого, перемещения $mи $hдеклараций в нее, а затем , используя логическое умножение. Как и так -param($n)';'*(($m=$n%60),($h=$n/60))[($b=$m-gt$h)]+'°'*(($h-$m)*!$b)+','*(($m-$h)*$b)
AdmBorkBork
1

Python 3, 98 байт

d=int(input());m=d%60;h=int((d-m)/60)
if m>=h:print(";"*h+","*(m-h))
else:print(";"*(m)+"'"*(h-m))

Вероятно, не самый лучший ответ, но это было очень весело!

Аднан
источник
1

Python 2, 61 байт

t=input();m,h=t%60,t/60
print";"*min(h,m)+","*(m-h)+"'"*(h-m)

Explaination:

t=input();              # Read input
          m,  t%60,     # Do a divmod, h = div, m = mod
            h=     t/60

print";"*min(h,m)+                    # Print the minimum of the h and m, but in ";"s
                  ","*(m-h)+          # Print (m-h) ","s (if m-h is negative, print nothing)
                            "'"*(h-m) # Print (h-m) "'"s (if h-m is negative, print nothing)
Loovjo
источник
1

PHP, 81 байт

Я выбрал переменную input, поскольку она короче, чем чтение STDINили принятие аргументов командной строки.

for($_=1439;$i<max($h=0|$_/60,$m=$_%60);++$i)echo$i<$h?$i<min($h,$m)?';':"'":",";
insertusernamehere
источник
Я думал, что довольно хорошо знаю PHP, но вижу | в первый раз. Я думаю, что я буду использовать это, чтобы немного тренироваться - я проанализирую это :)
Krzysiu
Терпит неудачу за 240. Попробуйте $i>=min($h,$m)?$h<$m?",":"'":";"(+1 байт). Или используйте for($_=1439;$i<max($h=0|$_/60,$m=$_%60);)echo"',;"[$i++<min($h,$m)?2:$h<$m];(76 байт). Кстати: одиночная кавычка делает -rневозможным; так что вы должны использовать backtick в течение нескольких часов, если в строке или° автономном режиме (без кавычек -> -1 байт).
Тит
1

JavaScript (ES6), 77 71 байт

x=>';'[r='repeat'](y=Math.min(h=x/60|0,m=x%60))+"'"[r](h-y)+','[r](m-y)
Mwr247
источник
Отличное использование назначений в доступе к атрибутам / аргументам функций. +1
Cyoce
1

Perl 6, 103 101 98 97 69 байт

$_=get;say ";"x min($!=($_-$_%60)/60,$_=$_%60)~"'"x $!-$_~","x $_-$!;

Выводит несколько массивов, но, блядь, наслаждайся. Как обычно, любые возможности игры в гольф присущи.

Редактировать: -2 байта: получил храбрость и снял некоторые броски.

Edit2: -3 байта, удалив массивы.

Edit3: -1 байт для печати в правильном формате, используя «лямбда-выражения» и удаляя паратезы.

Edit4: (извините, ребята) злоупотребляет тем, что часы - минуты должны возвращать 0 и наоборот. Удалены ли заявления. Затем снял скобки, потом понял, что лямбда мне вообще не нужна. -28 байт :)

Вау, мне становится лучше в этом.

Ховард Нигорд
источник
0

C, 141 байт

main(h,m){scanf("%d",&m);h=(m/60)%24;m%=60;while(h||m){if(h&&m){printf(";");h--;m--;}else if(h&&!m){printf("'");h--;}else{printf(",");m--;}}}
user2064000
источник
Я думаю, что вы могли бы сэкономить несколько байтов, используя h>0||m>0. Тогда вам нужно h--;m--;только один раз в каждой итерации, и {}for if/elseустареет.
имя пользователя здесь
Вы также можете сэкономить несколько байтов на своем втором условном выражении: вместо else if(h&&!m)него можно просто иметьelse if(h)
Геллион
И, наконец, попробуйте использовать троичный оператор, это избавит вас от использования «длинных» слов, таких как ifи else.
insertusername здесь
Рассмотрите рефакторинг как функцию, которая принимает входные данные как параметр int - это должно по крайней мере сохранить вас scanf().
Цифровая травма
Я не думаю, что %24это необходимо - максимальный ввод 23:59.
Цифровая травма
0

Гема, 119 знаков

<D>=@set{h;@div{$0;60}}@set{m;@mod{$0;60}}@repeat{@cmpn{$h;$m;$h;$h;$m};\;}@repeat{@sub{$h;$m};'}@repeat{@sub{$m;$h};,}

Образец прогона:

bash-4.3$ gema '<D>=@set{h;@div{$0;60}}@set{m;@mod{$0;60}}@repeat{@cmpn{$h;$m;$h;$h;$m};\;}@repeat{@sub{$h;$m};`}@repeat{@sub{$m;$h};,}' <<< '252'
;;;;,,,,,,,,
manatwork
источник
0

Matlab: 89 байт

i=input('');m=mod(i,60);h=(i-m)/60;[repmat(';',1,min(h,m)),repmat(39+5*(m>h),1,abs(h-m))]

Тест:

310
ans =
;;;;;,,,,,
brainkz
источник
0

SmileBASIC, 59 байт

INPUT M
H%=M/60M=M-H%*60?";"*MIN(H%,M);",'"[M<H%]*ABS(H%-M)

Разъяснение:

INPUT MINUTES 'input
HOURS=MINUTES DIV 60 'separate the hours and minutes
MINUTES=MINUTES MOD 60
PRINT ";"*MIN(HOURS,MINUTES); 'print ;s for all positions with both
PRINT ",'"[MINUTES<HOURS]*ABS(HOURS-MINUTES) 'print extra ' or ,

Это выглядит довольно ужасно, так как нижняя часть ;даже не такая, как ,в шрифте SmileBASIC

12Me21
источник
0

PHP, 81 байт

еще несколько решений:

echo($r=str_repeat)(";",min($h=$argn/60,$m=$argn%60)),$r(",`"[$h>$m],abs($h-$m));
// or
echo($p=str_pad)($p("",min($h=$argn/60,$m=$argn%60),";"),max($h,$m),",`"[$h>$m]);

Беги с echo <time> | php -R '<code>'.

<?=($r=str_repeat)(";",min($h=($_=1439)/60,$m=$_%60)),$r(",`"[$h>$m],abs($h-$m));
// or
<?=($r=str_repeat)(";",min($h=.1/6*$_=1439,$m=$_%60)),$r(",`"[$h>$m],abs($h-$m));
// or
<?=str_pad(str_pad("",min($h=($_=1439)/60,$m=$_%60),";"),max($h,$m),",`"[$h>$m]);

Заменить 1439вводом, сохранить в файл, запустить.

Titus
источник
0

Рубин, 50 знаков

->t{(?;*h=t/60)[0,m=t%60]+",',"[0<=>m-=h]*m.abs}

Благодаря:

  • ГБ для
    • напомнив мне, что я не могу взять больше символов из строки, чем она имеет (-1 символ)
    • реорганизация моего расчета (-1 символ)

Ждал так долго, чтобы использовать Numeric.divmod , просто чтобы понять, что это ужасно долго.

Образец прогона:

2.1.5 :001 > puts ->t{(?;*h=t/60)[0,m=t%60]+",',"[0<=>m-=h]*m.abs}[252]
;;;;,,,,,,,,
manatwork
источник
1
Сохраните 1 символ, обрезав строку вместо использования min:(?;*h=t/60)[0,m=t%60]
ГБ
1
И еще один байт, вычитая h из m:",',"[0<=>m-=h]*m.abs
GB
0

05AB1E , 25 байтов

60‰vy„'.Nè×}‚.BøJ„'.';:ðK

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

60‰vy„'.Nè×}может быть определенно сокращен, я просто не мог понять это, и сомневаюсь, что смогу сбрить 7 байтов, чтобы выиграть с этим подходом, если не будет векторной версии ×.


Пример (с вводом, равным 63):

60‰                       # Divmod by 60.
                          # STACK: [[1,3]]
   vy      }              # For each element (probably don't need the loop)...
                          # STACK: []
     „'.Nè×               # Push n apostrophe's for hours, periods for minutes.
                          # STACK: ["'","..."]
            ‚             # Group a and b.
                          # STACK: [["'","..."]]
             .B           # Boxify.
                          # STACK: [["'  ","..."]]
               ø          # Zip it (Transpose).
                          # STACK: [["'."," ."," ."]
                J         # Join stack.
                          # STACK: ["'. . ."]
                 „'.';:   # Replace runs of "'." with ";".
                          # STACK: ["; . ."]
                       ðK # Remove all spaces.
                          # OUTPUT: ;..

D60÷''×s60%'.ׂ.BøJ„'.';:ðK была моя оригинальная версия, но это даже дороже, чем divmod.

60‰WDµ';ˆ¼}-¬0Qi'.ë''}ZׯìJ еще один метод, который я попробовал ...

Урна волшебного осьминога
источник
0

Java 8, 101 99 86 байт

n->{String r="";for(int m=n%60,h=n/60;h>0|m>0;r+=h--*m-->0?";":h<0?",":"'");return r;}

Объяснение:

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

n->{                      // Method with integer parameter and String return-type
  String r="";            //  Result-String (starting empty)
  for(int m=n%60,h=n/60;  //   Get the minutes and hours from the input integer
      h>0|m>0;            //   Loop as long as either the hours or minutes is above 0
    r+=                   //   Append the result-String with:
       h--*m-->0?         //    If both hours and minutes are above 0
                          //    (and decrease both after this check):
        ";"               //     Use ";"
       :h<0?              //    Else-if only minutes is above 0 (hours is below 0)
        ","               //     Use ","
       :                  //    Else:
        "'"               //     Use "'"
  );                      //  End loop
  return r;               //  Return the result
}                         // End of method
Кевин Круйссен
источник