23
\$\begingroup\$

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)

\$\endgroup\$
5
  • \$\begingroup\$ 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 \$\endgroup\$ Commented Sep 3, 2015 at 20:50
  • \$\begingroup\$ When you say "no if", can I use use a conditional expression as an integer? E.g. 1+(1==1)? \$\endgroup\$ Commented Sep 3, 2015 at 20:57
  • \$\begingroup\$ Yes, those are fine. Only the three statements mentioned in the challenge (if, switch and ternary) are off limits. \$\endgroup\$
    – user43596
    Commented Sep 3, 2015 at 21:02
  • \$\begingroup\$ Related \$\endgroup\$ Commented Sep 3, 2015 at 21:05
  • 1
    \$\begingroup\$ @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. \$\endgroup\$
    – user43596
    Commented Sep 3, 2015 at 21:08

23 Answers 23

10
\$\begingroup\$

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.

\$\endgroup\$
9
\$\begingroup\$

Haskell, 24 bytes each

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]

bonus, Haskell, 36 bytes

a f 1=f+2
a f n=n+a f(n+f+1`div`f+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.

\$\endgroup\$
3
  • 1
    \$\begingroup\$ In the bonus, you should be able to use a f n=n+a f(n+f+div 1f+2). \$\endgroup\$
    – dfeuer
    Commented Mar 16, 2019 at 4:03
  • \$\begingroup\$ 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 \$\endgroup\$ Commented Mar 28, 2019 at 8:54
  • \$\begingroup\$ How is it ever too late? \$\endgroup\$
    – dfeuer
    Commented Mar 28, 2019 at 12:01
7
\$\begingroup\$

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)

\$\endgroup\$
5
\$\begingroup\$

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.

Screenshot

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];}
\$\endgroup\$
4
  • 1
    \$\begingroup\$ 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). \$\endgroup\$
    – user43596
    Commented Sep 3, 2015 at 20:54
  • \$\begingroup\$ How about p(i){return"@cefijk"[i]&15;}b(i){return"@bdghlm"[i]&15;}? \$\endgroup\$
    – r3mainer
    Commented Sep 3, 2015 at 21:16
  • \$\begingroup\$ @squeamishossifrage You should post those as your own answer. They're better than mine is. :) \$\endgroup\$ Commented Sep 3, 2015 at 21:16
  • \$\begingroup\$ @kirbyfan64sos Oh ok then \$\endgroup\$
    – r3mainer
    Commented Sep 3, 2015 at 21:18
4
\$\begingroup\$

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.

Test Suite for Buttons.

Test Suite for LEDS.

\$\endgroup\$
1
  • \$\begingroup\$ 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. \$\endgroup\$ Commented Sep 4, 2015 at 0:26
3
\$\begingroup\$

Pyth, Bonus only: 20 bytes

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.

\$\endgroup\$
1
  • 1
    \$\begingroup\$ 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. \$\endgroup\$
    – isaacg
    Commented Sep 5, 2015 at 19:35
2
\$\begingroup\$

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

\$\endgroup\$
1
  • \$\begingroup\$ Aren't we supposed to count the size of the source when golfing? :) \$\endgroup\$
    – nitro2k01
    Commented Sep 4, 2015 at 19:28
2
\$\begingroup\$

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
\$\endgroup\$
1
\$\begingroup\$

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.

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

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
\$\endgroup\$
1
  • \$\begingroup\$ This is deceptively clever use of symbols! +1 \$\endgroup\$ Commented Sep 5, 2015 at 15:56
1
\$\begingroup\$

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.

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

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.

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

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... :/

\$\endgroup\$
3
  • \$\begingroup\$ We have a challenge full of BF optimisers at your disposal if you wanted to use one ;) \$\endgroup\$
    – Beta Decay
    Commented Sep 5, 2015 at 21:09
  • \$\begingroup\$ @BetaDecay They look great, but none of them actually make my code any shorter... :/ \$\endgroup\$ Commented Sep 5, 2015 at 21:43
  • \$\begingroup\$ Hm, that's a shame :P \$\endgroup\$
    – Beta Decay
    Commented Sep 5, 2015 at 21:44
0
\$\begingroup\$

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
\$\endgroup\$
0
\$\begingroup\$

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

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

JavaScript 113 74 66 59 52 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}
*/
\$\endgroup\$
0
\$\begingroup\$

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)
\$\endgroup\$
0
\$\begingroup\$

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>

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

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.

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

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

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

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
\$\endgroup\$
0
\$\begingroup\$

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

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

Pyth, 19 bytes each

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

For pins and buttons, respectively.

\$\endgroup\$

Your Answer

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