Там можно убрать все Cast, но тогда нужно немного переписать решение, иначе TypeScript будет ругаться, я делал быстро и старался, чтобы финальное решение просто работало)
type UnionOfNumbersLessThan<N extends number, HelperArray extends number[] = []> = N extends HelperArray['length']
? HelperArray[number]
: UnionOfNumbersLessThan<N, [...HelperArray, HelperArray['length']]>
type NumberRange<L extends number, H extends number> = H | Exclude<UnionOfNumbersLessThan<H>, UnionOfNumbersLessThan<L>>
type ToNumber<S extends string> = S extends `${infer N extends number}` ? N : never;
type Cast<A1 extends any, A2 extends any> =
A1 extends A2
? A1
: A2
// split k1->k2->(s-e)->k3 like structure to array of keys
type SplitPath<Path extends string> = Path extends `${infer First}->${infer Rest}`? [First, ... SplitPath<Rest>] :[Path]
type RecursivePick<T extends unknown, Keys extends string[]> = Keys extends [infer Key, ...infer Rest]
? Key extends `(${infer Start}-${infer End})`
// If we have (start-end) range then
//@ts-ignore
? RecursivePick<T[Cast<NumberRange<ToNumber<Start>, ToNumber<End>>, keyof T> extends T[Cast<Key, keyof T>] ? T[Cast<Key, keyof T>] : never], Cast<Rest, string[]>>
// else recursively get property
: RecursivePick<T[Cast<Key, keyof T>], Cast<Rest, string[]>>
: T
type Get<T extends unknown, Path extends string> = SplitPath<Path>[0] extends keyof T
// if First key exists in object
? SplitPath<Path> extends [infer Key, ...infer Rest]
? RecursivePick<Cast<T[Cast<Key, keyof T>], object>, Cast<Rest, string[]>>
: never
: never
// TESTS!
type songAuthor = Get<typeof song, 'metaData->author'>; // AC/DC
type firstTrackVolume = Get<typeof song, 'tracks->0->volume'>; // 78
type tracksVolume = Get<typeof song, 'tracks->(0-2)->volume'>; // 78 | 60
type tracksVolume2 = Get<typeof song, 'tracks->(0-2)->regions->(0-2)->end'>; // 78 | 60
type notes = Get<typeof song, 'tracks->1->regions->0->midiData->(0-5)->note'>; // "F4" | "D4" | "E4" | "C4"
type midiData = Get<typeof song, 'tracks->1->regions->0->midiData->(0-2)'>; // { note: "C4", velocity: 10,
// startTime: 0, duration: 1, } | { note: "E4", velocity: 20, startTime: 1, duration: 1 }
type thirdNoteVelocity = Get<typeof song, 'tracks->1->regions->0->midiData->3->velocity'>; // 40
type qwe = Get<typeof song, 'lala->nana'>; // never
type asd = Get<typeof song, 'metaData->nana'>; // "Highway to Hell" | "AC/DC" | "27.07.1979"
Вот мое решение, которое набрало 40/40 баллов, по сути суть та же, думаю можно сократить до 20 строчек. Жаль, что уже нельзя проверить будет на тех тестах, что в самом Яндекс контесте используется
Постфактум уже же нельзя никак проверить, прошло бы решение или нет? Или все-таки можно? Может после всего соревнования или через год/два/три?
Все-таки те задачи 2019 года, которые были в примерах, и сейчас можно решать на yandex contest и получать обратную связь
Да, была, но я лично не делал там, так как неудобно, что на каждый чих шел запуск кода, ну и нет prettier)
@Alexandroppolus Выложил все условия в репозиторий -> https://github.com/GoldStrikeArch/yandex-cup-frontend-2023
Под второй задачей имеется в виду задача B
У меня вот не получилось вторую сделать, Wrong Answer постоянно приходил, у Вас еще осталось решение? А то прям любопытно что там не так
А Вы какие задачи еще делали?
Там можно убрать все Cast, но тогда нужно немного переписать решение, иначе TypeScript будет ругаться, я делал быстро и старался, чтобы финальное решение просто работало)
Вот мое решение, которое набрало 40/40 баллов, по сути суть та же, думаю можно сократить до 20 строчек. Жаль, что уже нельзя проверить будет на тех тестах, что в самом Яндекс контесте используется