8
\$\begingroup\$

This quite literally came to me in a dream.

A common combination padlock design has letters on the dials so you can set the combination to a word. Unfortunately, I can't read, but I can count. Considering I am in a hurry, send the shortest path around the dials to open the 4 letter lock, given the current letters and the correct combination.

The lock is set up so that the downward direction means going through the alphabet forwards

A->B->...Y->Z->A...

and upwards is in reverse

B->A->Z->Y....C->B->A->Z...

One turn refers to moving one letter in either direction.

Input

Any of

  • two strings "Position", "Combo"
  • a list of strings ["Position", "Combo"]
  • A list of each character in the position, and a list for the combo ['p1', 'p2' 'p3', 'p4'], ['c1', 'c2', 'c3', 'c4']

The order of position and combo may be switched but the letters cannot be rearranged or interleaved in any way.

Output

A list of the number of turns and the directions in which to turn. The directions can be indicated however you want, but it must be consistent and it cannot be a number. It can be a single list of tuples, paired [turns, direction] or [direction, turns] or two lists, one of turns and one of directions as long as direction[a] corresponds to turns[a]. Positive/Negative for Up/Down works as well. You can use either direction for zero turns or equidistant letters

Test cases:

[position, combo] -> [[turn[1], direction[1]], [t[2],d[2]], ...]
["NLWX", "GOLF"] -> [[7, up], [3, down], [11, up], [8, down]]
["CODE", "COOL"] -> [[0, up], [0, up], [11, down], [7, down]]
["AUGH", "NOPE"] -> [[13, up], [6, up], [9, down], [3, up]]
\$\endgroup\$
1
  • 1
    \$\begingroup\$ we're code golfing dreams now? \$\endgroup\$
    – qwr
    Jan 10 at 3:23

11 Answers 11

9
\$\begingroup\$

Uiua 0.8.0, 10 bytes SBCS

-13◿26+13-

Try on Uiua Pad!

Outputs positive and negative values.

18 bytes SBCS

+@a↥0⊃±⌵-13◿26+13-

Try on Uiua Pad!

Outputs 2 arrays, values and letters. Up is "a" and down is "b".

Explanation

-   # subtract the strings, get distances between letters
+13 # add 13
◿26 # mod 26
-13 # subtract 13
⊃±⌵ # get the signs and absolute values
↥0  # take the minimum with 0, turns -1 signs into 0
+@a # add "a" to the signs, makes up="a" and down="b"
\$\endgroup\$
2
  • \$\begingroup\$ It's a shame ⍜(+13|◿26) is longer. \$\endgroup\$
    – chunes
    Jan 8 at 4:16
  • \$\begingroup\$ @chunes agreed. \$\endgroup\$
    – Tbw
    Jan 8 at 5:13
5
\$\begingroup\$

Jelly, 7 bytes

O_/æ%13

Try it online!

A monadic link taking a list of two strings and returning a list of integers with negative integers as down and positive as up.

Explanation

O       | To codepoints
 _/     | Reduce by subtraction
   æ%13 | Symmetric mod 13
\$\endgroup\$
3
\$\begingroup\$

JavaScript (Node.js), 51 bytes

x=>y=>x.map((c,i)=>parseInt(c+57+y[i],36)%97%26-13)

Try it online!

Output pos/neg

JavaScript (Node.js), 68 bytes

x=>y=>x.map((c,i)=>[i=(c=parseInt(c+57+y[i],36)%97%26-13)<0,i?-c:c])

Try it online!

The directions can be indicated however you want, but it must be consistent and it cannot be a number.

I don't understand why but here true and false used

\$\endgroup\$
5
  • \$\begingroup\$ its to avoid ambiguity with the number of turns \$\endgroup\$
    – pacman256
    Jan 8 at 1:29
  • 1
    \$\begingroup\$ @pacman256 There is no ambiguity. Answers can just specify which comes first. \$\endgroup\$
    – noodle man
    Jan 8 at 1:44
  • \$\begingroup\$ 72: x=>y=>x.map((c,i)=>[(c=parseInt(c+'d'+y[i],36)%1297%26)>13?26-c:c,c>13]) \$\endgroup\$
    – tsh
    Jan 8 at 2:47
  • \$\begingroup\$ @tsh 71 is possible \$\endgroup\$
    – l4m2
    Jan 8 at 3:19
  • 1
    \$\begingroup\$ Comment ruling allows sign to be used to differentiate UP and DOWN, so x=>y=>x.map((c,i)=>(c=parseInt(c+'d'+y[i],36)%1297%26)>13?c-26:c) should be valid for 65 (Probably more golfable too) \$\endgroup\$
    – ATaco
    Jan 8 at 3:53
3
\$\begingroup\$

Scala 3, 78 75 bytes

A port of @l4m2's Javascript code in Scala.

Saved 3 bytes thanks to the comment of @l4m2


(x,y)=>x.zip(y).map{case(c,v)=>Integer.parseInt(s"${c}57${v}",36)%97%26-13}

Attempt This Online!

\$\endgroup\$
1
  • \$\begingroup\$ ${57} => 57 \$\endgroup\$
    – l4m2
    Jan 8 at 7:42
3
\$\begingroup\$

05AB1E, 11 bytes

Ç`-13+₂%13-

Port of @Tbw's Uiua's answer, so also uses negative values for down and positive for up.

Try it online or verify all test cases.

Explanation:

Ç            # Convert both strings in the (implicit) input-pair to a list of codepoint
             # integers
 `           # Pop and push both integer-lists separated to the stack
  -          # Subtract the values at the same positions from one another
   13+       # Add 13
      ₂%     # Modulo-26
        13-  # Subtract 13
             # (after which the result is output implicitly)
\$\endgroup\$
3
\$\begingroup\$

R, 38 bytes

\(s,t,`+`=utf8ToInt)(+s-+t--13)%%26-13

Attempt This Online!

Port of @Tbw's Uiua answer.

R, 42 bytes

\(s,t)strtoi(paste0(t,57,s),36)%%97%%26-13

Attempt This Online!

Port of @l4m2's JavaScript answer.

R, 73 66 bytes

\(s,t,`+`=utf8ToInt)Map(\(x,a=c(x,x-26))a[order(abs(a))[1]],+s-+t)

Attempt This Online!

Straightforward (?) implementation of the task.

\$\endgroup\$
3
\$\begingroup\$

Perl 5 -lF, 48 bytes

say+($_=(ord shift@F)-ord)-($_>13)*26for<>=~/./g

Try it online!

\$\endgroup\$
2
\$\begingroup\$

APL(Dyalog Unicode), 15 bytes SBCS

13-26|13+-⍥⎕UCS

Try it on APLgolf!

A tacit function which takes strings on the left and right and returns an array of positive and negative values. Port of my Uiua answer, but we have to get from letters to numbers first. This is done using ⎕UCS, which takes a string and converts to Unicode code points.

\$\endgroup\$
2
\$\begingroup\$

Google Sheets, 45 bytes

=index(mod(code(A1:A4)-code(B1:B4)+13,26)-13)

Put the position in cells A1:A4, the combination in cells B1:B4 and the formula in cell C1. The output will be in positive/negative integers.

Uses Tbw's method.

Microsoft Excel for the web, 38 bytes

=MOD(CODE(A1:A4)-CODE(B1:B4)+13,26)-13

Only works in Excel versions that spill result arrays by default.

\$\endgroup\$
2
\$\begingroup\$

Charcoal, 19 bytes

I⁻¹³﹪⁻¹³Eθ⁻℅ι℅§ηκ²⁶

Try it online! Link is to verbose version of code. Explanation: Similar to @Tbw's method, but subtracts the 13 in a different way to save bytes. (@l4m2's method would take 21 bytes in Charcoal.)

  ¹³                Literal integer `13`
 ⁻                  Vectorised subtract
      ¹³            Literal integer `13`
     ⁻              Vectorised subtract
         θ          First input
        E           Map over characters
            ι       Current character
           ℅        Ordinal
          ⁻         Subtract
               η    Second input
              §     Indexed by
                κ   Current index
             ℅      Ordinal
    ﹪               Vectorised modulo
                 ²⁶ Literal integer `26`
I                   Cast to string
                    Implicitly print
\$\endgroup\$
1
\$\begingroup\$

Retina 0.8.2, 90 bytes

O$#`.
$.%`
¶

M!`..
(.).
$&-$1
%{`.*?([A-Z])(-?)(#*)\1.*
$2$.3
T`L`ZL`^.
T`ZL`L`.$
.-
#$&#

Try it online! Takes input on separate lines but link is to test suite that splits on commas for convenience. Explanation:

O$#`.
$.%`
¶

M!`..

Transpose the input.

(.).
$&-$1

Duplicate the starting letters, but prefixed with -s, to indicate these copies are the ones going backwards.

%{`

Repeat the rest of the script on each line separately.

.*?([A-Z])(-?)(#*)\1.*
$2$.3

If the current line contains two identical letters, record the count of how long it took with the sign if appropriate.

T`L`ZL`^.

Advance the first letter forwards.

T`ZL`L`.$

Wind the last letter backwards.

.-
#$&#

Increment the count.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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