141
\$\begingroup\$

Write a program or function that takes in a positive integer N, and outputs an N×N pixel image of Google's "G" logo according to this* construction:

"G" logo construction

For example, if N is 400, a 400×400 pixel logo should be output, with correct dimensions and colors:

"G" logo 400x400 example

It should look accurate regardless of how large or small N is. e.g. here is N = 13: "G" logo 13x13 example

Your code should not need to connect to the internet. For example, scaling an externally hosted svg is not allowed. (Scaling an svg encoded in your code would be fine though.)

Anti-aliasing may be used or not. It's up to you.

Notice that the horizontal bar of the "G" does not extend all the way to the right edge of the image. The circle curves normally inward on the right edge before it is cut off.

The shortest code in bytes wins.


* The construction of the logo has been simplified for this challenge. The correct construction can be seen here and here.

\$\endgroup\$
6
  • 1
    \$\begingroup\$ Is there a minimum N? A 1x1 image would likely produce unrecognizable output regardless of how good the solution is. \$\endgroup\$
    – jpmc26
    Oct 14, 2016 at 22:27
  • \$\begingroup\$ @jpmc26 N is a positive integer, so minimum 1. Of course a 1x1 image can't be recognizable, but "It should look accurate" meaning, e.g. a black image wouldn't make sense, even at that scale. \$\endgroup\$ Oct 14, 2016 at 22:43
  • 4
    \$\begingroup\$ What's the expected output for a 1x1 image, then? A single pixel of any of the colors in the image? A white image? What about 2x2? There are still more colors in the image than pixels for that size. If any image is unacceptable at those scales, the challenge should define what is and is not acceptable, since you cannot produce an image even coming close to the correct appearance, shouldn't it? (If it were my challenge, I'd exclude them to keep it simple, but your decision. You would also need to verify that you don't exclude existing answers with the new specifications, I think.) \$\endgroup\$
    – jpmc26
    Oct 14, 2016 at 22:51
  • \$\begingroup\$ @jpmc26 No. People can use common sense to tell if a 1x1 or other small image looks accurate. \$\endgroup\$ Oct 14, 2016 at 22:57
  • 1
    \$\begingroup\$ Are we permitted to download a pre-made .svg and encode it into our solution, or do we have to originally make it? \$\endgroup\$
    – Joseph
    May 11, 2018 at 23:19

27 Answers 27

58
\$\begingroup\$

Mathematica, 229 226 225 224 221 206 169 bytes

Thanks @MartinEnder for 1 byte, @ChipHurst for 37 bytes!

Graphics[{RGBColor@{"#EA4335","#FBBC05","#34A853","#4285F4"}[[#]],{0,-1}~Cuboid~{√24,1},Annulus[0{,},{3,5},{(2#-9)Pi/4,ArcCsc@5}]}&~Array~4,ImageSize->#,PlotRange->5]&

What a fun challenge!

Explanation

...&~Array~4

Iterate from 1 to 4...

RGBColor@{"#EA4335","#FBBC05","#34A853","#4285F4"}[[#]]

Convert the color hex codes to RGBColor objects, so that they can be applied to the Google logo graphic. Change the color palette to the <input>th color.

{0,-1}~Cuboid~{√24,1}

Create a filled rectangle (2D cuboid), whose diagonal corners are (0, -1) and (sqrt(24), 1).

Annulus[0{,},{3,5},{(2#-9)Pi/4,ArcCsc@5}]}

Generate four filled quarter-Annuluss, centered at the origin, with inner radius 3 and outer radius 5. Do not draw past ArcCsc@5 (where the blue segment ends).

Graphics[ ... , ImageSize->#,PlotRange->5]

Create a graphic with size N x N, from x = -5 to x = 5 (removes the padding).

Outputs

N = 10

enter image description here

N = 100

enter image description here

N = 200

enter image description here

N = 10000 (click image for full resolution)

enter image description here

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

C (Windows), 311 bytes

#include <windows.h>
main(int c,char**v){float x,y,a,b,N=atoi(*++v);HDC d=GetDC(GetDesktopWindow());for(x=0;x<N;x+=1)for(y=0;y<N;y+=1){a=2*x/N-1;b=2*y/N-1;SetPixel(d,x,y,(a>0&&a<.8&&b*b<.04)?0xF48542:(a*a+b*b>1||a*a+b*b<.36)?0xFFFFFF:(a*a<b*b)?((b<0)?3490794:5482548):(a<0)?376059:(b<-.2)?0xFFFFFF:0xF48542);}}

Takes "N" as command line argument and draws directly on the screen.

Un-golfed:

#include <windows.h>
// atoi() will work fine without any #include file!
// -> don't #include it!

main(int c,char **v)
{
    float x,y,a,b,N=atoi(*++v);

    /* Access the screen for directly drawing! */
    HDC d=GetDC(GetDesktopWindow());

    /* Iterate over the pixels */
    for(x=0;x<N;x+=1)
        for(y=0;y<N;y+=1)
    {
        /* Convert x,y into "relative" coordinates: The image
         * is 2.0x2.0 in size with (0.0,0.0) in the center */
        a=2*x/N-1;
        b=2*y/N-1;

        /* Draw each pixel */
        SetPixel(d,x,y,
            (a>0 && a<.8 && b*b<.04)?0xF48542: /* The bar of the "G" in the middle */
            (a*a+b*b>1 || a*a+b*b<.36)?0xFFFFFF: /* Not on one of the circle segments */
            (a*a<b*b)?((b<0)?0x3543EA:0x53A834): /* Top and bottom segments */
            (a<0)?0x5BCFB: /* Left segment */
            (b<-.2)?0xFFFFFF:0xF48542); /* Right segment: A bit more complicated... */
    }

    /* Note: Under good old Windows 3.x we would require to
     * call "ReleaseDC" here; otherwise the system would
     * "crash" (however the image would have been drawn!)
     * No need for this in modern Windows versions! */
}
\$\endgroup\$
15
  • \$\begingroup\$ You could keep 0xF48542 and 0xFFFFFF in integers. \$\endgroup\$
    – Yytsi
    Oct 12, 2016 at 13:47
  • \$\begingroup\$ What compiler/linker did you use? Doesn't work with mingw \$\endgroup\$
    – vsz
    Oct 12, 2016 at 13:53
  • \$\begingroup\$ @vsz Presumably, Visual Studio's compiler. \$\endgroup\$
    – Kroltan
    Oct 12, 2016 at 17:04
  • \$\begingroup\$ @vsz I can compile it with gcc g.c -lgdi32 on mingw. \$\endgroup\$
    – jingyu9575
    Oct 13, 2016 at 2:17
  • 2
    \$\begingroup\$ -1>>8 may also work \$\endgroup\$ Oct 16, 2016 at 16:08
35
\$\begingroup\$

Python 2, 244 220 bytes

using Martin Rosenau's transformation on the [-1,1]^2 plane and minor golfing like removing 0. or brackets

N=input()
R=[2*z/(N-1.)-1for z in range(N)]
B="\xFF"*3,"B\x85\xF4"
print"P6 %d %d 255 "%(N,N)+"".join([B[0<x<.8and.04>y*y],["4\xA8S",B[y>-.2],"\xFB\xBC\x05","\xEAC5"][(x>y)+2*(-x>y)]][.36<x*x+y*y<1]for y in R for x in R)

Explanation:

N=input()
R=[2*z/(N-1.)-1for z in range(N)]
#N*N points on the [-1,1]^2 plane

B="\xFF"*3,"B\x85\xF4"
#white and blue

print"P6 %d %d 255 "%(N,N) + "".join(
#binary PPM header
 [
  B[0<x<.8and.04>y*y],
  #blue rectangle part of the G, or white
  ["4\xA8S",B[y>-.2],"\xFB\xBC\x05","\xEAC5"][(x>y)+2*(-x>y)]
  #[green, [white,blue], yellow, red]-arcs with 4 way selector
 ]
 [.36<x*x+y*y<1]
 #radius checker, outside=0 blue rectangle or white, inside=1 colored arcs
  for y in R for x in R
  #for all points
 )

Output as binary PPM, usage:

python golf_google.py > google.ppm

Examples

  • 13

13

  • 50

50

  • 100

100

  • 1337

1337

previous 244 bytes solution

N=input()
S="P6 %d %d 255 "%(N,N)
R=range(N)
B=["\xFF"*3,"B\x85\xF4"]
for Y in R:
 for X in R:y=Y-N/2;x=X-N/2;S+=[B[0<x<0.4*N and abs(y)<0.1*N],["4\xA8S",B[y>-0.1*N],"\xFB\xBC\x05","\xEAC5"][(x>y)+2*(-x>y)]][0.3*N<(y**2+x**2)**.5<0.5*N]
print S

Ungolfed beta Version before if/else elimination:

N=input()
print"P3 %d %d 255 "%(N,N)
R=range
M=N/2
r="255 0 0 "
g="0 255 0 "
b="0 0 255 "
c="255 255 0 "
w="255 255 255 "
for Y in R(N):
 for X in R(N):
  y=Y-M
  x=X-M
  d=(y**2+x**2)**.5 #radius
  if 0.3*N<d<0.5*N: #inside circle
   if x>y:          #diagonal cut bottom-left to top right
    if -x>y:        #other diagonal cut
     print r
    else:
     if y>-0.1*N:print b #leave some whitespace at blue
     else: print w
   else:
     if -x>y:
      print c
     else:
      print g
  else:
   if 0<x<0.4*N and -0.1*N<y<0.1*N: #the straight part of G
    print b
   else:
    print w
\$\endgroup\$
9
  • \$\begingroup\$ Hmm, not sure if 1for works. \$\endgroup\$
    – Yytsi
    Oct 12, 2016 at 14:12
  • 1
    \$\begingroup\$ @TuukkaX It does. \$\endgroup\$
    – mbomb007
    Oct 12, 2016 at 14:31
  • \$\begingroup\$ Can you include sample output? \$\endgroup\$
    – Cyoce
    Oct 12, 2016 at 20:35
  • \$\begingroup\$ @TuukkaX thanks for the 1for @Cyoce sample output added \$\endgroup\$
    – Karl Napf
    Oct 12, 2016 at 22:33
  • \$\begingroup\$ All the decimals in your code that are in the form of 0.x can be reduced to .x :) \$\endgroup\$
    – Yytsi
    Oct 13, 2016 at 8:33
27
\$\begingroup\$

JavaScript (ES6), 408 ... 321 317 bytes

384 383 371 367 359 327 316 308 304 bytes of JavaScript + 24 13 bytes for the canvas element

(f=d.style).width=f.height=(d.width=d.height=n=prompt(f.background='#FFF'))+'px';q=n/2;with(d.getContext`2d`)['#EA4335','#FBBC05','#34A853','#4285F4'].map((c,i)=>beginPath(lineWidth=y=n/5,strokeStyle=fillStyle=c,arc(q,q,z=q-y/2,(j=2*i+1)*(r=-.7854),(j+(i-3?2:1.256))*r,1),stroke(),fillRect(q,z,q*.98,y)))
<canvas id=d>

1 byte saved by drawing counter-clockwise.
11 bytes saved on the HTML thanks to Conor O'Brien.
12 bytes saved using with block thanks to Prinzhorn.
4 bytes saved with better use of z=q-y/2.
8 bytes saved by using parentNode and background thanks to Alexis Tyler.
32 bytes saved by using a more precise drawing of the blue arc/bar so I don't need to erase a part of it anymore.
11 bytes saved by setting canvas css instead of its parentNode thanks to Tejas Kale.
8 bytes saved using with and map with a single statement, `2d` instead of ('2d'), n/5 instead of .2*n and initializing the background in the prompt(...).
4 bytes saved replacing Math.PI/4 by .7854 which seems enough precision thanks to RobAu.


Explanation:

(f=d.style).width=f.height=(d.width=d.height=n=prompt(f.background='#FFF'))+'px';q=n/2 

The canvas dimensions are initilized with user input and the background is set to white. q is initialized.

with(d.getContext`2d`)['#EA4335','#FBBC05','#34A853','#4285F4'].map((c,i)=>beginPath(lineWidth=y=n/5,strokeStyle=fillStyle=c,arc(q,q,z=q-y/2,(j=2*i+1)*(r=-.7854),(j+(i-3?2:1.256))*r,1),stroke(),fillRect(q,z,q*.98,y)))

For each color draws the circle part, with some adjustement for the last (blue) one. The bar is drawn for each color at the same place with the same dimensions so only the last (blue) one is visible.

\$\endgroup\$
11
  • 2
    \$\begingroup\$ <canvas id=d></canvas> should work, and <canvas id=d> might work. \$\endgroup\$ Oct 12, 2016 at 15:32
  • 1
    \$\begingroup\$ You can lose another 5 chars by replacing backgroundColor with background. \$\endgroup\$ Oct 15, 2016 at 2:39
  • 1
    \$\begingroup\$ Also use d.parentNode instead of d.parentElement \$\endgroup\$ Oct 15, 2016 at 2:41
  • 1
    \$\begingroup\$ Why are you setting the parentNode dimensions. Just d.style works too. Which allows (f = d.style).width = f.height = n = prompt() + 'px'; \$\endgroup\$
    – Tejas Kale
    Oct 16, 2016 at 17:42
  • 1
    \$\begingroup\$ You could use .785398 instead of Math.PI/4 shaving off 2 bytes (or more if less precision is ok. \$\endgroup\$ Oct 17, 2016 at 6:56
25
\$\begingroup\$

BBC BASIC, 177 bytes

Download interpreter at http://www.bbcbasic.co.uk/bbcwin/download.html

I.n
V.19;16,234,67,53,275;64272;1468;531;16,43060;83,787;16,34114;7668;n;n;
F.t=1TO8.256S.1/n
a=t*PI/4y=n*SIN(a)x=n*COS(a)V.18;t-1>>1,25,85,x*.6;y*.6;25,85,x;y;
N.PLOT101,0,-n/5

BBC BASIC uses 2 units=1 pixel, so we plot a G of radius n units (=n/2 pixels) at centre n,n.

The idea is to plot a series of radial lines, changing colour as appropriate. It was found that there were small gaps between the lines due to truncation of the numbers when converted to pixels, so thin triangles are actually plotted instead.

Once the sweep of lines is completed, the cursor is at the top right corner of the blue area. A single coordinate for the diagonally opposite corner is given to draw a rectangle in order to complete the shape.

Ungolfed

INPUTn
REM reprogram pallette
VDU19;16,&EA,&43,&35,275;16,&FB,&BC,5,531;16,&34,&A8,&53,787;16,&42,&85,&F4
ORIGINn,n               :REM move origin to position n,n on screen.
FORt=1TO8.256STEP1/n    :REM from 1/8 turn to 8.56 turns in small steps
  GCOL0,t-1>>1          :REM set the colours, 0=red, 1=yellow, 2=green, 3=blue
  a=t*PI/4              :REM convert angle from 1/8 turns into radians
  y=n*SIN(a)            :REM find position of outer end of ray
  x=n*COS(a)            :REM plot to coordinates of inner and outer ends of ray
  PLOT85,x*.6,y*.6      :REM PLOT85 actually draws a triangle between the specified point              
  PLOT85,x,y            :REM and the last two points visited.
NEXT                    
PLOT101,0,-n/5          :REM once all is over, cursor is at top right corner of blue rectangle. Draw a rectangle to the bottom left corner as specified.
\$\endgroup\$
1
  • \$\begingroup\$ Nice work! I did mine in Logo using a similar method before I saw your answer. You have me beaten by about 81 bytes. \$\endgroup\$ Oct 16, 2016 at 7:13
21
\$\begingroup\$

HTML/JS, 680 624 bytes

To get 624 bytes, remove the last ;, this is needed for the snippet below due to the way it imports the HTML. Also, Firefox seems to not support image-rendering: pixelated and needs -moz-crisp-edges instead (thanks @alldayremix!) which makes a Firefox solution +7 but this does work in Chrome as expected.

Utilises JavaScript to request N and a <style> block to position/colour the elements. Uses basic HTML elements, rather than applying styles to a canvas (which, it appears, was a much shorter approach!). This is a revamped approach using a data: URI background image instead of just coloured elements. I've kept the previous approach below in case this new one works on fewer browsers.

I thought this was going to be a lot smaller than it ended up being, but it was an interesting exercise nonetheless!

<body id=x onload=x.style.fontSize=prompt()+'px'><u><a></a><b></b><i></i><s><style>u,a,b,i,s{position:relative;display:block}b,i,s{position:absolute}a,u{width:1em;height:1em}a,b{border-radius:50%}a{image-rendering:pixelated;background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAIAAAACCAIAAAD91JpzAAAAFklEQVQI12N45Wzq1PqF4fceVpMVwQAsHQYJ1N3MAQAAAABJRU5ErkJggg)no-repeat;background-size:100%;transform:rotate(45deg)}b{top:.2em;left:.2em;width:.6em;height:.6em;background:#fff}i{border-top:.4em solid transparent;border-right:.4em solid#fff;top:0;right:0}s{top:.4em;right:.1em;width:.4em;height:.2em;background:#4285f4;

Previous version:

<body id=x onload=x.style.fontSize=prompt()+'px'><a b><b l style=padding-left:.5em></b><b y></b><b g></b></a><i style=height:.4em></i><i style="background:#ea4335;border-radius:0 1em 0 0;transform-origin:0%100%;transform:rotate(-45deg)"></i><i b z style=top:.2em;left:.2em;width:.6em;height:.6em></i><i l z style="top:.4em;height:.2em;border-radius:0 2%10%0/0 50%50%0;width:.4em"><style>*{position:relative;background:#fff}a,b,i{display:block;float:left;width:.5em;height:.5em}a{height:1em;width:1em;transform:rotate(45deg);overflow:hidden}i{position:absolute;top:0;left:.5em}[b]{border-radius:50%}[g]{background:#34a853}[l]{background:#4285f4}[y]{background:#fbbc05}[z]{z-index:1

\$\endgroup\$
4
  • 1
    \$\begingroup\$ Traitor! (just kidding, nice one ;-) ) \$\endgroup\$
    – Dada
    Oct 12, 2016 at 20:36
  • \$\begingroup\$ On my browser the old version shows slight gaps between colors, and the new version gives a gradient transition between colors (Firefox 49.0.1 32-bit on Win10 x64) \$\endgroup\$ Oct 14, 2016 at 15:59
  • 1
    \$\begingroup\$ @alldayremix hmmm, looks like Firefox needs to have image-rendering: -moz-crisp-edges instead of pixelated. Will add a note to that effect. I quite like the gradient style! :) \$\endgroup\$ Oct 14, 2016 at 18:16
  • \$\begingroup\$ I've modified the header to read "HTML/JS", since you use both HTML and Javascript. \$\endgroup\$
    – user45941
    Oct 19, 2016 at 6:52
20
\$\begingroup\$

Bash with Imagemagick (but really Postscript), 268 255 249 bytes

C=' setrgbcolor 2.5 2.5 2'
A=' arc stroke '
echo "%!PS
122.4 dup scale
.92 .26 .21$C 45 136$A.98 .74 .02$C 135 226$A.20 .66 .33$C 225 316$A.26 .52 .96$C 315 371$A
4.95 2.5 moveto
2.5 2.5 lineto
stroke"|convert - -crop 612x612+0+180 -scale "$1" o.png

Doubled the scaling to remove setlinewidth, replaced one scale factor with dup, and merged a space into the A variable (can't with C because $C45 is parsed as "the variable C45").

Thanks to joojaa for suggesting these edits!

Old Scale, 255 bytes

C=' setrgbcolor 5 5 4'
A=' arc stroke'
echo "%!PS
61.2 61.2 scale
2 setlinewidth
.92 .26 .21$C 45 136$A
.98 .74 .02$C 135 226$A
.20 .66 .33$C 225 316$A
.26 .52 .96$C 315 371$A
9.9 5 moveto
5 5 lineto
stroke"|convert - -crop 612x612+0+180 -scale "$1" o.png

Takes N as the lone argument and outputs to o.png.

Ungolfed Postscript for Old Scale

%!PS
% Scale so default page has width of 10
61.2 61.2 scale
2 setlinewidth
% Red arc
.92 .26 .21 setrgbcolor
5 5 4 45 136 arc
stroke
% Yellow arc
.98 .74 .02 setrgbcolor
5 5 4 135 226 arc
stroke
% Green arc
.20 .66 .33 setrgbcolor
5 5 4 225 316 arc
stroke
% Blue arc
.26 .52 .96 setrgbcolor
5 5 4 315 371 arc
% Blue in-tick
9.9 5 moveto
5 5 lineto
stroke
\$\endgroup\$
1
  • 2
    \$\begingroup\$ You can make this shorter by shaving off one char from scale line 61.2 dup scale you can also add a space in C like C=' setrgbcolor 5 5 4 ' and shave 4 spaces. If you designed this at half scale then you could omit 2 setlinewidth \$\endgroup\$
    – joojaa
    Oct 17, 2016 at 11:17
19
\$\begingroup\$

MATLAB, 189 184 bytes

[X,Y]=meshgrid(-5:10/(input("")-1):5);[A,R]=cart2pol(-X,Y);I=round(A*2/pi+3);I(R<3)=1;I(X>0&Y.^2<1)=5;I(R>5)=1;image(I)
colormap([1,1,1;[234,67,53;251,188,5;52,168,83;66,133,244]/255])

ungolfed

[X,Y]=meshgrid(-5:10/(input("")-1):5);    % coordinates in 10th of image width
[A,R]=cart2pol(-X,Y);                     % angle and radius
I=round(A*2/pi+3); % map [0-45,45-135,135-225,225-315,315-360] to [1,2,3,4,5]
I(R<3)=1;                                 % clear inner pixels
I(X>0&Y.^2<1)=5;                          % draw horizontal line
I(R>5)=1;                                 % clear outer pixels
image(I)
colormap([1,1,1;[234,67,53;251,188,5;52,168,83;66,133,244]/255])
\$\endgroup\$
19
\$\begingroup\$

Perl 5, 486 477 476 450 (+7 for -MImager flag) = 457 bytes

I saved a few bytes thanks to Dada by using functional new calls and getting rid of parens, and by using pop instead of $ARGV[0] as well as the final semicolon. I saved some more by putting that $n=pop where it's first used, and by using Perl 4 namespace notation with ' instead of ::.

$i=new Imager xsize=>$n=pop,ysize=>$n;$h=$n/2;$s=$n*.6;$f=$n*.4;$c='color';($b,$r,$y,$g,$w)=map{new Imager'Color"#$_"}qw(4285f4 ea4335 fbbc05 34a853 fff);$i->box(filled=>1,$c,$w);$i->arc($c,$$_[0],r=>$h,d1=>$$_[1],d2=>$$_[2])for[$b,315,45],[$r,225,315],[$y,135,225],[$g,45,135];$i->circle($c,$w,r=>$n*.3,filled=>1);$i->box($c,$b,ymin=>$f,ymax=>$s,xmin=>$h,xmax=>$n*.9,filled=>1);$i->polygon($c,$w,x=>[$n,$n,$s],y=>[0,$f,$f]);$i->write(file=>'g.png')

It requires the module Imager, which needs to be installed from CPAN. Takes one integer as a command line argument. The image is not anti-aliased, so it's a bit ugly.

Copy the below code into a file g.pl. We need an additional +7 bytes for the -MImager flag, but it saves a few bytes because we don't need to use Imager;.

$ perl -MImager g.pl 200

Here are various sizes:

N=10

10px

N=100

100px

N=200

200px

The completely ungolfed code is straight-forward.

use Imager;
my $n = $ARGV[0];
my $i = Imager->new( xsize => $n, ysize => $n );

my $blue   = Imager::Color->new('#4285f4');
my $red    = Imager::Color->new('#ea4335');
my $yellow = Imager::Color->new('#fbbc05');
my $green  = Imager::Color->new('#34a853');
my $white  = Imager::Color->new('white');

$i->box( filled => 1, color => 'white' );
$i->arc( color => $blue,   r => $n / 2, d1 => 315, d2 => 45 );     # b
$i->arc( color => $red,    r => $n / 2, d1 => 225, d2 => 315 );    # r
$i->arc( color => $yellow, r => $n / 2, d1 => 135, d2 => 225 );    # y
$i->arc( color => $green,  r => $n / 2, d1 => 45,  d2 => 135 );    # g
$i->circle( color => $white, r => $n * .3, filled => 1 );
$i->box(
    color  => $blue,
    ymin   => $n * .4,
    ymax   => $n * .6,
    xmin   => $n / 2,
    xmax   => $n * .9,
    filled => 1
);
$i->polygon( color => $white, x => [ $n, $n, $n * .6 ], y => [ 0, $n * .4, $n * .4 ] );
$i->write( file => 'g.png' );

This post previously had the code shaped like the output image. Since that is against the rules for code golf I had to remove it. See the revision history if you want to take a look. I used Acme::EyeDrops to create that, with a shape that I created from an image created with the program itself that I converted to ASCII art. The code I obfuscated was already golfed, which can be seen by replacing the first eval with a print.

\$\endgroup\$
5
  • \$\begingroup\$ Very nice! Just a few details about the golfing : pop instead of $ARGV[0]. $h=($n=pop)/2 instead of $n=pop;...;$h=$n/2. new Imager::Color"#$_" instead of Imager::Color->new("#$_"). (and you forgot to drop the last semicolon). But once again, that's just some small details, your code is really great! (I couldn't have done it! I didn't even know about Imager, which is pretty convenient!) \$\endgroup\$
    – Dada
    Oct 18, 2016 at 21:29
  • \$\begingroup\$ @Dada thanks. Actually it's pretty straight-forward code. I correct people so much about using the method notation on SO that it's really hard to not do that on purpose. But you're right. This was the first time I used Imager myself. I think I saw it in the Perl Weekly. \$\endgroup\$
    – simbabque
    Oct 18, 2016 at 21:31
  • \$\begingroup\$ @Dada using Imager'Color with the Perl 4 namespace delimiter saves another byte. :) \$\endgroup\$
    – simbabque
    Oct 18, 2016 at 21:38
  • \$\begingroup\$ Indeed, first time I see a use for that syntax! Also, -MImager is shorter than use Imager; :) \$\endgroup\$
    – Dada
    Oct 18, 2016 at 21:42
  • 1
    \$\begingroup\$ @Dada I was going to do that one anyway :P And putting $n=pop into the new args saves the parens and a semicolon \$\endgroup\$
    – simbabque
    Oct 18, 2016 at 21:57
14
\$\begingroup\$

PHP + SVG, 300 Bytes

<svg width=<?=$_GET["w"]?> viewBox=0,0,10,10><def><path id=c d=M0,5A5,5,0,0,1,5,0V2A3,3,0,0,0,2,5 /></def><?foreach(["fbbc05"=>-45,"ea4335"=>45,"4285f4"=>168.5,"34a853"=>225]as$k=>$v)echo"<use xlink:href=#c fill=#$k transform=rotate($v,5,5) />"?><rect x=5 y=4 fill=#4285f4 width=4.9 height=2 /></svg>

The scaling part is width=<?=$_GET[w]?>

Output for value 333

<svg width="333" viewBox="0 0 10 10">
<def><path id="c" d="M 0,5 A 5 5 0 0 1 5,0 V 2 A 3,3 0 0 0 2,5"/></def>
<use xlink:href="#c" fill="#fbbc05" transform="rotate(-45,5,5)"/><use xlink:href="#c" fill="#ea4335" transform="rotate(45,5,5)"/><use xlink:href="#c" fill="#4285f4" transform="rotate(168.5,5,5)"/><use xlink:href="#c" fill="#34a853" transform="rotate(225,5,5)"/>
<rect x="5" y="4" fill="#4285f4" width="4.9" height="2"/>
</svg>

\$\endgroup\$
9
  • 1
    \$\begingroup\$ Can't you golf the space between the attributes' double quotes(") and the next attribute? E.g. <svg width="333" viewBox="0 0 10 10"> -> <svg width="333"viewBox="0 0 10 10"> \$\endgroup\$ Oct 12, 2016 at 13:44
  • \$\begingroup\$ @BojidarMarinov Yes it is corecct it saves a few Bytes. Thank You \$\endgroup\$ Oct 12, 2016 at 14:18
  • 1
    \$\begingroup\$ Remove spaces between letters and numbers in path data: M 0,5 A 5 5 0 0 1 5,0 V 2 A 3,3 0 0 0 2,5 => M0,5A5 5 0 0 1 5,0V2A3,3 0 0 0 2,5 \$\endgroup\$
    – darrylyeo
    Oct 12, 2016 at 22:39
  • 1
    \$\begingroup\$ Sure. Also, for your echo statement, use a double-quoted string to allow inline variables and remove the semicolon: echo'<use xlink:href="#c"fill="#'.$k.'"transform="rotate($v,5,5)"/>'; => echo"<use xlink:href='#c'fill='#$k'transform='rotate($v,5,5)'/>" \$\endgroup\$
    – darrylyeo
    Oct 12, 2016 at 22:51
  • 2
    \$\begingroup\$ I think most double quotes can be safely removed. Like <rect x=5 y=4 fill=#4285f4 width=4.9 height=2 /> (Here, you'll need a space before the /, though.) \$\endgroup\$
    – Arnauld
    Oct 12, 2016 at 23:59
14
\$\begingroup\$

Logo, 258 bytes

... because I figure logos should be made using Logo. This is implemented as a function. I developed it using Calormen.com's online Logo interpreter

I originally attempted to draw each segment and paint fill it, but that turned out to be bigger than expected. There was a lot of wasted movement backtracking and such. Instead, I decided to do a polar graph sweep, adjusting the color based on the heading. The harder part of the math was doing the geometry for the curve at the top of the G's rectangle. You could trim some decimals and have less accuracy, but I wanted this to be accurate to about 3 digits to accommodate typical screen sizes.

Golfed

to g:n
ht
make"a arctan 1/:n
seth 78.46
repeat 326.54/:a[make"h heading
pu fd:n/2 pd
setpc"#4285f4
if:h>135[setpc"#34a853]if:h>225[setpc"#fbbc05]if:h>315[setpc"#ea4335]bk:n*.2 pu bk:n*.3
rt:a]home bk:n*.1
filled"#4285f4[fd:n/5 rt 90 fd:n*.49 rt 90 fd:n/5]end

Sample

g 200 Google logo, size 200px

Ungolfed

to g :n ; Draw a G of width/height n

hideturtle ; Hide the turtle, since she's not part of the Google logo

;Determine the proper size of the angle to rotate so that the circle stays smooth within 1 px at this size
make "a arctan 1/:n 

setheading 78.46 ; Point toward the top corner of the upcoming rectangle

repeat 326.54 / :a [ ; Scoot around most of the circle, :a degrees at a time

  make"h heading ; Store heading into a variable for golfing purposes

  ; Position pen at the next stroke
  penup 
  forward :n / 2
  pendown

  ; Set the pen color depending on the heading
  setpencolor "#4285f4
  if :h > 135 [ setpencolor "#34a853]
  if :h > 225 [ setpencolor "#fbbc05]
  if :h > 315 [ setpencolor "#ea4335]

  ; Draw the stroke and return to center
  back :n * .2
  penup
  back :n * .3

  right :a ; Rotate to the next sweep heading
]

; Draw the rectangle
home
back :n * .1
filled "#4285f4 [
  forward :n/5
  right 90
  forward :n * .49 ;This is just begging to be :n / 2 but I couldn't bring myself to do it.  Proper math is more like :n * (sqrt 6) / 5
  right 90 
  forward :n / 5
]

end
\$\endgroup\$
12
\$\begingroup\$

JavaScript (ES7), 285 258 254 252 251 bytes

Prompts for the width of the logo (up to 999) and draws it in a canvas, pixel per pixel.

Edit: The initial version was converting Cartesian coordinates (x,y) to Polar coordinates (r,a), but we don't really need the angle. It's simpler (and significantly shorter) to just do comparisons between x and y to find out in which quarter we are.

Edit: Saved 1 byte thanks to ETHproductions.

JS, 251 224 220 218 217 bytes

for(w=x=y=prompt(c=c.getContext`2d`)/2;r=(x*x+y*y)**.5,q=(x<y)+2*(x<-y),c.fillStyle='#'+'4285F434A853EA4335FBBC05FFF'.substr(x>0&r<w&y*y<w*w/25?0:r<w*.6|r>w|!q&y<0?24:q*6,6),x-->-w||y-->-(x=w);)c.fillRect(x+w,y+w,1,1)

HTML, 34 bytes

<canvas id=c width=999 height=999>

ES6 version: 258 231 227 225 224 + 34 = 258 bytes

Recommended maximum width for the snippet: 190.

for(w=x=y=prompt(c=c.getContext`2d`)/2;r=Math.pow(x*x+y*y,.5),q=(x<y)+2*(x<-y),c.fillStyle='#'+'4285F434A853EA4335FBBC05FFF'.substr(x>0&r<w&y*y<w*w/25?0:r<w*.6|r>w|!q&y<0?24:q*6,6),x-->-w||y-->-(x=w);)c.fillRect(x+w,y+w,1,1)
<canvas id=c width=999 height=999>

\$\endgroup\$
7
  • \$\begingroup\$ I looked through the JavaScript part and immediately thought, "What on earth are these <- and --> operators??" I guess that's what happens when you've been thinking about hypothetical operators for a hypothetical language for 24 hours... :P \$\endgroup\$ Oct 13, 2016 at 19:13
  • \$\begingroup\$ @ETHproductions They're also confusing Notepad++ syntax highlighter which is interpreting --> as the start (?) of a html comment if this is put inside <script> tags in a html file. \$\endgroup\$
    – Arnauld
    Oct 13, 2016 at 20:33
  • \$\begingroup\$ Believe it or not, Notepad++ is sort of right (though not completely). Check out the very last item in the ES6 compat table. \$\endgroup\$ Oct 13, 2016 at 20:37
  • \$\begingroup\$ @ETHproductions - Wow. I suppose there's a good reason behind this syntax, but I fail to see it. Thanks for pointing this out. \$\endgroup\$
    – Arnauld
    Oct 13, 2016 at 20:51
  • \$\begingroup\$ Just so you know, I believe it's only valid at the start of a line. 123 --> comment throws an error in my browser console (Firefox 49), while --> comment does not. \$\endgroup\$ Oct 13, 2016 at 22:12
11
\$\begingroup\$

C#, 276 + 21 = 297 bytes

276 bytes for method + 21 bytes for System.Drawing import.

using System.Drawing;n=>{var q=new Bitmap(n,n);uint W=0xFFFFFFFF,B=0xFF4285F4;for(int y=0,x=0;x<n;y=++y<n?y:x-x++){float a=2f*x/n-1,b=2f*y/n-1,c=b*b;q.SetPixel(x,y,Color.FromArgb((int)(a>0&&a<.8&&c<.04?B:a*a+c>1||a*a+c<.36?W:a*a<c?b<0?0xFFEA4335:0xFF34A853:a<0?0xFFFBBC05:b<-.2?W:B)));}return q;};

Based on Martin Rosenau's algorithm. Thanks for doing the hard part of coming up with a way to construct the image!

using System.Drawing;             // Import System.Drawing
/*Func<int, Bitmap>*/ n =>
{
    var q = new Bitmap(n, n);     // Create nxn output bitmap
    uint W=0xFFFFFFFF,            // White, color used more than once
         B=0xFF4285F4;            // Blue, color used more than once
    for(int y = 0, x = 0; x < n;  // Loops for(x=0;x<N;x+=1) for(y=0;y<N;y+=1) combined
        y = ++y < n               // Increment y first until it reaches n
            ? y           
            : x - x++)            // Then increment x, resetting y
    {
        float a = 2f * x / n - 1, // Relative coords. Refer to Martin Rosenau's
              b = 2f * y / n - 1, // for what this magic is.
              c = b * b;          // b*b is used more than 3 times

        q.SetPixel(x, y,          // Set pixel (x,y) to the appropriate color
            Color.FromArgb((int)  // Cast uint to int :(
            ( // Here lies magic
                a > 0 && a < .8 && c < .04 
                    ? B
                    : a * a + c > 1 || a * a + c < .36
                        ? W
                        : a * a < c 
                            ? b < 0 
                                ? 0xFFEA4335
                                : 0xFF34A853
                            : a < 0
                                ? 0xFFFBBC05
                                : b < -.2
                                    ? W
                                    : B
            )));
    }
    return q;
};

26: 26

400: 400

\$\endgroup\$
1
  • \$\begingroup\$ You can save bytes by not including the transparency in the colour code i.e. 0xFF... \$\endgroup\$ Feb 8, 2017 at 12:43
11
\$\begingroup\$

JS/CSS/HTML(+JS), 40 0 + 701 644 617 593 + 173 90 97 121 = 914 774 754 730 714 bytes

*{position:absolute}a,h{height:100%;background:#4285F4}a,g{width:100%;border-radius:100%}h{width:30%;height:20%;top:40%}b,c,d,e,f{width:50%;height:50%}b,d,f,h{left:50%}e,f{top:50%}c{border-radius:100% 0 0;background:linear-gradient(45deg,#FBBC05 50%,#EA4335 50%)}d{border-radius:0 100% 0 0;background:linear-gradient(-45deg,transparent 50%,#EA4335 50%)}e{border-radius:0 0 0 100%;background:linear-gradient(-45deg,#34A853 50%,#FBBC05 50%)}f{border-radius:0 0 100%;background:linear-gradient(45deg,#34A853 50%,#4285F4 50%)}b,g{height:40%;background:#FFF}g{width:60%;height:60%;top:20%;left:20%}
<input oninput=with(o.style)height=width=value+"px"><o id=o><a></a><b></b><c></c><d></d><e></e><f></f><g></g><h></h></o>

Uses linear gradients rather than transforms. Edit: Saved 140 bytes thanks to @darrylyeo. Saved 20 bytes by using an extra element instead of a gradient. Saved 24 bytes thanks to @DBS. Saved 16 bytes thanks to @Hedi. From back to front, the various layers are:

  • a The blue circle
  • b A white rectangle to obscure the part above the bar
  • c The red/yellow top left quarter
  • d The red octant top right
  • e The yellow/green bottom left quarter
  • f The green/blue bottom right quarter
  • g The inner white circle
  • h The horizontal blue bar

JavaScript (ES6) (+SVG), 293 bytes, invalid

document.write(`<svg id=o width=${prompt()} viewbox=0,0,50,50>`);m=`39,11`;`#EA433511,11
#FBBC0511,39
#34A85339,39
#4285F445,25L25,25`.replace(/(.{7})(.{5})(.*)/g,(_,s,t,u)=>m=document.write(`<path stroke=${s} d=M${m}A20,20,0,0,0,${t+u} fill=none stroke-width=10 stroke-linejoin=round />`)||t)

Sadly the round line join isn't quite the requested effect, but it's pretty close.

\$\endgroup\$
7
  • \$\begingroup\$ Instead of IDs, you should use element names such as a, b, i, s, etc. Use * instead of div for the CSS selector. \$\endgroup\$
    – darrylyeo
    Oct 12, 2016 at 22:43
  • \$\begingroup\$ Also, use background as a shorthand for background-image. \$\endgroup\$
    – darrylyeo
    Oct 12, 2016 at 22:43
  • \$\begingroup\$ @darrylyeo Thanks, that's made a big difference to my score, not helped by me forgetting even to remove the quotes from my HTML... \$\endgroup\$
    – Neil
    Oct 12, 2016 at 23:22
  • \$\begingroup\$ Heh, no problem! \$\endgroup\$
    – darrylyeo
    Oct 13, 2016 at 0:16
  • \$\begingroup\$ I believe you could save a few characters here and there by using the compound border-radius. E.g. c{border-radius:100% 0 0; instead of c{border-top-left-radius:100%; \$\endgroup\$
    – DBS
    Oct 14, 2016 at 11:18
8
\$\begingroup\$

Ruby 2.3.1, 376 359 bytes

Using the RMagick gem.

d,f=$*[0].to_i,2.5;g,h,e,c=d-1,d/2,Magick::ImageList.new,Magick::Draw.new;e.new_image(d,d);c.stroke('#EA4335').fill_opacity(0).stroke_width(d*0.2).ellipse(h,h,g/f,g/f,225,315).stroke('#FBBC05').ellipse(h,h,g/f,g/f,135,225).stroke('#34A853').ellipse(h,h,g/f,g/f,45,135).stroke('#4285F4').ellipse(h,h,g/f,g/f,348.5,45).line(h,h,d*0.989,h).draw(e);e.write($*[1])

Examples

50x50

50x50

250x250

enter image description here

500x500

enter image description here

1000x1000

enter image description here

File takes two parameters- the first being the dimension and the second being the filename to save the output as.

Ungolfed

require "RMagick"

# Take the user's input for dimension
d = $*[0].to_i

e = Magick::ImageList.new
e.new_image(d, d)

c = Magick::Draw.new

# Start by setting the color to red
c.stroke('#EA4335')

  # set opacity to nothing so that we don't get extra color.
  .fill_opacity(0)

  # set thickness of line.
  .stroke_width(d*0.2)

  # #ellipse creates an ellipse taking
  # x, y of center
  # width, height,
  # arc start, arc end
  .ellipse(d / 2, d / 2, (d - 1) / 2.5, (d - 1) / 2.5, 225, 315)

  # change to yellow and draw its portion
  .stroke('#FBBC05')
  .ellipse(d / 2, d / 2, (d - 1) / 2.5, (d - 1) / 2.5, 135, 225)

  # change to green and draw its portion
  .stroke('#34A853')
  .ellipse(d / 2, d / 2, (d - 1) / 2.5, (d - 1) / 2.5, 45, 135)

  # change to blue and draw its portion
  .stroke('#4285F4')
  .ellipse(d / 2, d / 2, (d-1)/2.5, (d - 1)/2.5, 348.5, 45)

  # creates the chin for the G
  .line(d/2, d/2, d*0.99, d/2)

  # draws to the created canvas
  .draw(e)

# save out the file
# taking the filename as a variable saves a byte over
# "a.png"
e.write($*[1])

I had initially started solving this using oily_png/chunky_png but that would likely end up far too complicated compared to RMagick. RMagick's .ellipse function made this a breeze and the main work was around tuning the shapes/sizes of everything.

This is my first Code Golf submission(first SE answer also) and I only consider myself somewhat intermediate with Ruby. If you have any input on improvement/tips, please feel free to share!

\$\endgroup\$
1
  • \$\begingroup\$ I can't seem to edit my post(404 error) but if I were to remove the require line from my golfed solution that'd shave off 17 bytes and bring it down to 359 bytes. \$\endgroup\$
    – metropolis
    Oct 19, 2016 at 18:19
5
\$\begingroup\$

Python 2, 378 373 bytes

I really wanted to do this using turtle. I had to dust off my knowledge of Geometry for this, calculating angles and lengths not provided in the challenge description.

Edit: removed up(), since doing so removes the little sliver of white between green and blue and makes the inner circle look better. This slows down the program even more.

Edit: replaced 9*n with 2*n to make faster. I determined that it would still create a smooth circle.

from turtle import*
n=input()
C=circle
F=fill
K=color
q=90
w="white"
t=n*.3
lt(45)
def P(c,x,A):K(c);F(1);fd(x);lt(q);C(x,A,2*n);F(0);goto(0,0);rt(q)
for c in"#EA4335","#FBBC05","#34A853":P(c,n/2,q)
P(w,t,360)
K("#4285F4")
F(1)
fd(n/2)
lt(q)
a=11.537
C(n/2,45+a,2*n)
seth(0)
bk(.489*n)
rt(q)
fd(n/5)
lt(q)
fd(t)
F(0)
bk(t)
K(w)
F(1)
fd(.283*n)
lt(94-2*a)
C(t,a-45,2*n)
F(0)

Notes:

  1. The trinkets use Python 3, so the input must be cast to int.
  2. The trinkets go really slow for large n if you remove speed(0), which I added only for speed.
  3. The slowness of the code is mostly due to the third parameter of circle growing O(n), since it determines how many sides the inscribed polygon for drawing the circle has.

Try it online

Ungolfed: Try it online

Fun fact: Trinket is an anagram of Tkinter, Python's GUI package and the foundation for turtle.

\$\endgroup\$
5
  • \$\begingroup\$ Also, if someone has Python installed, could they run it with a large value of n for me? If it doesn't look nice, I may need to put some sqrts in there to be more exact. I rounded to the thousandths. \$\endgroup\$
    – mbomb007
    Oct 12, 2016 at 17:03
  • \$\begingroup\$ Output for 500. Looks fine to me \$\endgroup\$
    – acrolith
    Oct 12, 2016 at 18:03
  • \$\begingroup\$ It's only the large values I'm worried about. The canvas on Trinket has a max of 400. \$\endgroup\$
    – mbomb007
    Oct 12, 2016 at 18:53
  • \$\begingroup\$ Three big triangles appear and then this happens. \$\endgroup\$
    – acrolith
    Oct 12, 2016 at 19:02
  • \$\begingroup\$ @daHugLenny No idea. It might be a memory problem, since 10000 is such a large value. \$\endgroup\$
    – mbomb007
    Oct 12, 2016 at 20:42
5
\$\begingroup\$

PHP + GD, 529 449 bytes

This takes a query string parameter n and outputs a PNG version of the logo of the specified size.

<?php $n=$_GET['n'];$h=$n/2;$c='imagecolorallocate';$a='imagefilledarc';$i=imagecreatetruecolor($n,$n);$m=[$c($i,66,133,244),$c($i,52,168,83),$c($i,251,188,5),$c($i,234,67,53),$c($i,255,255,255)];imagefill($i,0,0,$m[4]);$j=-11.6;foreach([45,135,225,315]as$k=>$e){$a($i,$h,$h,$n,$n,$j,$e,$m[$k],0);$j=$e;}$a($i,$h,$h,$n*.6,$n*.6,0,0,$m[4],0);imagefilledrectangle($i,$h,$h-$n*.1,$h+$h*.98,$h+$h*.2,$m[0]);header('Content-Type:image/png');imagepng($i);

Ungolfed:

<?php

$n = $_GET['n'];$h=$n/2;
$c = 'imagecolorallocate';$a='imagefilledarc';
$i = imagecreatetruecolor($n,$n);

// Create array of colors
$m=[$c($i,66,133,244),$c($i,52,168,83),$c($i,251,188,5),$c($i,234,67,53),$c($i,255,255,255)];

// Fill background with white
imagefill($i, 0, 0, $m[4]);

// Create four arcs
$j=-11.6;
foreach([45,135,225,315]as$k=>$e){
    $a($i, $h, $h, $n, $n, $j, $e, $m[$k], 0);$j=$e;
}

// Hollow out the center and fill with white
$a($i, $h, $h, $n*.6,$n*.6,0,0,$m[4],0);

// create the horizontal bar
imagefilledrectangle($i,$h,$h-$n*.1,$h+$h*.98,$h+$h*.2,$m[0]);

// Output
header('Content-Type: image/png');
imagepng($i);

N=13:
13x13

N=200:
200x200

\$\endgroup\$
3
  • \$\begingroup\$ Most of the string constants need no quotes. True color image needs no imagecolorallocate; just give 0xRRGGBB as color to the drawing functions. Some more golfing and it´s down to 329 bytes: imagefill($i=imagecreatetruecolor($n=$argv[1],$n),0,0,($m=[4359668,3450963,0xfbbc05,0xea4335,0xffffff])[4]);for($j=-11.6;$e=[45,135,225,315][$k];$j=$e)($a=imagefilledarc)($i,$h=$n/2,$h,$n,$n,$j,$e,$m[$k++],0);$a($i,$h,$h,$n*.6,$n*.6,0,0,$m[4],0);imagefilledrectangle($i,$h,$h-$n*.1,$h+$h*.98,$h+$h*.2,$m[0]);imagepng($i,"g.png");, run with -r, takes input from command line and outputs to g.png. \$\endgroup\$
    – Titus
    Feb 8, 2017 at 1:21
  • \$\begingroup\$ Sorry my previous golf was two bytes too short: [$k has to be [+$k. But this one should work as well: imagefill($i=imagecreatetruecolor($n=$argv[1],$n),0,0,$w=2**24-1);$j=-11.6;foreach([$b=4359668,3450963,0xfbbc05,0xea4335]as$c)($a=imagefilledarc)($i,$h=$n/2,$h,$n,$n,$j,$j=45+90*$k++,$c,0);$a($i,$h,$h,$p=$n*.6,$p,0,0,$w,0);imagefilledrectangle($i,$h,$n*.4,$n*.99,$p,$b);imagepng($i,"g.png"); (291 bytes) \$\endgroup\$
    – Titus
    Feb 8, 2017 at 12:38
  • \$\begingroup\$ @Titus Thanks. I found out after this answer that you don't need imagecolorallocate. I'll update my answer with your code. But do you need to output to file name? Can't you just leave out the filename in imagepng and just have it output to stdout? \$\endgroup\$ Feb 10, 2017 at 20:19
5
\$\begingroup\$

Java, 568 bytes

Not the strongest language for golfing, but here is my earnest attempt:

import java.awt.image.*;class G{public static void main(String[]b)throws Exception{int n=Integer.parseInt(b[0]),x,y,a,c;BufferedImage p=new BufferedImage(n,n,BufferedImage.TYPE_INT_RGB);for(y=0;y<n;y++){for(x=0;x<n;x++){double u=(x+.5)/n-.5,v=.5-(y+.5)/n,r=Math.hypot(u,v);a=(int)(Math.atan2(v,u)*4/Math.PI);c=0xFFFFFF;if(0<u&u<.4&-.1<v&v<.1)c=0x4285F4;else if(r<.3|r>.5);else if(a==0&v<.1)c=0x4285F4;else if(a==1|a==2)c=0xEA4335;else if(a==-1|a==-2)c=0x34A853;else if(a!=0)c=0xFBBC05;p.setRGB(x,y,c);}}javax.imageio.ImageIO.write(p,"png",new java.io.File("G.png"));}}

Usage:

> javac G.java
--> Compiles to G.class
> java G 400
--> Writes G.png in current working directory

Un-golfed version - the basic idea is to work in the coordinate system u, v ∈ [−0.5, 0.5] and calculate the distance and angle of each pixel from the image center:

import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;

public class Google {

    public static void main(String[] args) throws IOException {
        int n = Integer.parseInt(args[0]);
        int[] pixels = new int[n * n];

        for (int y = 0; y < n; y++) {
            for (int x = 0; x < n; x++) {
                double u = (x + 0.5) / n - 0.5;
                double v = 0.5 - (y + 0.5) / n;
                double r = Math.hypot(u, v);
                int a = (int)(Math.atan2(v, u) * 4 / Math.PI);
                int c = 0xFFFFFF;
                if (0 < u && u < 0.4 && Math.abs(v) < 0.1)
                    c = 0x4285F4;
                else if (r < 0.3 || r > 0.5)
                    /*empty*/;
                else if (a == 0 && v < 0.1)
                    c = 0x4285F4;
                else if (a == 1 || a == 2)
                    c = 0xEA4335;
                else if (a == -1 || a == -2)
                    c = 0x34A853;
                else if (a != 0)
                    c = 0xFBBC05;
                pixels[y * n + x] = c;
            }
        }

        BufferedImage image = new BufferedImage(n, n, BufferedImage.TYPE_INT_RGB);
        image.setRGB(0, 0, n, n, pixels, 0, n);
        ImageIO.write(image, "png", new File("G.png"));
    }

}

My implementation computes and draws raw pixels. It is possible to create an alternative implementation that uses high-level graphics routines like Graphics2D and Arc2D to do the drawing, especially with anti-aliasing.

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

CJam, 141

ri:M.5*:K5/:T;'P3NMSMN255NM2m*[K.5-_]f.-{:X:mh:IK>0{X~0<\zT>|{IT3*<0{X~>X~W*>:Z2+{Z{X0=TW*>}4?}?}?}1?}?}%"^^G_8:nEhB%P9IW@zA"102b256b3/f=:+N*

Try it online

Outputs the image in ASCII ppm format.
For an ASCII-art version that's nicer to look at in the browser, try this code. It helps visualize the algorithm too.

Explanation:

ri:M                 read input, convert to int and store in M
.5*:K                multiply by 0.5 and store in K (M/2)
5/:T;                divide by 5 and store in T (M/10) and pop
'P3NMSMN255N         ppm header (N=newline, S=space)
M2m*                 generate all pixel coordinates - pairs of numbers 0..M-1
[K.5-_]              push the center (coordinates K-0.5, K-0.5)
f.-                  subtract the center from every pixel
{…}%                 map (transform) the array of coordinate pairs
  :X                 store the current pair in X
  :mh:I              calculate the hypotenuse of X (distance from the center)
                      and store in I
  K>0                if I>K (outside the big circle), push 0
  {…}                else…
    X~               dump X's coordinates (row, column)
    0<               check if the column is <0
    \zT>|            or the absolute value of the row is >T
    {…}              if true (outside the G bar)…
      IT3*<0         if I<T*3 (inside the small circle) push 0
      {…}            else (between the circles)…
        X~>          dump X and check if row>column (diagonal split)
        X~W*>:Z      also check if row>-column (other diagonal) and store in Z
                      (W=-1)
        2+           if in lower-left half, push Z+2 (2 for left, 3 for bottom)
        {…}          else (upper-right half)…
          Z{…}       if it's in the right quadrant
            X0=      get the row coordinate of X
            TW*>     compare with -T, resulting in 0 (above the bar) or 1
          4          else (top quadrant) push 4
          ?          end if
        ?            end if
      ?              end if
    1                else (inside the G bar) push 1
    ?                end if
  ?                  end if
"^^G … @zA"          push a string containing the 5 colors encoded
102b                 convert from base 102 to a big number
                      (ASCII values of chars are treated as base-102 digits)
256b                 convert to base 256, splitting into 15 bytes
3/                   split into triplets (RGB)
f=                   replace each generated number (0..4)
                      with the corresponding color triplet
:+N*                 join all the triplets, and join everything with newlines
\$\endgroup\$
4
\$\begingroup\$

Go, 379 bytes

import ."fmt"
func f(a int)(s string){
m:=map[string]float64{"fbbc05":-45,"ea4335":45,"4285f4":168.5,"34a853":225}
for k,v:=range m{s+=Sprintf("<use xlink:href=#c fill=#%v transform=rotate(%v,5,5) />",k,v)}
return Sprintf("<svg width=%v viewBox=0,0,10,10><def><path id=c d=M0,5A5,5,0,0,1,5,0V2A3,3,0,0,0,2,5 /></def>%v<rect x=5 y=4 fill=#4285f4 width=4.9 height=2 /></svg>",a,s)}

The function f takes a single int argument (the scale factor) and outputs an SVG image scaled appropriately.

Try it online at Ideone.

Example output:

<svg width=333 viewBox=0,0,10,10><def><path id=c d=M0,5A5,5,0,0,1,5,0V2A3,3,0,0,0,2,5 /></def><use xlink:href=#c fill=#34a853 transform=rotate(225,5,5) /><use xlink:href=#c fill=#fbbc05 transform=rotate(-45,5,5) /><use xlink:href=#c fill=#ea4335 transform=rotate(45,5,5) /><use xlink:href=#c fill=#4285f4 transform=rotate(168.5,5,5) /><rect x=5 y=4 fill=#4285f4 width=4.9 height=2 /></svg>

It seems wrong to appease our Google overlords in any programming language except their own.

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

FreeMarker+HTML/CSS, 46 + 468 = 514 bytes

HTML:

<div><div></div><div></div><span></span></div>

CSS:

div div,div span{position:absolute}div{width:10px;height:10px;box-sizing:border-box;transform-origin:top left;position:relative;transform:scale(${n*.1})}div div{border:2px solid;border-radius:9px;border-color:transparent #4285f4 transparent transparent;transform:rotate(33.4630409671deg);transform-origin:center}div div+div{border-color:#ea4335 transparent #34a853 #fbbc05;transform:none}div span{display:block;top:4px;bottom:4px;left:5px;right:.1px;background:#4285f4}

Assuming the FreeMarker processor is executed with a variable n set, representing input.

Explanation of magic numbers:

Everything is based on a 10x10px wrapper, then scaled by n/10.

  • Distance to right of blue horizontal box [px]: 5 - sqrt(5^2 - 1^2) = 0.10102051443 (Pythagoras)
  • Rotation of blue arc [deg]: 45 - arcSin(1/5) = 33.4630409671 (Sine)

Ungolfed JSFiddle

\$\endgroup\$
6
  • \$\begingroup\$ Put the CSS Part in a style element and use Javascript or PHP. replace transform:scale(n) with transform:scale(<?=$_GET[n])?> (PHP). In javascript you can append the CSS Part to the style Element \$\endgroup\$ Oct 13, 2016 at 10:52
  • \$\begingroup\$ I thought about JS but didn't want to spoil the code too much. However, templating languages seem ok, so I went with FreeMarker and quickly adjusted my answer, thanks. \$\endgroup\$ Oct 13, 2016 at 11:02
  • \$\begingroup\$ The blue bar is too far to the right on the right side it think \$\endgroup\$ Oct 14, 2016 at 10:42
  • \$\begingroup\$ No, you can easily calculate it by imagining a right triangle with side lengths 0.5, 0.1 and x, where x denotes the blue bar's width, or accordingly 0.5-x its distance to the right. x can then be determined by using Pythagoras' theorem (see the explanations I added). \$\endgroup\$ Oct 14, 2016 at 11:42
  • \$\begingroup\$ The JSFiddle doesn't display correctly in the two browsers I've tried (Win10 x64) -- with Chrome 54.0.2840.59 m (64-bit) the blue bar extends too far to the right, and with Firefox 49.0.1 (32-bit) there is a slight gap midway through the blue curved part \$\endgroup\$ Oct 14, 2016 at 16:35
3
\$\begingroup\$

343 octets of Haskell

roman@zfs:~$ cat ppmG.hs
ppmG n='P':unlines(map show([3,n,n,255]++concat[
 case map signum[m^2-(2*x-m)^2-(2*y-m)^2,
 (10*x-5*m)^2+(10*y-5*m)^2-(3*m)^2,
 m-x-y,x-y,5*y-2*m,3*m-5*y,2*x-m]of
 1:1:1:1:_->[234,67,53]
 1:1:1:_->[251,188,5]
 [1,_,_,_,1,1,1]->[66,133,244]
 1:1:_:1:1:_->[66,133,244]
 1:1:_:_:1:_->[52,168,83]
 _->[255,255,255]|m<-[n-1],y<-[0..m],x<-[0..m]]))
roman@zfs:~$ wc ppmG.hs
 10  14 343 ppmG.hs
roman@zfs:~$ ghc ppmG.hs -e 'putStr$ppmG$42'|ppmtoxpm
ppmtoxpm: (Computing colormap...
ppmtoxpm: ...Done.  5 colors found.)

/* XPM */
static char *noname[] = {
/* width height ncolors chars_per_pixel */
"42 42 6 1",
/* colors */
"  c #4285F4",
". c #EA4335",
"X c #FBBC05",
"o c #34A853",
"O c #FFFFFF",
"+ c None",
/* pixels */
"OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO",
"OOOOOOOOOOOOOOO............OOOOOOOOOOOOOOO",
"OOOOOOOOOOOO..................OOOOOOOOOOOO",
"OOOOOOOOOO......................OOOOOOOOOO",
"OOOOOOOOO........................OOOOOOOOO",
"OOOOOOOO..........................OOOOOOOO",
"OOOOOOO............................OOOOOOO",
"OOOOOOXX..........................OOOOOOOO",
"OOOOOXXXX........................OOOOOOOOO",
"OOOOXXXXXX.......OOOOOOOO.......OOOOOOOOOO",
"OOOXXXXXXXX....OOOOOOOOOOOO....OOOOOOOOOOO",
"OOOXXXXXXXXX.OOOOOOOOOOOOOOOO.OOOOOOOOOOOO",
"OOXXXXXXXXXXOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO",
"OOXXXXXXXXXOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO",
"OOXXXXXXXXXOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO",
"OXXXXXXXXXOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO",
"OXXXXXXXXXOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO",
"OXXXXXXXXOOOOOOOOOOOO                    O",
"OXXXXXXXXOOOOOOOOOOOO                    O",
"OXXXXXXXXOOOOOOOOOOOO                    O",
"OXXXXXXXXOOOOOOOOOOOO                    O",
"OXXXXXXXXOOOOOOOOOOOO                    O",
"OXXXXXXXXOOOOOOOOOOOO                    O",
"OXXXXXXXXOOOOOOOOOOOO                    O",
"OXXXXXXXXOOOOOOOOOOOO                    O",
"OXXXXXXXXXOOOOOOOOOOOOOOOOOOOOOO         O",
"OXXXXXXXXXOOOOOOOOOOOOOOOOOOOOOO         O",
"OOXXXXXXXXXOOOOOOOOOOOOOOOOOOOO         OO",
"OOXXXXXXXXXOOOOOOOOOOOOOOOOOOOO         OO",
"OOXXXXXXXXXXOOOOOOOOOOOOOOOOOO          OO",
"OOOXXXXXXXXooOOOOOOOOOOOOOOOOoo        OOO",
"OOOXXXXXXXoooooOOOOOOOOOOOOooooo       OOO",
"OOOOXXXXXooooooooOOOOOOOOoooooooo     OOOO",
"OOOOOXXXoooooooooooooooooooooooooo   OOOOO",
"OOOOOOXoooooooooooooooooooooooooooo OOOOOO",
"OOOOOOOooooooooooooooooooooooooooooOOOOOOO",
"OOOOOOOOooooooooooooooooooooooooooOOOOOOOO",
"OOOOOOOOOooooooooooooooooooooooooOOOOOOOOO",
"OOOOOOOOOOooooooooooooooooooooooOOOOOOOOOO",
"OOOOOOOOOOOOooooooooooooooooooOOOOOOOOOOOO",
"OOOOOOOOOOOOOOOooooooooooooOOOOOOOOOOOOOOO",
"OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO"
};

Explanation

  • "P3" == plaintext portable pixmap
  • show == produce ASCII decimals fearing UTF-8 corruption for "\xFF\xFF\xFF"
  • unlines == separate decimals into lines
  • m = n-1 for symmetry in n==length[0..m]
  • m²-(2x-m)²-(2y-m)²>0 == (x-m/2)² + (y-m/2)² < (m/2)² == insideOuterCircle
  • (10x-5m)²+(10y-5m)²-(3m)²>0 == (x-m/2)² + (y-m/2)² > (m3/10)² == outsideInnerCircle
  • m-x-y>0 == x+y < m == inUpperLeft
  • x-y>0 == x > y == inUpperRight
  • 5y-2m>0 == y > m2/5 == belowGbarTop
  • 3y-5y>0 == y < m3/5 == aboveGbarBot
  • 2x-m>0 == x > m/2 == inRightHalf
  • [234,67,53] == red
  • [251,188,5] == yellow
  • [52,168,83] == green
  • [66,13,244] == blue
  • [255,255,255] == white
\$\endgroup\$
1
  • 1
    \$\begingroup\$ Unless you encode it all with 7-bit ASCII (which you could do since the highest character codepoint you're using is 0x7C/124/|) in which case it would be 338 septets of Haskell. But considering how standard 8-bits-to-a-byte has become in data storage in the last couple of decades, I think the term “bytes” is specific enough without beating the dead horse. \$\endgroup\$ Oct 15, 2016 at 1:19
3
\$\begingroup\$

SAS - 590 536 521 bytes

This uses the GTL Annotation facility. Input is specified in a macro variable on the first line. For a few extra bytes you can define the whole thing as a macro. It still sneaks in below Java and a few of the HTML answers, even though you have to define a null graph template just to be able to plot anything at all!

I've left the line breaks in for a modicum of readability, but I'm not counting those towards the total as it works without them.

%let R=;
%let F=FILLCOLOR;
ods graphics/width=&R height=&R;
proc template;
define statgraph a;
begingraph;
annotate;
endgraph;
end;
data d;
retain FUNCTION "RECTANGLE" DISPLAY "FILL" DRAWSPACE "graphPERCENT";
length &F$8;
_="CX4285F4";
P=100/&R;
HEIGHT=P;
width=P;
do i=1to &R;
x1=i*P;
U=x1-50;
do j=1to &R;
y1=j*P;
V=y1-50;
r=euclid(U,V);
&F="";
if 30<=r<=50then if V>U then if V>-U then &F="CXEA4335";
else &F="CXFBBC05";
else if V<-U then &F="CX34A853";
else if V<10then &F=_;
if &F>'' then output;
end;
end;
x1=65;
y1=50;
width=30;
height=20;
&F=_;
output;
proc sgrender sganno=d template=a;

Edit: shaved off a few more bytes via use of macro vars, default settings and choice of operators.

Edit 2: got rid of the do-end blocks for the if-then-else logic and it somehow still works - I don't entirely understand how. Also, I discovered the euclid function!

\$\endgroup\$
2
\$\begingroup\$

SCSS - 415 bytes

Takes input as $N: 100px; and <div id="logo"></div>, not sure if these should count in the total though...

$d:$N*.6;$b:$d/3;#logo{width:$d;height:$d;border:$b solid;border-color:#ea4335 transparent #34a853 #fbbc05;border-radius:50%;position:relative;&:before,&:after{content:'';position:absolute;right:-$b;top:50%;border:0 solid transparent}&:before{width:$b*4;height:$d/2;border-width:0 $b $b 0;border-right-color:#4285f4;border-bottom-right-radius:50% 100%}&:after{width:$N/2;margin:-$b/2 0;border-top:$b solid #4285f4}}

Demo on JSFiddle

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

Haskell with JuicyPixels package, 306 bytes

import Codec.Picture
p=PixelRGB8
c=fromIntegral
b=p 66 133 244
w=p 255 255 255
(n%x)y|y<=x,x+y<=n=p 234 67 53|y>x,x+y<=n=p 251 188 5|y>x,x+y>n=p 52 168 83|y>=0.4*n=b|1>0=w
(n#x)y|d<=h,d>=0.3*n=n%x$y|x>=h,d<=h,abs(y-h)<=n/10=b|1>0=w where h=n/2;d=sqrt$(x-h)^2+(y-h)^2
f n=generateImage(\x y->c n#c x$c y)n n

Usage example:

main = writePng "google.png" $ f 1001

This could probably be improved. The idea is to pass a function to generateImage that selects the pixel (color really) that should go at position x, y. For that we use a lambda that adds n as a parameter and converts them all to floats at the same time. The # function basically checks if we're in the ring, the bar, or neither. If it's the ring we pass the baton to %, if the bar we just return blue, otherwise white. % checks which quadrant we're in and returns the appropriate color if it isn't blue. Blue is a special case since we need to make sure it doesn't wrap around to the red, so we only return blue if y is below the "bar line" otherwise we return white. That's the general overview.

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

JavaScript + HTML, 241 bytes

228 bytes for JavaScript + 13 bytes for HTML

(
// code start
n=>{with(c.getContext`2d`)['#4285f4','#34a853','#fbbc05','#ea4335'].map((c,i)=>{beginPath(fillStyle=strokeStyle=c,lineWidth=n/5,a=Math.PI/2);arc(h=n/2,h,r=n*.4,j=i*a-a/2,j+a);stroke();i||clearRect(0,0,n,r)+fillRect(h,r,r,n/5)})}
// code end
)(100);
<canvas id=c>

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

Processing.py - 244 bytes + 1 byte for number of digits in N

Let's start with the code. This can be pasted in the Processing environment and ran (changing N for different sizes).

N=400
n=N/2
f=fill
a=['#34A853','#FBBC05','#EA4335','#4285F4']
def setup():
 size(N,N);noStroke()
def draw():
 for i in 1,3,5,7: f(a[i/2]);arc(n,n,N,N,i*PI/4+[0,.59][i>6],(i+2)*PI/4)
 f(205);ellipse(n,n,.6*N,.6*N);f(a[3]);rect(n,n-.1*N,.98*n,.2*N)

Small cheat: the circle that cut's out a part from the logo is drawn in Processing's grayscale shade 205, which is the default background color. Exporting this to an image wouldn't look the same. This saves a call to background(255).

Explanation

N=400                 # set size
n=N/2                 # precompute center point
f=fill                # 3 usages, saves 3 bytes
a=['#34A853','#FBBC05','#EA4335','#4285F4']
                      # list of colors
def setup():          # called when starting sketch
 size(N,N)            # set size
 noStroke()           # disable stroking
def draw():           # drawing loop
 for i in 1,3,5,7:    # loop over increments of PI/4
  f(a[i/2])           # set fill color using integer
                      # division
  arc(n,n,N,N,i*PI/4+[0,.59][i>6],(i+2)*PI/4)
                      # draw a pizza slice between
                      # two coordinates. The 
                      #     [0,.59][i>6]
                      # accounts for the white part
 f(205)               # set fill color to Processing's
                      # default background
 ellipse(n,n,.6*N,.6*N)
                      # cut out center
 f(a[3])              # set fill to blue
 rect(n,n-.1*N,.98*n,.2*N)
                      # draw the straight part

Examples

N = 400

N=400

N = 13 (Processing's minimum size is 100x100)

enter image description here

Note

If we allow us to manually edit in multiple values for N the explicit calls to setup and draw are not needed and it is down to 213 bytes + 3 bytes per digit in N.

N=200
size(200,200)
n=N/2
f=fill
a=['#34A853','#FBBC05','#EA4335','#4285F4']
noStroke()
for i in 1,3,5,7:f(a[i/2]);arc(n,n,N,N,i*PI/4+[0,.59][i>6],(i+2)*PI/4)
f(205);ellipse(n,n,.6*N,.6*N);f(a[3]);rect(n,n-.1*N,.98*n,.2*N)
\$\endgroup\$
2
  • \$\begingroup\$ By itself, this is not a full program \$\endgroup\$
    – user41805
    Feb 8, 2017 at 12:30
  • \$\begingroup\$ Fair enough. I removed the incomplete program and substituted it for a complete version. \$\endgroup\$ Feb 9, 2017 at 0:09

Your Answer

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

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