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)
Actualizar
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")!)
Estoy en WWDC y acabo de obtener la versión beta de Xcode 8 con Swift 3. Apple hizo algunas de las llamadas de CoreGraphics más "Swifty", y puedo reducir el bytecount.
Código Swift 2 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)
Esta respuesta asume que UIKit está disponible y usa el marco Cocoa Touch.
Algunos ejemplos de imágenes de salida:
Sé que no puedo competir con la mayoría de las otras respuestas, pero quería intentarlo como un desafío personal. Definitivamente hay margen de mejora con esta respuesta, pero creo que será difícil reducirlo a unos cientos de bytes debido a la longitud de los nombres de los métodos de escritura de imágenes UIKit y CoreGraphics. Opté por escribir un archivo PNG real en lugar de los valores PPM como un ejercicio para mí, pero definitivamente sería posible obtener respuestas más cortas si usara el formato PPM.
Ya comienzan como una pérdida por tener que declarar una variable de semilla srand48
con time
. Elegí esto arc4random()
o arc4random_uniform()
porque, en última instancia, perdería más bytes con ellos. Siembro el rng para usarlo drand48
para generar un color aleatorio y elegir cuándo escribir un color en un píxel.
CGSize
vs CGSizeMake
y CGRect
vs CGRectMake
:
Cambio entre las funciones de la API C en línea y sus extensiones Swift para encontrar el constructor más corto para cada una. CGSizeMake
termina siendo más corto que CGSize()
, y CGRect
termina siendo más corto que 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)
Tendría que crear CGFloat
s x
, y y
debido a la naturaleza del bucle. Realmente no estoy entusiasmado con el ciclo 2D y si la igualdad se verifica, pero realmente estaba luchando por encontrar un camino más corto. Definitivamente hay espacio para recortar algunos bytes aquí.
Llamar CGContextFillRects
con una matriz de CGRect
estructuras es más barato que llamar CGContextFillRect
dos veces con dos valores diferentes, por lo que guardo algunos bytes con la matriz y el puntero.
También ahorro 27 bytes al no llamar UIGraphicsEndImageContext()
. Si bien esto normalmente sería un "error" en el código de producción, no es necesario para este programa de juguetes.
Colores:
Los colores también son difíciles de manejar, ya que estoy creando UIColor
objetos pero necesito escribir un CGColor
tipo opaco en cada píxel. El código más corto que encontré para crear un color al azar era utilizar el UIColor
constructor y obtener la CGColor
de aquel UIColor
. Lo mismo con el blanco. Si estuviera usando Cocoa Framework en lugar de Cocoa Touch, podría guardar algunos bytes usando CGColorGetConstantColor()
, pero desafortunadamente ese método no está disponible en el SDK de Cocoa Touch.
Escribiendo en el archivo:
Escribir en un archivo toma casi 100 bytes. No estoy seguro de cómo optimizar esto. En algunos sistemas, dependiendo de sus permisos, es posible que deba usar el directorio Documentos, que sería aún más largo:
UIImagePNGRepresentation(i)!.writeToURL(NSFileManager.defaultManager().URLsForDirectory(.DocumentDirectory,inDomains:.UserDomainMask).first!.URLByAppendingPathComponent("a.png"), atomically:true)
Definitivamente abierto a nuevas optimizaciones.
Edición 1: guardado algunos bytes al reorganizar algunas declaraciones de variables.