# Generate Probabilities around a Numpad

Inspired by this question earlier today, I'd like to see interesting ways various programming languages can turn a numpad into probabilities. Commonly, tile-based games will allow you to use a numpad to move in any direction based on where your character currently is. When making an AI for these games, Math.random() * 8 is not sufficient, so I had to get a little creative to make the movement look and feel somewhat natural.

A numpad is defined as such:

7 | 8 | 9
- - - - -
4 | x | 6
- - - - -
1 | 2 | 3


Please note, 5 is an invalid number, as you cannot move onto yourself.

All examples will use these probabilities: [50, 40, 30, 20, 10]

If I wanted to generate probabilities around 8, it would look like this:

40 | 50 | 40
-- | -- | --
30 | xx | 30
-- | -- | --
20 | 10 | 20


The output would be [20, 10, 20, 30, 30, 40, 50, 40] (with 5 omitted) or [20, 10, 20, 30, null, 30, 40, 50, 40] (with 5 present)

If I wanted to generate them around 1, it would look like this:

30 | 20 | 10
-- | -- | --
40 | xx | 20
-- | -- | --
50 | 40 | 30


The output would be [50, 40, 30, 40, 20, 30, 20, 10] (with 5 omitted) or [50, 40, 30, 40, null, 20, 30, 20, 10] (with 5 present)

You may write a full program that takes the input in any usual way (command line, stdin) and prints the output, or you may write a function with a number argument, that prints or returns the output. Your program or function should accept one number - the position to generate around. You should use these probabilities: [50, 40, 30, 20, 10] (they do not have to be hardcoded).

Shortest code in bytes wins. Standard loopholes are disallowed. Answers posted in the linked thread are disallowed. Trailing or leading spaces are allowed. You may treat position 4 as absent or empty, depending on your preference. I'm not too picky on output format - print it out as comma-separated strings or as an array.

(This is my first question, go easy on me!)

# CJam, 27 bytes

12369874s_$\_r#m<f{#4-z)0S}  Try it online in the CJam interpreter. ### Idea If we go through the digits around 5 in counterclockwise fashion, we obtain the string 12369874 or any of its rotations (depending on the starting point). After rotating this string so that the input digit n is at the leftmost position, the digits in the rotated string have the following probabilities: 50 40 30 20 10 20 30 40  If we consider the indexes of these digits, which are  0 1 2 3 4 5 6 7  subtract 4 from each to yield -4 -3 -2 -1 0 1 2 3  and take absolute values to get  4 3 2 1 0 1 2 3  we only have to add 1 and append a 0 to get the desired probabilities. ### Code 12369874s e# Push "12369874". _$                 e# Push a sorted copy, i.e., "12346789".
\                e# Swap it with the unsorted original.
_r#             e# Find the index of the input in an unsorted copy.
m<           e# Rotate the unsorted original that many units left.
f{       } e# For each character C in "12346789":
e#   Push the rotated string.
#        e#   Find the index of C.
4-      e#   Subtract 4.
z     e#   Compute the absolute value.
0S  e#   Push a 0 and a space.


# Prolog, 166 bytes

a(A,R):-I:J:K:L:M=50:40:30:20:10,B is abs(5-A),member(B:S,[4:[I,J,K,J,L,K,L,M],3:[J,I,J,K,K,L,M,L],2:[K,J,I,L,J,M,L,K],1:[J,K,L,I,M,J,K,L]]),(A/5>1,reverse(S,R);S=R).


This uses the fact that the result for 9 is the reverse of the result for 1, same for 2 and 8, 3 and 7 and 4 and 6. There are recognizable patterns to go from the result of 1 to the results of 2,3 and 4 but I'm pretty sure it would be longer to code this than hardcoding the sequences for 1 to 4, which is what I did.

Example: a(7,R). outputs R = [30, 20, 10, 40, 20, 50, 40, 30].

• A valid strategy, though I hope some languages make it easier to do algorithmically than it would be to hardcode it. I suppose we'll see. Jul 18, 2015 at 22:10
• @Seiyria I assume array-oriented languages will do just that. You unfortunately usually can't permute elements of lists in a short amount of bytes in Prolog. Jul 18, 2015 at 22:15

# Python - 115

a=[50,40,30,20,10,20,30,40]
b=[0,1,2,7,8,3,6,5,4]
def v(n):
c=8-b[n-1]
return[(a[c:]+a[:c])[e]for e in b if e-8]


a is an array with the values in order around the numpad (counter-clockwise from 1), and b maps numbers on the numpad to positions around it. Based on the number of spaces around the numpad for the input number (determined using b), it makes an array with that many elements moved from the front of a to the end, then uses b again to rearrange the elements to correspond with numpad numbers.

• You can save a lot by making a /10 and then putting a *10 in your loop. Jul 19, 2015 at 1:01
• Isn't (a[c:]+a[:c])[e] that same is a[(c+e)%8] or a[c+e-8]? And then plugging in c simplifies the expression.
– xnor
Jul 19, 2015 at 6:23

# Pyth - 38 bytes

Uses kinda the same technique as the Python answer except with base compression for the two arrays.

J_jC"3ê"T*RTm@.<jC"<àR"T-8@JtQd.DJ4

• What are the ê and à doing?
Jul 19, 2015 at 3:11
• @phase the aforementioned base compression: codegolf.stackexchange.com/questions/40039/… Jul 19, 2015 at 3:18
• These short answers will never cease to amaze me. Jul 19, 2015 at 3:30
• @Seiyria I can really suggest to learn Pyth - these programs look a lot more complicated than they are :)
– orlp
Jul 19, 2015 at 8:04

# Java, 190

void g(int n){int i[]={8,0,1,2,7,8,3,6,5,4};String v="54321234",s="";n=i[n];if(n>0)v=v.substring(8-n)+v.substring(0,8-n);for(n=0;n++<9;s=", ")if(n!=5)System.out.print(s+v.charAt(i[n])+"0");}


String v holds the probabilities (divided by 10) in countrclockwise order with input = 1 being the default 50.

int[]i translates the input into an index into v. For example, v.charAt(i) is 5. Inputs 0 and 5 are invalid so both i and i have a placeholder value of 8 which is the index for '\0' at the end of v.

I rotate the numbers in v to the right by the value i[n], and then print the probabilities as comma separated strings.