Pull to refresh
4
0
Send message

В google music меня сильно парила "неуправляемость". Вот ему как-то почудилось что мне нравится немецкий вокал, (а мне за некоторым исключением не то чтобы) — и никаким количеством дислайков его не переубедишь


Завезли миграцию в Youtube Music, там другая проблема — у меня куча "понравившихся" композиция но он выбрал штук 10 групп и крутит их по кругу. Попал неплохо, но странно когда "случайная" музыка начинает приедаться. Ничего нового даже не пытается добавить.


Поэтому пойду тестить Spotify :)

  1. Игры, в большинстве своем, развлечение больше чем на пару часов, зачастую на два-три порядка
  2. Про игру можно прочитать много всего в интернете, посмотреть на твитче/ютубе и выбрать самую подходящую себе, и после этого в нее все равно будет интересно играть (это, наверное, не про все игры)

Игры в этом смысле как-то больше похожи на сериалы, чем на фильмы.

Мне ок (но кстати какое к примеру?). Но если вдруг будут добавлять в существующий язык то добавят else чтобы не добавлять новые ключевые слова (новые ключевые слова это проблема для обратной совместимости)

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

Я делал генератор лабиринтов для (старой версии, в новой не работает) игры Shenzhen I/O
https://www.youtube.com/watch?v=geT2uP7MYGc
доп. материалы https://imgur.com/a/Vwvit


Там памяти еще сильно меньше чем 128 байт (всего где-то около 30 значений от -999 до 999 и без стека и произвольного доступа)


Алгоритм был такой что он возвращал для каждой позиции является ли она стеной или проходом. Вся игра работала так что для всех видимых на экране кусочков (их всего штук 10) вызывалась функция и соответственно стена рисовалась или нет.


Алгоритм работет так:


  • На входе ширина(w) и высота(h) лабиринта и запрашиваемые координаты (x, y)
  • Псевдослучайно выбираем на какой x0 будет сплошная вертикальная стена.
  • если x < x0 то поворачиваем прямоугольник на 90 градусов и повторяем алгоритм для левого прямоугольника (для всей части x < x0)
  • если x > x0 то то же самое для правой части
  • если x == x0 то выбираем одно или два места (y0 и y1) где в этой вертикальной стене будут проходы. Если y == y0 или y == y1 то проход, иначе стена.
  • Еще нюанс: стены могут быть только на четных значениях x, а проходы только на нечетных y
  • Позиция старта захардкожена, позиция выхода находится там где на каждом шаге алгоритма выбиралась левая секция

Статья описывает эмоции которые испытывает старшее поколение при первой встрече с роботом в интернете?

интересно, когда доберутся до слова man в значении "человек"
Частично уже начали с "man hours"

Решал как-то подобную задачу на codinGame и там у меня определение комбинации заняло всего строк 10 (правда функция выглядела как взрыв на фабрике символов хоть и написана была на c#)


Если что то функция под спойлером

На вход подается 5 отсортированных карт, каждая карта это число 0-51, к примеру 0-3 это четыре масти двойки, 4-7 четыре масти тройки


На выходе — число, больше число — сильнее комбинация, меньше — слабее, равное — равная. Учитывается и кикеры, и A2345


static int GetComboStrength(byte c0, byte c1, byte c2, byte c3, byte c4) // :troll:
{
    byte v0 = (byte) (c0 >> 2), v1 = (byte) (c1 >> 2), v2 = (byte) (c2 >> 2), v3 = (byte) (c3 >> 2), v4 = (byte) (c4 >> 2), cb = (byte)(c0 & 3);
    bool p01 = v0 == v1, p12 = v1 == v2, p23 = v2 == v3, p34 = v3 == v4;
    return p01 ? p12 ? p23 ? Pack(7,v0,v0,v0,v0,v4) : p34 ? Pack(6,v0,v0,v0,v4,v4) : Pack(3,v0,v0,v0,v4,v3) : p23 ? p34 ? Pack(6,v4,v4,v4,v0,v0) : Pack(2,v2,v2,v0,v0,v4) : 
        p34 ? Pack(2,v4,v4,v0,v0,v2) : Pack(1, v0,v0,v4,v3,v2) : p12 ? p23 ? p34 ? Pack(7,v4,v4,v4,v4,v0) : Pack(3,v1,v1,v1,v4,v0) : p34 ? Pack(2,v4,v4,v2,v2,v0) : 
        Pack(1,v2,v2,v4,v3,v0) : p23 ? p34 ? Pack(3,v3,v3,v3,v1,v0) : Pack(1,v3,v3,v4,v1,v0) : p34 ? Pack(1,v3,v3,v2,v1,v0) : 
        Pack((cb == (c1 & 3) && cb == (c2 & 3) && cb == (c3 & 3) && cb == (c4 & 3) ? 5 : 0) + (v0+3 == v3 && v0+2 == v2 && v0+1 == v1 && (v0+4 == v4 || v0==0 && v4==12) ? 4 : 0),v4,v3,v2,v1,v0);
}

static int Pack(int type, byte k0, byte k1, byte k2, byte k3, byte k4) {
    var res = k4 | (k3 << 4) | (k2 << 8) | (k1 << 12) | (k0 << 16) | (type << 20);
    if ((res & 0xFFFFF) == 0xC3210) // fix to order straight ending with A
        res -= 0x91104;
    return res;
}

Как это работает?

Вытаскивается 4 бита существенной информации: Первая карта равна второй (по значению), вторая равна третьей, третья равна четвертой, четвертая равна пятой


дальше все 16 (на самом деле 15 так как "все равны" это не вариант) вариантов комбинаций рассматриваются (для каждой комбинации кроме "все не равны" сразу очевиден результат, ну типа если с0==с1 и с2==с3==с4 то это фул хаус, и сразу понятно какой кикер первый и какой второй)


потом для случая "все не равны" еще проверяется стрит и флаш (они суммируются так что стрит флаш оказывается больше)


Если что то в прод я так код не пишу, это была игра :)

Еще можно добавить что при написании библиотек приходится выставлять публичный интерфейс наружу (или, к примеру, читать json по сети), и вот тут то без указаний типа никакой линтер не скажет ничего более ценного чем "ээээ ну а тут будет any"

Кроме того, я не согласен что не ставя типы экономится время.


Немножно времени экономися сначала, но потом:


Чуть больше времени тратится когда в следующий раз этот код пришлось почитать
Чуть больше времени тратится на написание дополнительных проверок который в системе с типами делать не нужно
Чуть больше времени тратится на написание дополнительных тестов, которые в системе с типами писать не нужно
Чуть больше времени тратится на коментирование (в тех случаях когда имя типа и есть достаточный комментарий)
Чуть больше времени тратится потом на рефакторинг
Систему с большим числом использований потом сложно менять "мало ли кто полагается на текущую деталь реализации". А для работы со старой системой приходится тратить чуть больше времени
и т.п.


В итоге, код которые "write once" и больше никогда не нужно менять/читать (скрипты и простейшие сервисы) получается выгоднее писать на языках без типизации. Но как только дело разрастается до серьезных вещей — на все приходится тратить "чуть больше времени".

Ну вот пример выше с координатами
Дано — куча функций, некоторые работают с 2d координатами, некоторые с 3d, некоторые даже и с теми и с теми.
Задача — у всех использований 2d координат заменить y на z (т.е. превратить 2d координату в 3d). 3d координаты не трогать.
Как решить эту задачу точно? В смысле без ложноположительных и ложноотрицательных срабатваний?
Бонус: Часть данных грузится с диска (к примеру)
Мега бонус: Если нужно поменять не все 2d координаты, а только часть (но существенную часть). В системе с типами можно просто "начать" менять, а дальше просто пофиксить все места где компилятор говорит что "вот тут тип неправильный".


Еще на всякий случай скажу что это не искусственная задача.

Упадет. Но по крайней мере в базе данных не окажется лицензионного соглашения в поле "широта" :)


Вообще-то все современные языки умеют приводить типы. И решать задачу "как получить int из json если там вдруг строка" должен автор библиотеки json сериализации (т.е. в 99% случаев — не пользователь библиотеки). Т.е. ситуация оказывается строго лучше — мы все также можем распарсить число пришедшее в json в виде строки, но только у нас теперь есть еще и дополнительные гарантии от компилятора.

Да. Поэтому и мой комментарий:


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

метры вместо килограмм — редкая. Секунды вместо миллисекунд — уже почаще.


Строчки/числа пришедшие из враждебного внешнего мира должны на этапе парсинга валидироваться/конвертироваться, а не добираться до внутренней логики (так то там вообще null или объект может оказаться, сервис то сторонний, и если это не чекать то получится null island), и здесь как раз языки со статической типизацией сделают все что могут — либо сконвертируют, либо выдадут ошибку сразу при парсинге. Так то еще есть локаль, и в некоторых странах десятичный разделитель это точка, в других запятая, в третьих что-то типа апострофа. Тут никакие операторы уже не помогут если сразу корректно не сконвертить.


Вон даже в NASA ньютоны с фунтами путали, и грохали межпланетный зонд из-за этого.
Так то если писать код сразу без ошибок, без архитектурных просчетов, без "новичков", сразу зная (и понимая) все ТЗ целиком, если писать код 1 раз и никогда его не читать — типы (а также комментарии и тесты, читаемые названия переменных, да и вообще функции) не нужны.


Ну и самое главное преимущества из-за которого я никогда не смогу продуктивно работать на динамическом языке — это то что с нормальным инструментарием можно всегда точно сказать что какой-то объект/функция не используется, и точно найти все использования. Это очень сильно играет на чистоту кода — любое "старье" можно быстро отрефакторить или выпилить с минимальными шансами что-то сломать.

Ну кому как. Мне так наоборот хочется разделить все числа посильнее, чтобы метры с килограммами сложить было нельзя. Или чтобы id пользователя и id товара были разные типы, несмотря на то что оба номинально int (или string, неважно)

«Ритуальная шелуха» в современных статически типизированных языках существет только в интерфейсах методов и объектов. И в динамических языках она также существует, только занимает гораздо больше места (в виде проверок на правильность типов аргументов и/или тестов вида «что если передать объект неправильного типа»). В «проектах» на 20 строк кода такого, конечно, может и не быть.

Вот недавно была задачка. В проекте использовались 2d координаты (x, y) в одном домене. Потом понадобилось соединить их с другим доменом в котором использовались 3d координаты (x, y, z) причем «y» там означала высота, и правильная конвертация была такая: (x, y) => (x, 0, y) т.е. y переименовывался в z

Я могу только представить какая это была бы боль в структурно типизированном языке или вообще языке без типов. Но к счастью язык был статически типизируемым и все что понадобилось — это пара предоставляемых IDE рефакторов плюс обновить несколько математических функций.
Интересно, какое количество посетителей дочитало только до этого коммента?
Похоже на то что у ютуба/твитча не так много российских рекламодателей, плюс они еще пытаются «задротов» на уровне таргетинга отрезать, вот и остается одна яндекс-станция.
Возник такой же вопрос. Когда я учился, ДЗ писали в углу доски в виде номеров из учебника.
Помню даже когда болел сильно классе в третьем мне сказали «каждый день решай из последующего параграфа один пример и одну задачу»
Тут еще проблема в том что если Intel выпускает новый процессор в котором добавятся out-of-order блоки или теневые регистры — то все программы начинут работать немного быстрее. А если выходит новый VLIW процессор с еще больше увеличенной длиной слова, то старые программы быстрее работать не начинают, а новые начинают занимать еще больше места.

Information

Rating
Does not participate
Registered
Activity