Передвижная зубная щетка

10

Введение

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

Вызов

Для этой задачи мы будем использовать макет среднего рта взрослого человека:

Расположение человеческого рта.

Эта диаграмма показывает широко используемую систему нумерации ISO . Система делит рот на четыре части и присваивает им номера: верхний правый (1), верхний левый (2), нижний левый (3) и нижний правый (4). Затем они нумеруют зубы каждой секции от середины рта до 1-8. Поэтому четвертый зуб от центра в верхней правой части (секция 1) - это зуб № 14.

Давайте предположим, что чистка одного зуба занимает 1 единицу времени. Переход от одного зуба к следующему в сторону занимает 0 единиц времени. Вы также можете перейти от зуба к зубу непосредственно над или под ним, что также занимает 1 единицу времени. Так сколько же времени у вас уходит на то, чтобы почистить зубы с 14 до 31? Посмотрев на диаграмму выше, вы увидите, что это занимает 7 единиц времени. Вот как это рассчитывается:

Action : Unit of time
Brushing tooth 14 : 1 unit
Brushing tooth 13 : 1 unit
Brushing tooth 12 : 1 unit
Brushing tooth 11 : 1 unit
Brushing tooth 21 : 1 unit
Cross to bottom of mouth : 1 unit
Brushing tooth 31 : 1 unit
------------------------------
Total: 7 units

Обратите внимание, что это не единственный маршрут, по которому мы могли бы пойти, но нет более коротких маршрутов.

Итак, ваша задача:

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

    14, 21 => 5
    14, 44 => 3
    14, 14 => 1
    33, 37 => 5
    

Удачи!

Уклоняющийся
источник
1
@JonathanAllan добавит, когда я вернусь к своему компьютеру.
Амфибологическое
1
«Переход от зуба к зубу занимает 0 единиц времени». <- Точнее, я думаю, что вы имеете в виду «Переход от одного зуба к другому в сторону занимает 0 единиц времени». (Сначала я понял, что переход от любого зуба к любому другому занимает 1 единицу, что делает следующее предложение непонятным.)
sundar - Восстановить Монику
@ sundar ты прав, отредактируешь.
Амфибология
1
@JonathanAllan сделано.
Амфибологическое

Ответы:

3

Желе ,  24  20 байт

d30%20ị2¦⁵R;C$¤)ạ/Ḅ‘

Монадическая ссылка, принимающая список из двух целых чисел (например, [14,31]для примера от 14 до 31), который дает время чистки.

Попробуйте онлайн!


Предыдущие 24 байта строили рот и использовали базу 8, входные данные представляли собой список списков цифр:

8R;C$C+⁴U,+ɗ⁴
ḅ8¢œiⱮạ/Ḅ‘
Джонатан Аллан
источник
5

JavaScript (ES6), 65 байт

f=([s,t],[u,v])=>s<3^u<3?f(s+t,5-u+v)+2:s-u?t-+-v:t<v?++v-t:++t-v

for(i=1;i<5;i++)for(j=1;j<9;j++){let o=document.createElement("option");o.text=""+i+j;s.add(o);t.add(o.cloneNode(true));}
<div onchange=o.textContent=f(s.value,t.value)><select id=s></select><select id=t></select><pre id=o>1

Принимает ввод как строки.

Нил
источник
1

JavaScript (ES6), 67 байт

([a,b],[x,y])=>(u=(a==x)+3*!(a+x-5))?Math.abs(b-y)+u:2*!(a-x&1)+b+y

Ожидает входные данные в виде двух 2-элементных массивов цифр. 12-> [1, 2]Я надеюсь, что это приемлемо.

Попробуйте онлайн!

Выглядит как почти дубликат с ответом Python @Chas Brown , так что я могу удалить его при необходимости (неуверен в соглашениях здесь).

объяснение

var g =
([a,b], [x,y]) =>
    (u = (a == x)                // if same quadrant of mouth
     + 3 * !(a + x - 5))         // or strictly traversing vertically (e.g. 1 to 4, or 2 to 3)
        ? Math.abs(b - y) + u    // absolute difference plus additional units of time
        : 2 * !(a - x & 1)       // = 2 if traversing diagonally
            + b + y
избыточность
источник
2
« Выглядит как почти дубликат с ответом Python @Chas Brown, поэтому я могу удалить его, если это необходимо (не зная соглашения здесь). » Поскольку они являются разными языками, оба могут остаться. Только если два ответа на одном и том же языке в точности совпадают, лучше всего, если последний опубликовал последний, удаляет свой ответ (хотя если два человека имеют одинаковый ответ и считают его независимым друг от друга, им разрешается оставить оба; большинство будет удалите их ответ, если они точно такие же, как и у тех, кто писал раньше). Но с разными языками проблем нет. Добро пожаловать в PPCG! :)
Кевин Круйссен,
1

Python 2 ,  80  78 байт

Вероятно, некоторые возможности для игры в гольф здесь все еще

lambda s,e,l=(range(11)+range(0,-9,-1))*2:abs(l[s%30]-l[e%30]+s/30*2-e/30*2)+1

Безымянная функция, принимающая два целых числа, sи e, которая возвращает время чистки.

Попробуйте онлайн!

Джонатан Аллан
источник
0

Чистый , 134 128 126 байтов

import StdEnv
@n=hd[i\\i<-[0..]&k<-[18,17..11]++[21..28]++[48,47..41]++[31..38]|n==k]rem 16
$a b=abs(@a- @b)+a/30bitxor b/30+2

Попробуйте онлайн!

Определяет функцию $ :: Int Int -> Int, которая просто находит расстояние между двумя зубцами как декартовы координаты. Довольно скучное решение на самом деле.

Οurous
источник