12
\$\begingroup\$

In North America, most electrical outlets/receptacles follow standards set by NEMA. For this challenge, you'll be given a few properties of a device you need to plug in, and your program (or function) should return all of the outlets that would be compatible.

For this challenge, an outlet has three properties: voltage, current rating, and grounding.

I/O:

Input will consist of a voltage, current usage, and grounding requirements for some device. The first two are positive integers, and the third can be represented by a boolean (though you are allowed to represent it in any reasonable way).

The output should be a list of outlets which are compatible, following the rules below. Each outlet's name is formatted as NN-nn, with NN and nn being numbers. All outlets should either be returned as strings with this formatting, or arrays of [NN, nn]. You can return the compatible outlets in an array, or separated with spaces/newlines/commas, or via any other reasonable method.

Requirements:

In order for an outlet to be compatible with the inputted device, it must meet three requirements:

  • The voltage should be within ±10% of the device's voltage
  • The current rating should be at least as high as the device's current usage
  • If the device requires a grounded outlet, the outlet must be grounded (otherwise it may or may not be)

Outlets:

These are the outlets your program must be able to handle:

1-15     120    15     
2-15     240    15     
2-20     240    20     
2-30     240    30     
5-15     120    15    G
5-20     120    20    G
5-30     120    30    G
6-15     240    15    G
6-20     240    20    G
6-30     240    30    G
6-50     240    50    G
7-15     277    15    G
7-20     277    20    G
7-30     277    30    G
7-50     277    50    G
10-30    240    30     
10-50    240    50     
11-20    240    20     
11-30    240    30     
11-50    240    50     
12-20    480    20     
14-15    240    15    G
14-30    240    30    G
14-50    240    50    G
14-60    240    60    G

The first column is the name of the outlet, followed by the voltage, then the current rating, then a G if it's grounded. Some of these may be slightly inaccurate.

Test Cases:

Formatted with a voltage, then current usage, then a G for grounded or an x for ungrounded. Some do not have any compatible outlets.

120    16    G    5-20, 5-30
260    5     x    2-15, 2-20, 2-30, 6-15, 6-20, 6-30, 6-50, 7-15, 7-20, 7-30, 7-50, 10-30, 10-50, 11-20, 11-30, 11-50, 14-15, 14-30, 14-50, 14-60
260    5     G    6-15, 6-20, 6-30, 6-50, 7-15, 7-20, 7-30, 7-50, 14-15, 14-30, 14-50, 14-60
260    35    x    6-50, 7-50, 10-50, 11-50, 14-50, 14-60
480    10    x    12-20
108    10    x    1-15, 5-15, 5-20, 5-30
528    20    x    12-20
249    50    G    6-50, 14-50, 14-60
250    50    G    6-50, 7-50, 14-50, 14-60
304    10    x    7-15, 7-20, 7-30, 7-50
480    10    G    
480    25    x
400    10    x
600    10    x
180    10    x
80     10    x    

Other:

This is , so shortest answer in bytes per language wins!

\$\endgroup\$
4
  • \$\begingroup\$ Can we take input as an array ([voltage,current,grounding])? \$\endgroup\$ – A username Mar 27 at 8:30
  • \$\begingroup\$ @Ausername Sure, the order/method which you take those three don't matter at all, as long as their reasonable. \$\endgroup\$ – Redwolf Programs Mar 27 at 16:54
  • 1
    \$\begingroup\$ Minor complaint: your data makes NEMA 14 outlets equivalent to NEMA 6 ones, but actual NEMA 14 outlets can provide both 120V and 240V, unlike NEMA 6, and there's also a missing distinction between single-phase and 3-phase. \$\endgroup\$ – Joseph Sible-Reinstate Monica Apr 11 at 3:32
  • \$\begingroup\$ @JosephSible-ReinstateMonica I considered adding some rules to account for those, but I didn't want to make the challenge overly complicated. \$\endgroup\$ – Redwolf Programs Apr 11 at 15:17
9
\$\begingroup\$

JavaScript (ES10), 159 bytes

Same logic as my original answer, but with the data stored as a string with several unprintable characters.

(v,r,g)=>[..."_Î^~248ÕScž"].flatMap(x=>(x=x.charCodeAt(),n+=x>>6,V=(120<<x/16%4)%683,R=~(x/2&7)*10%65,-R<r|x&g|(V-v)**2>V*V/100?[]:n+[R]),n=1)

Try it online!


JavaScript (ES10),  200 190 186  181 bytes

Expects (voltage, current, ground), where ground is a Boolean value. Returns an array of strings in NN-nn format.

(v,r,g)=>"0F5F1315CE02045E1214187E323438D519531519639E14181A".match(/../g).flatMap(x=>(x='0x'+x,n+=x>>6,V=(120<<x/16%4)%683,R=~(x/2&7)*10%65,-R<r|x&g|(V-v)**2>V*V/100?[]:n+[R]),n=1)

Try it online!

How?

Encoding format

Each outlet is encoded as a byte x whose bit-mask is DDVVRRRG with:

  • DD = difference between the leading outlet ID and the previous leading outlet ID
  • VV = voltage: [120,240,480,277] mapped to [0,1,2,3]
  • RRR = current rating: [20,30,50,60,15] mapped to [1,2,4,5,7]
  • G = flag set if there's no ground

For instance, the outlet 10-30 is encoded as 0xD5 = 0b11010101:

11 01 010 1
 |  |   | |
 |  |   | +--> no ground
 |  |   +----> rating 2 (30A)
 |  +--------> voltage 1 (240V)
 +-----------> previous ID + 3 (7 + 3 = 10)

The whole data is stored as a single string of two-nibble hexadecimal values, which are split with a match().

Decoding

The leading ID is updated with:

n += x >> 6

Because \$277\$ is \$960\bmod683\$, the voltage is decoded with:

V = (120 << x / 16 % 4) % 683

Because \$15\$ is \$80\bmod65\$, the current rating is decoded with:

R = -~(x / 2 & 7) * 10 % 65
\$\endgroup\$
2
  • \$\begingroup\$ I don't know how this works, but I am in awe... \$\endgroup\$ – A username Mar 27 at 10:17
  • \$\begingroup\$ @Ausername I've added an explanation. \$\endgroup\$ – Arnauld Mar 27 at 10:33
3
\$\begingroup\$

Charcoal, 115 bytes

≔¹⁰⁰εNθNηNζIEΦI⪪”)⧴→WuJSN4⊘Rf⎚θ⊕∧H,\`m↖⊗?Yς×≧üλθ▷TE⦄→×◧Àλ≧”⁴¬∨›ζ‹⁵﹪÷ιε⁸∨›η﹪ιε‹·¹↔⁻¹∕θ⎇⁼⁷÷ιε²⁷⁷×¹²⁰⎇⁼¹¹÷ιε²⊕﹪⊖÷ιε⁴↨ιε

Try it online! Link is to verbose version of code. Takes the groundedness as an integer, 1 = grounded, 0 = ungrounded and outputs in array format [[N, nn], ...] (string format is possible at the cost of 1 byte). Explanation:

≔¹⁰⁰ε

Save the value 100 as it gets used a lot. (Charcoal only has predefined variables for 10 and 1000.)

NθNηNζ

Input the voltage, current and groundedness.

IEΦI⪪”)⧴→WuJSN4⊘Rf⎚θ⊕∧H,\`m↖⊗?Yς×≧üλθ▷TE⦄→×◧Àλ≧”⁴¬

Split the compressed string of outlets in NNnn format into individual outlets in decimal, and filter out any that fail any of the following tests:

∨›ζ‹⁵﹪÷ιε⁸

The device needs to be grounded, but NN (modulo 8) is less than 5.

∨›η﹪ιε

The device requires more than nn current.

‹·¹↔⁻¹∕θ⎇⁼⁷÷ιε²⁷⁷×¹²⁰⎇⁼¹¹÷ιε²⊕﹪⊖÷ιε⁴

Dividing the device's voltage by the receptacle's voltage results in a value outside the range 0.9..1.1. The receptacle's voltage is calculated as NN (modulo 4, or 4 if NN is a multiple of 4, or 2 if NN is 11) multiplied by 120, unless NN is 7, in which case 277 is used instead.

↨ιε

Split the NNnn integer into separate NN and nn values by converting into base 100.

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

Ruby, 155 150 bytes

f=->v,a,g{z=0
"yQxwxwTxwuUuuwubvuw	 xwu".bytes{|i|z+=121-i
(v-q=(16<<z/140)*7.5%683)**2<=q*q/100&&g*4<=(t=z/10%14)%8&&a<=(c=z%10*5+15)&&(p [t+1,c])}}

Try it online!

The magic string contains one character 14 and one tab (character 9).

A function taking 3 inputs: volts, amps, ground (where ground is 0 or 1.)

Prints a list of two-element arrays to stdout. These are ordered by rated voltage, so the ordering of the output may differ a little from the test cases in the question, but they are all there.

Commented code

f=->v,a,g{z=0                         #Input voltage, current and grounding. Set z=0
"yQxwxwTxwuUuuwubvuw     xwu".        #Magic string, one byte per outlet spec.
     bytes{|i|z+=121-i                #Iterate through bytes and increment z.
     (v-q=(16<<z/140)*7.5%683)**2<=   #16*7.5=120V. rightshift by z/140 to get 240, 480 or 960%683=277V. Find the difference from input and square it.
     q*q/100&&                        #If the difference is 1/10 of the outlet rating or less... (NB. q/10 must be squared to compare with the above) 
       g*4<=(t=z/10%14)%8&&           #Extract the outlet type (minus 1.) Grounded outlets have t%8 greater or equal to 4. If grounding acceptable....
         a<=(c=z%10*5+15)&&           #Decode the current rating. If acceptable...
           (p [t+1,c])}               #Print the outlet spec: type and current rating.
}

I decided to order by voltage rating as there are only 4 possible values, hence only 3 steps in voltage, only 2 of which result in nonprintable characters in the magic string.

Realising that subtracting 1 from the outlet type and taking modulo 8 always gives a number of 4 or greater for grounded outlets and never for ungrounded ones was handy as I didn't have to compress this.

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

JavaScript (Node.js), 310 294 bytes

(x,y,z)=>[...'demu`hpaiqybjrzu}mu}oaqyY'].map((x,i)=>[[120,240,277,480][(s=x.charCodeAt())%4],h=[12,3,4,6,10][(s-s%8)/8-11]*5,(s-s%4)/4%2,[[...'11000300100010003010012000'].map(x=>+x).slice(0,i+2).reduce((a,b)=>a+b),h]]).filter(m=>9*m[0]/10<=x&&11*m[0]/10>=x&&y<=m[1]&&(z?!m[2]:1)).map(x=>x[3])

[Try it online!

Arnauld beat me to this, and did it better, but I put two hours of work into this...

The string compression is interesting. Above, each character in

demu`hpaiqybjrzu}mu}oaqyY
is the binary data for:


d
To char code is 100
To binary is 1100100

1 - just on the start
100 - Represents current 15 - 100 => 15, 101 => 20, 110 => 30, 111 => 50, 011 => 60
1 - No ground (0 for ground)
00 - Voltage 120 - 00 => 120, 01 => 240, 10 => 277, 11 => 480.

And in this way each outlet is encoded into a single character.

Explanation

(x,y,z)=>                                        // declare function
[...'demu`hpaiqybjrzu}mu}oaqyY']                 // see above on compression
.map((x,i)=>                                     //map by item / index
[                                                //return array of:
[120,240,277,480]                                // possible voltages
[(s=x.charCodeAt())%4],                          //decipher from string & get correct value
h=                                               //save following for use in name
[12,3,4,6,10]                                    //possible current values, 
[(s-s%8)/8-8]*5,                                 //get correct one from decoded string item and multiply by 5
(s-s%4)/4%2,                                     // get ground boolean
[[...'11000300100010003010012000']               // change in first part of string each time - sum of first m will be first part of name m
.map(x=>+x)                                      // to array of numbers
.slice(0,i+2).reduce((a,b)=>a+b)                 //sum of first [index]
,h]                                              // + '-' + h, the current value we saved earlier, produces name
])
//This is where all the magic happens, up to here is just data compression
.filter(m=>                                      //filter m by if all are true:
9*m[0]/10<=x                                     //9/10 of m[0] (voltage) is less than given voltage
&&11*m[0]/10>=x                                  // 11/10 of m[0] (voltage) is greater than given voltage (so voltage is within 10%)
&&y<=m[1]                                        // given current is less than or equal to m[1] (current)
&&(z?                                            //if breaker required
!m[2]                                            //check if breaker
:1)                                              //else always true
).map(x=>x[3])                                   // convert to list of names
\$\endgroup\$
2
\$\begingroup\$

Excel, 220 bytes

135 bytes for this formula.

=LET(f,B1:J1*B2:J6,r,A2:A6,v,XLOOKUP(f,L1:L4,M1:M4,240),TEXTJOIN(",",,IF((ABS(A8-v)<=v/10)*(B8<=r)*((MOD(f,10)>3)+1-C8)*f,f&"-"&r,"")))

68 bytes for this array of cells that shows the valid pairs of numbers before and after the dash.

    1   2   5   6   7   10  11  12  14
15  1   1   1   1   1   0   0   0   0
20  0   1   1   1   1   0   1   1   1
30  0   1   1   1   1   1   1   0   1
50  0   0   0   1   1   1   1   0   1
60  0   0   0   0   0   0   0   0   1

17 byte for this array of cells that maps the numbers before the dash to voltages other than 240.

 1 120
 5 120
 7 277
12 480
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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