@dmitriyivvvv

Как упростить подсчёт нажатий кнопок?

Я решаю следующую задачу:

Имеется клавиатура:

a	b	c	d	e	1	2	3
f	g	h	i	j	4	5	6
k	l	m	n	o	7	8	9
p	q	r	s	t	.	@	0
u	v	w	x	y	z	_	/

Представим, что у нас есть возможность перемещаться по ней с помощью стрелок (вверх, вниз, влево, вправо).
Функция принимает слово, и возвращает количество всех нажатых кнопок начиная с левого верхнего угла, т.е. с буквы 'a', для набора слова. Плюс также должно приплюсоваться нажатие кнопки 'ОК' каждый раз, когда нажимается буква.
Пример:

слово = codewars
c => a-b-c-OK = 3
o => c-d-e-j-o-OK = 5
d => o-j-e-d-OK = 4
e => d-e-OK = 2
w => e-j-o-t-y-x-w-OK = 7
a => w-r-m-h-c-b-a-OK = 7
r => a-f-k-p-q-r-OK = 6
s => r-s-OK = 2
Ответ = 3 + 5 + 4 + 2 + 7 + 7 + 6 + 2 = 36

Вот что у меня получилось, но язык не поворачивается назвать это решением, хотя все работает как нужно:

var tvRemote = function(word) {
  var kb = {'a':[0, 0], 'b':[0, 1], 'c':[0, 2], 'd':[0, 3], 'e':[0, 4], '1':[0, 5], '2':[0, 6], '3':[0, 7],
            'f':[1, 0], 'g':[1, 1], 'h':[1, 2], 'i':[1, 3], 'j':[1, 4], '4':[1, 5], '5':[1, 6], '6':[1, 7],
            'k':[2, 0], 'l':[2, 1], 'm':[2, 2], 'n':[2, 3], 'o':[2, 4], '7':[2, 5], '8':[2, 6], '9':[2, 7],
            'p':[3, 0], 'q':[3, 1], 'r':[3, 2], 's':[3, 3], 't':[3, 4], '.':[3, 5], '@':[3, 6], '0':[3, 7],
            'u':[4, 0], 'v':[4, 1], 'w':[4, 2], 'x':[4, 3], 'y':[4, 4], 'z':[4, 5], '_':[4, 6], '/':[4, 7]
  };
  var steps = 0;
  var arr = word.split('').map(n => kb[n]);
  arr.unshift([0, 0]);
  for (var i = 0; i < arr.length - 1; i++) {
    if (arr[i][0] >= arr[i + 1][0]) {
      steps += arr[i][0] - arr[i + 1][0];
    } else {
      steps += arr[i + 1][0] - arr[i][0];
    }
    if (arr[i][1] >= arr[i + 1][1]) {
      steps += arr[i][1] - arr[i + 1][1];
    } else {
      steps += arr[i + 1][1] - arr[i][1];
    }    
  }
  return steps + arr.length - 1;
}
  • Вопрос задан
  • 162 просмотра
Решения вопроса 1
0xD34F
@0xD34F Куратор тега JavaScript
А зачем двигаться "пошагово"? Известны же координаты кнопок - можно вычитать одни из других, и сразу получать количество шагов:

const keyboard = [
  'abcde123',
  'fghij456',
  'klmno789',
  'pqrst.@0',
  'uvwxyz_/',
].reduce((acc, [...row], iRow) => {
  row.forEach((key, iCol) => acc[key] = [ iRow, iCol ]);
  return acc;
}, {});

function tvRemote(word) {
  let steps = word.length;
  let prev = [ 0, 0 ];

  for (const n of word) {
    const curr = keyboard[n];
    steps += Math.abs(prev[0] - curr[0]) + Math.abs(prev[1] - curr[1]);
    prev = curr;
  }

  return steps;
}
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы