В 2021 году на просторах интернета случайно увидел Sber на geecko.com, тогда компания Sber проводила fight типа «староверы» против «новокодеров». (Простите за неточности, вспоминаю по памяти.)
И когда запустили конкурс Sberfight я уже автоматически попал в рассылку.
Я относительно молод в Swift и тренировка умений или же проверка навыков на скорость очень привлекла. А формат в стиле «Денди» поднимает давно забытое чувство детства. (Моей любимой игрой были «танчики», «контра» и «червяк Джим»- правда у друзей на «Сеге».)
Однако, первый неприятный сюрприз ждал в условиях конкурса — подсчет баллов. Оказывается подсчет баллов теперь осуществляется — 100 баллов за задание(при учете, что все тест кейсы положительные) и + за скорость(по формуле где Swift имеет коэффициент примерно 1.29, как и JS, а вот максимальный С# — 2). Всего 8 заданий — значит минимум 800 баллов без надбавок. А вот сколько за скорость? Ответ был найден быстро — только взглянув на турнирную таблицу (Топ-1 — примерно — 3400 баллов). То есть 2400 надбавка за скорость (предположим C# — значит в общем за Swift при таком же идеальном выполнении я получу — 2477 баллов). Тут-то интерес начал угасать.
А, эскиз победителей уже нарисовался.
Пройдя два задания и поняв, что быстрее отведенного времени я не успеваю, а значит надбавки за скорость нет. Я взглянул на обновленный топ и увидев (Топ-1 — 5500 баллов) моей грусти не было предела.
Так и закрыл я Sberfight до конца февраля, пока мне на почту не упало письмо от рекрутера Sber. (Что это была массовая рассылка — это понятно, но зачем за два задания из 8 для меня осталось вопросом.) Но такая напоминалка заинтриговала меня глянуть на лидеров и каким же было мое удивление, когда Топ 1 — стоял 3400 баллов. Понятно, кто-то нашел баг, накрутил себе баллов, а теперь все пофиксили. Вот тут интерес и разогрелся, увы оставалось два дня.
Однако, пройти все тест кейсы быстрее отведенного времени для меня все равно осталось непреодолимым.
Ради интереса других и комментариев выложу тут свое решение. Увы, из-за спешки забыл скопировать задания и восстанавливаю по памяти.
Тест #1
Задание:
Вывести номера тех чисел, которые будут самыми большими при увеличении их на K
func getResult(cash: [Int], k: Int) -> [Int] { var tempArrOfThiefes: [Int] = [] for index in 0..<cash.count { print("cash - ", cash[index]) var tempArr: [Int] = [] for ygrek in 0..<cash.count { if (cash[index]+k) > cash[ygrek] { tempArr.append(index) } } print("temp arr count - ", tempArr.count) if (tempArr.count + 1) >= cash.count { print("index appended - ", index) tempArrOfThiefes.append(index + 1 ) tempArr = [] } } return tempArrOfThiefes } // Test #1 let x = [1,3,4,2] let k = 2 let res = getResult(cash: x, k: k) print(res)
Тест #2 (тут задание я так и не вспомнил)
func getResult(nums: [Int], k: Int) -> Int { if k == 0 { return 0 } var tempInt: Int = 0 var tempArr = nums var tempK = k repeat { for index in 0..<tempArr.count{ if tempArr[index] <= tempK { tempArr[index] = 0 tempArr.sort() tempK += 1 tempInt += 1 } } } while (tempK < tempArr.min()!) return tempInt } // Test #1 let x = [1,2,3,4,5] let k = 1 let res = getResult(nums: x, k: k) print(res)
Тест #3 (для данного теста на просторах Интернета нашел решение на Python, на которое пытался опираться)
Задание:
Мы знаем количество гостей, ваша задача рассадить всех за стол. Однако, некоторые гости дали вам список неприятелей, с которыми они не сядут. Стулья расставили так, что у стола оказалось два крайних места, у которых только один соседний гость. В остальных случаях соседа два. Определите, можно ли рассадить гостей так, чтобы все оказались довольны.
Ввод:
invited_list — количество приглашённых гостей, 0<invited_list<10
dislike_list — строчный массив неприятелей, [«1-2,3»] — означает, что гость под номером 1 не сядет с гостями 2 и 3
Вывод:
Boolean — возможно ли рассадить гостей так, чтобы они все были довольны
Пример:
invited_list = 4
dislike_list = [«1-2», «3-4»]
get_result(invited_list, dislike_list) = True // [1, 4, 2, 3]
Python (эргономичностью решения я восхитился, источник решения: https://www.cyberforum.ru/python-tasks/thread2943547.html)
def guests_seating( n, dis ): lis = list( range(1, n + 1) ) bad_pairs = set() for e in dis: L, de, R = e.partition('-') not_frends = set( int(x) for x in R.split(',') ) for nf in not_frends: bad_pairs.add( frozenset( [int(L), nf] ) ) res = [ [x] for x in lis ] flag = True while flag: flag = False for x in res: for y in lis: if frozenset([x[-1],y]) not in bad_pairs and y not in x: x.append(y) flag = True if len(x) == n: #return x return True return False #============================================================================== n = 10 dis = '1-2,4,6,8 3-5,7,9 4-1,2,3 5-2,4 6-3'.split() print( guests_seating( n, dis ) )
func getResult(invitedList: Int, dislikeList: [String]) -> Bool { if invitedList == 0 { return true } else if invitedList == 1 { return true } let allGuest = [Int](1...invitedList) print("allGuest created - ", allGuest) var badPairs:[Int:[Int]] = [:] for indexB in 0..<invitedList { var tempBadPairs:[Int: [Int]] = [:] for indexK in 0..<dislikeList.count { let guestArr = dislikeList[indexK].components(separatedBy: "-") let keyElement = Int(guestArr.first!)! let dislikeElements = guestArr.last!.components(separatedBy: ",") let valueElement = dislikeElements.map{Int($0)!} tempBadPairs[keyElement] = valueElement } if tempBadPairs.keys.contains(indexB+1) { let newValue = tempBadPairs[indexB+1] badPairs[indexB+1] = newValue } else { badPairs[indexB+1] = [0] } } print("Done well - ", badPairs) var sortedGuests: [Int] = [] sortedGuests.append(1) var flag = 0 while flag<invitedList { flag += 1 for indexQ in 2...badPairs.count { print("x is - ", indexQ) if !badPairs[sortedGuests.last!]!.contains(indexQ) { if !sortedGuests.contains(indexQ) { sortedGuests.append(indexQ) print("sortedGuests.append(x.key) - ", indexQ) } } } if sortedGuests.count == invitedList { print("sorted guests - ", sortedGuests) return true } print("sorted guests - ", sortedGuests) } return false } // Test #1 let invited_list1 = 4 let dislike_list1 = ["1-2,3", "3-4"] let intT1 = getResult(invitedList: invited_list1, dislikeList: dislike_list1) print(intT1) // Test #2 let invited_list2 = 5 let dislike_list2 = ["1-2,3", "3-4,5", "2-3"] let intT2 = getResult(invitedList: invited_list2, dislikeList: dislike_list2) print(intT2)
Тест #4 (тут все тест кейсы сильно сопротивлялись 🙂 )
Задание:
Существует массив из N количества 3 видов букв — [«x», «x», «y», «z»]
Если буквы заменить на целые числа, то можно ли получить общую сумму в X число
Пример:
// Test #1
let sub_array = [«x», «x», «x», «y», «y»]
let k = 12
let result = getResult(sub_array, k)
print(result)
// = True
// Можно заменить x на 2, y на 3, тогда получится
//[2, 2, 2, 3, 3]
func getResult(_ subArray: [String], _ k: Int) -> Bool { if subArray.count == 1 { return true } if subArray.count > k { return false } if subArray.count == k { return true } var tempSetOfTypeLetters: Set<String> = [] var dictOfCountOfLetters: [String: Int] = [:] subArray.forEach { str in tempSetOfTypeLetters.insert(str) if !dictOfCountOfLetters.keys.contains(str) { dictOfCountOfLetters[str] = 1 } else { dictOfCountOfLetters[str]! += 1 } } var totalCount: Int = 0 var tempArray: [Int] = [] for indexA in dictOfCountOfLetters { tempArray.append(indexA.value) totalCount = totalCount + indexA.value } tempArray = tempArray.sorted{$0>$1} print("Well done - tempArray is - ", tempArray) var tempCounter: Int = 0 while tempCounter < k { tempCounter += 1 var tempArrOfInt:[Int] = [] for indexE in 0..<tempArray.count-1 { tempArrOfInt.append(tempArray[indexE] * tempCounter) print("tempArrOfInt.append - ", tempArrOfInt) if indexE >= 0 { print("<<<---->>>") print("indexE is - ", indexE) for indexY in 1..<k { var temp:[Int] = [] temp.append(tempArray[indexE+1] * (tempCounter + indexY)) print("temp appended - ", temp ) if tempArray.count == 3 { print("tempArray.count == 3 - ", tempArray.count) for indexK in (indexY+1)..<k { temp.append(tempArray[2] * (tempCounter + indexK)) print("temp appended - ", temp) var total = tempArrOfInt.first print("total 2.1 - ", total) temp.forEach{ total = total! + $0 } print("total 2.2 is - ", total as Any) if (k - total!) == 0 { return true } } } print("temp - ", temp) var total = tempArrOfInt.first print("total 1.1 - ", total) temp.forEach{ total = total! + $0 } print("total is 1.2 - ", total as Any) if (k - total!) == 0 { return true } } } } } return false } // Test #1 let sub_array = ["x", "x", "x", "y", "y"] let k = 12 let result = getResult(sub_array, k) print(result) // = True // Можно заменить x на 2, y на 3, тогда получится //[2, 2, 2, 3, 3] // Test #2 let sub_array2 = ["x", "x", "y", "y"] let k2 = 20 let result2 = getResult(sub_array2, k2) print(result2) // Test #3 let sub_array4 = ["x", "x"] let k4 = 2 let result4 = getResult(sub_array4, k4) print(result4) // Test #4 let sub_array5 = ["x", "x", "y"] let k5 = 4 let result5 = getResult(sub_array5, k5) print(result5) // Test #5 let sub_array6 = ["x", "x", "y", "z"] let k6 = 24 let result6 = getResult(sub_array6, k6) print(result6) // Test #6 let sub_array7 = ["x", "x", "y", "z"] let k7 = 34 let result7 = getResult(sub_array7, k7) print(result7)
Тест #5 (Тут я упустил, что убирать можно не только первые символы, но и в середине, из-за чего быстрее положенного все тест кейсы не прошел. На том и остановился…)
Задание:
Дана строка s. Вы можете удалить из нее не более k символов. Определите максимально возможное количество совпадений символов с stringGoal, то есть совпадением считается s[i] = stringGoal[i]. Например, строка «agddb» совпадает с «gdda» только одним символом. Если убрать первый символ, тогда будет уже 3 совпадения — «gddb» «gdda».
Ввод:
s — строка с символами, 0<length(s)<20
k — максимальное количество удалений, 0<k<10
stringGoal — строка для сравнения
Вывод:
Integer — максимальное количество совпадений s[i] = stringGoal[i]
Пример:
s = «agdd»
k = 1
stringGoal = «gdd»
getResult(s, k, stringGoal) = 3
extension String { var length: Int { return count } subscript (i: Int) -> String { return self[i ..< i + 1] } func substring(fromIndex: Int) -> String { return self[min(fromIndex, length) ..< length] } func substring(toIndex: Int) -> String { return self[0 ..< max(0, toIndex)] } subscript (r: Range<Int>) -> String { let range = Range(uncheckedBounds: (lower: max(0, min(length, r.lowerBound)), upper: min(length, max(0, r.upperBound)))) let start = index(startIndex, offsetBy: range.lowerBound) let end = index(start, offsetBy: range.upperBound - range.lowerBound) return String(self[start ..< end]) } } func getResult(_ s: String, _ k: Int, _ stringGoal: String) -> Int { var maxCounterOfMatched: Int = 0 // Первая попытка // проходит Тестов 6 из 10 var flagFromPrefixToBody: Bool = false var whileCounter: Int = 0 while whileCounter <= k { var tempMainString: String = "" if flagFromPrefixToBody == false { tempMainString = s.substring(fromIndex: whileCounter) print("do it 1") } else { var tempString = s if tempString.count > (whileCounter+1) { let indexToDelete = tempString.firstIndex(of: Character(tempString[whileCounter+1]))! tempString.remove(at: indexToDelete) tempMainString = tempString } print("do it 2") } print("tempMainString is - ", tempMainString) var counterOfMatched: Int = 0 for indexA in 0..<tempMainString.count { if tempMainString[indexA] == stringGoal[indexA] { counterOfMatched += 1 } } print("compare results") if maxCounterOfMatched < counterOfMatched { maxCounterOfMatched = counterOfMatched } if whileCounter == k && flagFromPrefixToBody == false { flagFromPrefixToBody = true whileCounter = 0 } whileCounter += 1 } print("Part #1 finished, maxCounterOfMatched - ", maxCounterOfMatched) // Вторая попытка print("<<---->>") print("Part# 2") for indexA in 0..<s.count { print("do it 1") for indexB in 0...k { print("do it 3") var tempString = s let startIndex = tempString.index(tempString.startIndex, offsetBy: indexA) //print("startIndex - ", startIndex) guard let endIndex = tempString.index(tempString.startIndex, offsetBy: (indexA + indexB)) as? String.Index else { break } //print("endIndex - ", endIndex) if startIndex >= endIndex { break } tempString.removeSubrange(startIndex...endIndex) print("tempString - ", tempString) print("do it 4") var counterOfMatched: Int = 0 for indexC in 0..<tempString.count { if tempString[indexC] == stringGoal[indexC] { counterOfMatched += 1 } } if maxCounterOfMatched < counterOfMatched { maxCounterOfMatched = counterOfMatched } } } /* вторая часть проходит Тестов 6 из 10 */ return maxCounterOfMatched } // 1,2,3,6,7,8 // need - 4,5,9,10 // need - 3,7,8,10 // (stringGoal.count - 1,2,3,6,7,8) // need - 2,6,7,8 let s = "agdd" let k = 1 let stringGoal = "gdd" let result = getResult(s, k, stringGoal) //= 3 print(result) let s2 = "ababcde" let k2 = 3 let stringGoal2 = "abcde" let result2 = getResult(s2, k2, stringGoal2) //= 5 print(result2) let s3 = "aqwerty" let k3 = 3 let stringGoal3 = "qwerty" let result3 = getResult(s3, k3, stringGoal3) print(result3) // Test that fails let s4 = "aqawerty" let k4 = 3 let stringGoal4 = "qwerty" let result4 = getResult(s4, k4, stringGoal4) print(result4)
ссылка на оригинал статьи https://habr.com/ru/post/654659/
Добавить комментарий