# Question
Title: Encode Images into Tweets (Extreme Image Compression Edition)
*Based on the very successful Twitter image encoding challenge at Stack Overflow.*

If an image is worth 1000 words, how much of an image can you fit in 114.97 bytes?

I challenge you to come up with a general-purpose method to compress images into a standard Twitter comment that contains *only printable ASCII text*.

## Rules:

1. You must write a program that can take an image and output the encoded text.
2. The text created by the program must be at most 140 characters long and must only contain characters whose code points are in the range of 32-126, inclusive.
3. You must write a program (possibly the same program) that can take the encoded text and output a decoded version of the photograph.
4. Your program can use external libraries and files, but cannot require an internet connection or a connection to other computers.
5. The decoding process cannot access or contain the original images in any way.
6. Your program must accept images in at least one of these formats (not necessarily more): Bitmap, JPEG, GIF, TIFF, PNG. If some or all of the sample images are not in the correct format, you can convert them yourself prior to compression by your program.

## Judging:

This is a somewhat subjective challenge, so the winner will (eventually) be judged by me. I will focus my judgment on a couple of important factors, listed below in decreasing importance:

1. Ability to do a reasonable job of compressing a wide variety of images, including those not listed as a sample image
2. Ability to preserve the outlines of the major elements in an image
3. Ability to compress the colors of the major elements in an image
4. Ability to preserve outlines and colors of the minor details in an image
5. Compression time. Although not as important as how well an image is compressed, faster programs are better than slower programs that do the same thing.

Your submission should include the resulting images after decompression, along with the Twitter comment generated. If possible, you could also give a link to the source code.

## Sample images:

The Hindenburg, Mountainous Landscape, Mona Lisa, 2D Shapes

# Answer
I've improved my method by adding actual compression. It now operates by iteratively doing the following:

1. Convert the image to YUV
2. Downsize the image preserving the aspect ratio (if the image is color, the chroma is sampled at 1/3 the width & height of the luminance)
3. Reduce the bit depth to 4 bits per sample
4. Apply median prediction to the image, making the sample distribution more uniform
5. Apply adaptive range compression to the image.
6. See if the size of the compressed image is \<= 112

The largest image that fits in the 112 bytes is then used as the final image, with the remaining two bytes used to store the width & height of the compressed image, plus a flag indicating if the image is in color. For decoding, the process is reversed, and the image scaled up so the smaller dimension is 128.

There is some room for improvement, namely not all the available bytes are used typically, but I feel I'm at the point of significantly diminishing returns for downsampling + lossless compression.

Quick & dirty C++ source

Windows exe

**Mona Lisa** (13x20 luminance, 4x6 chroma)

```
&Jhmi8(,x6})Y"f!JC1jTzRh}$A7ca%/B~jZ?[_I17+91j;0q';|58yvX}YN426@"97W8qob?VB'_Ps`x%VR=H&3h8K=],4Bp=$K=#"v{thTV8^~lm vMVnTYT3rw N%I

```

**Hindenburg** (21x13 luminance)

```
GmL<B&ep^m40dPs%V[4&"~F[Yt-sNceB6L>Cs#/bv`\4{TB_P Rr7Pjdk7}<*<{2=gssBkR$>!['ROG6Xs{AEtnP=OWDP6&h{^l+LbLr4%R{15Zc<D?J6<'#E.(W*?"d9wdJ'

```

**Mountains** (19x14 luminance, 6x4 chroma)

```
Y\Twg]~KC((s_P>,*cePOTM_X7ZNMHhI,WeN(m>"dVT{+cXc?8n,&m$TUT&g9%fXjy"A-fvc 3Y#Yl-P![lk~;.uX?a,pcU(7j?=HW2%i6fo@Po DtT't'(a@b;sC7"/J

```

**2D Shapes** (21x15 luminance, 7x5 chroma)

```
n@|~c[#w<Fv8mD}2LL!g_(~CO&MG+u><-jT#{KXJy/``#S@m26CQ=[zejo,gFk0}A%i4kE]N ?R~^8!Ki*KM52u,M(his+BxqDCgU>ul*N9tNb\lfg}}n@HhX77S@TZf{k<CO69!

```
> 58 votes

# Answer
## Go

Works by dividing the image into regions recursively. I try to divide regions with high information content, and pick the dividing line to maximize the difference in color between the two regions.

Each division is encoded using a few bits to encode the dividing line. Each leaf region is encoded as a single color.

```
4vN!IF$+fP0~\}:0d4a's%-~@[Q(qSd<<BDb}_s|qb&8Ys$U]t0mc]|! -FZO=PU=ln}TYLgh;{/"A6BIER|{lH1?ZW1VNwNL 6bOBFOm~P_pvhV)]&[p%GjJ ,+&!p"H4`Yae@:P

```

```
<uc}+jrsxi!_:GXM!'w5J)6]N)y5jy'9xBm8.A9LD/^]+t5#L-6?9 a=/f+-S*SZ^Ch07~s)P("(DAc+$[m-:^B{rQTa:/3`5Jy}AvH2p!4gYR>^sz*'U9(p.%Id9wf2Lc+u\&\5M>

```

```
lO6>v7z87n;XsmOW^3I-0'.M@J@CLL[4z-Xr:! VBjAT,##6[iSE.7+as8C.,7uleb=|y<t7sm$2z)k&dADF#uHXaZCLnhvLb.%+b(OyO$-2GuG~,y4NTWa=/LI3Q4w7%+Bm:!kpe&

```

```
ZoIMHa;v!]&j}wr@MGlX~F=(I[cs[N^M`=G=Avr*Z&Aq4V!c6>!m@~lJU:;cr"Xw!$OlzXD$Xi>_|*3t@qV?VR*It4gB;%>,e9W\1MeXy"wsA-V|rs$G4hY!G:%v?$uh-y~'Ltd.,(

```

The Hindenburg picture looks pretty crappy, but the others I like.

```
package main

import (
    "os"
    "image"
    "image/color"
    "image/png"
    _ "image/jpeg"
    "math"
    "math/big"
)

// we have 919 bits to play with: floor(log_2(95^140))

// encode_region(r):
//   0
//      color of region (12 bits, 4 bits each color)
// or
//   1
//      dividing line through region
//        2 bits - one of 4 anchor points
//        4 bits - one of 16 angles
//      encode_region(r1)
//      encode_region(r2)
//
// start with single region
// pick leaf region with most contrast, split it

type Region struct {
    points []image.Point
    anchor int  // 0-3
    angle int // 0-15
    children [2]*Region
}

// mean color of region
func (region *Region) meanColor(img image.Image) (float64, float64, float64) {
    red := 0.0
    green := 0.0
    blue := 0.0
    num := 0
    for _, p := range region.points {
        r, g, b, _ := img.At(p.X, p.Y).RGBA()
        red += float64(r)
        green += float64(g)
        blue += float64(b)
        num++
    }
    return red/float64(num), green/float64(num), blue/float64(num)
}

// total non-uniformity in region's color
func (region *Region) deviation(img image.Image) float64 {
    mr, mg, mb := region.meanColor(img)
    d := 0.0
    for _, p := range region.points {
        r, g, b, _ := img.At(p.X, p.Y).RGBA()
        fr, fg, fb := float64(r), float64(g), float64(b)
        d += (fr - mr) * (fr - mr) + (fg - mg) * (fg - mg) + (fb - mb) * (fb - mb)
    }
    return d
}

// centroid of region
func (region *Region) centroid() (float64, float64) {
    cx := 0
    cy := 0
    num := 0
    for _, p := range region.points {
        cx += p.X
        cy += p.Y
        num++
    }
    return float64(cx)/float64(num), float64(cy)/float64(num)
}

// a few points in (or near) the region.
func (region *Region) anchors() [4][2]float64 {
    cx, cy := region.centroid()

    xweight := [4]int{1,1,3,3}
    yweight := [4]int{1,3,1,3}
    var result [4][2]float64
    for i := 0; i < 4; i++ {
        dx := 0
        dy := 0
        numx := 0
        numy := 0
        for _, p := range region.points {
            if float64(p.X) > cx {
                dx += xweight[i] * p.X
                numx += xweight[i]
            } else {
                dx += (4 - xweight[i]) * p.X
                numx += 4 - xweight[i]
            }
            if float64(p.Y) > cy {
                dy += yweight[i] * p.Y
                numy += yweight[i]
            } else {
                dy += (4 - yweight[i]) * p.Y
                numy += 4 - yweight[i]
            }
        }
        result[i][0] = float64(dx) / float64(numx)
        result[i][1] = float64(dy) / float64(numy)
    }
    return result
}

func (region *Region) split(img image.Image) (*Region, *Region) {
    anchors := region.anchors()
    // maximize the difference between the average color on the two sides
    maxdiff := 0.0
    var maxa *Region = nil
    var maxb *Region = nil
    maxanchor := 0
    maxangle := 0
    for anchor := 0; anchor < 4; anchor++ {
        for angle := 0; angle < 16; angle++ {
            sin, cos := math.Sincos(float64(angle) * math.Pi / 16.0)
            a := new(Region)
            b := new(Region)
            for _, p := range region.points {
                dx := float64(p.X) - anchors[anchor][0]
                dy := float64(p.Y) - anchors[anchor][1]
                if dx * sin + dy * cos >= 0 {
                    a.points = append(a.points, p)
                } else {
                    b.points = append(b.points, p)
                }
            }
            if len(a.points) == 0 || len(b.points) == 0 {
                continue
            }
            a_red, a_green, a_blue := a.meanColor(img)
            b_red, b_green, b_blue := b.meanColor(img)
            diff := math.Abs(a_red - b_red) + math.Abs(a_green - b_green) + math.Abs(a_blue - b_blue)
            if diff >= maxdiff {
                maxdiff = diff
                maxa = a
                maxb = b
                maxanchor = anchor
                maxangle = angle
            }
        }
    }
    region.anchor = maxanchor
    region.angle = maxangle
    region.children[0] = maxa
    region.children[1] = maxb
    return maxa, maxb
}

// split regions take 7 bits plus their descendents
// unsplit regions take 13 bits
// so each split saves 13-7=6 bits on the parent region
// and costs 2*13 = 26 bits on the children, for a net of 20 bits/split
func (region *Region) encode(img image.Image) []int {
    bits := make([]int, 0)
    if region.children[0] != nil {
        bits = append(bits, 1)
        d := region.anchor
        a := region.angle
        bits = append(bits, d&1, d>>1&1)
        bits = append(bits, a&1, a>>1&1, a>>2&1, a>>3&1)
        bits = append(bits, region.children[0].encode(img)...)
        bits = append(bits, region.children[1].encode(img)...)
    } else {
        bits = append(bits, 0)
        r, g, b := region.meanColor(img)
        kr := int(r/256./16.)
        kg := int(g/256./16.)
        kb := int(b/256./16.)
        bits = append(bits, kr&1, kr>>1&1, kr>>2&1, kr>>3)
        bits = append(bits, kg&1, kg>>1&1, kg>>2&1, kg>>3)
        bits = append(bits, kb&1, kb>>1&1, kb>>2&1, kb>>3)
    }
    return bits
}

func encode(name string) []byte {
    file, _ := os.Open(name)
    img, _, _ := image.Decode(file)

    // encoding bit stream
    bits := make([]int, 0)

    // start by encoding the bounds
    bounds := img.Bounds()
    w := bounds.Max.X - bounds.Min.X
    for ; w > 3; w >>= 1 {
        bits = append(bits, 1, w & 1)
    }
    bits = append(bits, 0, w & 1)
    h := bounds.Max.Y - bounds.Min.Y
    for ; h > 3; h >>= 1 {
        bits = append(bits, 1, h & 1)
    }
    bits = append(bits, 0, h & 1)

    // make new region containing whole image
    region := new(Region)
    region.children[0] = nil
    region.children[1] = nil
    for y := bounds.Min.Y; y < bounds.Max.Y; y++ {
        for x := bounds.Min.X; x < bounds.Max.X; x++ {
            region.points = append(region.points, image.Point{x, y})
        }
    }

    // split the region with the most contrast until we're out of bits.
    regions := make([]*Region, 1)
    regions[0] = region
    for bitcnt := len(bits) + 13; bitcnt <= 919-20; bitcnt += 20 {
        var best_reg *Region
        best_dev := -1.0
        for _, reg := range regions {
            if reg.children[0] != nil {
                continue
            }
            dev := reg.deviation(img)
            if dev > best_dev {
                best_reg = reg
                best_dev = dev
            }
        }
        a, b := best_reg.split(img)
        regions = append(regions, a, b)
    }

    // encode regions
    bits = append(bits, region.encode(img)...)

    // convert to tweet
    n := big.NewInt(0)
    for i := 0; i < len(bits); i++ {
        n.SetBit(n, i, uint(bits[i]))
    }
    s := make([]byte,0)
    r := new(big.Int)
    for i := 0; i < 140; i++ {
        n.DivMod(n, big.NewInt(95), r)
        s = append(s, byte(r.Int64() + 32))
    }
    return s
}

// decodes and fills in region.  returns number of bits used.
func (region *Region) decode(bits []int, img *image.RGBA) int {
    if bits[0] == 1 {
        anchors := region.anchors()
        anchor := bits[1] + bits[2]*2
        angle := bits[3] + bits[4]*2 + bits[5]*4 + bits[6]*8
        sin, cos := math.Sincos(float64(angle) * math.Pi / 16.)
        a := new(Region)
        b := new(Region)
        for _, p := range region.points {
            dx := float64(p.X) - anchors[anchor][0]
            dy := float64(p.Y) - anchors[anchor][1]
            if dx * sin + dy * cos >= 0 {
                a.points = append(a.points, p)
            } else {
                b.points = append(b.points, p)
            }
        }
        x := a.decode(bits[7:], img)
        y := b.decode(bits[7+x:], img)
        return 7 + x + y
    }
    r := bits[1] + bits[2]*2 + bits[3]*4 + bits[4]*8
    g := bits[5] + bits[6]*2 + bits[7]*4 + bits[8]*8
    b := bits[9] + bits[10]*2 + bits[11]*4 + bits[12]*8
    c := color.RGBA{uint8(r*16+8), uint8(g*16+8), uint8(b*16+8), 255}
    for _, p := range region.points {
        img.Set(p.X, p.Y, c)
    }
    return 13
}

func decode(name string) image.Image {
    file, _ := os.Open(name)
    length, _ := file.Seek(0, 2)
    file.Seek(0, 0)
    tweet := make([]byte, length)
    file.Read(tweet)

    // convert to bit string
    n := big.NewInt(0)
    m := big.NewInt(1)
    for _, c := range tweet {
        v := big.NewInt(int64(c - 32))
        v.Mul(v, m)
        n.Add(n, v)
        m.Mul(m, big.NewInt(95))
    }
    bits := make([]int, 0)
    for ; n.Sign() != 0; {
        bits = append(bits, int(n.Int64() & 1))
        n.Rsh(n, 1)
    }
    for ; len(bits) < 919; {
        bits = append(bits, 0)
    }

    // extract width and height
    w := 0
    k := 1
    for ; bits[0] == 1; {
        w += k * bits[1]
        k <<= 1
        bits = bits[2:]
    }
    w += k * (2 + bits[1])
    bits = bits[2:]
    h := 0
    k = 1
    for ; bits[0] == 1; {
        h += k * bits[1]
        k <<= 1
        bits = bits[2:]
    }
    h += k * (2 + bits[1])
    bits = bits[2:]

    // make new region containing whole image
    region := new(Region)
    region.children[0] = nil
    region.children[1] = nil
    for y := 0; y < h; y++ {
        for x := 0; x < w; x++ {
            region.points = append(region.points, image.Point{x, y})
        }
    }

    // new image
    img := image.NewRGBA(image.Rectangle{image.Point{0, 0}, image.Point{w, h}})

    // decode regions
    region.decode(bits, img)

    return img
}

func main() {
    if os.Args[1] == "encode" {
        s := encode(os.Args[2])
        file, _ := os.Create(os.Args[3])
        file.Write(s)
        file.Close()
    }
    if os.Args[1] == "decode" {
        img := decode(os.Args[2])
        file, _ := os.Create(os.Args[3])
        png.Encode(file, img)
        file.Close()
    }
}

```
> 37 votes

# Answer
## Python

***Encoding requires numpy, SciPy and scikit-image.<br>Decoding requires only PIL.***

This is a method based on superpixel interpolation. To begin, each image is divided into *70* similar sized regions of similar color. For example, the landscape picture is divided in the following manner:

The centroid of each region is located (to the nearest raster point on a grid containing no more than 402 points), as well as it's average color (from a 216 color palette), and each of these regions is encoded as a number from *0* to *86832*, capable of being stored in *2.5* printable ascii characters (actually *2.497*, leaving just enough room to encode for a greyscale bit).

If you're attentive, you may have noticed that *140 / 2.5 = 56* regions, and not *70* as I stated earlier. Notice, however, that each of these regions is a unique, comparable object, which may be listed in any order. Because of this, we can use the *permutation* of the first *56* regions to encode for the other *14*, as well as having a few bits left over to store the aspect ratio.

More specifically, each of the additional *14* regions is converted to a number, and then each of these numbers concatenated together (multiplying the current value by *86832*, and adding the next). This (gigantic) number is then converted to a permutation on *56* objects.

For example:

```
from my_geom import *

# this can be any value from 0 to 56!, and it will map unambiguously to a permutation
num = 595132299344106583056657556772129922314933943196204990085065194829854239
perm = num2perm(num, 56)
print perm
print perm2num(perm)

```

will output:

```
[0, 3, 33, 13, 26, 22, 54, 12, 53, 47, 8, 39, 19, 51, 18, 27, 1, 41, 50, 20, 5, 29, 46, 9, 42, 23, 4, 37, 21, 49, 2, 6, 55, 52, 36, 7, 43, 11, 30, 10, 34, 44, 24, 45, 32, 28, 17, 35, 15, 25, 48, 40, 38, 31, 16, 14]
595132299344106583056657556772129922314933943196204990085065194829854239

```

The resulting permutation is then applied to the original *56* regions. The original number (and thus the additional *14* regions) can likewise be extracted by converting the permutation of the *56* encoded regions into its numerical representation.

When the `--greyscale` option is used with the encoder, *94* regions are used instead (separated *70*, *24*), with *558* raster points, and *16* shades of grey.

When decoding, each of these regions is treated as a 3D cone extended into infinity, with its vertex at the centroid of the region, as viewed from above (a.k.a. a Voronoi Diagram). The borders are then blended together to create the final product.

### Future Improvements

1. ~~The dimensions of the Mona Lisa are a bit off, due to the way I'm storing the aspect ratio. I'll need to use a different system.~~ *Fixed, by assuming that the original aspect ratio is somewhere between 1:21 and 21:1, which I think is a reasonable assumption.*
2. ~~The Hindenburg could be improved a lot. The color palette I'm using only has 6 shades of grey. If I introduced a greyscale-only mode, I could use the extra information to increase the color depth, number of regions, number of raster points, or any combination of the three.~~ *I've added a `--greyscale` option to the encoder, which does all three.*
3. ~~2d Shapes would probably look better with blending turned off. I'll likely add a flag for that.~~ *Added an encoder option to control the segmentation ratio, and a decoder option to turn off blending.*
4. More fun with combinatorics. *56!* is actually large enough to store *15* additional regions, and *15!* is large enough to store *2* more for a grand total of *73*. But wait, there's more! The partitioning of these *73* object could also be used to store more information. For example, there are *73 choose 56* ways to select the initial *56* regions, and then *17 choose 15* ways to select the next *15*. A grand total of *2403922132944423072* partitionings, big enough to store *3* more regions for a total of *76*. I'd need to come up with a clever way to uniquely number all partitions of *73* into groups of *56*, *15*, *2* ... *and back*. Perhaps not practical, but an interesting problem to think about.

---

```
0VW*`Gnyq;c1JBY}tj#rOcKm)v_Ac\S.r[>,Xd_(qT6 >]!xOfU9~0jmIMG{hcg-'*a.s<X]6*%U5>/FOze?cPv@hI)PjpK9\iA7P ]a-7eC&ttS[]K>NwN-^$T1E.1OH^c0^"J 4V9X

```

---

```
0Jc?NsbD#1WDuqT]AJFELu<!iE3d!BB>jOA'L|<j!lCWXkr:gCXuD=D\BL{gA\ 8#*RKQ*tv\\3V0j;_4|o7>{Xage-N85):Q/Hl4.t&'0pp)d|Ry+?|xrA6u&2E!Ls]i]T<~)58%RiA

```

and

```
4PV 9G7X|}>pC[Czd!5&rA5 Eo1Q\+m5t:r#;H65NIggfkw'h4*gs.:~<bt'VuVL7V8Ed5{`ft7e>HMHrVVUXc.{#7A|#PBm,i>1B781.K8>s(yUV?a<*!mC@9p+Rgd<twZ.wuFnN dp

```

The second one encoded with the `--greyscale` option.

---

```
3dVY3TY?9g+b7!5n`)l"Fg H$ 8n?[Q-4HE3.c:[pBBaH`5'MotAj%a4rIodYO.lp$h a94$n!M+Y?(eAR,@Y*LiKnz%s0rFpgnWy%!zV)?SuATmc~-ZQardp=?D5FWx;v=VA+]EJ(:%

```

Encoded with the `--greyscale` option.

---

```
.9l% Ge<'_)3(`DTsH^eLn|l3.D_na,,sfcpnp{"|lSv<>}3b})%m2M)Ld{YUmf<Uill,*:QNGk,'f2; !2i88T:Yjqa8\Ktz4i@h2kHeC|9,P` v7Xzd Yp&z:'iLra&X&-b(g6vMq

```

Encoded with `--ratio 60`, and decoded with `--no-blending` options.

---

encoder.py

```
from __future__ import division
import argparse, numpy
from skimage.io import imread
from skimage.transform import resize
from skimage.segmentation import slic
from skimage.measure import regionprops
from my_geom import *

def encode(filename, seg_ratio, greyscale):
  img = imread(filename)

  height = len(img)
  width = len(img[0])
  ratio = width/height

  if greyscale:
    raster_size = 558
    raster_ratio = 11
    num_segs = 94
    set1_len = 70
    max_num = 8928  # 558 * 16
  else:
    raster_size = 402
    raster_ratio = 13
    num_segs = 70
    set1_len = 56
    max_num = 86832 # 402 * 216

  raster_width = (raster_size*ratio)**0.5
  raster_height = int(raster_width/ratio)
  raster_width = int(raster_width)

  resize_height = raster_height * raster_ratio
  resize_width = raster_width * raster_ratio

  img = resize(img, (resize_height, resize_width))

  segs = slic(img, n_segments=num_segs-4, ratio=seg_ratio).astype('int16')

  max_label = segs.max()
  numpy.place(segs, segs==0, [max_label+1])
  regions = [None]*(max_label+2)

  for props in regionprops(segs):
    label = props['Label']
    props['Greyscale'] = greyscale
    regions[label] = Region(props)

  for i, a in enumerate(regions):
    for j, b in enumerate(regions):
      if a==None or b==None or a==b: continue
      if a.centroid == b.centroid:
        numpy.place(segs, segs==j, [i])
        regions[j] = None

  for y in range(resize_height):
    for x in range(resize_width):
      label = segs[y][x]
      regions[label].add_point(img[y][x])

  regions = [r for r in regions if r != None]

  if len(regions)>num_segs:
    regions = sorted(regions, key=lambda r: r.area)[-num_segs:]

  regions = sorted(regions, key=lambda r: r.to_num(raster_width))

  set1, set2 = regions[-set1_len:], regions[:-set1_len]

  set2_num = 0
  for s in set2:
    set2_num *= max_num
    set2_num += s.to_num(raster_width)

  set2_num = ((set2_num*85 + raster_width)*85 + raster_height)*25 + len(set2)
  perm = num2perm(set2_num, set1_len)
  set1 = permute(set1, perm)

  outnum = 0
  for r in set1:
    outnum *= max_num
    outnum += r.to_num(raster_width)

  outnum *= 2
  outnum += greyscale

  outstr = ''
  for i in range(140):
    outstr = chr(32 + outnum%95) + outstr
    outnum //= 95

  print outstr

parser = argparse.ArgumentParser(description='Encodes an image into a tweetable format.')
parser.add_argument('filename', type=str,
  help='The filename of the image to encode.')
parser.add_argument('--ratio', dest='seg_ratio', type=float, default=30,
  help='The segmentation ratio. Higher values (50+) will result in more regular shapes, lower values in more regular region color.')
parser.add_argument('--greyscale', dest='greyscale', action='store_true',
  help='Encode the image as greyscale.')
args = parser.parse_args()

encode(args.filename, args.seg_ratio, args.greyscale)

```

decoder.py

```
from __future__ import division
import argparse
from PIL import Image, ImageDraw, ImageChops, ImageFilter
from my_geom import *

def decode(instr, no_blending=False):
  innum = 0
  for c in instr:
    innum *= 95
    innum += ord(c) - 32

  greyscale = innum%2
  innum //= 2

  if greyscale:
    max_num = 8928
    set1_len = 70
    image_mode = 'L'
    default_color = 0
    raster_ratio = 11
  else:
    max_num = 86832
    set1_len = 56
    image_mode = 'RGB'
    default_color = (0, 0, 0)
    raster_ratio = 13

  nums = []
  for i in range(set1_len):
    nums = [innum%max_num] + nums
    innum //= max_num

  set2_num = perm2num(nums)

  set2_len = set2_num%25
  set2_num //= 25

  raster_height = set2_num%85
  set2_num //= 85
  raster_width = set2_num%85
  set2_num //= 85

  resize_width = raster_width*raster_ratio
  resize_height = raster_height*raster_ratio

  for i in range(set2_len):
    nums += set2_num%max_num,
    set2_num //= max_num

  regions = []
  for num in nums:
    r = Region()
    r.from_num(num, raster_width, greyscale)
    regions += r,

  masks = []

  outimage = Image.new(image_mode, (resize_width, resize_height), default_color)

  for a in regions:
    mask = Image.new('L', (resize_width, resize_height), 255)
    for b in regions:
      if a==b: continue
      submask = Image.new('L', (resize_width, resize_height), 0)
      poly = a.centroid.bisected_poly(b.centroid, resize_width, resize_height)
      ImageDraw.Draw(submask).polygon(poly, fill=255, outline=255)
      mask = ImageChops.multiply(mask, submask)
    outimage.paste(a.avg_color, mask=mask)

  if not no_blending:
    outimage = outimage.resize((raster_width, raster_height), Image.ANTIALIAS)
    outimage = outimage.resize((resize_width, resize_height), Image.BICUBIC)
    smooth = ImageFilter.Kernel((3,3),(1,2,1,2,4,2,1,2,1))
    for i in range(20):outimage = outimage.filter(smooth)
  outimage.show()

parser = argparse.ArgumentParser(description='Decodes a tweet into and image.')
parser.add_argument('--no-blending', dest='no_blending', action='store_true',
    help="Do not blend the borders in the final image.")
args = parser.parse_args()

instr = raw_input()
decode(instr, args.no_blending)

```

my\_geom.py

```
from __future__ import division

class Point:
  def __init__(self, x, y):
    self.x = x
    self.y = y
    self.xy = (x, y)

  def __eq__(self, other):
    return self.x == other.x and self.y == other.y

  def __lt__(self, other):
    return self.y < other.y or (self.y == other.y and self.x < other.x)

  def inv_slope(self, other):
    return (other.x - self.x)/(self.y - other.y)

  def midpoint(self, other):
    return Point((self.x + other.x)/2, (self.y + other.y)/2)

  def dist2(self, other):
    dx = self.x - other.x
    dy = self.y - other.y
    return dx*dx + dy*dy

  def bisected_poly(self, other, resize_width, resize_height):
    midpoint = self.midpoint(other)
    points = []
    if self.y == other.y:
      points += (midpoint.x, 0), (midpoint.x, resize_height)
      if self.x < midpoint.x:
        points += (0, resize_height), (0, 0)
      else:
        points += (resize_width, resize_height), (resize_width, 0)
      return points
    elif self.x == other.x:
      points += (0, midpoint.y), (resize_width, midpoint.y)
      if self.y < midpoint.y:
        points += (resize_width, 0), (0, 0)
      else:
        points += (resize_width, resize_height), (0, resize_height)
      return points
    slope = self.inv_slope(other)
    y_intercept = midpoint.y - slope*midpoint.x
    if self.y > midpoint.y:
      points += ((resize_height - y_intercept)/slope, resize_height),
      if slope < 0:
        points += (resize_width, slope*resize_width + y_intercept), (resize_width, resize_height)
      else:
        points += (0, y_intercept), (0, resize_height)
    else:
      points += (-y_intercept/slope, 0),
      if slope < 0:
        points += (0, y_intercept), (0, 0)
      else:
        points += (resize_width, slope*resize_width + y_intercept), (resize_width, 0)
    return points

class Region:
  def __init__(self, props={}):
    if props:
      self.greyscale = props['Greyscale']
      self.area = props['Area']
      cy, cx = props['Centroid']
      if self.greyscale:
        self.centroid = Point(int(cx/11)*11+5, int(cy/11)*11+5)
      else:
        self.centroid = Point(int(cx/13)*13+6, int(cy/13)*13+6)
    self.num_pixels = 0
    self.r_total = 0
    self.g_total = 0
    self.b_total = 0

  def __lt__(self, other):
    return self.centroid < other.centroid

  def add_point(self, rgb):
    r, g, b = rgb
    self.r_total += r
    self.g_total += g
    self.b_total += b
    self.num_pixels += 1
    if self.greyscale:
      self.avg_color = int((3.2*self.r_total + 10.7*self.g_total + 1.1*self.b_total)/self.num_pixels + 0.5)*17
    else:
      self.avg_color = (
        int(5*self.r_total/self.num_pixels + 0.5)*51,
        int(5*self.g_total/self.num_pixels + 0.5)*51,
        int(5*self.b_total/self.num_pixels + 0.5)*51)

  def to_num(self, raster_width):
    if self.greyscale:
      raster_x = int((self.centroid.x - 5)/11)
      raster_y = int((self.centroid.y - 5)/11)
      return (raster_y*raster_width + raster_x)*16 + self.avg_color//17
    else:
      r, g, b = self.avg_color
      r //= 51
      g //= 51
      b //= 51
      raster_x = int((self.centroid.x - 6)/13)
      raster_y = int((self.centroid.y - 6)/13)
      return (raster_y*raster_width + raster_x)*216 + r*36 + g*6 + b

  def from_num(self, num, raster_width, greyscale):
    self.greyscale = greyscale
    if greyscale:
      self.avg_color = num%16*17
      num //= 16
      raster_x, raster_y = num%raster_width, num//raster_width
      self.centroid = Point(raster_x*11 + 5, raster_y*11+5)
    else:
      rgb = num%216
      r, g, b = rgb//36, rgb//6%6, rgb%6
      self.avg_color = (r*51, g*51, b*51)
      num //= 216
      raster_x, raster_y = num%raster_width, num//raster_width
      self.centroid = Point(raster_x*13 + 6, raster_y*13 + 6)

def perm2num(perm):
  num = 0
  size = len(perm)
  for i in range(size):
    num *= size-i
    for j in range(i, size): num += perm[j]<perm[i]
  return num

def num2perm(num, size):
  perm = [0]*size
  for i in range(size-1, -1, -1):
    perm[i] = int(num%(size-i))
    num //= size-i
    for j in range(i+1, size): perm[j] += perm[j] >= perm[i]
  return perm

def permute(arr, perm):
  size = len(arr)
  out = [0] * size
  for i in range(size):
    val = perm[i]
    out[i] = arr[val]
  return out

```
> 36 votes

# Answer
# PHP

OK, took me a while, but here it is. All images in greyscale. Colors took too many bits to encode for my method :P

---

**Mona Lisa**
**47** Colors Monochrome
**101** byte string.

```
dt99vvv9t8G22+2eZbbf55v3+fAH9X+AD/0BAF6gIOX5QRy7xX8em9/UBAEVXKiiqKqqqiqqqqNqqqivtXqqMAFVUBVVVVVVVVVVU

```

---

**2D Shapes**
**36** Colors Monochrome
**105** byte string.

```
oAAAAAAABMIDUAAEBAyoAAAAAgAwAAAAADYBtsAAAJIDbYAAAAA22AGwAAAAAGwAAAAAAAAAAKgAAAAAqgAAAACoAAAAAAAAAAAAAAAAA

```

---

**Hindenburg**
**62** Colors Monochrome
**112** characters.

```
t///tCSuvv/99tmwBI3/21U5gCW/+2bdDMxLf+r6VsaHb/tt7TAodv+NhtbFVX/bGD1IVq/4MAHbKq/4AABbVX/AQAFN1f8BCBFntb/6ttYdWnfg

```

---

**Mountains**
**63** Colors Monochrome
**122** characters.

```
qAE3VTkaIAKgqSFigAKoABgQEqAABuAgUQAGenRIBoUh2eqhABCee/2qSSAQntt/s2kJCQbf/bbaJgbWebzqsPZ7bZttwABTc3VAUFDbKqqpzY5uqpudnp5vZg

```

---

**My Method**

I encode my bitstream with a type of base64 encoding. Before it's encoded into readable text, here's what happens.

I load the source image and resize it to a maximum height or width (depending on orientation, portrait/landscape) of 20 pixels.

Next I recolor each pixel of the new image to it's closest match on a 6 color greyscale palette.

After that's done, I create a string with each pixel color represented by the letters \[A-F\].

I then calculate the distribution of the 6 different letters within the string and select the most optimized binary tree for encoding based on the letter frequencies. There are 15 possible binary trees.

I start my bit stream with a single bit, `[1|0]` depending on whether the image is tall or wide. I then use the next 4 bits in the stream to inform the decoder which binary tree should be used to decode the image.

What follows is the stream of bits representing the image. Each pixel and it's color is represented by either 2 or 3 bits. This allows me to store at least 2 and up to 3 pixels worth of information for every printed ascii character. Here's a sample of binary tree `1110`, which is used by the Mona Lisa:

```
    TREE
   /    \
  #      #
 / \    / \
E   #  F   #
   / \    / \
  A   B  C   D

```

The letters E `00` and F `10` are the most common colors in the Mona Lisa. A `010`, B `011`, C `110`, and D `111` are the least frequent.

Binary trees work like this: Going from bit to bit, `0` means go left, `1` means go right. Keep going until you hit a leaf on the tree, or a dead end. The leaf you end up on is the character you want.

Anyways, I encode the binary sting into base64 characters. When decoding the string, the process is done in reverse, assigning all the pixels to the appropriate color, and then the image is scaled twice the encoded size (maximum 40 pixels either X or Y, whichever is larger) and then a convolution matrix is applied to the whole thing to smooth out the colors.

Anyways, here's the current code: "pastebin link"

It's ugly, but if you see any room for improvements, let me know. I hacked it together as I want along. I LEARNED **A LOT** FROM THIS CHALLENGE. Thank you OP for posting it!
> 17 votes

# Answer
My first attempt. This has room for improvement. I think that the format itself actually works, the issue is in the encoder. That, and I'm missing individual bits from my output... my (slightly higher quality then here) file ended up at 144 characters, when there should have been some left. (and I really wish there was - the differences between these and those are noticeable). I learnt though, never overestimate how big 140 characters is...

I bring it down to a modified version of the RISC-OS palette - basically, because I needed a 32 colour palette, and that seemed like a good enough place to start. This could do with some changing too I think.

I break it down into the following shapes: and split the image into palette blocks (in this case, 2x2 pixels) of a front and back color.

## Results:

Following are the tweets, the originals and how the tweet is decoded

```
*=If`$aX:=|"&brQ(EPZwxu4H";|-^;lhJCfQ(W!TqWTai),Qbd7CCtmoc(-hXt]/l87HQyaYTEZp{eI`/CtkHjkFh,HJWw%5[d}VhHAWR(@;M's$VDz]17E@6

```

```
"&7tpnqK%D5kr^u9B]^3?`%;@siWp-L@1g3p^*kQ=5a0tBsA':C0"*QHVDc=Z='Gc[gOpVcOj;_%>.aeg+JL4j-u[a$WWD^)\tEQUhR]HVD5_-e`TobI@T0dv_el\H1<1xw[|D

```

```
)ey`ymlgre[rzzfi"K>#^=z_Wi|@FWbo#V5|@F)uiH?plkRS#-5:Yi-9)S3:#3 Pa4*lf TBd@zxa0g;li<O1XJ)YTT77T1Dg1?[w;X"U}YnQE(NAMQa2QhTMYh..>90DpnYd]?

```

```
%\MaaX/VJNZX=Tq,M>2"AwQVR{(Xe L!zb6(EnPuEzB}Nk:U+LAB_-K6pYlue"5*q>yDFw)gSC*&,dA98`]$2{&;)[ 4pkX |M _B4t`pFQT8P&{InEh>JHYn*+._[b^s754K_

```

I know the colours are wrong, but I actually like the Monalisa. If I removed the blur (which wouldn't be too hard), it's a reasonable cubist impression :p

I need to work on

* Adding shape detection
* A better colour "difference" algorithm
* Figuring out where my missing bits went

I'll give it some more work later to try to fix those, and improved the encoder. Those extra 20 or so characters make a massive amount of difference. I'd like them back.

The C# source and colour palette are on https://dl.dropboxusercontent.com/u/46145976/Base96.zip \- although, in hindsight, may not work perfectly when run separately (as spaces in arguments to programs don't go so well).

The encoder takes less then a couple of seconds on my fairly average machine.
> 13 votes

# Answer
I gave up on trying to keep the colour and went black and white, since everything I tried with colour was unrecognisable.

Basically all it does is divide pixels into 3 approximately equal parts: black, grey and white. It also doesn't keep the size.

## Hindenburg

```
~62RW.\7`?a9}A.jvCedPW0t)]g/e4 |+D%n9t^t>wO><",C''!!Oh!HQq:WF>\uEG?E=Mkj|!u}TC{7C7xU:bb`We;3T/2:Zw90["$R25uh0732USbz>Q;q"

```

## Mona Lisa

```
=lyZ(i>P/z8]Wmfu>] T55vZB:/>xMz#Jqs6U3z,)n|VJw<{Mu2D{!uyl)b7B6x&I"G0Y<wdD/K4hfrd62_8C\W7ArNi6R\Xz%f U[);YTZFliUEu{m%[gw10rNY_`ICNN?_IB/C&=T

```

## Mountains

```
+L5#~i%X1aE?ugVCulSf*%-sgIg8hQ3j/df=xZv2v?'XoNdq=sb7e '=LWm\E$y?=:"#l7/P,H__W/v]@pwH#jI?sx|n@h\L %y(|Ry.+CvlN $Kf`5W(01l2j/sdEjc)J;Peopo)HJ

```

## Shapes

```
3A"3yD4gpFtPeIImZ$g&2rsdQmj]}gEQM;e.ckbVtKE(U$r?{,S>tW5JzQZDzoTy^mc+bUV vTUG8GXs{HX'wYR[Af{1gKwY|BD]V1Z'J+76^H<K3Db>Ni/D}][n#uwll[s'c:bR56:

```

Here's the program. `python compress.py -c img.png` compresses `img.png` and prints the tweet.

`python compress.py -d img.png` takes the tweet from stdin and saves the image to `img.png`.

```
from PIL import Image
import sys
quanta  = 3
width   = 24
height  = 24

def compress(img):
    pix = img.load()
    psums = [0]*(256*3)
    for x in range(width):
        for y in range(height):
            r,g,b,a = pix[x,y]
            psums[r+g+b] += 1
    s = 0
    for i in range(256*3):
        s = psums[i] = psums[i]+s

    i = 0
    for x in range(width):
        for y in range(height):
            r,g,b,a = pix[x,y]
            t = psums[r+g+b]*quanta / (width*height)
            if t == quanta:
                t -= 1
            i *= quanta
            i += t
    s = []
    while i:
        s += chr(i%95 + 32)
        i /= 95
    return ''.join(s)

def decompress(s):
    i = 0
    for c in s[::-1]:
        i *= 95
        i += ord(c) - 32
    img = Image.new('RGB',(width,height))
    pix = img.load()
    for x in range(width)[::-1]:
        for y in range(height)[::-1]:
            t = i % quanta
            i /= quanta
            t *= 255/(quanta-1)
            pix[x,y] = (t,t,t)
    return img

if sys.argv[1] == '-c':
    img = Image.open(sys.argv[2]).resize((width,height))
    print compress(img)
elif sys.argv[1] == '-d':
    img = decompress(raw_input())
    img.resize((256,256)).save(sys.argv[2],'PNG')

```
> 13 votes

# Answer
My modest contribution in R:

```
encoder<-function(img_file){
    img0 <- as.raster(png::readPNG(img_file))
    d0 <- dim(img0)
    r <- d0[1]/d0[2]
    f <- floor(sqrt(140/r))
    d1 <- c(floor(f*r),f)
    dx <- floor(d0[2]/d1[2])
    dy <- floor(d0[1]/d1[1])
    img1 <- matrix("",ncol=d1[2],nrow=d1[1])
    x<-seq(1,d0[1],by=dy)
    y<-seq(1,d0[2],by=dx)
    for(i in seq_len(d1[1])){
        for (j in seq_len(d1[2])){
            img1[i,j]<-names(which.max(table(img0[x[i]:(x[i]+dy-1),y[j]:(y[j]+dx-1)])))
            }
        }
    img2 <- as.vector(img1)
    table1 <- array(sapply(seq(0,255,length=4),function(x)sapply(seq(0,255,length=4),function(y)sapply(seq(0,255,length=4),function(z)rgb(x/255,y/255,z/255)))),dim=c(4,4,4))
    table2 <- array(strsplit(rawToChar(as.raw(48:(48+63))),"")[[1]],dim=c(4,4,4))
    table3 <- cbind(1:95,sapply(32:126,function(x)rawToChar(as.raw(x))))
    a <- as.array(cut(colorspace::hex2RGB(img2)@coords,breaks=seq(0,1,length=5),include.lowest=TRUE))
    dim(a) <- c(length(img2),3)
    img3 <- apply(a,1,function(x)paste("#",c("00","55","AA","FF")[x[1]],c("00","55","AA","FF")[x[2]],c("00","55","AA","FF")[x[3]],sep=""))
    res<-paste(sapply(img3,function(x)table2[table1==x]),sep="",collapse="")
    paste(table3[table3[,1]==d1[1],2],table3[table3[,1]==d1[2],2],res,collapse="",sep="")
    }

decoder<-function(string){
    s <- unlist(strsplit(string,""))
    table1 <- array(sapply(seq(0,255,length=4),function(x)sapply(seq(0,255,length=4),function(y)sapply(seq(0,255,length=4),function(z)rgb(x/255,y/255,z/255)))),dim=c(4,4,4))
    table2 <- array(strsplit(rawToChar(as.raw(48:(48+63))),"")[[1]],dim=c(4,4,4))
    table3 <- cbind(1:95,sapply(32:126,function(x)rawToChar(as.raw(x))))
    nr<-as.integer(table3[table3[,2]==s[1],1])
    nc<-as.integer(table3[table3[,2]==s[2],1])
    img <- sapply(s[3:length(s)],function(x){table1[table2==x]})
    png(w=nc,h=nr,u="in",res=100)
    par(mar=rep(0,4))
    plot(c(1,nr),c(1,nc),type="n",axes=F,xaxs="i",yaxs="i")
    rasterImage(as.raster(matrix(img,nr,nc)),1,1,nr,nc)
    dev.off()
    }

```

The idea is simply to reduce the raster (file has to be in png) to a matrix whose number of cell is lower than 140, the tweets is then a serie of colors (in 64 colors) preceded by two characters indicated the number of rows and columns of the raster.

```
encoder("Mona_Lisa.png")
[1] ",(XXX000@000000XYi@000000000TXi0000000000TX0000m000h00T0hT@hm000000T000000000000XX00000000000XXi0000000000TXX0000000000"

```

```
encoder("630x418.png") # Not a huge success for this one :)
[1] "(-00000000000000000000EEZZooo00E0ZZooo00Z00Zooo00Zo0oooooEZ0EEZoooooooEZo0oooooo000ooZ0Eo0000oooE0EE00oooEEEE0000000E00000000000"

```

```
encoder("2d shapes.png")
[1] "(,ooooooooooooooooooooo``ooooo0o``oooooooooo33ooooooo33oo0ooooooooooo>>oooo0oooooooo0ooooooooooooolloooo9oolooooooooooo"

```

```
encoder("mountains.png")
[1] "(,_K_K0005:_KKK0005:__OJJ006:_oKKK00O:;;_K[[4OD;;Kooo4_DOKK_o^D_4KKKJ_o5o4KK__oo4_0;K___o5JDo____o5Y0____440444040400D4"

```
> 7 votes

# Answer
**Not a complete solution, just putting the method out there. (Matlab)**

I used a 16 color palette and 40 position to create a weighted voronoi diagram. Used genetic algorithm and simple hill-climbing algorithm to fit the image.

Album with original image and I also have a **16 byte version** with 4 colors and fixed positions there. :)

(Can I resize image here?)
> 4 votes

# Answer
# C#

# Update - Version 2

---

I made another attempt at this, now using MagickImage.NET(https://magick.codeplex.com/) to encode the JPEG data, I also wrote some basic code to better process JPEG header data(as primo suggested), I also used GuassianBlur on the output which help soften some of the JPEG compression. As the new version preforms better, I've updated my post to reflect the new method.

# Method

---

I've tried something unique(hopefully), rather than trying to manipulate the color depth, or edge identification, or trying to use different ways to reduce the images size myself I've used the JPEG algorithm at maximum compression on scaled down versions of the images, then by eliminating everything but the "StartOfScan"(http://en.wikipedia.org/wiki/JPEG#Syntax\_and\_structure) and a few key header elements I'm able to get the size down to a acceptable amount. The results are actually pretty impressive for 140 characters, gives me a new found respect for JPEG's:

## Hindenburg

```
,$`"(b $!   _ &4j6k3Qg2ns2"::4]*;12T|4z*4n*4<T~a4- ZT_%-.13`YZT;??e#=*!Q033*5>z?1Ur;?2i2^j&r4TTuZe2444b*:>z7.:2m-*.z?|*-Pq|*,^Qs<m&?:e--

```

## Mountains

```
,$  (a`,!  (1 Q$ /P!U%%%,0b*2nr4 %)3t4 +3#UsZf3S2 7-+m1Yqis k2U'm/#"h q2T4#$s.]/)%1T &*,4Ze w$Q2Xqm&: %Q28qiqm Q,48Xq12 _

```

## Mona Lisa

```
23  (a`,!  (1 Q$ /P q1Q2Tc$q0,$9--/!p Ze&:6`#*,Tj6l0qT%(:!m!%(84|TVk0(*2k24P)!e(U,q2x84|Tj*8a1a-%** $r4_--Xr&)12Tj8a2Tj* %r444 %%%% !

```

## Shapes

```
(ep 1# ,!  (1 Q$ /P"2`#=WTp $X[4 &[Vp p<T +0 cP* 0W=["jY5cZ9(4 (<]t  ]Z %ZT -P!18=V+UZ4" #% i6%r}#"l p QP>*r $!Yq(!]2 jo* zp!0 4 % !0 4 % '!

```

# Code

---

## Version 2 - http://pastebin.com/Tgr8XZUQ

I'm really starting to miss ReSharper + I have allot of things to improve, still allot of hard coding going on here, interesting to mess with though(remember you need MagickImage dll's to get this to run in VS)

## Original(Deprecated) - http://pastebin.com/BDPT0BKT

Still bit of a mess.
> 4 votes

# Answer
## Python 3

# Method

What the program does first is scaling down the image, greatly decreasing its size.

Second, it converts the rgb values into binary, and snips off the last few digits.

Then it converts the base 2 data into base 10, where it adds the dimensions of the picture.

Then it converts the data in base 10 to base 95, using all the ascii I could find. However, I could not use /x01 and the like because of its ability to negate the function that wrote out the text file.

And (for added ambiguity), the decode function does it in reverse.

# compress.py

```
    from PIL import Image
def FromBase(digits, b): #converts to base 10 from base b
    numerals='''0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!@#$%^&*()_-+={[}]|:;"',<.>/?`~\\ '''
    D=[]
    for d in range(0,len(digits)):
        D.append(numerals.index(digits[d]))
    s=0
    D=D[::-1]
    for x in range(0,len(D)):
        s+=D[x]*(b**x)
    return(str(s))
def ToBase(digits,b): #converts from base 10 to base b
    numerals='''0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!@#$%^&*()_-+={[}]|:;"',<.>/?`~\\ '''
    d=int(digits)
    D=''
    B=b
    while(B<=d):
        B*=b
    B//=b
    while(B>=1):
        D+=numerals[d//B]
        d-=((d//B)*B)
        B//=b
    return(D)
im=Image.open('1.png')
size=im.size
scale_factor=40
im=im.resize((int(size[0]/scale_factor),int(size[1]/scale_factor)), Image.ANTIALIAS)
a=list(im.getdata())
K=''
for x in a:
    for y in range(0,3):
        Y=bin(x[y])[2:]
        while(len(Y))<9:
            Y='0'+Y
        K+=str(Y)[:-5]
K='1'+K
print(len(K))
K=FromBase(K,2)
K+=str(size[0])
K+=str(size[1])
K=ToBase(K,95)
with open('1.txt', 'w') as outfile:
    outfile.write(K)

```

# decode.py

```
    from random import randint, uniform
from PIL import Image, ImageFilter
import math
import json
def FromBase(digits, b): #str converts to base 10 from base b
    numerals='''0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!@#$%^&*()_-+={[}]|:;"',<.>/?`~\\ \x01\x02\x03\x04\x05\x06\x07'''
    D=[]
    for d in range(0,len(digits)):
        D.append(numerals.index(digits[d]))
    s=0
    D=D[::-1]
    for x in range(0,len(D)):
        s+=D[x]*(b**x)
    return(str(s))
def ToBase(digits,b): #str converts from base 10 to base b
    numerals='''0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!@#$%^&*()_-+={[}]|:;"',<.>/?`~\\ \x01\x02\x03\x04\x05\x06\x07'''
    d=int(digits)
    D=''
    B=b
    while(B<=d):
        B*=b
    B//=b
    while(B>=1):
        D+=numerals[d//B]
        d-=((d//B)*B)
        B//=b
    return(D)
scale_factor=40
K=open('1.txt', 'r').read()
K=FromBase(K,95)
size=[int(K[-6:][:-3])//scale_factor,int(K[-6:][-3:])//scale_factor]
K=K[:-6]
K=ToBase(K,2)
K=K[1:]
a=[]
bsize=4
for x in range(0,len(K),bsize*3):
    Y=''
    for y in range(0,bsize*3):
        Y+=K[x+y]
    y=[int(Y[0:bsize]+'0'*(9-bsize)),int(Y[bsize:bsize*2]+'0'*(9-bsize)),int(Y[bsize*2:bsize*3]+'0'*(9-bsize))]
    y[0]=int(FromBase(str(y[0]),2))
    y[1]=int(FromBase(str(y[1]),2))
    y[2]=int(FromBase(str(y[2]),2))
    a.append(tuple(y))
im=Image.new('RGB',size,'black')
im.putdata(a[:size[0]*size[1]])
im=im.resize((int(size[0]*scale_factor),int(size[1]*scale_factor)), Image.ANTIALIAS)
im.save('pic.png')

```

# The Scream

```
hqgyXKInZo9-|A20A*53ljh[WFUYu\;eaf_&Y}V/@10zPkh5]6K!Ur:BDl'T/ZU+`xA4'\}z|8@AY/5<cw /8hQq[dR1S 2B~aC|4Ax"d,nX`!_Yyk8mv6Oo$+k>_L2HNN.#baA

```

# Mona Lisa

```
f4*_!/J7L?,Nd\#q$[f}Z;'NB[vW%H<%#rL_v4l_K_ >gyLMKf; q9]T8r51it$/e~J{ul+9<*nX0!8-eJVB86gh|:4lsCumY4^y,c%e(e3>sv(.y>S8Ve.tu<v}Ww=AOLrWuQ)

```

# Spheres

```
})|VF/h2i\(D?Vgl4LF^0+zt$d}<M7E5pTA+=Hr}{VxNs m7Y~\NLc3Q"-<|;sSPyvB[?-B6~/ZHaveyH%|%xGi[Vd*SPJ>9)MKDOsz#zNS4$v?qM'XVe6z\

```
> 1 votes

---
Tags: code-challenge, printable-ascii, compression, image-processing
---


title: Separate my integers

text:
# Question
Title: Separate my integers
## Introduction

In the field of mathematics known as topology, there are things called separation axioms. Intuitively, you have a set `X` and a collection of subsets of `X`, which we can think of as properties. The system is well separated, if one can distinguish between all items of `X` based on their properties. The separation axioms formalize this idea. In this challenge, your task is to check three separation axioms, given `X` and the list of properties.

## Input

Your inputs are an integer `n ≥ 2`, and a list of lists `T` of integers. The integers in `T` are drawn from `X = [0, 1, ..., n-1]`. The lists in `T` may be empty and unsorted, but they will not contain duplicates.

## Output

Your output is one of four strings, determined by three separation axioms, each stronger than the last. There are other axioms, but we stick with these for simplicity.

* Suppose that for all distinct `x` and `y` in `X`, there exists a list in `T` containing exactly one of them. Then `X` and `T` satisfy *axiom T0*.
* Suppose that for all distinct `x` and `y` in `X`, there exist two lists in `T`, one of which contains `x` but not `y`, and the other contains `y` but not `x`. Then `X` and `T` satisfy *axiom T1*.
* Suppose that the two lists above also contain no common elements. Then `X` and `T` satisfy *axiom T2*.

Your output is one of `T2`, `T1`, `T0` or `TS`, depending on which of the above conditions holds (`TS` means none of them do). Note that T2 is stronger than T1, which is stronger than T0, and you should always output the strongest possible axiom.

## Rules and scoring

You can write a full program or a function. The lowest byte count wins, and standard loopholes are disallowed.

## Test cases

```
2 [] -> TS
2 [[],[1]] -> T0
2 [[0],[1]] -> T2
3 [[0],[0,1,2],[1,2]] -> TS
3 [[],[0],[0,1],[2]] -> T0
3 [[0],[0,1],[2,1],[0,1,2]] -> T0
3 [[0],[0,1],[2,1],[2,0]] -> T1
6 [[0,2,4],[0,3,5],[1,2],[3,4,5]] -> TS
6 [[0,2,4],[0,3,5],[1,2],[2,5],[3,4,5]] -> T0
6 [[0,2,4],[0,3,5],[1,2],[2,5],[3,1],[3,4,5]] -> T1
6 [[0,1],[0,2,3],[1,4],[2,4],[2,3,5],[1,3],[4,5]] -> T2

```

# Answer
# Haskell, ~~317~~ ~~209~~ ~~174~~ 168 bytes

The function f does the job.

```
(#)=elem
x?y=[1|a<-x,b<-y,not$any(#a)b]
f n l|t(++)="TS"|t zip="T0"|t(?)="T1"|1>0="T2"where
    t p=any null[p(x%y)(y%x)|x<-[0..n-1],y<-[0..x-1]]
    x%y=[z|z<-l,x#z,not$y#z]

```

tests :

```
main=do
    putStrLn $ f 2 []
    putStrLn $ f 2 [[],[1]]
    putStrLn $ f 2 [[0],[1]]
    putStrLn $ f 3 [[0],[0,1,2],[1,2]]
    putStrLn $ f 3 [[],[0],[0,1],[2]]
    putStrLn $ f 3 [[0],[0,1],[2,1],[0,1,2]]
    putStrLn $ f 3 [[0],[0,1],[2,1],[2,0]]
    putStrLn $ f 6 [[0,2,4],[0,3,5],[1,2],[3,4,5]]
    putStrLn $ f 6 [[0,2,4],[0,3,5],[1,2],[2,5],[3,4,5]]
    putStrLn $ f 6 [[0,2,4],[0,3,5],[1,2],[2,5],[3,1],[3,4,5]]
    putStrLn $ f 6 [[0,1],[0,2,3],[1,4],[2,4],[2,3,5],[1,3],[4,5]]

```

output:

```
TS
T0
T2
TS
T0
T0
T1
TS
T0
T1
T2

```
> 9 votes

---
Tags: code-golf, math, array, topology
---


title: Detect my accent

text:
# Question
Title: Detect my accent
Your task is to write a program or function that detects accents in UTF-8 input. The catch is that your code must be written entirely in an 8-bit character encoding. The code will output a single integer which is the count of the number of accented letters in the input. Since Unicode is huge, the test input will consist solely of the characters found in Windows-1252, stored in the UTF-8 encoding, then treated as ASCII with extended characters (0x09, 0x0A, 0x0D, 0x20-0xFF only). The input won't contain any characters below 0x20, except for the three common ones, 0x09 (tab), 0x0A (line feed) & 0x0D (carriage return). It also won't contain 0x7F.

Unicode permits most common accented characters to be represented in multiple ways (only two for the characters in this challenge). `é` could be a pre-composed character: `U+00E9` (`C3 A9` in UTF-8) or a basic letter plus a combining mark: `U+0065`+`U+0301` (`65`+`CC 81` in UTF-8). Your code must correctly handle both.

In the following table `*` marks an accented letter. All letters that have two forms will be considered accented, plus `Œ`, `œ`, `Æ` & `æ`. All other characters will be considered as symbols or non-accented letters.

```
1252  Char  Unicode   Char  Unicode
         Bytes           Bytes
   Accented?
-----------------------------------------
80 _  €  3  U+20AC
81 Undefined
82 _  ‚  3  U+201A
83 _  ƒ  2  U+0192
84 _  „  3  U+201E
85 _  …  3  U+2026
86 _  †  3  U+2020
87 _  ‡  3  U+2021
88 _  ˆ  2  U+02C6
89 _  ‰  3  U+2030
8A *  Š  2  U+0160    Š  3  U+0053 U+030C
8B _  ‹  3  U+2039
8C *  Œ  2  U+0152
8D Undefined
8E *  Ž  2  U+017D    Ž  3  U+005A U+030C
8F Undefined
90 Undefined
91 _  ‘  3  U+2018
92 _  ’  3  U+2019
93 _  “  3  U+201C
94 _  ”  3  U+201D
95 _  •  3  U+2022
96 _  –  3  U+2013
97 _  —  3  U+2014
98 _  ˜  2  U+02DC
99 _  ™  3  U+2122
9A *  š  2  U+0161    š  3  U+0073 U+030C
9B _  ›  3  U+203A
9C *  œ  2  U+0153
9D Undefined
9E *  ž  2  U+017E    ž  3  U+007A U+030C
9F *  Ÿ  2  U+0178    Ÿ  3  U+0059 U+0308
A0 _     2  U+00A0
A1 _  ¡  2  U+00A1
A2 _  ¢  2  U+00A2
A3 _  £  2  U+00A3
A4 _  ¤  2  U+00A4
A5 _  ¥  2  U+00A5
A6 _  ¦  2  U+00A6
A7 _  §  2  U+00A7
A8 _  ¨  2  U+00A8
A9 _  ©  2  U+00A9
AA _  ª  2  U+00AA
AB _  «  2  U+00AB
AC _  ¬  2  U+00AC
AD _  2  U+00AD
AE _  ®  2  U+00AE
AF _  ¯  2  U+00AF
B0 _  °  2  U+00B0
B1 _  ±  2  U+00B1
B2 _  ²  2  U+00B2
B3 _  ³  2  U+00B3
B4 _  ´  2  U+00B4
B5 _  µ  2  U+00B5
B6 _  ¶  2  U+00B6
B7 _  ·  2  U+00B7
B8 _  ¸  2  U+00B8
B9 _  ¹  2  U+00B9
BA _  º  2  U+00BA
BB _  »  2  U+00BB
BC _  ¼  2  U+00BC
BD _  ½  2  U+00BD
BE _  ¾  2  U+00BE
BF _  ¿  2  U+00BF
C0 *  À  2  U+00C0    À  3  U+0041 U+0300
C1 *  Á  2  U+00C1    Á  3  U+0041 U+0301
C2 *  Â  2  U+00C2    Â  3  U+0041 U+0302
C3 *  Ã  2  U+00C3    Ã  3  U+0041 U+0303
C4 *  Ä  2  U+00C4    Ä  3  U+0041 U+0308
C5 *  Å  2  U+00C5    Å  3  U+0041 U+030A
C6 *  Æ  2  U+00C6
C7 *  Ç  2  U+00C7    Ç  3  U+0043 U+0327
C8 *  È  2  U+00C8    È  3  U+0045 U+0300
C9 *  É  2  U+00C9    É  3  U+0045 U+0301
CA *  Ê  2  U+00CA    Ê  3  U+0045 U+0302
CB *  Ë  2  U+00CB    Ë  3  U+0045 U+0308
CC *  Ì  2  U+00CC    Ì  3  U+0049 U+0300
CD *  Í  2  U+00CD    Í  3  U+0049 U+0301
CE *  Î  2  U+00CE    Î  3  U+0049 U+0302
CF *  Ï  2  U+00CF    Ï  3  U+0049 U+0308
D0 _  Ð  2  U+00D0
D1 *  Ñ  2  U+00D1    Ñ  3  U+004E U+0303
D2 *  Ò  2  U+00D2    Ò  3  U+004F U+0300
D3 *  Ó  2  U+00D3    Ó  3  U+004F U+0301
D4 *  Ô  2  U+00D4    Ô  3  U+004F U+0302
D5 *  Õ  2  U+00D5    Õ  3  U+004F U+0303
D6 *  Ö  2  U+00D6    Ö  3  U+004F U+0308
D7 _  ×  2  U+00D7
D8 _  Ø  2  U+00D8
D9 *  Ù  2  U+00D9    Ù  3  U+0055 U+0300
DA *  Ú  2  U+00DA    Ú  3  U+0055 U+0301
DB *  Û  2  U+00DB    Û  3  U+0055 U+0302
DC *  Ü  2  U+00DC    Ü  3  U+0055 U+0308
DD *  Ý  2  U+00DD    Ý  3  U+0059 U+0301
DE _  Þ  2  U+00DE
DF _  ß  2  U+00DF
E0 *  à  2  U+00E0    à  3  U+0061 U+0300
E1 *  á  2  U+00E1    á  3  U+0061 U+0301
E2 *  â  2  U+00E2    â  3  U+0061 U+0302
E3 *  ã  2  U+00E3    ã  3  U+0061 U+0303
E4 *  ä  2  U+00E4    ä  3  U+0061 U+0308
E5 *  å  2  U+00E5    å  3  U+0061 U+030A
E6 *  æ  2  U+00E6
E7 *  ç  2  U+00E7    ç  3  U+0063 U+0327
E8 *  è  2  U+00E8    è  3  U+0065 U+0300
E9 *  é  2  U+00E9    é  3  U+0065 U+0301
EA *  ê  2  U+00EA    ê  3  U+0065 U+0302
EB *  ë  2  U+00EB    ë  3  U+0065 U+0308
EC *  ì  2  U+00EC    ì  3  U+0069 U+0300
ED *  í  2  U+00ED    í  3  U+0069 U+0301
EE *  î  2  U+00EE    î  3  U+0069 U+0302
EF *  ï  2  U+00EF    ï  3  U+0069 U+0308
F0 _  ð  2  U+00F0
F1 *  ñ  2  U+00F1    ñ  3  U+006E U+0303
F2 *  ò  2  U+00F2    ò  3  U+006F U+0300
F3 *  ó  2  U+00F3    ó  3  U+006F U+0301
F4 *  ô  2  U+00F4    ô  3  U+006F U+0302
F5 *  õ  2  U+00F5    õ  3  U+006F U+0303
F6 *  ö  2  U+00F6    ö  3  U+006F U+0308
F7 _  ÷  2  U+00F7
F8 _  ø  2  U+00F8
F9 *  ù  2  U+00F9    ù  3  U+0075 U+0300
FA *  ú  2  U+00FA    ú  3  U+0075 U+0301
FB *  û  2  U+00FB    û  3  U+0075 U+0302
FC *  ü  2  U+00FC    ü  3  U+0075 U+0308
FD *  ý  2  U+00FD    ý  3  U+0079 U+0301
FE _  þ  2  U+00FE
FF *  ÿ  2  U+00FF    ÿ  3  U+0079 U+0308

```
* Input will be in any 8-bit encoding which is a super-set of ASCII, i.e. the lower half of the code points will match exactly with ASCII, the upper half (0x80-0xFF) will be used exclusively for multi-byte UTF-8 encoded codepoints, e.g.  (`U+201C`) will be treated as both three bytes and three characters by your code: `E2 80 9C`
* Language features or pre-existing libraries that convert character encodings or handle Unicode are forbidden, e.g. JSON (can convert Unicode text to hex), Unicode flag on regex, etc.

Sample output and input:

* `3` `Zoë reads the encyclopædia in a café`
* `0` `Zoe reads the encyclopaedia in a cafe`
* `1` `Zoë` (pre-composed character, 3 codepoints, 4 bytes)
* `1` `Zoë` (base letter + combining mark, 4 codepoints, 5 bytes)
* `2` `déjà vu`

## Scoring

Simple code-golf: lowest number of bytes wins!

This is a re-write as my computer crashed just before posting the first version and I lost all but the first few lines of the challenge. Apologies if I've left anything out!

# Answer
> 2 votes
# Mathematica, 46 bytes

```
Count[Characters@#,c_/;RemoveDiacritics@c!=c]&

```

**Explanations:**

`Chatacters` extract every characters in the string. Note that there is a difference between two `Zoë` even if they look the same:

```
Characters["Zoë"]
(* {"Z", "o", "ë"} *)

Characters["Zoë"]
(* {"Z", "o", "e", "̈ ̈"} *)

```

Here, the pattern `c_/;RemoveDiacritics@c!=c` will be matched with those characters that change with diacritics removed. For the first case, only `ë` will match since `ë` becomes `e`. While for the second case, only `̈` will match since it becomes nothing. Whatever case the string is, the counting will be correct.

**Test cases:**

```
f=%; (* assign the function to f. *)

f["Zoë reads the encyclopædia in a café"]
(* 3 *)
f["Zoe reads the encyclopaedia in a cafe"]
(* 0 *)
f["Zoë"]
(* 1 *)
f["Zoë"]
(* 1 *)
f["déjà vu"]
(* 2 *)

```

---
Tags: code-golf, restricted-source
---


# Question
Title: Use what you know: Your take on Diceware
If you're not familiar, Diceware is a method for creating passwords using an ordinary die from a pair of dice as a hardware random number generator.

For the sake of fun, let's ignore anything about the security of computer's random number generators.

Write a function or program that prints or returns a single five-character string containing a random selection of the numbers 1 through 6. These should be chosen with equal probability.

Example valid outputs:

```
21321
14654
53552
63641

```

No standard loopholes! This is code-golf, so shortest code in bytes wins.

# Answer
> 2 votes
# Dyalog APL, 7 bytes

```
10⊥?5⍴6

```

Try it online on TryAPL.

### How it works

```
    5⍴6  Yield (6 6 6 6)
   ?     Roll; turn each 6 into a random integer between 1 and 6.
10⊥      Decode with base 10.

```

# Answer
> 1 votes
# Julia, 24 bytes

```
print(join(rand(1:6,5)))

```

We use `rand` to get an array of length five consisting of elements randomly chosen from the range 1:6. We join it into a string using `join` then print it to STDOUT using `print`.

# Answer
> 1 votes
## J, 11 bytes

```
a.{~49+?5$6

```

Explanation:

```
        5$6    NB. repeat 6 five times      output: 6 6 6 6 6
       ?5$6    NB. 5 random integers < 6    output: 4 5 1 0 2
    49+?5$6    NB. add 49 ('1') to them     output: 53 54 50 49 51
a.{~49+?5$6    NB. convert them to ASCII    output: 56213

```

# Answer
> 0 votes
# TeaScript, 11 bytes

```
r6)ΣN6))j(u

```

Try it online

# Answer
> 0 votes
# Pyth, ~~9~~ 8 bytes

```
jkO^S6 5

```

Try it online.

Get list of numbers 1 to 6, Cartesian 5th power, pick random element, join by empty string.

# Answer
> 0 votes
## CJam, 8 bytes

```
{6mr)}5*

```

Test it here.

### Explanation

```
{       e# Run this block 5 times.
   6mr  e# Get a random integer in [0,5] with uniform distribution.
   )    e# Increment.
}5*

```

# Answer
> 0 votes
# Mathematica, 36 bytes

```
""<>ToString/@{1,6}~RandomInteger~5&

```

*cough cough* string formatting *cough cough*

# Answer
> 0 votes
# MATLAB / Octave, 12 bytes

```
[49+6*rand(1,6),'']
ans = 153361

```

`rand(x,y)` creates a random array with dimensions `(x-by-y)` with numbers between `0` and `1`. Multiply this by 6 to get values between 0 and 6. Add `49` to get a value `49 < n < 55` (the random number will never be exactly 0 or 1). `[...,'']` converts this to strings with the floored values of n (integers `[49 54]` corresponding to `[1 6]` in ASCII.

---
Tags: code-golf, random
---


title: Russian Roulette, Reloaded

text:
# Question
Title: Russian Roulette, Reloaded
Let's play Russian Roulette!

Normally, this would be a race to write the shortest MOD 6 program, but that's not very realistic, as the chance of winning decreases with each click. Here are the rules:

1. Emulate a real six-shooter:
    * A single bullet is placed into one of the six chambers, and the barrel is spun once, only before playing.
    * The chance of losing on the *n*th try is 1/6.
    * The chance of losing *after* *n* tries is 1/(6-n)
    * You are guaranteed to lose in, at most, 6 tries.
2. Losing:
    * Display the text `*BANG!*`
    * Terminate the program.
3. Winning:
    * "Winning" means the gun does not fire, but the bullet is one chamber closer to the hammer.
    * Display the text `*click*`
    * Present a "trigger" to the user, along with the ability to terminate the program (e.g. "ctrl+c", see below).
4. Program specific:
    * Pulling the trigger is some form of user input, including the first try. (This can be a keystroke, a mouse click, whatever; text prompts are not required.)
    * Only one instance of the program is allowed until it is terminated. (Running a new instance of the program is akin to giving the barrel a good spin, i.e. the probability of losing on the next click is reset to 1/6.)

Shortest code wins!

### Leaderboard

```
<style>body { text-align: left !important} #answer-list { padding: 10px; width: 290px; float: left; } #language-list { padding: 10px; width: 290px; float: left; } table thead { font-weight: bold; } table td { padding: 5px; }</style><script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <link rel="stylesheet" type="text/css" href="//cdn.sstatic.net/codegolf/all.css?v=83c949450c8b"> <div id="language-list"> <h2>Shortest Solution by Language</h2> <table class="language-list"> <thead> <tr><td>Language</td><td>User</td><td>Score</td></tr> </thead> <tbody id="languages"> </tbody> </table> </div> <div id="answer-list"> <h2>Leaderboard</h2> <table class="answer-list"> <thead> <tr><td></td><td>Author</td><td>Language</td><td>Size</td></tr> </thead> <tbody id="answers"> </tbody> </table> </div> <table style="display: none"> <tbody id="answer-template"> <tr><td>{{PLACE}}</td><td>{{NAME}}</td><td>{{LANGUAGE}}</td><td>{{SIZE}}</td><td><a href="{{LINK}}">Link</a></td></tr> </tbody> </table> <table style="display: none"> <tbody id="language-template"> <tr><td>{{LANGUAGE}}</td><td>{{NAME}}</td><td>{{SIZE}}</td><td><a href="{{LINK}}">Link</a></td></tr> </tbody> </table><script>var QUESTION_ID = 66763; var ANSWER_FILTER = "!t)IWYnsLAZle2tQ3KqrVveCRJfxcRLe"; var COMMENT_FILTER = "!)Q2B_A2kjfAiU78X(md6BoYk"; var OVERRIDE_USER = 38512; var answers = [], answers_hash, answer_ids, answer_page = 1, more_answers = true, comment_page; function answersUrl(index) { return "https://api.stackexchange.com/2.2/questions/" + QUESTION_ID + "/answers?page=" + index + "&pagesize=100&order=desc&sort=creation&site=codegolf&filter=" + ANSWER_FILTER; } function commentUrl(index, answers) { return "https://api.stackexchange.com/2.2/answers/" + answers.join(';') + "/comments?page=" + index + "&pagesize=100&order=desc&sort=creation&site=codegolf&filter=" + COMMENT_FILTER; } function getAnswers() { jQuery.ajax({ url: answersUrl(answer_page++), method: "get", dataType: "jsonp", crossDomain: true, success: function (data) { answers.push.apply(answers, data.items); answers_hash = []; answer_ids = []; data.items.forEach(function(a) { a.comments = []; var id = +a.share_link.match(/\d+/); answer_ids.push(id); answers_hash[id] = a; }); if (!data.has_more) more_answers = false; comment_page = 1; getComments(); } }); } function getComments() { jQuery.ajax({ url: commentUrl(comment_page++, answer_ids), method: "get", dataType: "jsonp", crossDomain: true, success: function (data) { data.items.forEach(function(c) { if (c.owner.user_id === OVERRIDE_USER) answers_hash[c.post_id].comments.push(c); }); if (data.has_more) getComments(); else if (more_answers) getAnswers(); else process(); } }); } getAnswers(); var SCORE_REG = /<h\d>\s*([^\n,<]*(?:<(?:[^\n>]*>[^\n<]*<\/[^\n>]*>)[^\n,<]*)*),.*?(\d+)(?=[^\n\d<>]*(?:<(?:s>[^\n<>]*<\/s>|[^\n<>]+>)[^\n\d<>]*)*<\/h\d>)/; var OVERRIDE_REG = /^Override\s*header:\s*/i; function getAuthorName(a) { return a.owner.display_name; } function process() { var valid = []; answers.forEach(function(a) { var body = a.body; a.comments.forEach(function(c) { if(OVERRIDE_REG.test(c.body)) body = '<h1>' + c.body.replace(OVERRIDE_REG, '') + '</h1>'; }); var match = body.match(SCORE_REG); if (match) valid.push({ user: getAuthorName(a), size: +match[2], language: match[1], link: a.share_link, }); else console.log(body); }); valid.sort(function (a, b) { var aB = a.size, bB = b.size; return aB - bB }); var languages = {}; var place = 1; var lastSize = null; var lastPlace = 1; valid.forEach(function (a) { if (a.size != lastSize) lastPlace = place; lastSize = a.size; ++place; var answer = jQuery("#answer-template").html(); answer = answer.replace("{{PLACE}}", lastPlace + ".") .replace("{{NAME}}", a.user) .replace("{{LANGUAGE}}", a.language) .replace("{{SIZE}}", a.size) .replace("{{LINK}}", a.link); answer = jQuery(answer); jQuery("#answers").append(answer); var lang = a.language; lang = jQuery('<a>'+lang+'</a>').text(); languages[lang] = languages[lang] || {lang: a.language, lang_raw: lang.toLowerCase(), user: a.user, size: a.size, link: a.link}; }); var langs = []; for (var lang in languages) if (languages.hasOwnProperty(lang)) langs.push(languages[lang]); langs.sort(function (a, b) { if (a.lang_raw > b.lang_raw) return 1; if (a.lang_raw < b.lang_raw) return -1; return 0; }); for (var i = 0; i < langs.length; ++i) { var language = jQuery("#language-template").html(); var lang = langs[i]; language = language.replace("{{LANGUAGE}}", lang.lang) .replace("{{NAME}}", lang.user) .replace("{{SIZE}}", lang.size) .replace("{{LINK}}", lang.link); language = jQuery(language); jQuery("#languages").append(language); } }</script>
```

# Answer
# Pyth, 23 bytes

```
VO6"*click*" w;"*BANG!*

```

Really simple. A random number of iterations 0 - 5 display click and request a line of input, followed by a bang at the end.
> 4 votes

# Answer
## Ruby, 51 bytes

```
[*['*click*']*rand(6),'*BANG!*'].map{|x|gets;$><<x}

```

Ungolfed:

```
[
  *(                        # Unwrap the following array into the outer one
    ['*click*'] * rand(6)   # An array of 0-5 clicks, see Array#*
  ),
  '*BANG!*'                 # The End
].map do |x| # Shortest way to iterate I was able to find
  gets       # Await input
  $> << x    # Shove the output string to `stdout`
end          # Return value is an array of several (0-5) `stdout`s. Who cares.

```

### or

```
(['*click*']*rand(6)<<'*BANG!*').map{|x|gets;$><<x}

```

Ungolfing left for the readers. Not that difficult

* Again, kudos to Martin, this time for a trick with `$><<` as a `puts` replacement.
* Doesn't output newlines, but that was not required.
* The shorter, the simpler. The gist of the required behaviour is to do 0-5 clicks and then fire. For that, outputs are accumulated inside the array.
* **2 more bytes** can be shaved off if outputs like `"*click*"` are okay (what's required is printed in the end), by replacing `$><<` with . I wasn't sure if this would still follow the rules.

---

### ~~68~~ 64 bytes

(another approach)

```
[*0..5].shuffle.find{|x|gets;x<1||puts('*click*')};puts'*BANG!*'

```

I didn't put much thought into the algorithm (it can possibly be even more compact, but not so clear), but I really like the model inside it:

* An array emulates a barrel with its elements being chambers' contents. Since only one element is a bullet, rotating it and shuffling it are equivalent.
* `0` is a bullet. Other numbers are not.
* `find` finds a first return value for which the block is neither `false` nor `nil`.
* `||`-expression is implicitly returned from the block. It's a short-circuit: it returns its first operand (unless it's `nil` or `false`) or a second one (otherwise). So it either returns `true` (if `x<1` or, clearer but longer `x == 0`) or the return value of `puts`, while...
* `puts` always returns `nil`. Yep.
* `gets` requests input. Merely hitting `Enter` suffices.
* `Ctrl`+`C` terminates the program
> 14 votes

# Answer
# JavaScript, 64 bytes

```
for(i=6;i<7&&prompt();)alert(new Date%i--?"*click*":i="*BANG!*")

```

## Explanation

To pull the trigger enter any text into the prompt. Enter nothing or click cancel to terminate.

```
for(
  i=6;             // i = number of chambers
  i<7              // i equals "*BANG!*" (not less than 7) if we lost
    &&prompt();    // see if we should do another shot
)
  alert(           // alert the result
    new Date%i--   // use the current time in milliseconds as a random number, this is safe
                   //     to use because the gap between shots is greater than i (max 6ms)
      ?"*click*"   // on win pass "*click*" to alert
      :i="*BANG!*" // on lose alert "*BANG!*" and set i to not less than 7
  )

```
> 9 votes

# Answer
# Lua, ~~82~~ 75 bytes

Pretty long, but there's lot of verbose in lua.

```
for a=math.random(6),1,-1 do io.read()print(a>1 and"*click*"or"*BANG!*")end

```
> 7 votes

# Answer
# LabVIEW, 46 LabVIEW Primitives

Creates an Array of 0s and one 1, has a loop to wait for clicks and outputs the string. It initially says BANG becuase i forgot to reset the indicator before starting it.

Also note that this is a gif, if if does not play/load for you please reopen the page.
> 6 votes

# Answer
## Pyth, ~~31~~ ~~30~~ 28 bytes

```
FN.S6 EI!N"*BANG!*"B"*click*

```

Almost certainly can be improved. Input any number to pull the trigger, blank input to terminate early (with an error).

Explanation:

```
FN                               for N in...
  .S6                            shuffle(range(6))...
      E                          get a line of input
       I!N                       if N is falsy (i.e. 0)
          "*BANG!*"              implicit output
                   B             break
                    "*click*     else, print click

```
> 5 votes

# Answer
## Seriously, ~~27~~ 25 bytes

```
"*BANG!*"6J"*click*"nW,X.

```

No online link because there is no way to do a prompt with piped input. The program can be CTRL-C'd at any time to ~~chicken out~~ terminate.

Explanation:

```
"*BANG!*"6J"*click*"nW,X.
"*BANG!*"                  push "*BANG!*"
         6J                push a random integer in [0,6) (n)
           "*click*"n      push "*click*" n times
                     W     while loop (implicitly closed at EOF):
                      ,X.    get input and discard, pop and print top of stack

```
> 5 votes

# Answer
# Perl 5, 43 bytes

Run with `perl -p`. Stable bullet variant - i.e. bullet position is decided only once in very beginning.

```
$i//=0|rand 6;$_=$i--?'*click*':die'*BANG*'

```
> 4 votes

# Answer
# PHP, 52 bytes

```
*<?=$n=&rand(0,6-$argi)?click:"BANG!*";$n||@\n?>*

```

Requires the `-F` command line option, counted as three. The trigger is pulled by pressing `Enter`.

Because `-F` literally runs the script again for every input (I kid you not), `die` and the like won't actually terminate, so we exit via suppressed runtime error instead, `@\n`.

---

**Sample Usage**

```
$ php -F primo-roulette.php

*click*
*click*
*BANG!*
$

```
> 4 votes

# Answer
# C, ~~110~~ ~~74~~ 72 bytes

Thanks to Dennis for getting rid of the includes and a lot less bytes.

```
main(r){for(r=time(0)%6;getchar(),r--;)puts("*click*");puts("*BANG!*");}

```

```
main(r)
{
    for(r=time(0)%6;getchar(),r--;)
        puts("*click*");
    puts("*BANG!*");
}

```
> 4 votes

# Answer
# Candy, 36 bytes

About half the program is the text to print out :(

```
:6H_(=b"*click*"(;):=)"*BANG!*\n"(;)

```

long form:

```
getc
digit6 rand range0  # build a range from 0 .. rand#
while
  popA              # these are the *click* instances
  stack2
  "*click*"
  while
    printChr
  endwhile
  getc
  popA
endwhile
"*BANG!*\n"         # out of luck
while
  printChr
endwhile

```
> 3 votes

# Answer
# PlatyPar, ~~26~~ 25 bytes

```
6#?;wT"*click*"O;"*BANG!*

```

Explanation:

```
6#?;                        ## random integer [0,6)
    w           ;           ## while stack.last
     T                      ## stack.last--
      "*click*"O            ## alert "*click*"
                 "*BANG!*   ## alert "*BANG!*"

```

Try it online!
> 3 votes

# Answer
# Python, 81 Bytes

```
import time
for i in["*click*"]*(int(time.time())%6)+["*BANG!*"]:input();print(i)

```

inspired by the Ruby(51) and Python solutions
> 3 votes

# Answer
# Emacs Lisp, ~~94~~ 89 bytes

```
(set'b(%(random)6))(dotimes(a(+ b 1))(read-string"")(message(if(eq a b)"BANG""*click*")))

```

Ungolfed:

```
(set 'b (% (random) 6))
(dotimes (a (+ b 1))
  (read-string"")
  (message (if (eq a b) "BANG" "*click*")))

```
> 2 votes

# Answer
# R, ~~86~~ ~~80~~ 77 bytes

As usual, R has awesome features to code golfing but looooooong function names.

```
sapply(sample(0:5),function(n){!n&&{cat('*BANG!*');q()};readline('*click*')})

```
> 2 votes

# Answer
# Python 2, ~~108~~ ~~104~~ ~~102~~ ~~100~~ 98 bytes

My first attempt at golfing:

```
from random import*
a=[1]+[0]*5
shuffle(a)
for i in a:input();print("*click*","*BANG!*")[i];" "[i]

```

Maybe I should add that the program doesn't terminate *correctly* when you lose, it just throws an exception (which results in termination):

```
Traceback (most recent call last):
  File "russian_roulette.py", line 4, in <module>
    for i in a:input();print("*click*","*BANG!*")[i];" "[i]
IndexError: string index out of range

```
> 2 votes

# Answer
# Python 3, 95 bytes

Also my first golf attempt, also in Python 3. I swear Bruce and I aren't the same person.

```
from random import*
for a in range(randint(0,5)):input();print("*click*")
input();print("*bang*")

```

**Ungolfed:**

```
from random import*
for a in range(randint(0,5)):
    input()
    print("*click*")
input()
print("*bang*")

```

Generate a random number between 0 and 5 inclusive, print *click* that many times, then print *bang*. Press enter/return to pull the trigger.
> 2 votes

# Answer
# Perl 5, 40 bytes

```
<>,print"*$_*"for(click)x rand 5,'BANG!'

```

Run without command line options, the trigger is pulled by pressing `Enter`.
> 2 votes

# Answer
## C, 96 bytes (Without counting comment)

```
#define R 4//chosen by playing russian roulette, guaranteed to be random
int main(){for(;c++<R&&puts(c<R?"Fire?":"☠Bang!☠");getchar(),puts("*click*"));}

```

### Formatted :

```
#define R 4 // chosen by playing russian roulette, guaranteed to be random
int main(int c) {
    for( ; c++ < R && puts(c < R ? "Fire?" : "☠Bang!☠") ; getchar(), puts("*click*") );
}

```

### Explanation :

There also is a click when it fires, that's the sound of the hammer being released.

After the bang you need to hit enter to take the gun out of the dead man's hand, rigor mortis squeezed his finger around the trigger. While you are prying his hand open you hear another click as the trigger snaps back into normal position.
> 2 votes

# Answer
## Common Lisp, 109

```
(do(g(b(nthcdr(random 6)#1='(t()()()()() . #1#))))(g)(read-char)(princ(if(setf g(pop b))"*BANG!*""*click*")))

```

Not very competitive, but I like circular lists:

```
(do (;; auxiliary variable x
     x
     ;; initialize infinite barrel, rotate randomly
     (b (nthcdr (random 6) #1='(t()()()()() . #1#))))

    ;; we end the loop when x is T (a bullet is fired)
    (x)

  ;; press enter to shoot
  (read-char)

  ;; pop from b, which makes b advance down the list. The popped value
  ;; goes into x and is used to select the appropriate string for
  ;; printing.
  (princ
   (if (setf x(pop b))
       "*BANG!*"
       "*click*")))

```
> 1 votes

# Answer
# Perl 5, 43 bytes

42 bytes + `-p` command line option. Just press `enter` to trigger.

```
$_=0|rand 7-$.<++$i?die"*BANG!*":"*click*"

```

Thanks to Dom Hastings for his help! Original answer was 67 bytes:

```
$i++;$a=$i>=int(rand(6));print$_=$a?'*BANG!*':'*click*';last if($a)

```
> 1 votes

# Answer
# MATL, 41 bytes

```
6Yr`j?t@=?'*BANG!*'DT.}'*click*'DT]}T.]]x

```

To pull the trigger, input a non-empty string (such as `'try'`).

To terminate, input an empty string

### Examples

In this case the trigger was pulled once and... bad luck:

```
>> matl
 > 6Yr`j?t@=?'*BANG!*'DT.}'*click*'DT]}T.]]x
 >
> try
*BANG!*

```

In this case the user stopped (note the final empty input) after two lucky pulls:

```
>> matl
 > 6Yr`j?t@=?'*BANG!*'DT.}'*click*'DT]}T.]]x
 >
> try
*click*
> try
*click*
>

```

### Explanation

```
6Yr                  % random avlue from 1 to 6
`                    % do...while
  j                  % input string
  ?                  % if nonempty
    t                % duplicate the orignal random value
    @                % loop iteration index
    =                % are the equal?
    ?                % if so
      '*BANG!*'D     % display string
      T.             % unconditional break
    }                % else
      '*click*'D     % display string
      T              % true value, to go on with do...while loop
    ]                % end if
  }                  % else
    T.               % unconditional break
  ]                  % end
]                    % end
x                    % delete original random value

```
> 1 votes

# Answer
# Python 2, ~~88~~ 84 bytes

This solution is inspired by the python 3 solutions already given. I chose python 2 to remove the print parenthesis even though this changes the behavior of input().

```
import time
for i in[0]*int(time.time()%6)+[1]:input();print("*click*","*BANG!*")[i]

```
* I am using modulo of the time as a random function (good enough for russian roulette)
* the player input should be "i" then Enter (otherwise input() will throw an error), this trick relies on the fact that the input can be "whatever".
> 1 votes

# Answer
# Perl 6,  ~~58~~  53 bytes

~~```
for ^6 .pick(*) {get;say <*BANG!* *click*>[?$_];!$_&&last} # 58 bytes

```~~
```
$ perl6 -pe '$///=^6 .pick;$_=$/--??"*click*"!!say("BANG!")&&last' # 52+1= 53 bytes

```

Press enter to pull the trigger, or ctrl+c to put it down.
> 1 votes

# Answer
# Perl 5, ~~69~~ ~~51~~ 49 bytes

```
map{<>;print"*click*"}1..rand 6;<>;print"*BANG!*"

```

There is probably some more golfing potential, I will look into this.

Changes:

* Saved 8 bytes by removing `$l` and some semicolons, and 10 bytes by changing `<STDIN>` to `<>`
* Saved 2 bytes thanks to Oleg V. Volkov
> 1 votes

# Answer
# Ruby, 45+1=46

Not as clever as D-side's but slightly shorter.

With command-line flag `p`, run

```
rand(7-$.)<1?(puts'*BANG*';exit):$_='*click*'

```

The user can pull the trigger with return and leave with control-c. `p` causes the program to run in a loop, reading lines from STDIN and outputting `$_`. Each time it runs, it increments `$.`. So on the first run, it chooses a random positive integer less than 6, then 5, then 4, and so on. On the first 0, we output manually and exit, until then we output implicitly.

(and now I notice that there's already a very similar Perl. Oh well.)
> 1 votes

# Answer
# VBA, 126 bytes

Golf Version for Minimal Bytes

```
Sub S()
r=Int(5*Rnd())
e:
a=MsgBox("")
If a=1 Then: If i=r Then MsgBox "*BANG!*" Else: MsgBox "*click*": i=i+1: GoTo e
End Sub

```

Fun Version that Makes The Buttons more Clear for Increased User Acceptance.

```
Sub RR()
r = Int(5 * Rnd())
e:
a = MsgBox("Are you Feeling Lucky?", 4)
If a=6 Then: If i=r Then MsgBox "*BANG!*", 16 Else: MsgBox "*click*", 48: i=i+1: GoTo e
End Sub

```

Some Fun with Custom Forms and You could make a pretty Slick Game in VBA.
> 0 votes

# Answer
# APL, 39/65 bytes

```
{⍞⊢↑⍵:⍞←'*BANG*'⋄∇1↓⍵⊣⍞←'*click*'}6=6?6

```

Pretty straightforward answer.
> 0 votes

# Answer
# C, 180 Bytes

```
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
int main(){srand(time(NULL));int r,i=6;while(i!=1){getchar();r=rand()%i;if(r){puts("CLICK");}else{puts("BANG");exit(0);}i--;}}

```

My first attempt at code golf, there's probably a lot of room for improvement :)
> 0 votes

# Answer
# Julia, 71 bytes

```
b=rand(1:6);while b>0 readline();print(b>1?"*click*":"*BANG!*");b-=1end

```

Press `Enter` to fire or `Ctrl`+`C` to quit. The latter ends with an `InterruptException`.

Ungolfed:

```
# Set an initial bullet location
b = rand(1:6)

while b > 0
    # Read user input
    readline()

    # Check the location
    if b > 1
        print("*click*")
    else
        print("*BANG!*")
    end

    b -= 1
end

```
> 0 votes

# Answer
# Lua, 73 bytes

```
q=io.read q()for i=2,math.random(6)do print"*click*"q()end print"*BANG!*"

```
> 0 votes

# Answer
# R, 79 bytes

### code

```
readline();for(n in 6:1)ifelse(1/n>=runif(1),cat("*Bang*"),readline("*click*"))

```

### ungolfed

```
readline()                    # Waits for user to press [Enter] if [Esc] is pressed exits
for(n in 6:1) {               # for n=6 to n=1
  ifelse(1/n >= runif(1),     # if 1/n >= a random float from 0 to 1 (uniform dist)
     cat("*Bang*"),           # *You're dead*
     readline("*click*")    # else you have another chance, waits for [Enter] again
  )
}

```

The program will wait for an `[Enter]` before every try, if the user press `[Esc]` instead the program will end. If the `*Bang*` happens the program will print it and throw an error, thus terminating itself (is this correct?).
> 0 votes

---
Tags: code-golf, game, random
---


title: String Shenanigans

text:
# Question
Title: String Shenanigans
# Challenge

In this challenge, you are to code in any language a program or function that will take a string and replace certain characters within it with different characters.

# Input

The input is the same for both functions and full programs:

```
[string] [char1] [char2]

```
* `string` will be an indefinite line of characters surrounded by quotation mars, such as "Hello, World!" or "1 plus 2 = 3".
* `char1` will be a single character within `string`.
* `char2` will be a single character not necessarily in `string`.

# Output

```
[modified string]

```

Your output will take `string` and replace all instances of `char1` with `char2`, then output the result as `modified string`. Case should be ignored, so the input `"yolO" o u` should output `yulu`.

# Examples

**Input**

```
"Hello, World!" l r

```

**Output**

```
Herro, Worrd!

```

---

**Input**

```
"Slithery snakes slurp Smoothies through Silly Straws" s z

```

**Output**

```
zlithery znakez zlurp zmoothiez through zilly ztrawz

```

---

**Input**

```
"Grant Bowtie: Only the best future bass artist ever" : -

```

**Output**

```
Grant Bowtie- Only the best future bass artist ever

```

---

**Input**

```
"019 + 532 * 281 / ? = waht/?" / !

```

**Output**

```
019 + 532 * 281 ! ? = waht!?

```

# Other details

This is code golf, so the shortest answer (in bytes) at the end of the week (the 14th of September) wins. Also, *anything not specified in this challenge is fair game,* meaning that stuff I don't explain is up to you.

# Answer
> 6 votes
# Pyth, 10 bytes

```
XQr*2w4*2w

```

Try in online: Demonstration or Test Suite

### Explanation:

```
 Q             read a line and evaluates (reads a string with quotes)
     w         reads a char: a (actually reads a line)
   *2          make it twice as long: aa (repeat the char)
  r   4        capitalize this string: Aa
       *2w     read another char and repeat it: bb
X              replace the letters Aa by bb in Q

```

# Answer
> 12 votes
# Vim, 18 keystrokes

```
$bD:s/<C-R>"<Left><BS>/<Right>/i<CR>x$x

```

Assuming the cursor is on the first column of the first line, and the open file contains this:

```
"yolO" o u

```

The file will end up containing:

```
"yulu"

```

# Answer
> 10 votes
# JavaScript ES6, 28 bytes

```
(s,a,b)=>s.replace(a,b,'gi')

```

Firefox only as it uses a mozilla-specific feature.

# Answer
> 6 votes
# Retina, 29 bytes

```
i`(.)(?=.*\1 (.)$)|"|....$
$2

```

For scoring purposes each line goes in a separate file, but for convenience you can run the above from a single file with the `-s` flag.

As this is just a single regex replacement, you can test it here.

The regex consists of three parts, one to do the substitution and two to clean up the rest of the input. This is the substitution part:

```
(.)       # Match a character and capture it in group 1.
(?=       # Lookahead to ensure that this is the character we're searching for.
  .*      # Consume arbitrary characters to move to the end of the string.
  \1 (.)$ # Ensure we can match the captured character, then a space, then
          # another character and then the end of input. That other character
          # is captured in group 2.
)

```

This match is replaced by `$2`, i.e. the character to be substituted in.

The other two possibilities are either to match a `"`, or to match the last four characters of the input. In either case group two is empty, so the replacement string `$2` evaluates to an empty string and the match is simply removed from the input. This cleans up the quotes and the characters at the end.

`i`` simply activates case insensitive matching.

# Answer
> 5 votes
# gawk - 48

```
IGNORECASE=gsub(/"/,_),gsub($(NF-1),$NF)+(NF-=2)

```

That IGNORECASE hurts...

*How to use*

In bash enter: `awk 'IGNORECASE=gsub(/"/,_),gsub($(NF-1),$NF)+(NF-=2)'`

Then enter a string in quotes and the two characters. In front of some characters ("\[" and "(" I know of) you have to enter a backslash, because awk would try to interpret them as regular expression instead.

# Answer
> 4 votes
# Octave, 28

An anonymous function using built in functions.

```
@(W,T,F)strrep(lower(W),T,F)

```

Assuming it is stored in `f` we can call it as follows:

```
f('Slithery snakes slurp Smoothies through Silly Straws','s','z')

```

# Answer
> 3 votes
## R, 28

```
function(s,c,r)gsub(c,r,s,T)

```

Had the order of the arguments been (c,r,s), I thought of doing

```
functional::Curry(gsub,i=T)

```

`functional` is a 3rd-party package whose `Curry` functional allows redefining function arguments: here, returns a function like `gsub` but with the modified `ignore.case = TRUE`.

# Answer
> 3 votes
# CJam, ~~18~~ 17 bytes

Kind of awkward handling the quotes and upper vs. lower case. But I believe it works for all cases:

```
l'"%~S%(eu_el+\er

```

Try it online

Thanks to @Dennis for golfing 1 byte.

Note that this is a full program that takes the input exactly as specified in the question. I can make this shorter if the input requirements are interpreted more flexibly.

Explanation:

```
l     Get input.
'"%   Split at quotes. This separates the string from the remaining arguments,
      and gets rid of the quotes.
~     Unwrap the list. We now have two strings on the stack, the input text
      and a string containing the two letters.
S%    Split the string containing the two letters.
(     Pop off the first ("source") letter.
eu    Convert it to upper case.
_el   Copy and convert to lower case.
+     Concatenate the two, giving us a string with upper and lower case.
\     Swap the second ("target") letter to top.
er    Transliterate.

```

# Answer
> 3 votes
# PowerShell, 33 30 Bytes

```
param($a,$b,$c)$a-replace$b,$c

```

Expects input via command-line argument. PowerShell has many built-in case-insensitive operators that just tack on an `i` in front of the usual operator -- here as `-ireplace` instead of `-replace` -- so the case-insensitive matching was actually pretty easy.

```
PS C:\Tools\Scripts\golfing> .\string-shenanigans.ps1 "Hello, World!" l r
Herro, Worrd!

PS C:\Tools\Scripts\golfing> .\string-shenanigans.ps1 "Slithery snakes slurp Smoothies through Silly Straws" s z
zlithery znakez zlurp zmoothiez through zilly ztrawz

PS C:\Tools\Scripts\golfing> .\string-shenanigans.ps1 "019 + 532 * 281 / ? = waht/?" / !
019 + 532 * 281 ! ? = waht!?

```

Saved 3 bytes thanks to briantist

# Answer
> 3 votes
# Scala, 59 bytes

```
(s:String,a:Char,b:Char)=>(s"(?i)$a"r).replaceAllIn(s,""+b)

```

An anonymous function that uses `s""` alongwith `""r` to dynamically build a case-insensitive regex.

# Answer
> 3 votes
# Ruby, 17 bytes

```
f=->s,*r{s.tr *r}

```

For example:

```
> f["Hello there!", ?e, ?a]
=> Hallo thara!

```

# Answer
> 2 votes
# Pyth, ~~7~~ 19? / 15 bytes

```
jwcjrz1cwrz0rz1

```

Example Input

(My second Pyth program, ever). Any tips on golfing are welcome. A lot of the bytes are going to the repeated `rz1/rz0`. I could chop some of these I could be guaranteed the case.

---

If quotes are *required*, a slightly larger 19-byte program handles that:

```
jwcjrz1c:w1_1rz0rz1

```

---

## Explanation:

This basically. Takes a string:

```
Slithery snaKEs

```

Then, chops all lowercase instances of the the character to replace.

```
['Slithery ','naKE','']

```

Then joins with the uppercase instance:

```
Slithery SnaKES

```

Then chops on the uppercase instance:

```
['','lithery ','naKE']

```

Then joins with the *new character*:

```
qlithery qnaKEq

```

# Answer
> 2 votes
# Pyth - 11 bytes

A simple regexp solution with case insensitive. Will try to translate to Retina if I get it to compile.

```
:Q+"(?i)"ww

```

Test Suite.

# Answer
> 2 votes
# mSL, 68 bytes

```
$replace($gettok($1-,-3-1,32),$gettok($1-,-2,32),$gettok($1-,-1,32))

```

# Answer
> 2 votes
# C#, 93 120 124 123 bytes

```
class A{static void Main(string[]a){System.Console.Write(a[0].Replace(a[1].ToLower(),a[2]).Replace(a[1].ToUpper(),a[2]));}}

```

Not sure if I can golf this much better than this, but surprisingly low byte count for C# =D

**EDIT:** Thanks, Reto Koradi for pointing out the case sensitivity.

**EDIT 2:** More stuff I missed out on. Maybe doing this during a break in work isn't the best time.

# Answer
> 2 votes
## Bash 4.0+, 21 bytes

Command-line arguments.

```
tr ${2^}${2,} $3<<<$1

```

# Answer
> 2 votes
# C++ 11, Stand-alone: 213 202 198 bytes

Since I haven't seen a solution on C++ yet, I decided to try something myself. This is my first version and I will try to optimize it later.

Source code running:

Live Version: 213 202 198 bytes

```
#include <algorithm>
#include <iostream>
using namespace std;int main(){string a;getline(cin,a);char b,c;cin.get(b);cin.get(c);replace_if(begin(a),end(a),[b](char d){return!((d-b)%32);},c);cout<<a;}

```

.

## Only the replace function: 121 110 107 bytes

```
getline(cin,a);cin.get(b);cin.get(c);replace_if(begin(a),end(a),[b](char d){return!((d-b)%32);},c);cout<<a;

```

.

Feedback is welcome.

# Answer
> 2 votes
# Shell 15 bytes:

```
sed s/$1/$2/gi

```

Save as `submission.sh` and run as:

```
$ echo "Hello, World" | ./submission.sh h e
eello, World

```

## Explanation:

sed (stream editor) has a substitute command, which parses standard input and substitutes string $1 for string $2. The `g` modifier substitutes globally in the input string, and `i` modifier produces a case-insensitive match.

# Old Solution:

## Shell, 14 bytes `submission_1.sh`

```
tr $2 $3<<<$1

```

Call with

```
$ ./submission_1.sh 'hello there!lgge lfewf lger3%#@ %@#T @EG' l r
herro there!rgge rfewf rger3%#@ %@#T @EG

```

## Alternate, Shell 9 bytes: `submission_2.sh` (May be too rule-bendy)

```
tr $1 $2

```

Call with

```
$ ./submission_2.sh l r <<<'hello there!lgge lfewf lger3%#@ %@#T @EG'
herro there!rgge rfewf rger3%#@ %@#T @EG

```

### Explanation

tr by default (without any flags) replaces all chars in the first set with the chars in the second set, completing the operation with the data on standard input.

I'm using this to my advantage by calling TR with the arguments in the correct order, and (in the alternate submission) taking advantage of the handling of standard input by Bourne Shell (sh) to pass standard input to tr without any additional code.

# Answer
> 2 votes
# Sed, 43 Chars

```
:;s/(.)(.*\1 (.))$/\3\2/I;t;s/(. .$|")//g

```

Invoked with the -r flag for extended regex.

# Answer
> 2 votes
# Python, 58 bytes

Uses case-insensitive regex for substitution.

```
from re import*
lambda s,t,u:compile(escape(t),I).sub(u,s)

```

# Answer
> 1 votes
# Javascript ES6, 54 chars

```
f=s=>s.replace(/(.)(?=.* \1 (.)$)/ig,"$2").slice(1,-5)

```

# Answer
> 1 votes
# PHP, 44 Bytes

```
<?=str_ireplace($argv[2],$argv[3],$argv[1]);

```

Called from the command line via `php golf.php "Grant Bowtie: Only the best future bass artist ever" : -`

# Answer
> 1 votes
## Python 2.7, 117 bytes

```
def r(s): print ''.join([list(s)[-1]  if x.lower() == list(s)[-3] else x if x != '\"' else '' for x in list(s)][:-4])

```

Python certainly won't compare to other golfing languages for this challenge, but nothing beats it for list (in)comprehensions.

If you want it to be a 'standalone' program it increases the size to about 120

```
import sys
if __name__ == "__main__":
  l, y, z = sys.argv[1:]
  print ''.join([z  if x.lower() == y else x for x in l])

```

# Answer
> 1 votes
# Shell, ~~34~~ ~~27~~ 35 bytes

```
#!/bin/sh
echo $1|sed "s/$2/$3/gi"

```

# Answer
> 1 votes
# Lua, 36 bytes

```
a=arg[1]:gsub(arg[2],arg[3])print(a)

```

# Answer
> 1 votes
# Gema, 40 characters

```
"*" ? ?=@subst{\\C@quote{?}=@quote{?};*}

```

Sample run:

```
bash-4.3$ gema '"*" ? ?=@subst{\\C@quote{?}=@quote{?};*}' <<< '"Hello, World!" l r'
Herro, Worrd!

```

# Answer
> 1 votes
# O, 31 bytes

```
i`' /l3-{' \++}d`'"-"(?i)"@+@%p

```

# Answer
> 0 votes
# Perl, 33 chars (without !#) 48 (including !#)

```
#!/usr/bin/perl
($_,$b,$c)=@ARGV;
s/$b/$c/i;
print;

```

My first golf, one of my first perl programs. Probably could be golfed a little more

---
Tags: code-golf, string
---


title: Can the king catch the pawn?

text:
# Question
Title: Can the king catch the pawn?
Given an input of four integers *x1*, *y1*, *x2*, and *y2*, output whether a white king in chess (with coordinates (*x1*, *y1*)) could catch a black pawn (with coordinates (*x2*, *y2*)) and capture it if the pawn is moving to promote to a queen as fast as possible.

The coordinates of the board are as follows:

```
       first coordinate (x)
             12345678

           1 .#.#.#.#
           2 #.#.#.#.
           3 .#.#.#.#
  second   4 #.#.#.#.
coordinate 5 .#.#.#.#
    (y)    6 #.#.#.#.
           7 .#.#.#.#
           8 #.#.#.#.

```

Assume it is white to move (the king's turn) and that both players play optimally (the king will move as fast as possible to catch the pawn, and the pawn will move as fast as possible to promote). The input coordinates will always be distinct, and the pawn will never start with a y-coordinate of 8.

The king moves one square in any direction every turn (it can move diagonally), and the pawn can only move one space forwards (decrease its y-coordinate), unless it's at its initial position (with our coordinate system, y-coordinate of 7), in which case it can move two spaces forwards.

The input can be given as a whitespace-/comma-separated string, an array of strings/integers, or four function/command line/etc arguments. The coordinates can be given in whichever order is most convenient/golfy (so, accepting input as \[y2, y1, x1, y2\] is okay as long as it's consistent). The output must be a truthy or falsy value.

Since this is , the shortest code in bytes wins.

**Truthy test cases**:

`5 3 3 2`

`6 1 1 7`

`3 3 3 2`

`4 1 4 7`

`7 7 1 7`

`1 8 1 7`

**Falsy test cases**:

`6 4 3 2`

`8 8 1 7`

`3 4 3 2`

# Answer
# Jelly, 33 bytes

```
‘»Ɠ_2<®
Ɠ©<7
:5+Ɠ>7$¤<1.4
Ɠ_ƓA2£Ŀ

```

This program reads the coordinates as `x2\nx1\ny2\ny1` from STDIN. Try it online!

### Non-competing version

Unfortunately, the Jelly interpreter had a bug when this question was posted. Said bug prevented it from accepting more than two command-line arguments. The newest version of Jelly can solve the given task in **23 bytes**.

```
⁶>7×5
_A+⁵>6$¤+¢’»⁶_2<⁵

```

Try it online!
> 3 votes

# Answer
## Python 2, 53 40

```
lambda x,y,p,q:y-2<q>=abs(x-p)+q/7+y/8*5

```

The king has coordinates `(x, y)` and the pawn `(p, q)`.

There are three significant cases:

1. The pawn is on rank 7 and the king on rank 8. To capture the pawn, the king must be on the same file or an adjacent one.

Result: `q = 7 ⋀ y = 8 → |x - p| ≤ 1`
2. The pawn is on rank 7. To capture the pawn, the king must be within six files.

Result: `q = 7 → |x - p| ≤ 6`
3. The pawn is on a lower rank. To capture the pawn, the king must be able to reach the promotion square at most one move after the pawn.

Result: `q < 7 → |x - p| ≤ q ⋀ y - 1 ≤ q`

My solution is just these conditions golfed down. Hopefully there aren't mistakes this time.
> 18 votes

# Answer
# Prolog, ~~48~~ 42 bytes

**Code:**

```
p(X,Y,P,Q):-Y-2<Q,Q>=abs(X-P)+Q//7+Y//8*5.

```

**Examples:**

```
p(1,8,1,7).
true

p(3,4,3,2).
false

```

Not a bad challenge for Prolog compared to most.

**Edit:** Saved 6 bytes by switching to the formula used in grc's Python 2 answer.
Unfortunately Prolog can't chain comparisons as python can and integer division is 1 byte longer than float division.

Try it online here
> 2 votes

# Answer
# JavaScript (ES6), 52

```
(x,y,u,t,d=x>u?x-u:u-x)=>(d>=y?d:y-1)<=(d<2|t<7?t:6)

```

I hope to have saved bytes not using Math.abs, Math.min, Math.max

The pawn at row seven can escape moving 2 spaces, if and only if the king is not in a near column - that's why there is a check on `d` before substituting 7 with 6.

Test case to run in console:

```
;[f(5,3,3,2),f(6,1,1,7),f(3,3,3,2),f(1,8,1,7),f(6,4,3,2),f(8,8,1,7),f(3,4,3,2)]

```

Result: `[true, true, true, true, false, false, false]`
> 0 votes

# Answer
# Ruby, 50 bytes

```
def f(a,b,c,d)(a-c).abs<=(d==7?6-b/8*5:d)&&b-d<2;end

```

Arguments are (king x, king y, pawn x, pawn y), all integers.
> 0 votes

---
Tags: code-golf, chess
---