Github Messenger

13

Цель: Цель состоит в том, чтобы взять строку и вывести, сколько вкладов следует сделать в какие дни, чтобы отобразить сообщение.

введите описание изображения здесь

Спецификация

  • вход
    • Поддержка букв плюс пробел (то есть [A-Za-z ])
    • Пространство пустое 3X7
    • Буквы определены в этом шрифте DOT Matrix 5x7, указанном ниже.
    • Размер каждой буквы - это минимальный ограничивающий прямоугольник (например l = 3x7, e = 5x5)
  • раскраска
    • Есть 5 цветов C0, C1, C2, C3, C4
    • CXтребует Yвзносов с3X <= y < 3(X+1)
    • Письма должны чередоваться C1иC2
    • Пространства не имеют цвета
    • Каждый размер буквы должен перекрывать ровно 1 столбец с соседними буквами
    • Если ячейка имеет более одного цвета, используйте C3
  • Dot Matrix
    • Матрица точек - это граф истории вклада Github
    • Если сегодня понедельник, 1 мая 2017 года:
 4-30    5-07    5-15
[5-01]   5-08    5-16
 5-02    5-09     .
 5-03    5-10     .
 5-04    5-12     .
 5-05    5-13    
 5-06    5-14    
  • Выход
    • Гибко, как это дается
    • (x, y) пары
    • x дата больше или равна текущей дате
    • y количество вкладов, сделанных на дату, x
    • Должен быть в хронологическом порядке (чтобы я мог заполнить свой календарь)
    • Если для каждой даты сделаны xуказанные yвклады, входное сообщение должно отображаться на графике Github (с правильной окраской)
    • Первое свидание должно быть как можно раньше
  • счет
    • Кратчайшая программа / функция в байтах побеждает

Алфавит

Создано sylvan.black под CC

введите описание изображения здесь введите описание изображения здесь


Тестовые случаи

Для этих тестовых случаев предположим, что текущая дата 25 мая 2017 года.

Input -> Output
-----    ------
l        5-28-17, 3
         6-3-17, 3
         6-4-17, 3
         6-5-17, 3
         6-6-17, 3
         6-7-17, 3
         6-8-17, 3
         6-9-17, 3
         6-10-17, 3
         6-17-17, 3

He       5-28-17, 3
         5-29-17, 3
         5-30-17, 3
         5-31-17, 3
         6-1-17, 3
         6-2-17, 3
         6-3-17, 3
         6-7-17, 3
         6-14-17, 3
         6-21-17, 3
         6-25-17, 3
         6-26-17, 3
         6-27-17, 3
         6-28-17, 9
         6-29-17, 9
         6-30-17, 9
         7-1-17, 3
         7-4-17, 6
         7-6-17, 6
         7-8-17, 6
         7-11-17, 6
         7-13-17, 6
         7-15-17, 6
         7-18-17, 6
         7-20-17, 6
         7-22-17, 6
         7-26-17, 6
         7-27-17, 6

o W      5-31-17, 3
         6-1-17, 3
         6-2-17, 3
         6-6-17, 3
         6-10-17, 3
         6-13-17, 3
         6-17-17, 3
         6-20-17, 3
         6-24-17, 3
         6-28-17, 3
         6-29-17, 3
         6-30-17, 3
         7-9-17, 6
         7-10-17, 6
         7-11-17, 6
         7-12-17, 6
         7-13-17, 6
         7-14-17, 6
         7-22-17, 6
         7-26-17, 6
         7-27-17, 6
         7-28-17, 6
         8-5-17, 6
         8-6-17, 6
         8-7-17, 6
         8-8-17, 6
         8-9-17, 6
         8-10-17, 6
         8-11-17, 6
NonlinearFruit
источник
С4 когда-либо использовался?
FryAmTheEggman
@FryAmTheEggman Это не так, но я включил его, чтобы избежать путаницы, потому что в легенде Github отображает 5 цветов.
Нелинейный
Насколько строгий / свободный у вас формат вывода даты?
Стивен
1
@StephenS Он гибкий, если он удобочитаемый для человека (например May 20th, 2017: 3, (3,"20/5/17"))
NonlinearFruit
Где вы нашли эту таблицу взносов?
Эрик Outgolfer

Ответы:

11

JavaScript (ES6), 743 байта

s=>(n=y=>d.setDate(d.getDate()+y),d=new Date,(h=d.getDay())&&n(7-h),r={},i=0,[...s].map(c=>{c<"!"?n(14):([...parseInt("jn4x733nx8gjw6nhricv6nx8dpz2vilui81vikl7b4nhridnzvgc1svznx8dji8g16fkg0vgc6341vg38oe9vh669ofvgm1dvjnhricvyvikl7aonhrjrjxvikmm29m0rqqp2nqmi6o0vbnf6dav2t14e4vbnjqpqs0g34o3tlqqwdso43oixtg1uyt8vvgddxn2hizrn2ahizrmdbhj4suq4gtytq8wgshvtzyvgc4mq7gzhwhz4g15ymf4vg72q9snx7r2f4jmffjm7jm5gavjhizrn2mjmkh3wogsgmianjm5gavcgwxpc3mhvni2kijhgqujjj8mcsgsjhgslnihw2cx75iqyv1cuhwdrh5d".substr((c.charCodeAt()-(c>"`"?71:65))*7,7),36).toString(2).slice(1).replace(/(0{7})+$/,"")].map(b=>(+b&&(r[+d]=r[+d]?9:i%2?6:3),n(1))),i++,n(-7))}),Object.keys(r).map(k=>[k,r[k]]).sort((i,j)=>i[0]-j[0]>0?1:-1).map(i=>[(new Date(+i[0])+"").slice(4,15),i[1]]))

Выходные данные - это массив массивов из 2 элементов в форме [dateString, contribs]. Фрагмент ниже показывает, как это можно отформатировать, чтобы сделать его более читабельным.

Un-Golfed

s=>(
    n=y=>d.setDate(d.getDate()+y),
    d=new Date,
    (h=d.getDay()) && n(7-h),
    r={},
    i=0,
    [...s].map(c=>{
        c<"!" ? n(14) : (
            [...parseInt("<...>".substr((c.charCodeAt()-(c>"`"?71:65))*7,7),36).toString(2).slice(1).replace(/(0{7})+$/,"")].map(b=>(
                +b && (r[+d] = r[+d] ? 9 : i%2?6:3),
                n(1)
            )),
            i++,
            n(-7)
        )
    }),
    Object.keys(r)
        .map(k=>[k,r[k]])
        .sort((i,j)=>i[0]-j[0] > 0 ? 1 : -1)
        .map(i => [ (new Date(+i[0])+"").slice(4,15), i[1] ])
)

Где <...>представляет 364-байтовую строку символов, которую я создал для кодирования точечной матрицы каждой буквы.

объяснение

Закодированная строка:

jn4x733nx8gjw6nhricv6nx8dpz2vilui81vikl7b4nhridnzvgc1svznx8dji8g16fkg0vgc6341vg38oe9vh669ofvgm1dvjnhricvyvikl7aonhrjrjxvikmm29m0rqqp2nqmi6o0vbnf6dav2t14e4vbnjqpqs0g34o3tlqqwdso43oixtg1uyt8vvgddxn2hizrn2ahizrmdbhj4suq4gtytq8wgshvtzyvgc4mq7gzhwhz4g15ymf4vg72q9snx7r2f4jmffjm7jm5gavjhizrn2mjmkh3wogsgmianjm5gavcgwxpc3mhvni2kijhgqujjj8mcsgsjhgslnihw2cx75iqyv1cuhwdrh5d

Каждые 7 символов представляют собой двоичное число в кодировке base-36, которое содержит сопоставление для символа с этим индексом. Бинарная форма всегда имеет ведущий 1, чтобы сохранить ведущие 0s. Например, в верхнем регистре Tотображается nqmi6o0, который преобразуется в 1100 00001000 00011111 11100000 01000000. Пропустив первую 1, каждый бит - один день. Большинство чисел имеют 5 столбцов / недель, поэтому числа с менее чем 5 столбцами имеют один или два набора из 7 конечных нулей, которые впоследствии удаляются перед синтаксическим анализом ( .replace(/(0{7})+$/,"")). Это сохраняет все закодированные строки одинаковой длины, устраняя необходимость в разделителях.

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

Двоичный формат сопоставления букв (синтаксис JS, с префиксом 0b) можно найти здесь .

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

f=
s=>(n=y=>d.setDate(d.getDate()+y),d=new Date,(h=d.getDay())&&n(7-h),r={},i=0,[...s].map(c=>{c<"!"?n(14):([...parseInt("jn4x733nx8gjw6nhricv6nx8dpz2vilui81vikl7b4nhridnzvgc1svznx8dji8g16fkg0vgc6341vg38oe9vh669ofvgm1dvjnhricvyvikl7aonhrjrjxvikmm29m0rqqp2nqmi6o0vbnf6dav2t14e4vbnjqpqs0g34o3tlqqwdso43oixtg1uyt8vvgddxn2hizrn2ahizrmdbhj4suq4gtytq8wgshvtzyvgc4mq7gzhwhz4g15ymf4vg72q9snx7r2f4jmffjm7jm5gavjhizrn2mjmkh3wogsgmianjm5gavcgwxpc3mhvni2kijhgqujjj8mcsgsjhgslnihw2cx75iqyv1cuhwdrh5d".substr((c.charCodeAt()-(c>"`"?71:65))*7,7),36).toString(2).slice(1).replace(/(0{7})+$/,"")].map(b=>(+b&&(r[+d]=r[+d]?9:i%2?6:3),n(1))),i++,n(-7))}),Object.keys(r).map(k=>[k,r[k]]).sort((i,j)=>i[0]-j[0]>0?1:-1).map(i=>[(new Date(+i[0])+"").slice(4,15),i[1]]))

I.value="Hello World";
(I.oninput=_=>O.innerHTML = f(I.value).map(e=>e.join(": ")).join("\n"))();
<input id="I">
<pre id="O">

Интерактивный пример

Используя библиотеку cal-heatmap , я создал интерактивную тепловую карту дат, которые выводятся. Это было использовано для проверки всего во время работы, и это выглядит просто аккуратно.

Джастин Маринер
источник
1
Интерактивный пример действительно потрясающий. Хорошая работа!
Нелинейный
1
О боже, кто-то на самом деле сделал это! Ницца!
Волшебная Осьминог Урна
Спасибо ребята! Это был действительно крутой вызов, я хотел бы, чтобы больше людей приехало, чтобы попробовать его. Я отредактировал свой ответ, включив в него двоичные буквы матрицы, чтобы другие могли использовать ту же идею.
Джастин Маринер
1
@JustinMariner Я добавил это в свой профиль, надеюсь, ты не возражаешь. Хороший ответ, рад, что кто-то выполнил этот вызов :)
Стивен
@StephenS Хорошо, рад, что тебе понравилось!
Джастин Маринер