19
\$\begingroup\$

Chameleon challenges are a bad thing, apparently. Too bad, chameleons are beautiful creatures. Time for a change!

Picture of a chameleon

As we all know, many chameleons posses a remarkable ability to blend in with their surroundings by changing the color of their skin. Which is also the objective of this challenge.

Challenge

Imagine a square of nine pixels. Eight pixels are the surroundings. At the center is the chameleon.

Like this: Eight gray squares around a center square.

The chameleon naturally tries to blend in with its surroundings. It does so by changing its color to the average of that of the surrounding pixels. So, in this case, the chameleon would change its color to gray.

Objective

Given the colors of the surrounding pixels, output the color of the chameleon.

The color of the chameleon is defined as the total of all red, green and blue in the pixels ÷ 8.

Input

An array of color values for the eight surrounding pixels, starting at the top left and continuing clockwise, like this:

[[<red>,<green>,<blue>],[<red>,<green>,<blue>],[<red>,<green>,<blue>],[<red>,<green>,<blue>],[<red>,<green>,<blue>],[<red>,<green>,<blue>],[<red>,<green>,<blue>],[<red>,<green>,<blue>]]

You may choose to receive input in a different form, as long as it consists of eight triples of decimal numbers 0-255.

If you receive input in a different form, numbers must either be of a consistent length or have a non-numeric separator between them. Triples must have a separating character unless they are 0-padded to 9 digits. (E.g. 044200255044200255044200255044200255044200255044200255044200255044200255 is valid, so are 44 200 255 44 200 255 44 200 255 44 200 255 44 200 255 44 200 255 44 200 255 44 200 255 and 44?200?255$44?200?255$44?200?255$44?200?255$44?200?255$44?200?255$44?200?255$44?200?255, but 4420025544200255442002554420025544200255442002554420025544200255 is not.)

Output

An array / string / etc. containing the colors of the center pixel (in decimal), like this:

[<red>,<green>,<blue>]

In case you output something other than an array: Numbers must either be of a consistent length or have a non-numeric separator between them. (E.g. 044200255 is valid, so is 44 200 255, but 44200255 is not.)

The numbers may not contain decimal points, so e.g. 44.0 200 255.0 is invalid.

Rounding

Output must be rounded to the nearest integer. (Halves must be rounded up.) E.g., if the sum of all red is 1620, you must output 203, not 202 or 202.5.

Examples

Pictures are for illustration only. The middle pixel is the output, the surrounding pixels are the input.

Input:

[[200,200,200],[200,200,200],[200,200,200],[200,200,200],[200,200,200],[200,200,200],[200,200,200],[200,200,200]]

Output:

[200,200,200]


Input:

[[0,0,0],[255,255,255],[0,0,0],[255,255,255],[255,255,255],[0,0,0],[255,255,255],[0,0,0]]

Output:

[128,128,128]


Input:

[[0,200,200],[200,0,200],[200,200,0],[60,200,0],[200,0,200],[0,200,220],[2,200,0],[0,0,0]]

Output:

[83,125,103]


Input:

[[0,56,58],[65,0,200],[33,200,0],[60,33,0],[98,0,200],[0,28,220],[2,200,0],[99,0,5]]

Output:

[45,65,85]

Submissions can be a full program or a function. Standard I/O and loophole rules apply.

\$\endgroup\$
  • 13
    \$\begingroup\$ The average of colors ain't the average of their RGB values. \$\endgroup\$ – Leaky Nun Jul 8 '16 at 19:24
  • \$\begingroup\$ @LeakyNun Thanks for the link. It won't really matter for this challenge, but I'll keep it in mind should I do a something similar in the future. \$\endgroup\$ – user2428118 Jul 8 '16 at 19:29
  • 9
    \$\begingroup\$ Funnily enough, I think this is a bit of a chameleon question for handling rounding. \$\endgroup\$ – xnor Jul 8 '16 at 19:43
  • \$\begingroup\$ "as long as it consists of eight triples of decimal numbers 0-255" Can it be in binary? Unary? \$\endgroup\$ – Leaky Nun Jul 8 '16 at 19:48
  • \$\begingroup\$ Also, can I transpose it beforehand? \$\endgroup\$ – Leaky Nun Jul 8 '16 at 19:48

13 Answers 13

8
\$\begingroup\$

MATL, 8 4 bytes

YmYo

Try it online!

4 bytes saved thanks to beaker!

Explanation:

Ym          "Get the average of each column
  Yo        "And round up
\$\endgroup\$
  • \$\begingroup\$ I like the abuse of the python array syntax! You can replace s8/ with Xm (i.e mean down the columns). Also you may be able to specify input as 3 x 8 to begin with and get rid of the 3e! \$\endgroup\$ – Suever Jul 8 '16 at 22:04
  • \$\begingroup\$ Yeah, YmYo should do it... just take the input as [[R,G,B];[R,G,B];...] with semicolons between the RGB rows. \$\endgroup\$ – beaker Jul 8 '16 at 23:01
  • \$\begingroup\$ @beaker Woah! Thanks! \$\endgroup\$ – DJMcMayhem Jul 8 '16 at 23:04
  • \$\begingroup\$ does Yo round up, or round to closest with ties being rounded up? The challenge wants the latter. \$\endgroup\$ – John Dvorak Jul 9 '16 at 8:55
  • \$\begingroup\$ @JanDvorak It rounds to the nearest integer (up or down) matl.tryitonline.net/… \$\endgroup\$ – Suever Jul 9 '16 at 13:26
11
\$\begingroup\$

Python, 38 bytes

lambda l:[sum(r)+4>>3for r in zip(*l)]

Rounds the average (towards the nearest integer, with halves rounding up) by adding 4 to the sum, then floor-dividing by 8 via the bit-shift >>3.

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

Jelly, 5 bytes

S+4:8

Test suite. (Slightly modified so as to verify all testcases at once.)

S+4:8
S      sum (vectorized)
 +4    add 4
   :8  floor division by 8
\$\endgroup\$
4
\$\begingroup\$

C, 151 123 103 91

Requires 24 parameters passed to the program, in the order R G B R G B ... and outputs the triplet R G B without a newline.

i,t;main(c,v)char**v;{for(i=0;t=4,i++<3;printf("%d ",t/8))for(c=i;c<24;c+=3)t+=atoi(v[c]);}
\$\endgroup\$
  • \$\begingroup\$ main(c,v)char**v;{ to save 2 bytes? Also +1 for <3 in source code! \$\endgroup\$ – betseg Jul 27 '16 at 13:38
1
\$\begingroup\$

Pyth, 8 bytes

m.R.Od0C

Test suite.

m.R.Od0C     input: Q
m.R.Od0CQ    implicit arguments
        Q    input
       C     transpose
m    d       for each:
   .O            take average
 .R   0          round off
\$\endgroup\$
1
\$\begingroup\$

Pyke, 7 bytes

,FsOO8f

Try it here!

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

J, 11 bytes

0.5<.@++/%#

Takes the input as an 8x3 array where each row is an RGB value

Explanation

0.5<.@++/%#  Input: a
          #  Count the number of rows
       +/    Sum along the columns
         %   Divide each sum by the count to get the averages
0.5   +      Add 0.5 to each average
   <.@       Floor each value and return
\$\endgroup\$
1
\$\begingroup\$

JavaScript, 75 64 55 bytes

a=>a.reduce((p,c)=>p.map((e,i)=>e+c[i])).map(x=>x+4>>3)

A JavaScript answer to get you started.

Edit: Saved 11 bytes thanks to Dendrobium, and another 9 thanks to Neil.

\$\endgroup\$
  • \$\begingroup\$ 55 bytes: a=>a.reduce((p,c)=>p.map((e,i)=>e+c[i])).map(x=>x+7>>3) \$\endgroup\$ – Dendrobium Jul 8 '16 at 20:06
  • \$\begingroup\$ @Dendrobium [[0,200,200],[200,0,200],[200,200,0],[60,200,0],[200,0,200],[0,200,220],[2,200,0],[0,0,7]] yields 83, 125, *104* instead of 83, 125, *103* with your code. \$\endgroup\$ – user2428118 Jul 8 '16 at 20:24
  • \$\begingroup\$ Ah, misread the question, thought it was supposed to ceil. 64 bytes: a=>a.reduce((p,c)=>p.map((e,i)=>e+c[i])).map(x=>(x/8).toFixed()) \$\endgroup\$ – Dendrobium Jul 8 '16 at 20:51
  • \$\begingroup\$ x+4>>3 should round correctly. \$\endgroup\$ – Neil Jul 8 '16 at 21:08
1
\$\begingroup\$

Lisp - 180 179 bytes

EDIT: Formatted for further golfing.

(defun a(l)(/(apply #'+ l)(length l)))(defun r(a)(if(integerp(* a 2))(ceiling a)(round a)))(defun c(s)(mapcar(lambda(i)(r(sqrt(a(mapcar(lambda(x)(expt(nth i x)2))s)))))'(0 1 2)))

Does it the correct way, I guess. Untested.

  • a is just average
  • r is this challenge's proper rounding, since Lisp round rounds to the nearest even integer
  • c does the real work, taking in input in the format '((R G B) (R G B) (R G B) (R G B) (R G B) (R G B) (R G B) (R G B)), and returning a '(R G B) list containg the answer.
\$\endgroup\$
1
\$\begingroup\$

Nim, 134 126 115 108 78 bytes

import math,future
x=>lc[(lc[x[j][i]|(j<-0..7),int].sum+4)shr 3|(i<-0..2),int]

Defines an anonymous procedure, which requires the input passed in as a double-nested sequence and outputs as a 3-element array. The procedure can only be used as an argument to another procedure; to test, use the following wrapper:

import math,future
import strutils
proc test(x: seq[seq[int]] -> seq[int]) =
 echo x(#[ Insert your input here ]#)
test(x=>lc[(lc[x[j][i]|(j<-0..7),int].sum+4)shr 3|(i<-0..2),int])

A Nim sequence is an array with @ in front, like @[1, 2, 3]. An input to this procedure could therefore be:

@[@[0,0,0],@[255,255,255],@[0,0,0],@[255,255,255],@[255,255,255],@[0,0,0],@[255,255,255],@[0,0,0]]
\$\endgroup\$
1
\$\begingroup\$

Japt, 8 bytes

yx ®/8 r

Try it

Alternative, 9 bytes

3Æxv /8 r

Try it

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

Forth (gforth), 65 bytes

: f 3. do 8. do 3 j - i * 2 + roll loop 4 8. do + loop 8 / loop ;

Try it online!

Takes input as stack arguments (r g b order)

Explanation

For each of the 3 color channels:

  • move all the numbers of that channel to the top of the stack
  • add them together
  • add 4 (to handle rounding)
  • divide by 8

Code Explanation

: f            \ start new word definition
  3. do        \ start a counted loop from 0 to 2
    8. do      \ start a counted loop from 0 to 7
      3 j -    \ get the offset of the channel
      i * 2 +  \ get the absolute position of the channel value
      roll     \ move the value to the top of the stack
    loop       \ end the inner loop
    4          \ add 4 to the top of the stack
    8. do      \ loop from 0 to 7
      +        \ add the top two stack numbers
    loop       \ end loop. (Result on top of stack with be sum of values for channel + 4)
    8 /        \ divide by 8
  loop         \ end outer loop
;              \ end word definition
\$\endgroup\$
1
\$\begingroup\$

Runic Enchantments, 41 bytes

>iRi+ i+ i+ i+ i+ i+ i+8,'rA' q$;
>iU
>iU

Try it online!

Utilizes 3 instruction pointers to parse the input in the correct order (as the input values are always in the order RGB, RGB,...) and as long as each of the three IPs don't merge, and don't advance to the next read input command too early (hence all the spaces), it works out and saves bytes over having to continuously rotate the stack to keep the correct value on top in order to calculate the sums.

Technically this code contains an error in correctly rounding x.5 values for some inputs, but this is due to the default rounding method used by C#, which is to round to the nearest event number, rather than upwards and is due to issues in floating point accuracy loss, and I was unaware of this issue prior to writing this answer and checking the test cases. This will be fixed in a future build, along with a few other things such as this unhandled exception.

In the meantime, this modification makes the necessary adjustment.

\$\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.