10
\$\begingroup\$

Introduction

Today's challenge is all about teeth. Specifically, how long it takes to brush from one tooth to another. Your challenge is, given the locations of two teeth, output the shortest amount of time possible to brush from the first to the second.

Challenge

For this challenge we will be using a layout of an average adult human mouth:

Layout of human mouth.

This diagram shows the widely used ISO numbering system. The system divides the mouth in four parts and assigns them each a number: upper right (1), upper left (2), lower left (3), and lower right (4). They then number the teeth of each section from the middle of the mouth out from 1-8. Therefore the fourth tooth from the center in the upper right side (section 1) is tooth number 14.

Let's assume brushing one tooth takes 1 unit of time. Moving from one tooth to the next one sideways takes 0 units of time. You can also cross from a tooth to the tooth directly above or below it, which also takes 1 unit of time. So how long does it take you to brush from tooth 14 to tooth 31? By looking at the diagram above, you will see it takes 7 units of time. Here is how that's calculated:

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

Note his is not the only route we could have took, but there are no shorter routes.

So your challenge is:

  • You will write a full program or function which accepts two arguments that are teeth numbers, and outputs (or returns) the shortest time to brush from one to the other.
  • You make take input as numbers or strings, and output how ever you wish (within acceptable methods).
  • Standard loopholes are forbidden by default.
  • This question is , so shortest bytecount wins.
  • Here are some testcases (Thanks Jonathan Allan):

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

Good luck!

\$\endgroup\$
  • 1
    \$\begingroup\$ @JonathanAllan will add when I get back to my computer. \$\endgroup\$ – Amphibological Jul 23 '18 at 17:46
  • 1
    \$\begingroup\$ "Moving from tooth to tooth takes 0 units of time." <- More precisely, I think you mean "Moving from one tooth to the next sideways takes 0 units of time". (I first took it to mean moving from any tooth to any other takes 1 unit, which made the next sentence confusing.) \$\endgroup\$ – sundar - Reinstate Monica Jul 23 '18 at 17:55
  • \$\begingroup\$ @sundar you're right, will edit. \$\endgroup\$ – Amphibological Jul 23 '18 at 18:06
  • 1
    \$\begingroup\$ @JonathanAllan done. \$\endgroup\$ – Amphibological Jul 23 '18 at 18:27
3
\$\begingroup\$

Jelly,  24  20 bytes

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

A monadic link accepting a list of two integers (e.g. [14,31] for the from 14 to 31 example) which yields the brushing-time.

Try it online!


Previous 24 byter built the mouth and used base 8, input was a list of lists of digits:

8R;C$C+⁴U,+ɗ⁴
ḅ8¢œiⱮạ/Ḅ‘
\$\endgroup\$
5
\$\begingroup\$

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

Takes input as strings.

\$\endgroup\$
1
\$\begingroup\$

Python 2, 91 bytes

def f(a,b):A,B=a/10,b/10;return[abs(a-b)%10+1+2*(A!=B),a%10+b%10+2-(A+B)%2*2][A!=B!=A+B!=5]

Try it online!

\$\endgroup\$
1
\$\begingroup\$

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

Expects inputs as two 2-element arrays of digits. 12 -> [1, 2] I hope this is acceptable.

Try it online!

Looks like a near duplicate to @Chas Brown's Python answer, so I can remove it if necessary (unsure of the conventions here).

Explanation

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
\$\endgroup\$
  • 2
    \$\begingroup\$ "Looks like a near duplicate to @Chas Brown's Python answer, so I can remove it if necessary (unsure of the conventions here)." Since they are different languages both may stay. Only if two answers in the same language are exactly the same it's best practice that the one posted last delete their answer (although if two people having the exact same answer and they found it independent of each other they are allowed to keep both; most will delete their answer if they have the exact same as someone who posted sooner, though). But with different languages there is no problem. Welcome to PPCG! :) \$\endgroup\$ – Kevin Cruijssen Jul 24 '18 at 12:43
1
\$\begingroup\$

Python 2,  80  78 bytes

Probably some golfing opportunities here still

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

An unnamed function accepting two integers, s and e, which returns the brushing-time.

Try it online!

\$\endgroup\$
0
\$\begingroup\$

Clean, 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

Try it online!

Defines the function $ :: Int Int -> Int, which just finds the distance between the two teeth as Cartesian coordinates. Pretty boring solution really.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.