Swift 2.3, 593 585 bytes
var t = 0,g = UIGraphicsGetCurrentContext(),c = UIColor(hue:CGFloat(drand48()),saturation:1,brightness:1,alpha:1).CGColor
srand48(time(&t))
UIGraphicsBeginImageContext(CGSizeMake(5,5))
for x in 0..<3 {for y in 0..<5 {CGContextSetFillColorWithColor(g,drand48()>0.5 ? c : UIColor.whiteColor().CGColor)
var r = [CGRect(x:x,y:y,width:1,height:1)]
if x<2 {let m = x==0 ? 4 : 3;r.append(CGRect(x:m,y:y,width:1,height:1))}
CGContextFillRects(g,&r,r.count)}}
let i = UIGraphicsGetImageFromCurrentImageContext()
UIImagePNGRepresentation(i)!.writeToURL(NSURL(string:"/a/a.png")!,atomically:true)
Update
Swift 3, 551 bytes
var t = 0,g = UIGraphicsGetCurrentContext()!,c = UIColor(hue:CGFloat(drand48()),saturation:1,brightness:1,alpha:1).cgColor
srand48(time(&t))
UIGraphicsBeginImageContext(CGSize(width:5,height:5))
for x in 0..<3 {for y in 0..<5 {g.setFillColor(drand48()>0.5 ? c : UIColor.white().cgColor)
var r = [CGRect(x:x,y:y,width:1,height:1)]
if x<2 {let m = x==0 ? 4 : 3;r.append(CGRect(x:m,y:y,width:1,height:1))}
g.fill(&r,count: r.count)}}
let i = UIGraphicsGetImageFromCurrentImageContext()!
try!UIImagePNGRepresentation(i)!.write(to: URL(string:"/a/a.png")!)
I'm at WWDC and just got the Xcode 8 beta with Swift 3. Apple made some of the CoreGraphics calls more "Swifty," and I am able to reduce the bytecount.
Swift 2 code Ungolfed:
var t = 0
srand48(time(&t))
UIGraphicsBeginImageContext(CGSizeMake(5,5))
let context = UIGraphicsGetCurrentContext()
let color = UIColor(hue: CGFloat(drand48()),saturation:1,brightness:1,alpha:1).CGColor
for x in 0..<3 {
for y in 0..<5 {
CGContextSetFillColorWithColor(context, drand48() > 0.5 ? color : UIColor.whiteColor().CGColor)
var rects = [CGRect(x:x,y:y,width:1,height:1)]
if x < 2 {
let mirror = x==0 ? 4 : 3
rects.append(CGRect(x: mirror, y: y, width: 1, height: 1))
}
CGContextFillRects(context, &rects, rects.count)
}
}
let image = UIGraphicsGetImageFromCurrentImageContext()
UIImagePNGRepresentation(image)!.writeToURL(NSFileManager.defaultManager().URLsForDirectory(.DocumentDirectory,inDomains:.UserDomainMask).first!.URLByAppendingPathComponent("a.png"), atomically:true)
This answer assumes UIKit is available and uses the Cocoa Touch framework.
Some example output images:
I know I can't compete with most of the other answers but I wanted to give this a shot as a personal challenge. There is definitely room for improvement with this answer, but I think it will be hard to get this down below a few hundred bytes due to the length of the UIKit and CoreGraphics image writing method names. I opted to write an actual PNG file rather than PPM values as an exercise for myself, but shorter answers would definitely be possible if I used the PPM format.
I already start out as a loss by having to declare a variable to seed srand48
with time
. I chose this over arc4random()
or arc4random_uniform()
because ultimately I would lose more bytes with those. I seed the rng to use drand48
to generate a random color and pick when to write a color to a pixel.
CGSize
vs CGSizeMake
and CGRect
vs CGRectMake
:
I switch between the inline C API functions and their Swift extensions to find the shortest constructor for each. CGSizeMake
ends up being shorter than CGSize()
, and CGRect
ends up being shorter than CGRectMake()
:
CGSizeMake(5,5)
CGSize(width:5,height:5)
CGRect(x:x,y:y,width:1,height:1)
CGRectMake(CGFloat(x),CGFloat(y),1,1)
I would have to create CGFloat
s x
and y
due to the nature of the for loop. I'm really not thrilled with the 2D loop and if equality checks, but I was really struggling to find a shorter way. There's definitely room to shave off a few bytes here.
Calling CGContextFillRects
with an array of CGRect
structs is cheaper than calling CGContextFillRect
twice with two different values, so I save a few bytes with the array and pointer.
I also save 27 bytes by not calling UIGraphicsEndImageContext()
. While this would normally be a "bug" in production code, it's not necessary for this toy program.
Colors:
Colors are also a pain to deal with, since I'm creating UIColor
objects but need to write a CGColor
opaque type to each pixel. The shortest code I found to create a random color was to use the UIColor
constructor and get the CGColor
from that UIColor
. Same with white. If I were using the Cocoa framework instead of Cocoa Touch, I might be able to save some bytes using CGColorGetConstantColor()
, but unfortunately that method is unavailable in the Cocoa Touch SDK.
Writing to to file:
Writing to a file takes almost 100 bytes. I'm not sure how to even go about optimizing this. On some systems depending on your permissions, you may need to use the Documents directory which would be even longer:
UIImagePNGRepresentation(i)!.writeToURL(NSFileManager.defaultManager().URLsForDirectory(.DocumentDirectory,inDomains:.UserDomainMask).first!.URLByAppendingPathComponent("a.png"), atomically:true)
Definitely open to further optimizations.
Edit 1: Saved a few bytes by rearranging some variable declarations.
@trichoplax The output is a 5x5 pixel image, thanks. Also note the space around the 5x5 pixels (shown in the example GitHub avatars) should be excluded. – MCMastery – 2016-06-05T03:23:20.260
5
I'd suggest some smaller sample images. These take up way more space than necessary. Also the technical term for these is "identicons" and they are not actually random but based on the hash of a username (but having them random for the challenge is fine).
– Calvin's Hobbies – 2016-06-05T03:29:42.257@HelkaHomba thank you, I added better examples. – MCMastery – 2016-06-05T03:37:15.600
@trichoplax thank you, I'm editing now – MCMastery – 2016-06-05T03:38:30.793
1I assume "random pixels" means each pixel is colored or blank with 0.5 probability, independently of all other pixels on the same size. And "random color" means each RGB component is independently uniform on [0, 255]. Correct? – Luis Mendo – 2016-06-05T03:48:12.510
Trivia: You can use the identicon API to generate your own identicon, even if you have a real avatar, at
https://github.com/identicons/<your_github_username>.png
. – mınxomaτ – 2016-06-05T04:17:51.910@LuisMendo It does not matter for randomness if you pick 3 uniform 256 values or one 256^3 value (if the period of the RNG is over 256^3 of course). – Karl Napf – 2016-06-05T12:12:11.013
GitHub identicons are... based on the hash of a username
Hold on a second, how can this be a hash? – user8397947 – 2016-06-05T16:54:08.0501
I didn't feel it was a valid answer since it doesn't output an actual image, but I made a command line version using ANSI codes: https://gist.github.com/anonymous/3c879c5b01983a07fb7da7a25d778f1b%21
– Dom Hastings – 2016-06-06T07:45:15.880@dorukayhan the same input always generates the same output, and you can't determine the input from the output. it's a hash – undergroundmonorail – 2016-06-07T03:21:58.707
@DomHastings Displaying output on the screen is acceptable by default. I'd say that output via ANSI color codes to a console is close enough, but that's ultimately the OP's call.
– Mego – 2016-06-07T05:55:42.170