Given an integer from 1 to 999 inclusive, output a truthy value if it appears horizontally, vertically, or diagonally, either forwards or backwards, anywhere in the 3x3 square of digits 1-9 on a standard number pad:
789
456
123
If the number does not appear, output a falsy value.
The exact 65 numbers you need to output truthy for are:
1
2
3
4
5
6
7
8
9
12
14
15
21
23
24
25
26
32
35
36
41
42
45
47
48
51
52
53
54
56
57
58
59
62
63
65
68
69
74
75
78
84
85
86
87
89
95
96
98
123
147
159
258
321
357
369
456
654
741
753
789
852
951
963
987
Everything else is falsy.
The shortest code in bytes wins.
-
\$\begingroup\$ Relevant OEIS. \$\endgroup\$Fatalize– Fatalize2016年12月04日 14:41:32 +00:00Commented Dec 4, 2016 at 14:41
-
\$\begingroup\$ The input may contain 0, it can be a string. \$\endgroup\$Calvin's Hobbies– Calvin's Hobbies2016年12月04日 19:43:52 +00:00Commented Dec 4, 2016 at 19:43
-
\$\begingroup\$ I see Luis Mendo showing up with a MATL answer in the near future heh. \$\endgroup\$Magic Octopus Urn– Magic Octopus Urn2016年12月05日 13:32:50 +00:00Commented Dec 5, 2016 at 13:32
7 Answers 7
JavaScript (ES6), (削除) 83 (削除ここまで) ... (削除) 74 (削除ここまで) 73 bytes
Takes input as a string.
n=>1/([a,b,c]=[...n].map(v=>--v+v/3|0))||45242>>(a^b)&(~c&&n<99|b*2==a+c)
Saved 3 bytes thanks to ETHproductions
How it works
We transform the number pad by applying an offset to each digit according to the row it belongs to:
- +1 for the top row
- 0 for the middle row
- -1 for the bottom row.
All codes below are represented in hexadecimal.
7 8 9 8 9 A (+1)
4 5 6 => 4 5 6 (unchanged)
1 2 3 0 1 2 (-1)
Let's consider all XOR combinations of these new key codes. Contiguous keys are highlighted with brackets.
XOR| 0 1 2 4 5 6 8 9 A
---+------------------------------------
0 | 0 [1] 2 [4] [5] 6 8 9 A
1 | [1] 0 [3] [5] [4] [7] 9 8 B
2 | 2 [3] 0 6 [7] [4] A B 8
4 | [4] [5] 6 0 [1] 2 [C] [D] E
5 | [5] [4] [7] [1] 0 [3] [D] [C] [F]
6 | 6 [7] [4] 2 [3] 0 E [F] [C]
8 | 8 9 A [C] [D] E 0 [1] 2
9 | 9 8 B [D] [C] [F] [1] 0 [3]
A | A B 8 E [F] [C] 2 [3] 0
We can see that two keys are contiguous if and only if XORing their codes leads to one of the following values:
1, 3, 4, 5, 7, C, D, F
This list can be packed into the following binary mask:
FEDCBA9876543210
----------------
0b1011000010111010 =わ 0xB0BA = 45242
Hence the test to determine if two key codes (a, b) correspond to two contiguous keys:
45242 >> (a ^ b) & 1
For three key codes (a, b, c), we need this additional test:
b * 2 == a + c
Example:
a = 0xA
b = 0x6
c = 0x2
0xB0BA >> (0xA ^ 0x6) & 1 == 0xB0BA >> 0xC & 1 == 1
=> 0xA and 0x6 are contiguous key codes
0x6 * 2 == 0xA + 0x2
=> 0xA, 0x6 and 0x2 are contiguous key codes on the same row, column or diagonal
Demo
This snippet outputs the list of truthy values.
let f =
n=>1/([a,b,c]=[...n].map(v=>--v+v/3|0))||45242>>(a^b)&(~c&&n<99|b*2==a+c)
console.log([...Array(1000).keys()].filter(n=>n && f(n+'')).join(' '))
-
\$\begingroup\$ Coercion is your friend here:
a-.5returns true for any arrayacontaining (zero or) one integer.n=>([a,b,c]=[...n].map(v=>--v+v/3|0))-.5||n%10&&n<100|b*2==a+c&&45242&1<<(a^b)\$\endgroup\$ETHproductions– ETHproductions2016年12月04日 20:38:33 +00:00Commented Dec 4, 2016 at 20:38 -
\$\begingroup\$ @ETHproductions Ah, nice!
1/ais even shorter and should work just as well, I think. \$\endgroup\$Arnauld– Arnauld2016年12月04日 20:56:26 +00:00Commented Dec 4, 2016 at 20:56
Python3, 72 bytes
lambda n,s="123 456 789 741 852 963 42 753 86 26 159 84 ":n in s+s[::-1]
Input is taken as a string.
Golfing suggestions welcome! :D
-
\$\begingroup\$ Does this take the number as a string? \$\endgroup\$FlipTack– FlipTack2016年12月04日 18:29:02 +00:00Commented Dec 4, 2016 at 18:29
-
\$\begingroup\$ @Flp.Tkc Yes it does. I'll mention that in the post. Thanks! \$\endgroup\$Yytsi– Yytsi2016年12月04日 18:54:47 +00:00Commented Dec 4, 2016 at 18:54
-
\$\begingroup\$ @TuukkaX there is an additional space in string
s, you can save 1 byte. \$\endgroup\$Gurupad Mamadapur– Gurupad Mamadapur2016年12月05日 15:38:35 +00:00Commented Dec 5, 2016 at 15:38 -
\$\begingroup\$ @GurupadMamadapur I don't see why I would change my current 72 bytes solution to your 74 bytes solution... :D And if you refer to my string
s, which has an whitespace after84, then you're incorrect, since it's required. If it wouldn't contain a whitespace, the resulted string would have a chain '8448', which would lead to failed testcases. Thanks for the suggestions though! \$\endgroup\$Yytsi– Yytsi2016年12月05日 22:53:44 +00:00Commented Dec 5, 2016 at 22:53 -
\$\begingroup\$ @TuukkaX Yeah you're right about the extra whitespace, missed that one :) \$\endgroup\$Gurupad Mamadapur– Gurupad Mamadapur2016年12月06日 09:12:48 +00:00Commented Dec 6, 2016 at 9:12
Befunge, (削除) 169 (削除ここまで) (削除) 161 (削除ここまで) 159 bytes
38*:2+"*0>DTV{51"3*3円*"kV"3*3円*"{w"3*3円*"mr"v
v:\&+*83:++66:+"c":+"?":+"$":++66:+"W":*6\*4<
_v#:\_v#*-+%+55g00*+55g02\*-g02\*-g00\`9::::p02/+55p00%"d":
0<@.!!<
The first two lines are just pushing the list of test numbers onto the stack. This is done in order of size, since it can sometimes be easier to generate a number as an offset from the previous one in the series rather than generating it from scratch. Once we get to the larger numbers, we can also sometimes save a byte by generating them in pairs, e.g. "kV"3*3円* gives us 258 and 321 in nine bytes, where individually they would take five bytes each.
The main loop is on line three, executing right to left with wrap around. This just iterates through all the test numbers on the stack, comparing the value itself, value%100, and value/10. If any of those match the input number or the number <= 9 then we output 1 and exit. If there is no match, we continue looping. If we run out of test numbers on the stack then we output 0 and exit.
Thanks to Mistah Figgins for saving me a couple of bytes.
-
\$\begingroup\$ I think you can change the last line to
0<@.!!<to save 2 bytes. This relies on the top of the stack being non-zero when the IP comes down onto the second arrow. Try it Online! \$\endgroup\$MercyBeaucou– MercyBeaucou2016年12月05日 03:10:49 +00:00Commented Dec 5, 2016 at 3:10
Jelly, (削除) 29 (削除ここまで) (削除) 24 (削除ここまで) 19 bytes
Saved 5 bytes thanks to @Dennis's suggestion of K and Ɠ.
9s3μUŒD;;Z;ŒDμ;UKƓẇ
Explanation
9Rs3μUŒD;;Z;ŒDμ;UKƓẇ Main link. Argument: number
9s3 Split [1..9] into [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
μ New monadic chain
U Reverse the rows
ŒD Take the diagonals of the result
; Append the original rows
;Z Append the original columns
;ŒD Append the original diagonals
μ New monadic chain
;U Append the reverse of everything
K Join by spaces
Ɠẇ Check if a line from STDIN is in the result
-
\$\begingroup\$ If you read the input from STDIN,
9s3µUŒD;;Z;ŒDµ;UKƓẇsaves 5 bytes. \$\endgroup\$Dennis– Dennis2016年12月04日 19:02:28 +00:00Commented Dec 4, 2016 at 19:02 -
\$\begingroup\$ Do you need to reverse the rows? They can appear forward or backwards, so
123,456,789should be the same as789,456,123\$\endgroup\$Riley– Riley2016年12月05日 14:41:02 +00:00Commented Dec 5, 2016 at 14:41 -
\$\begingroup\$ @Riley I reverse each row, not the rows as an array. I guess I could've been clearer there. Anyway, it's done in order to get half of the diagonals. \$\endgroup\$PurkkaKoodari– PurkkaKoodari2016年12月05日 14:51:49 +00:00Commented Dec 5, 2016 at 14:51
Ruby, 77 bytes
->n{!!((s='123 456 789 147 258 369 753 951 86 62 24 48 ')+s.reverse)["#{n}"]}
-
\$\begingroup\$ You are creating a string that is '123 456 789 147 258 369 753 951 ' + the same string reversed, and checking whether the parameter is found on the string, right? If it's so, then this solution is invalid. For example,
86and24will fail. \$\endgroup\$Yytsi– Yytsi2016年12月04日 15:26:27 +00:00Commented Dec 4, 2016 at 15:26 -
\$\begingroup\$ The rules say you need only output a truthy or falsey value, so you don't need
!!or the attendant parentheses. \$\endgroup\$Jordan– Jordan2016年12月05日 01:22:11 +00:00Commented Dec 5, 2016 at 1:22
bash, 75
printf %s\\n 123 456 789 741 852 963 42 753 86 26 159 84|tee >(rev)|grep 1ドル
outputs something and returns 0 for all the values in that list
prints nothing and returns 1 in all other cases
Java, 397 bytes
public class Numpad {public static void main(String[] args){Scanner input=new Scanner(System.in);int in=input.nextInt();int h=in/100;int u=in%10;int t=(in%100)/10;boolean out=false;input.close();if(in<10)out=true;else if( h==0){int decider=Math.abs(t-u);if((decider==1)||(decider==3)||(decider==4))out=true;}else{if ( Math.abs(h-t) == Math.abs(t-u))out=true;}System.out.println("RESULT : "+out);}}
-
\$\begingroup\$ I am new to this .. kindly excuse any oblivionism. \$\endgroup\$Nefi knomore– Nefi knomore2016年12月07日 04:37:07 +00:00Commented Dec 7, 2016 at 4:37
-
\$\begingroup\$ Hello, and welcome to the site! I've edited your post so that the code section is displayed as code and added a byte count, which is standard for answers here. This competition is a code-golf competition, meaning the ultimate goal is to make your code as short as possible. For example, you can use short variable names, and define a function instead of a full class. I'm not great at Java, but some more tips are available here. You should try to make your code shorter, and then edit the new version into your post. \$\endgroup\$DJMcMayhem– DJMcMayhem2016年12月07日 04:44:26 +00:00Commented Dec 7, 2016 at 4:44
Explore related questions
See similar questions with these tags.