A escova de dentes itinerante

10

Introdução

O desafio de hoje é sobre dentes. Especificamente, quanto tempo leva para escovar de um dente para outro. Seu desafio é, dada a localização de dois dentes, produzir o menor tempo possível para escovar do primeiro ao segundo.

Desafio

Para esse desafio, usaremos o layout de uma boca humana adulta média:

Layout da boca humana.

Este diagrama mostra o sistema de numeração ISO amplamente utilizado . O sistema divide a boca em quatro partes e atribui-lhes um número: superior direito (1), superior esquerdo (2), inferior esquerdo (3) e inferior direito (4). Eles então numeram os dentes de cada seção do meio da boca de 1 a 8. Portanto, o quarto dente do centro no lado superior direito (seção 1) é o número 14.

Vamos supor que escovar um dente leva 1 unidade de tempo. Mover de um dente para o próximo de lado leva 0 unidades de tempo. Você também pode passar de um dente para o dente diretamente acima ou abaixo dele, o que também leva 1 unidade de tempo. Então, quanto tempo você leva para escovar do dente 14 ao dente 31? Observando o diagrama acima, você verá que são necessárias 7 unidades de tempo. Aqui está como isso é calculado:

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

Observe que ele não é o único caminho que poderíamos seguir, mas não há rotas mais curtas.

Portanto, seu desafio é:

  • Você escreverá um programa ou função completo que aceita dois argumentos que são números de dentes e gera (ou retorna) o menor tempo possível para passar de um para o outro.
  • Você faz a entrada como números ou seqüências de caracteres e a saída como desejar ( dentro de métodos aceitáveis ).
  • As brechas padrão são proibidas por padrão.
  • Esta questão é , pelo que o menor número de vitórias vence.
  • Aqui estão alguns casos de teste ( Obrigado Jonathan Allan ):

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

Boa sorte!

Anfibológico
fonte
11
@ JonathanAllan adicionará quando eu voltar ao meu computador.
Amphibological
11
"Mudar de dente para dente leva 0 unidades de tempo." <- Mais precisamente, acho que você quer dizer "Mover de um dente para o próximo de lado leva 0 unidades de tempo". (I primeiro levou-o a mover-se média de qualquer dente para qualquer outra leva 1 unidade, o que tornou a frase seguinte confuso.)
sundar - Reintegrar Monica
@ Sundar você está certo, irá editar.
Amphibological
11
@JonathanAllan done.
Amphibological

Respostas:

3

Geléia ,  24  20 bytes

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

Um link monádico que aceita uma lista de dois números inteiros (por exemplo, [14,31]do exemplo de 14 a 31), que gera o tempo de escovação.

Experimente online!


Anterior 24 byter construiu a boca e usou a base 8, a entrada era uma lista de listas de dígitos:

8R;C$C+⁴U,+ɗ⁴
ḅ8¢œiⱮạ/Ḅ‘
Jonathan Allan
fonte
5

JavaScript (ES6), 65 bytes

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

Recebe entrada como strings.

Neil
fonte
1

JavaScript (ES6), 67 bytes

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

Espera entradas como duas matrizes de dois elementos com dígitos. 12-> [1, 2]Espero que isso seja aceitável.

Experimente online!

Parece quase duplicado para quase da resposta Python do @Chas Brown , para que eu possa removê-la, se necessário (não tenho certeza das convenções aqui).

Explicação

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
redundância
fonte
2
" Parece uma duplicata quase próxima da resposta Python do @Chas Brown, para que eu possa removê-la se necessário (não tenho certeza das convenções aqui). " Como são idiomas diferentes, ambos podem permanecer. Somente se duas respostas no mesmo idioma são exatamente as mesmas, é uma boa prática que a última postada exclua a resposta (embora se duas pessoas tenham exatamente a mesma resposta e a acharam independente uma da outra, poderão manter as duas; a maioria vai exclua a resposta se eles tiverem exatamente o mesmo que alguém que postou antes). Mas com idiomas diferentes, não há problema. Bem-vindo ao PPCG! :)
Kevin Cruijssen
1

Python 2 ,  80  78 bytes

Provavelmente algumas oportunidades de golfe aqui ainda

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

Uma função sem nome que aceita dois números inteiros see , que retorna o tempo de escovação.

Experimente online!

Jonathan Allan
fonte
0

Limpo , 134 128 126 bytes

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

Experimente online!

Define a função $ :: Int Int -> Int, que apenas encontra a distância entre os dois dentes como coordenadas cartesianas. Solução bastante chata realmente.

Furioso
fonte