Lookup without conditional statements

This challenge was inspired by programming an Arduino microcontroller. I have 6 LEDs and 6 buttons connected to various pins on the board. In the code, each button and LED is assigned an ID number (1-6). Pin numbers (ranging from 0-13) corresponding to the ID numbers are looked up using a switch statement. Purely for amusement, I was wondering if these switches could be circumvented with an arithmetic/other function just to horrify future code maintainers.

The challenge

Provide the function/functions that take the ID number (integer) as a parameter and return the pin number (integer) for the 6 LEDs and/or the 6 buttons, without using conditional statements (no if, no switch and no ternary).

Return values for LEDs:

ID    Pin
1      3
2      5
3      6
4      9
5     10
6     11


Return values for buttons:

ID    Pin
1      2
2      4
3      7
4      8
5     12
6     13


Bonus challenge

Provide a single function that takes an ID number (integer) and second parameter (any type) indicating whether LED or button pins are requested, and returns the corresponding pin (integer).

Rules

This is not an Arduino-specific challenge. Use any language, do whatever you want.

Edit: at the suggestion of steveverril, this is now a code golf challenge.

Good luck!

(If you're still reading: although patently absurd and arbitrary by programming standards, the mappings are based on the Arduino Micro's pinout. Pins 0 and 1 are reserved for serial communication, LEDs are assigned to the 6 lowest-numbered PWM-capable pins, buttons are assigned to remaining pins)

• WeIcome to PPCG! I didn't downvote, but I think this would go better as a codegolf. Popularity contest is very broad in a situation like this. BTW, you can post questions at our sandbox meta.codegolf.stackexchange.com/q/2140/15599 to have them reviewed prior to posting – Level River St Sep 3 '15 at 20:50
• When you say "no if", can I use use a conditional expression as an integer? E.g. 1+(1==1)? – kirbyfan64sos Sep 3 '15 at 20:57
• Yes, those are fine. Only the three statements mentioned in the challenge (if, switch and ternary) are off limits. – user43596 Sep 3 '15 at 21:02
• Related – Peter Taylor Sep 3 '15 at 21:05
• @steveverrill thank you for the suggestion, challenge is now code golf. Had I met the reputation requirement of +5 for meta, I would have posted in the Sandbox :) So double thank you for not downvoting a lowly +1 rep casual. – user43596 Sep 3 '15 at 21:08

C, 28 bytes each

p(i){return"@cefijk"[i]&15;}
b(i){return"@bdghlm"[i]&15;}


This is basically the same as the answer by kirbyfan64sos, but uses a char array instead of integers, and has a dummy first byte so there is no need to subtract 1 from the function parameter.

l 1=3
l n=n+l(div(n+2)3)


to check:

> map l [1..6]
[3,5,6,9,10,11]


.

b 1=2
b n=n+b(div(n+1)2)


to check:

> map b [1..6]
[2,4,7,8,12,13]


a f 1=f+2
a f n=n+a f(n+f+1divf+2)


to check:

> map (a 0) [1..6]
[2,4,7,8,12,13]
> map (a 1) [1..6]
[3,5,6,9,10,11]


0 for buttons, 1 for LEDs.

• In the bonus, you should be able to use a f n=n+a f(n+f+div 1f+2). – dfeuer Mar 16 at 4:03
• Yuck! I know it's not in the spirit of codegolf, but this is way too late and too minor to edit a perfectly good solution. Appreciate the attention (to detail) though – Leif Willerts Mar 28 at 8:54
• How is it ever too late? – dfeuer Mar 28 at 12:01

C (math), 32 / 27 26 bytes (45 for bonus challenge)

Several people have posted various table-lookup solutions, but that seemed to me like taking the easy way out.. I wanted to see how well I could do with purely mathematical operations:

p(i){return~i&1|i*2^i*!(i%5-1);}
b(i){return i/5*5+1^p(i);}


It wasn't clear whether one function calling the other was acceptable or not; if not, one can use this alternate definition of b(i) (33 bytes) instead:

b(i){return(i&1|i*2)+i/5-!(i/2);}


Bonus Challenge (45 bytes):

f(i,t){return(i&1|i*2)+i/5-!(i/2)^t+i/5*5*t;}


(pass t=0 for buttons, t=1 for LEDs)

C, 36 bytes each (49 bytes for the bonus challenge)

p(i){return 3500459>>(4*(7+~i))&15;}
b(i){return 2390221>>(4*(7+~i))&15;}


I'm sorry...I just couldn't help it... Ok, I put a real solution now.

Bonus challenge, 49 bytes

f(i,t){return(2390221+t*1110238)>>(4*(7+~i))&15;}


Use f(button,0) and f(pin,1).

Live demo at Ideone.

Originals:

p(i){int a[]={3,5,6,9,10,11};return a[i-1];}
b(i){int a[]={2,4,7,8,12,13};return a[i-1];}

• If I wanted sensible answers, I wouldn't be posting in PPCG now would I :P Interestingly, using this in the actual Arduino program results in a larger size for the compiled binary (which, given ~28K of storage space on the board, is something to be avoided). – user43596 Sep 3 '15 at 20:54
• How about p(i){return"@cefijk"[i]&15;}b(i){return"@bdghlm"[i]&15;}? – squeamish ossifrage Sep 3 '15 at 21:16
• @squeamishossifrage You should post those as your own answer. They're better than mine is. :) – kirbyfan64sos Sep 3 '15 at 21:16
• @kirbyfan64sos Oh ok then – squeamish ossifrage Sep 3 '15 at 21:18

Pyth - 12 bytes each

Base encodes the array.

@jC"Ý"14tQ (buttons)
@jC"\r'"12tQ (leds)


The last one is actually twelve bytes except I can't write a carriage return so i escaped it.

• I think the OP intended for this to be a function ("Provide the function/functions"); with that it should be trivial to get the bonus: something like M@jC@"\rÝ"H+12*G2, which uses 0 for pins and 1 for buttons should work. – kirbyfan64sos Sep 4 '15 at 0:26

M@jC"5i«$xÍ"16+*6HtG  param#2 is 0 for LEDs, 1 for Buttons. To get Pin# for LED4,g4 0 I would have posted this as a comment to Maltysen's entry, but I just started, so lack the required reputation. I've just started using PYTH tonight, and admit that I shamelessly adapted his method of efficiently encoding a list. If this was inappropriate, my deepest apologies, and I'll remove my entry. • Hey Brian Tuck! I'm glad you've started using my language. This reuse of Maltysen's idea was probably fine, since base encoding isn't exactly a new idea. Giving credit, which you did, is important, however. By the way, Pyth shouldn't be written in all caps - it's not an acronym, it's just a name. – isaacg Sep 5 '15 at 19:35 MIPS, 16 bytes Bit shifting and bitmask. Input in $a0, output in $v0. sll$t0, $a0, 2 li$t1, 0xba96530
srlv    $t0,$t1, $t0 andi$v0, $t0, 0xf  For bonus, use immediate 0xdc87420 • Aren't we supposed to count the size of the source when golfing? :) – nitro2k01 Sep 4 '15 at 19:28 F#, 28+28 bytes I wanted to try this without a lookup table. let L x=1+x*2-x%4/3-x/5-x/6 let B x=x*2+x/3-x/4+x%6/5*2  SWI-Prolog, 34 bytes each l(I,P):-nth1(I,[3,5,6,9,10,11],P). b(I,P):-nth1(I,[2,4,7,8,12,13],P).  l/2 is for LEDs, b/2 is for buttons. Bonus, 66 bytes a(I,S,P):-nth1(I,[3:2,5:4,6:7,9:8,10:12,11:13],A:B),(S=0,P=A;P=B).  S = 0 for LEDs, anything else for Buttons. q/k (18 bytes each) Simply a case of indexing: L:0N 3 5 6 9 10 11 B:0N 2 4 1 8 12 13  Example: q) L[2] 5 q) B[6] 13  Bonus (1 byte, given L & B defined) @  Example: q) @[L;2] 5 q) @[B;6] 13  • This is deceptively clever use of symbols! +1 – kirbyfan64sos Sep 5 '15 at 15:56 CJam, 10 bytes each These are anonymous functions. The links to the online interpreter show then within a small test harness that executes the function for all input values. Function 1 (LEDs): {5*3|4+3/}  Try it online Function 2 (buttons): {_6|5+*5/}  Try it online I wrote a small program that generates and evaluates these expressions. For both of them, it found a number of solutions with 8 characters (counting the expression only without the braces), but none with less. Javascript (ES6), 26/27 bytes LEDs: a=>0 .charCodeAt(a)  Buttons: a=>0\r.charCodeAt(a)  If the above doesn't run (which is likely), here's a hexdump: 00000000: 6C 3D 61 3D 3E 60 30 03 - 05 06 09 0A 0B 60 2E 63 |l=a=>0 .c| 00000010: 68 61 72 43 6F 64 65 41 - 74 28 61 29 0A 62 3D 61 |harCodeAt(a) b=a| 00000020: 3D 3E 60 30 02 04 07 08 - 0C 5C 72 60 2E 63 68 61 |=>0 \r.cha| 00000030: 72 43 6F 64 65 41 74 28 - 61 29 |rCodeAt(a)|  I couldn't get the second one to work with a raw CR so I had to use \r Bonus, 41 bytes (a,b)=>0 \r.charCodeAt(a+b*6)  Hexdump 00000000: 28 61 2C 62 29 3D 3E 60 - 30 03 05 06 09 0A 0B 02 |(a,b)=>0 | 00000010: 04 07 08 0C 5C 72 60 2E - 63 68 61 72 43 6F 64 65 | \r.charCode| 00000020: 41 74 28 61 2B 62 2A 36 - 29 |At(a+b*6)|  Second parameter is 0 for LEDs, and 1 for buttons. Brainf**k, 107 bytes ,>++++++++[>+>++++++<<-<------>]<[>+++<-[>++<-[>+<-[>+++<-[>>>+>+<<<[-]+<-]]]]]>>[<++++++>-]<.>>>[-[-]<-.>]  This being my first hand-coded BF program, I don't doubt that there are several optimizations to be made. But it's still awesome. :) I'm not sure if [] counts as a conditional, though... :/ • We have a challenge full of BF optimisers at your disposal if you wanted to use one ;) – Beta Decay Sep 5 '15 at 21:09 • @BetaDecay They look great, but none of them actually make my code any shorter... :/ – kirbyfan64sos Sep 5 '15 at 21:43 • Hm, that's a shame :P – Beta Decay Sep 5 '15 at 21:44 POWERSHELL - 27-27-72 LED use 1..6 as args :\>wc -c LED.PS1 & cat LED.PS1 & echo.& powershell -nologo -f LED.PS1 1 27 LED.PS1 (0,3,5,6,9,10,11)[$args[0]]
3


button use 1..6 as args

:\>wc -c button.PS1 & cat button.PS1 & echo.& powershell -nologo -f button.PS1 6
27 button.PS1
(0,2,4,7,8,12,13)[$args[0]] 13  LED or BUTTON use b 1 ; l 2 ; b 6 ; l 5 etc as args :\>wc -c ledbutt.PS1 & cat ledbutt.PS1 & echo.& powershell -nologo -f ledbutt.PS1 b 5 72 ledbutt.PS1$a=@{"b"=(0,3,5,6,9,10,11);"l"=(0,2,4,7,8,12,13)};$a[$args[0]][$args[1]] 10 :\>powershell -nologo -f ledbutt.PS1 l 5 12 :\>powershell -nologo -f ledbutt.PS1 b 3 6 :\>powershell -nologo -f ledbutt.PS1 l 2 4  Octave, 40 bytes (bonus challenge) Using an anonuymous function: @(x,y)[3 2;5 4;6 7;9 8;10 12;11 13](x,y)  After defining this function, call this function as ans(x,y), where x is the pin/button number and y indicates pin or button with values 1 and 2 respectively. Try it online JavaScript 11374665952 33 (one function) Using bit shift to get 4bit values. Must be called with p(n, 195650864 or 231240736). /* 11 10 9 6 5 3 1011 1010 1001 0110 0101 0011 0000 = 195650864 13 12 8 7 4 2 1101 1100 1000 0111 0100 0010 0000 = 231240736 b >> i * 4 xxxx & 15 1111 yyyy (matching 1s) */ // Where b = 195650864 for pins and 231240736 for buttons. function p(i,b){return b>>i*4&15}  Alternate. /* Using bitwise * 4 for bitwise only. function p(i,b){return b>>(i<<2)&15} */  Perl 4 (37 and 31 bytes) LEDs (37 bytes): $c=pop;$c*2+($c~~[1,2,4,6]&&5.5<=>$c)  ... but it uses a lookup table. Buttons (31 bytes, no lookup): $c=pop;2*($c+($c==5))+(\$c%3==0)


JavaScript(ES6) 18,22,44

Edit Shorter but boring

// LED
l=i=>1-~' 134789'[i]
// Buttons
b=i=>[,2,4,7,8,12,13][i]

// bonus
f=(i,t)=>1-~[' 134789',[,0,2,5,6,10,11]][t][i]

//Test

out=x=>O.innerHTML+=x+'\n'

for(i=1;i<=6;i++) out(i +' -> '+l(i) + ' '+b(i) +' '+f(i,0)+' '+f(i,1))
<pre id=O></pre>

Python, 31 Bytes Each

Not exactly creative or anything, but it works!

l=lambda x:int(" 3569AB"[x],16)
b=lambda x:int(" 2478CD"[x],16)


Bonus, 44 Bytes

k=lambda x,y:int("3569AB2478CD"[x-1+6*y],16)


y should be 0 for LEDs, and 1 for buttons.

Python, 60 + 58 = 118 bytes

p=lambda i:(2**i)*(i<3)+1+(i>2)*(5+3*(i-3))-(i>4)*(i-3+~i%2)
b=lambda i:2**i-(i>2)-(i>3)*(2**(i-1)-1)-4*(i>4)-15*(i==6)


These are awful. i don't even know what I'm doing here...

But they're pretty interesting nonetheless! :D

Ruby, 45 Bytes

->i,t{[3,5,6,9,10,11,2,4,7,8,12,13][t*6+i-1]}


Test Inputs:

->i,t{[3,5,6,9,10,11,2,4,7,8,12,13][t*6+i-1]}.call 1,0
=> 3

->i,t{[3,5,6,9,10,11,2,4,7,8,12,13][t*6+i-1]}.call 3,1
=> 7


Forth, 26 bytes each, 34 for bonus

Similar to the C version by squeamish.

: P " CEFIJK" + C@ F AND ;
: B " BDGHLM" + C@ F AND ;


Bonus:

: A " CEFIJKBDGHLM" + + C@ F AND ;


Use 0 for LEDs and 6 for buttons. And the parameter order doesn't matter

Pyth, 19 bytes each

L.&.>3500459*4-6b15
L.&.>2390221*4-6b15


For pins and buttons, respectively.