title: Put in the quotes

text:
# Question
Title: Put in the quotes
## Background

There's a terrible problem in my console - the quotes never get included inside the arguments! So, when given this argument:

```
["abc","def","ghi","jkl"]

```

it says that the argument is like this:

```
[abc,def,ghi,jkl]

```

It would be very nice if you can fix this problem!

## Challenge

Add double-quotes (`"`) in order to surround a word (i.e. something that matches `[a-z]+`).

## Test cases

```
[[one, two, three], -> [["one", "two", "three"],
[one, two, three],     ["one", "two", "three"],
[one, two, three],     ["one", "two", "three"],
[one, two, three]]     ["one", "two", "three"]]

[abc,def,ghi,jkl] -> ["abc","def","ghi","jkl"]

this is a test    -> "this" "is" "a" "test"

test              -> "test"

this "one" "contains' "quotations -> "this" ""one"" ""contains"' ""quotations"

But This One Is SpeciaL! -> B"ut" T"his" O"ne" I"s" S"pecia"L!

```

## Rules

* The inputted words are never capitalized. Capital letters are not considered part of a word.
* The input is always a string, not a list. The test-cases aren't quoted because that's the only possible type.
* A word is something that matches `[a-z]+`.

# Answer
> 6 votes
# Gema, 8 characters

```
<J>="$0"

```

Copy of Adám's QuadR solution, just adjusted the syntax and the explanation:

Replace
`<J>` one or more lowercase letters
with
`"$0"` the quoted match.

Sample run:

```
bash-5.0$ gema '<J>="$0"' <<< '[abc,def,ghi,jkl]'
["abc","def","ghi","jkl"]

```

Try it online!

# Answer
> 5 votes
# perl -pE, 15 bytes

```
s/[a-z]+/"$&"/g

```

# Answer
> 3 votes
# QuadR, 10 bytes

```
[a-z]+
"&"

```

Try it online!

Replace
`[a-z]+` one or more lowercase letters
with
`"&"` the quoted match.

# Answer
> 2 votes
# sed -E, ~~20~~ ~~15~~ 14 bytes

Saved 5 bytes thanks to @Neil! And then 1 more byte thanks to @manatwork pointing out that we no longer have to add bytes to our score for command-line options.

```
s/[a-z]+/"&"/g

```

---

Original solution:

```
s/\([a-z]\+\)/"\1"/g

```

Test run:

```
$ cat quotelc.sed
s/\([a-z]\+\)/"\1"/g

$ sed -f quotelc.sed << EOF
> [abc,def,ghi,jkl]
> this is a test
> test
> this "one" "contains' "quotations
> But This One Is SpeciaL!
> EOF
["abc","def","ghi","jkl"]
"this" "is" "a" "test"
"test"
"this" ""one"" ""contains"' ""quotations"
B"ut" T"his" O"ne" I"s" S"pecia"L!

```

Note: In TIO's sed, there's some issue with the collating sequence; the pattern `[a-z]` matches upper-case letters too. If you want to run this in TIO, you can do something like this.

# Answer
> 2 votes
# Japt, 11 bytes

```
r"%a+"`"$&"

```

Try it

# Answer
> 1 votes
# Python 3, 47 bytes

```
lambda s:re.sub('([a-z]+)',r'"\1"',s)
import re

```

Try it online!

# Answer
> 1 votes
# Jelly, 15 bytes

```
Ż;0e€ØaIkƊj”"ḊṖ

```

Try it online!

A monadic link taking a Jelly string and returning a Jelly string. No regex in Jelly so identifies boundaries between lower letter segments and others, splits and joins with quotes.

# Answer
> 1 votes
# 05AB1E, ~~14~~ 13 bytes

```
0.ø.γ.l}'"ý¦¨

```

Try it online!

# Answer
> 1 votes
# , 39 35 bytes

```
load'regex'
f=.'[a-z]+'dquote rxapply]

```

Try it online!

*-4 bytes thanks to Bubbler teaching me about dquote builtin*

NOTE: The TIO link is showing an error, but this works correctly on my machine (j807), and passes the test cases. I'm unsure if it's a version issue or something else causing TIO to fail.

Task is accomplished almost entirely by the `rxapply` adverb. We simply have to supply the regex to apply to `[a-z]+` and the verb to apply: surround in quotes `dquote`

# Answer
> 1 votes
# Charcoal, 20 bytes

```
Ｆ⁺Ｓ «ω✂"⁼№⪪β¹ω№βι≔ιω

```

Try it online! Link is to verbose version of code. I was stuck at 24 bytes for some time until I came up with this approach. Explanation:

```
Ｆ⁺Ｓ «

```

Loop over the input with a space appended. (Any non-alphalower character would do.)

```
ω

```

Print the previous character. On the first pass through the loop, this variable holds the empty string, so nothing is output. Additionally, we never print the appended space, as it's never the previous character.

```
✂"⁼№⪪β¹ω№βι

```

Check whether both or neither the previous or current characters are alphalower characters. If exactly one is, then output a quote. (The predefined alphalower string has to be split for the first check otherwise the empty string would match 27 times on the first pass.)

```
≔ιω

```

Save the current character so that it's the previous character on the next pass of the loop.

# Answer
> 1 votes
# Retina, 11 bytes

```
[a-z]+
"$0"

```

Pretty straight-forward approach.

Try it online.

# Answer
> 1 votes
# Husk, 10 bytes

```
ṁ?sIΛ√ġo¬√

```

Try it online!

# Answer
> 0 votes
# Deorst, 20 bytes

```
'"\1"'@
'([a-z]+)'gs

```

Try it online!

Again, just uses a regex based approach

# Answer
> 0 votes
# PHP, 69 bytes

```
for(;$c=$argn[$i++];){if(($n=$c>'`'&$c<'{')^$p)echo'"';echo$c;$p=$n;}

```

Try it online!

# Answer
> 0 votes
# Japt, 12 bytes

```
r"%a+"@Q+X+Q

```

Try it

# Answer
> 0 votes
# Jelly, 13 bytes

```
Ø1je€ØanƝ”"ẋż

```

A full program which prints the result.

**Try it online!** Or see the test-suite.

### How?

```
Ø1je€ØanƝ”"ẋż - Main Link: list of characters e.g.  Foo 'Bar', baz
                                                ->  ['F','o','o',' ',"'",'B','a','r',"'",',',' ','b','a','z']
Ø1            - ones                                [1,1]
  j           - join                                [1,'F','o','o',' ',"'",'B','a','r',"'",',',' ','b','a','z',  1]
     Øa       - lower-case alphabet                 ['a','b',...,'z']
    €         - for each:
   e          -   exists in?                        [0,  0,  1,  1,  0,  0,  0,  1,  1,  0,  0,  0,  1,  1,  1,  0]
        Ɲ     - for neighbouring pairs:
       n      -   not equal?                        [  0,  1,  0,  1,  0,  0,  1,  0,  1,  0,  0,  1,  0,  0,  1]
         ”"   - quote character                     '"'
           ẋ  - repeat (vectorises)                 [ [],['"'],[],['"'],[],[],['"'],[],['"'],[],[],['"'],[],[],['"']]
            ż - zip together                        [[[],'F'],[['"'],'o'],[[],'o'],[['"'],' '],[[],"'"],[[],'B'],[['"'],'a'],[[],'r'],[['"'],"'"],[[],','],[[],' '],[['"'],'b'],[[],'a'],[[],'z'],[['"']]]
              - implicit, smashing print            F"oo" 'B"ar"', "baz"

```

# Answer
> 0 votes
# PHP, ~~43~~ 41 bytes

```
<?=preg_replace('/[a-z]+/','"$0"',$argn);

```

Try it online!

A simple straightforward regex implementation

EDIT: Thanks to @manatwork for saving 2 bytes!

# Answer
> 0 votes
# Burlesque, 32 bytes

```
J"[^a-z]+"~?[~jqup"[a-z]+"~aj.+Q

```

Try it online!

Depressingly, more than half of this is attempting to overcome what I can only assume is a bug where the `~a` cuts off the last non-match.

```
J            # Duplicate
"[^a-z]+"~?  # All matches for not a-z
[~           # Take the last one
j            # Swap
# Main block (13 bytes)
qup          # Unparse to string
"[a-z]+"     # Matches a-z
~a           # Apply to those that match regex
####
j.+          # Add on hacky fix
Q            # Pretty print

```

# Answer
> 0 votes
# JavaScript (V8), 33 bytes

```
f=i=>i.replace(/[a-z]+/g,'"$&"');

```

-9 Bytes thanks to manatwork

Try it online!

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


title: A Mapping of Primes

text:
# Question
Title: A Mapping of Primes
Recently, I have found a bijective mapping \\$f\\$ from positive integers to finite, nested sequences. The purpose of this challenge is to implement it in the language of your choice.

## The Mapping

Consider a number \\$n\\$ with the factors \\$2^{a\_1}3^{a\_2}5^{a\_3}\cdots p^{a\_i}\\$ where \\$a\_i \> 0\\$

$$f(n) = \\{f(a\_2+1),f(a\_3+1),\cdots,f(a\_i+1),\underbrace{\\{\\},\\{\\},\cdots,\\{\\}}\_{a\_1}\\}$$

For example:

$$\begin{align} f(22308) & = \\{f(2),f(1),f(1),f(2),f(3),\\{\\},\\{\\}\\} \\ & = \\{\\{\\{\\}\\},\\{\\},\\{\\},\\{\\{\\}\\},\\{f(2)\\},\\{\\},\\{\\}\\} \\ & = \\{\\{\\{\\}\\},\\{\\},\\{\\},\\{\\{\\}\\},\\{\\{\\{\\}\\}\\},\\{\\},\\{\\}\\} \end{align}$$

## Rules

* You may write a full program or a function to do this task.
* Output can be in any format recognisable as a sequence.
* Built-ins for prime factorization, primality testing, etc. are **allowed**.
* Standard loopholes are disallowed.
* Your program must complete the last test case in under 10 minutes on my machine.
* This is code-golf, so the shortest code wins!

## Test Cases

* `10`: `{{},{{}},{}}`
* `21`: `{{{}},{},{{}}}`
* `42`: `{{{}},{},{{}},{}}`
* `30030`: `{{{}},{{}},{{}},{{}},{{}},{}}`
* `44100`: `{{{{}}},{{{}}},{{{}}},{},{}}`
* `16777215`: `{{{{}}},{{}},{{}},{},{{}},{{}},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{{}}}`
* `16777213`: pastebin

# Answer
# 05AB1E, 10 bytes

```
ÓćÅ0«ε¯sF¸

```

Output with `[]` instead of `{}`.

Try it online or verify all test cases, where test case `16777213` is replaced with `1009` (another prime number) - the output for `16777213` would be similar, just with *a lot* more leading `[],` ..

**Explanation:**

```
Ó           # Get the exponents of the prime factorization of the (implicit) input
            #  ([a,b,c,d,...] in 2^a*3^b*5^c*7^d*...=input)
 ć          # Extract head; pop and push remainder-list and first item separated
  Å0        # Get a list of 0s with a length equal to the `a` exponent
    «       # Merge that as trailing items to the remainder-list
     ε      # Map over each integer in the list:
      ¯     #  Push an empty list
       s    #  Swap so the current number is at the top of the stack
        F   #  Loop that many times
         ¸  #   And wrap the list into a list every iteration
            # (after which the result is output implicitly)

```
> 1 votes

# Answer
# CJam, ~~51~~ ~~48~~ ~~44~~ ~~42~~ ~~41~~ ~~39~~ ~~34~~ ~~33~~ 31 bytes

```
{mf_W=)1|{mp},\fe=(0a*+{)J}%}:J

```

Try it online in the CJam interpreter.

*Thanks to @MartinBüttner for golfing off 3 bytes!*

*Thanks to @PeterTaylor for golfing off 3 bytes and paving the way for 1 more!*

At least on my computer, downloading the file takes longer than running the program...

### I/O

This is a named function that pops and integer from STDIN and pushes an array in return.

Since CJam does not distinguish between empty arrays and empty strings – a string is simply a list that contains only characters –, the string representation will look like this:

```
[[""] "" [""] ""]

```

referring to the following, nested array

```
[[[]] [] [[]] []]

```

### Verification

```
$ wget -q pastebin.com/raw.php?i=28MmezyT -O test.ver
$ cat prime-mapping.cjam
ri
  {mf_W=)1|{mp},\fe=(0a*+{)J}%}:J
~`
$ time cjam prime-mapping.cjam <<< 16777213 > test.out

real    0m25.116s
user    0m23.217s
sys     0m4.922s
$ diff -s <(sed 's/ //g;s/""/{}/g;y/[]/{}/' < test.out) <(tr -d , < test.ver)
Files /dev/fd/63 and /dev/fd/62 are identical

```

### How it works

```
{                           }:J  Define a function (named block) J.
 mf                              Push the array of prime factors, with repeats.
   _W=                           Push a copy and extract the last, highest prime.
      )1|                        Increment and OR with 1.
         {mp},                   Push the array of primes below that integer.

                                 If 1 is the highest prime factor, this pushes
                                 [2], since (1 + 1) | 1 = 2 | 1 = 3.
                                 If 2 is the highest prime factor, this pushes
                                 [2], since (2 + 1) | 1 = 3 | 1 = 3.
                                 If p > 2 is the highest prime factor, it pushes
                                 [2 ... p], since (p + 1) | 1 = p + 2, where p + 1
                                 is even and, therefor, not a prime.

              \fe=               Count the number of occurrences of each prime
                                 in the factorization.

                                 This pushes [0] for input 1.

                  (              Shift out the first count.
                   0a*           Push a array of that many 0's.
                      +          Append it to the exponents.

                                 This pushes [] for input 1.

                       {  }%     Map; for each element in the resulting array:
                                   Increment and call J.

```
> 5 votes

# Answer
# Mathematica, 88 bytes

```
f@1={};f@n_:=f/@Join[1+{##2},1&~Array~#]&@@SparseArray[PrimePi@#->#2&@@@FactorInteger@n]

```
> 3 votes

# Answer
# Jelly, 14 bytes

```
ÆEµ“”WẋḢ;@‘ß€$

```

Try it online!

The last test case times out on TIO. The Footer runs the program over the inputs, gets their raw form (Jelly doesn't display empty lists well) and replaces the `[]` with `{}`

## How it works

```
ÆEµ“”WẋḢ;@‘ß€$ - Main link. Takes n on the left
ÆE             - Compute the prime exponents of n
  µ            - Begin a new link with the exponents E as the argument
   “”          - []
     W         - [[]]
       Ḣ       - Take the first exponent, a
      ẋ        - Repeat each element of [[]] a times
             $ - Group the previous 2 links as a monad f(E):
          ‘    -   Increment each exponent
            €  -   Over each:
           ß   -     Recursively run the main link
        ;@     - Append the [[]] to the recursive call result

```
> 3 votes

# Answer
# Pyth, 29 bytes

```
L+'MhMtbmYhbL&JPby/LJf}TPTSeJ

```

Demonstration

This defines a function, `'`, which performs the desired mapping.

A helper function, `y`, performs the mapping recursively given a prime decomposition. The base case and the prime decomposition are performed in `'`.
> 2 votes

# Answer
# Stax, 34 bytes

```
ÑE│♂█ⁿt2N╔₧Ñ↓Ls&ûΦ}eóâÇΔ-ë╖»8Kq+╔r

```

Run and debug it

There's very likely a better way to do this with recursion, but I just can't seem to find anything related to it in the builtin docs. So, this is a manually built implementation.

Takes very, very long after the third test case.

## Explanation (Unpacked)

```
z]Yx{c2>{|nBs{y@msz]s|*+c]ys+Yd}{vy@}?F|u
z]                                        array [[]]
  Y                                       write that to register Y
   x{                                 F   for i in [1..input]
     c2>                                  if i < 2,
                                {vy@}     increment and take element at that index from y
        {|n                               otherwise take prime exponents
           Bs                             push the first element and the rest of the array separately
             {  m                         map the rest of the array to:
              y@                          elements in y at those indices
                 sz]s                     push [[]] and first element
                     |*                   repeat it's elements that many times
                       +                  add those together
                        c]ys+Y            and append that to register Y
                              d}          then delete it
                                       |u convert the last element on stack to string
                                          implicit output

```
> 0 votes

---
Tags: code-golf, sequence, primes
---


title: Concatenating Primes

text:
# Question
Title: Concatenating Primes
**Challenge:**

You are given a string containing only digits. Your task is to output the minimum number of primes which must be concatenated to form the string. If this is impossible, output `0`.

**Test Cases:**

Input -\> Output:

```
252 -> 3
235 -> 2
92 -> 0
31149 -> 2

```

# Answer
# JavaScript (ES6), ~~123~~ ~~121~~ 120 bytes

```
f=(s,v)=>(p=n=>--n-1?s%n&&p(n):1)(s)||[...s].map((_,i)=>!(n=i&&(a=f(s.slice(0,i)))&&(b=f(s.slice(i)))&&a+b)|n>v?0:v=n)|v

```

*Saved a byte thanks to @Neil!*

## Explanation

Takes a single string as input. Due to the prime checking method (recursive trial division), the greatest number that can be safely checked is `13840`. Some numbers above this will fail due to the maximum call stack size being exceeded. It does, however, finish instantly for every case it can handle.

```
f=(s,v)=>
  (p=n=>--n-1?s%n&&p(n):1)(s) // if s is prime, return 1
  ||[...s].map((_,i)=>        // else for each index in s, split s into 2
    !(n=i&&                   // v = return value (initialised to undefined)
      (a=f(s.slice(0,i)))&&
      (b=f(s.slice(i)))&&
      a+b
    )|n>v?0:v=n               // if i, a, b and n are all > 0 and !(n > v), v = n
  )|v                         // cast v to an integer and return it

// Test
var testCases = [ "252", "235", "92", "3149", "24747" ];
document.write("<pre>" + testCases.map(c => c + ": " + f(c)).join("\n"));
```
> 6 votes

# Answer
# MATL, ~~26~~ 24 bytes

```
0in:"GUtZq@Z^V10ZA=a?x@.

```

It takes a few seconds for some of the test cases.

**Try it online!**

### Explanation

```
0       % Push 0
in:     % Take input. Generate array [1,2,...,N] where N is input length
"       % For each. In each iteration the number of used primes is increased
  GU    %   Push input. Convert to number
  tZq   %   Duplicate. Array of primes smaller than the input
  @     %   Push number of primes to bes tested in this iteration
  Z^    %   Cartesian power
  V     %   Convert to 2D array. Each row is a combination of primes
  10ZA  %   Convert each row to base 10, disregarding spaces
  =a    %   Do any of the results equal the input number?
  ?     %   If so
    x   %     Remove the 0 that's at the bottom of the stack
    .   %     Break for each loop
        %   Implicitly end if
        % Implicitly end for each
        % Implicitly display

```
> 5 votes

# Answer
# Pyth - ~~19~~ ~~17~~ 16 bytes

```
lhf.AmP_sdTa./zY

```

Test Suite.
> 4 votes

# Answer
# Pyth, 16 bytes

```
lhaf!f!P_sYT./zY

```

Test suite

Explanation to follow.
> 4 votes

# Answer
# Bash + coreutils, ~~169~~ ~~158~~ 149 bytes

```
c()
{
test $1||echo a
for i in `seq ${#1}`
do factor ${1::$i}|grep -q ': \w*$'&&printf b%s\\n `c ${1:$i}`
done
}
c $1|sort|sed '/a/!d;s/..//;q'|wc -c

```

We count in unary, outputting a line with one `b` for each prime and a terminating `a` at the end of line (so that `printf` has a token to work with).

The primality test is `factor $n | grep -q ': \w*$'`, which determines whether the number has exactly one prime factor.

We recursively partition the input; if the left half is prime, we filter the results of the right half by adding one to each value. Returning `a` for a zero-length input terminates the recursion.

Finally, we take all the results and sort to find the shortest (ignoring any that don't have the `a` to indicate success); we must delete two (for the inserted `a` and for the newline), then count characters to give the result.

### Tests

```
$ for i in 252 235 92 31149 111; do echo "$i:"$'\t'"$(./77623.sh $i)"; done
252:    3
235:    2
92:     0
31149:  2
111:    0

```

I added `111` to the tests to show that `1` is correctly considered non-prime.
> 2 votes

# Answer
# Mathematica, ~~142~~ 135 bytes

```
Min[Length/@Select[Join@@@Permutations/@IntegerPartitions@Length[a=#],And@@PrimeQ@*FromDigits/@a~Internal`PartitionRagged~#&]]/.∞->0&

```

As you can see, Mathematica was not built for this task. Takes a list of digits.
> 2 votes

# Answer
# Stax, 18 bytes

```
¬∞ÿ╔>÷▀↓☼~î☼ó♀RàEx

```

Run and debug it
> 0 votes

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


# Question
Title: Normal and inverted exclamation and question mark pairs
# Challenge

¡We're going to give exclamation and question marks inverted buddies!

Given a body of text containing sentences ending in `.`, `?`, or `!`, prepend inverted question marks, `¿`, to interrogative sentences (sentences ending in `?`) and inverted exclamation marks, `¡`, to exclamatory (sentences ending in `!`). Sentences ending in `.` are to be ignored.

Sentences will be separated by whitespace (spaces, tabs, and/or newlines) and will only contain alphanumerics, commas, apostrophes, and spaces. Every sentence will have at least one word. The first word of every sentence is guaranteed to be capitalized. Input can start and end with any whitespace.

## Example

Input:

```
  Hello there!      What is your name?
My name is Ron. What's your name?
My name is Alex.  Nice to meet you!
Nice to meet you to!  How was your break?
It was great, I spent all my time code golfing!
What's that?
        Wow, you're such a n00b! Here, let me show you.

```

Output:

```
  ¡Hello there!      ¿What is your name?
My name is Ron. ¿What's your name?
My name is Alex.  ¡Nice to meet you!
¡Nice to meet you to!  ¿How was your break?
¡It was great, I spent all my time code golfing!
¿What's that?
        ¡Wow, you're such a n00b! Here, let me show you.

```

## Rules

* All default Code Golf rules apply.
* The program with the shortest amount of bytes wins.

# Bonus (17% off) - Parse multiple marks

A sentence can also end in multiple exclamation/question marks. Give each of these marks a paired inverse exclamation/question mark for an extra 17% off your byte count.

## Example

Input:

```
I am a man in a can doing a dance?? Maybe...
              Doing it for the views??!???!

```

Output:

```
¿¿I am a man in a can doing a dance?? Maybe...
              ¡¿¿¿¡¿¿Doing it for the views??!???!

```

*Incorrect* output:

```
¿¿I am a man in a can doing a dance?? Maybe...
              ¿¿¡¿¿¿¡Doing it for the views??!???!

```

# Answer
> 5 votes
## Retina, ~~39~~ ~~37~~ 34 bytes

```
\w[^.]*?([!?])
$1$0
T`?!`¿¡`\S\b

```

Try it online.

### Explanation

```
\w[^.]*?([!?])
$1$0

```

This matches a sentence ending in an exclamation or question mark, and prepends that punctuation character to the sentence. Now we know that all the `!` or `?` which are immediately followed by a non-space character must be those we inserted, because the original ones should be separated from the next character by a space.

```
T`!?`¡¿`\S\b

```

This transliteration stage turns all `!` and `?` into `¡` and `¿`, respectively, provided they're found in a match of `\S\b`, which applies only to the ones we just inserted. Replacing both in two separate substitutions in the same byte count, but I prefer the semantics of a transliteration stage here.

# Answer
> 3 votes
## Javascript (ES6), ~~86~~ ~~79~~ ~~66~~ 63 bytes

```
i=>i.replace(/\w[^.!?]*[!?]/g,k=>(k.slice(-1)>'>'?'¿':'¡')+k)

```

Ungolfed:

```
func = inp => inp.replace(/\w[^.!?]*[!?]/g, sentence => (sentence.slice(-1) > '>' ? '¿' : '¡') + sentence)

```

Usage:

```
console.log(func(`Hello there!      What is your name?
My name is Ron. What's your name?
My name is Alex.  Nice to meet you!
Nice to meet you to!  How was your break?
It was great, I spent all my time code golfing!
What's that?
            Wow, you're such a n00b! Here, let me show you.`))

```

Will implement bonus solution soon.

*Thanks to: <br>@user81655, 86 =\> 79 bytes*

# Answer
> 3 votes
## Mathematica, ~~101~~ ~~92~~ 91 bytes

```
StringReplace[#,RegularExpression@"[A-Z][^.]*?([?!])":><|"?"->"¿","!"->"¡"|>@"$1"<>"$0"]&

```

# Answer
> 3 votes
# Mathematica 137 bytes

Not the shortest, but it was fun to do.

`TextSentences` breaks up the input text into sentences and `StringPosition` finds the beginning and end positions of each sentence in the text. The upside down punctuation is inserted at the beginning of each sentence as required.

```
w=StringPosition;f[x_,y_,q_]:=StringInsert[x,q,x~w~y/.{a_,a_}->a/.(x~w~#&/@TextSentences@#&@x/.{{c_,d_}}:>d->c)];f[f[t,"!","¡"],"?","¿"]&

```

---

Usage, assuming the text is input at `t`,

```
f[f[#,"!","¡"],"?","¿"]&[t]

```

# Answer
> 3 votes
# Sed, 61 bytes

```
s/\(\s*\)\([^.!?]*!\)/\1¡\2/g;s/\(\s*\)\([^.!?]*?\)/\1¿\2/g

```

---

Test run :

```
$ echo """Hello there!      What is your name?
My name is Ron. What's your name?
My name is Alex.  Nice to meet you!
Nice to meet you to!  How was your break?
It was great, I spent all my time code golfing!
What's that?
        Wow, you're such a n00b! Here, let me show you.""" | sed 's/\(\s*\)\([^.!?]*!\)/\1¡\2/g;s/\(\s*\)\([^.!?]*?\)/\1¿\2/g'
¡Hello there!      ¿What is your name?
My name is Ron. ¿What's your name?
My name is Alex.  ¡Nice to meet you!
¡Nice to meet you to!  ¿How was your break?
¡It was great, I spent all my time code golfing!
¿What's that?
        ¡Wow, you're such a n00b! Here, let me show you.

```

# Answer
> 1 votes
# Python 2, 127.82 (154-17%) bytes

```
import re
print re.sub("([A-Z][\w ,']*)([\.!\?]+)",lambda m:''.join({'!':'¡','?':'¿','.':''}[c]for c in m.group(2))[::-1]+m.group(1)+m.group(2),input())

```

# Answer
> 1 votes
# , 36 chars / 53 bytes

```
ïċ/\w⁅.!?]*[!?]⌿,⇏(aē-1>⍘>?⍘¿:⍘¡)+a)

```

`Try it here (Firefox only).`

# Answer
> 1 votes
# Jelly, 41 bytes

```
0ị⁾!?iị“¡¿ ”t⁶
e€“!?.”kµOe€“µ½ ‘«\nƝkjÇ)F

```

Try it online!

Bah, who needs regex?

## How it works

```
e€“!?.”kµOe€“µ½ ‘«\nƝkjÇ)F - Main link. Takes a string S on the left
  “!?.”                    - Yield "!?."
 €                         - For each character in S:
e                          -   Is it in "!?."?
       k                   - Split S after occurrences of any of "!?."
        µ                  - Call this list of lists of characters L and use it as the argument
                        )  - For each list of characters C in L:
         O                 -   Convert to a list of char codes
            “µ½ ‘          -   Yield [9, 10, 32]
           €               -   For each char code in C:
          e                -     Is it in [9, 10, 32]?
                               This yields 1s at whitespace characters else 0
                               However, we only want to consider leading whitespace,
                               not whitespace in the string, when inserting ¡¿
                  \        -   Scan:
                 «         -     Minimum
                               This changes all non-leading 1s to 0s
                     Ɲ     -   Over overlapping pairs:
                    n      -     Does not equal?
                               This turns the leading run of 1s into 0s with a final 1
                      k    -   Split C at this 1
                        Ç  -   Call the helper link on C
                       j   -   Join the split C on the helper link
                         F - Flatten into a single string

0ị⁾!?iị“¡¿ ”t⁶ - Helper link. Takes a list of characters C on the left
0ị             - Last character of C, c
  ⁾!?          - "!?"
     i         - Index of c in "!?" or 0 (for sentences ending with ".")
       “¡¿ ”   - "¡¿ "
      ị        - 1-index into this string. "." -> " "
             ⁶ - " "
            t  - Trim spaces. "." -> ""

```

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


# Question
Title: Convert Magic the Gathering colours to a Colour based deck name
Magic the gathering has many unique names for colour combinations in decks, as an example when Blue and White appear together in a deck, the deck maye sometimes be named after the Ravnican Guild that features those colours, namely 'Azorius'. There are some exceptions, and oddities though.

Below is a list of colour letters (one of WUBRG) combinations, and a list of their corresponding example colour deckname part (the order of letters is not fixed for this challenge):

```
W: Monowhite/Mono-White
U: Monoblue/Mono-Blue
B: Monoblack/Mono-Black
R: Monored/Mono-Red
G: Monogreen/Mono-Green
WU: Azorius
WB: Orzhov
WR: Boros
WG: Selesnya
UB: Dimir
UR: Izzet
UG: Simic
BR: Rakdos
BG: Golgari
RG: Gruul
GWU: Bant
WUB: Esper
UBR: Grixis
BRG: Jund
RGW: Naya
WBG: Abzan/Indatha/Necra
URW: Jeskai/Raka/Raugrin
BUG: Sultai/Ana/Bug/Zagoth
RWB: Mardu/Dega/Savai
URG: Temur/Ceta/Rug/Ketria
UBRG: Chaos/Glint/Glint-Eye/Non-White
BRGW: Aggression/Dune/Dune-Brood/Non-Blue
RGWU: Altruism/Ink/Ink-Treader/Non-Black
GWUB: Growth/Witch/Witch-Maw/Non-Red
WUBR: Artifice/Yore/Yore-Tiller/Non-Green
WUBRG: Domain/Five-Color
C: Colorless/Monobrown/Mono-Brown

```

The challenge is to take in any of the letter combination entries above as *input*, and then output only *one* of the listed names. As previously started, the order of letters is not important, so BWRG is the same as BRGW etc, and should output one of Aggression/Dune/Dune-Brood/Non-Blue.

Input and output should be case insensitive, so that it will accept either as input, but either case of output (or both!) is fine.

Nonsense input is allowed to error or give a nonsense output. e.g. inputting 'wubrger' can throw an error or output 'Mark Rosewater' (or any string, even valid output) for example.

# Answer
> 5 votes
# 05AB1E, ~~136~~ ~~135~~ ~~133~~ 132 bytes

```
“ƒÏˆ¨†¾‡—„¸ ŽÌ“#'Î×ì.•вO₁ŸĀ0Ðëœ´0+Eм/#‰TôbHüÆΣÇÐζfβq₅([²åOÇηB₂È¥ƶ]9í$µÅ–tå(h0!Ãα9½êT₄Ì€+µxΩ;'Äçî9©ÙÝ“R_Ÿ U„δ
ÅíÂu•#5ǝ˜.•Iλβ•æé¦Il{kè

```

Outputs in full lowercase; uses the shortest outputs if multiple are allowed.

Try it online or verify all test cases (uses a random permutations for each test case input).

**Explanation:**

```
“ƒÏˆ¨†¾‡—„¸ ŽÌ“ # Push dictionary string "black green red blue white  brown"
 #              # Split it on spaces: ["black","green","red","blue","white","","brown"]
  'Î×ì         '# Prepend dictionary string "mono" to each string
.•вO₁ŸĀ0Ðëœ´0+Eм/#‰TôbHüÆΣÇÐζfβq₅([²åOÇηB₂È¥ƶ]9í$µÅ–tå(h0!Ãα9½êT₄Ì€+µxΩ;'Äçî9©ÙÝ“R_Ÿ U„δ\nÅíÂu•
                # Push compressed string "golgari rakdos gruul dimir simic izzet orzhov selesnya boros azorius jund ana grixis rug abzan dega naya esper bant raka chaos dune witch yore ink domain"
 #              # Split on spaces as well
  5ǝ            # Insert this list at 0-based index 5
    ˜           # And flatten the list to complete the list of deck-names
.•Iλβ•          # Push compressed string "bgruw"
      æ         # Pop and push all its permutations
       é        # Sort them by length: ["","b","g","r","u","w","bg","br","gr","bu","gu","ru","bw","gw","rw","uw","bgr","bgu","bru","gru","bgw","brw","grw","buw","guw","ruw","bgru","bgrw","bguw","bruw","gruw","bgruw"]
        ¦       # Remove the first empty string
I               # Push the input-string
 l              # Convert it to lowercase
  {             # Sort its characters
   k            # Get the index of this string in the list of permutations,
                # or -1 if it isn't present in the case of input "c"/"C"
    è           # And use that index to index into the list of deck-names
                # (0-based, where -1 will wrap around to the end)
                # (after which the result is output implicitly)

```

See this 05AB1E tip of mine (sections *How to use the dictionary?* and *How to compress strings not part of the dictionary?*) to understand how the compressed strings work.

# Answer
> 4 votes
# 05AB1E, ~~133~~ 132 bytes

Thanks to Kevin Cruijssen for -1 byte!

```
.•αćðoвÍ‘óÉp₂›qt8¬Ôтõ—qŠ¤öôI‚¦æâ\₄²5₃1.Ćåuc[âY™FŒ¸VOœ₂9>îÓ‰ìîʒO=|e₁e²Ì¯ß₅m4ÖāHŠBÌz©?Ωć¨_¶∊á‘ÂΔHÓÄ÷U}úÙÕF„k{%ì6?“:Rƒá•#¬æIl{kèIgi'Î×ì

```

Try it online!

**Commented**:

```
.•α...á•                  -- compressed alphabet string
                          --   "bgruw black ... domain brown"
        #                 -- split on spaces
         ¬                -- get the first element "bgruw"
          æ               -- take the powerset ["", "b", "g", ..., "bgruw"]
           I              -- push the input
            l             -- convert to lowercase
             {            -- sort it
              k           -- find the index of this string in the powerset
                          --   b -> 1, ..., bgruw -> 31, c -> -1
               è          -- index with this integer into the word list
                Ig        -- push the length of the input
                  i       -- if this is truthy (equal to 1):
                   'Î×ì   --   prepend compressed string "mono"

```

# Answer
> 3 votes
# JavaScript (ES6), 254 bytes

Expects an array of characters as input.

```
a=>`SelesnyaXXGolgariChaosXDuneXXXXMonoblackColorlessEsperRakdosXMonogreenDimirJundOrzhovDomainAnaXAbzanGrixisInkDegaMonoredXIzzetMonoblueBorosMonowhiteRugAzoriusNayaXWitchBantGruulYoreRakaSimic`.match(/.[a-z]*/g)[parseInt(a.sort().join``,33)%472%244%44]

```

Try it online!

# Answer
> 2 votes
# Charcoal, 138 bytes

```
×›²Ｌθmono§⪪”&⌈⧴ν;ＩjＷκ,êQＤ↷$εe⪫_Ｓ�✂σ¶⍘↶Ｊa↧ ‖wυ^z‖U›ï^？Ｆ$←Ｐ↗Wιº+Ｆ|γaÀ⁹？t*a≕∨0]Ｘ‹75·¡≔⁸“↨⊟E⦃⌈&?q⍘⌕�,ＱDπnB ✂a|⁹℅Uξ⟲ⅈK´φN›～t\`$⊕ζ⊕”q↨Ｅwubrg№↧θι²

```

Try it online! Link is to verbose version of code. Explanation:

```
×›²Ｌθmono

```

Print `mono` if the number of characters in the input is less than 2.

```
§⪪”...”q↨Ｅwubrg№↧θι²

```

Split the compressed string of colour names on `q` and index it by taking the counts of each of the colour letters in the input and interpreting them as a number in base 2.

# Answer
> 1 votes
# Jelly, 149 bytes

```
“®×bẒAJ²ṘẈ!sỵḷ:-Þ5M£LƇ(¥Ḋg½Bm%³ḣʠĊ¢*¶|ƭ⁾Ḳ¹øṡ(:d,g5ṚVW]t;/ẓẇpⱮṄḟɗæ(ƓYẎĖẹḲA’b27ṣ0ịØa
“-e“ẠỤ“¡cy“/⁷“¡ḷọ»µ“ċ¦⁶»;Ɱ;¢;Ṛ“ċ=€»;ⱮƊ;“ÐOẈ“µƬḞ»
ŒuṢ“BGRUW”ŒPḊ¤iị¢

```

Try it online!

## Explanation

```
“...’b27ṣ0ịØa   Auxiliary niladic link
“...’           A big number in base 250
     b27        Convert to base 27
        ṣ0      Split on zeros
          ịØa   Index into the lowercase alphabet
                => ["golgari", "rakdos", ..., "bant", "raka"]

“...»µ“ċ¦⁶»;Ɱ;¢;Ṛ“ċ=€»;ⱮƊ;“ÐOẈ“µƬḞ»   Auxiliary niladic link
“...»                                 ["Black", "Green", "Red", "Blue", "White"]
     µ                                Use as new argument
      “ċ¦⁶»;                          Prepend "Mono-"
            Ɱ                           to each
             ;¢                       Join with link above
               ;                      Join with
                        Ɗ             (
                Ṛ                       Reverse [the list of colors]
                 “ċ=€»;                 Prepend "Non-"
                       Ɱ                  to each
                        Ɗ             )
                         ;            Join with
                          “ÐOẈ“µƬḞ»     ["Domain", "Colorless"]

ŒuṢ“BGRUW”ŒPḊ¤iị¢   Main monadic link
Œu                  Uppercase
  Ṣ                 Sort
              i     Find index in
             ¤      (
   “BGRUW”            "BGRUW"
          ŒP          Power set
            Ḋ         Remove first element [the empty string]
             ¤      )
               ị    Index into
                ¢     Link above

```

---
Tags: code-golf, kolmogorov-complexity
---


title: The Abelian Orders

text:
# Question
Title: The Abelian Orders
## Some background

In math, a **group** is a tuple \\$(G, \*)\\$ where \\$G\\$ is a set and \\$\*\\$ is an operation on \\$G\\$ such that for any two elements \\$x, y \in G, x * y \in G\\$.

For some \\$x,y,z\in G\\$, basic group axioms are as follows:

* \\$G\\$ is **closed** under \\$\*\\$, i.e. \\$x * y \in G\\$
* The operation \\$\*\\$ is **associative**, i.e. \\$x * (y * z) = (x * y) * z\\$
* \\$G\\$ has an **identity** element, i.e. there exists \\$e \in G\\$ such that \\$x * e = x\\$ for all *x*
* The operation \\$\*\\$ is **invertible**, i.e. there exist \\$a, b \in G\\$ such that \\$a * x = y\\$ and \\$y * b = x\\$

Okay, so those are groups. Now we define an **Abelian group** as a group \\$(G, \*)\\$ such that \\$\*\\$ is a **commutative** operation. That is, \\$x * y = y * x\\$.

Last definition. The **order** of a group \\$(G, \*)\\$, denoted \\$|G|\\$, is the number of elements in the set \\$G\\$.

## Task

The Abelian orders are the integers \\$n\\$ such that every group of order \\$n\\$ is Abelian. The sequence of Abelian orders is A051532 in OEIS. Your job is to produce the \\$n\\$th term of this sequence (1-indexed) given an integer \\$n\\$. You must support input up to the largest integer such that nothing will overflow.

Input can come from function arguments, command line arguments, STDIN, or whatever is convenient.

Output can be returned from a function, printed to STDOUT, or whatever is convenient. Nothing should be written to STDERR.

Score is number of bytes, shortest wins.

## Examples

Here are the first 25 terms of the sequence:

```
1, 2, 3, 4, 5, 7, 9, 11, 13, 15, 17, 19, 23, 25, 29, 31, 33, 35, 37, 41, 43, 45, 47, 49, 51

```

# Answer
> 6 votes
## CJam (35 32 bytes)

```
0q~{{)_mF_z~2f>@::#@m*::%+1&}g}*

```

Online demo

### Dissection

To rephrase some of the information in OEIS, the Abelian orders are the cube-free nilpotent orders; and the nilpotent orders are the numbers `n` for which no prime power divisor `p^k | n` is congruent to `1` modulo another prime divisor.

If we pass the cube-free test, the nilpotency test reduces to

* No prime factor is equal to `1` modulo another prime factor
* If the multiplicity of prime `p` is `k`, `p^k` must not equal `1` modulo another prime factor.

But then the second condition implies the first, so we can reduce it to

* If the multiplicity of prime `p` is `k`, `p^k` must not equal `1` modulo another prime factor.

Note that the word "another" is unnecessary, because `p^a == 0 (mod p)` for `a > 0`.

```
0q~{       e# Loop n times starting from a value less than the first Abelian order
  {        e#   Find a number which doesn't satisfy the condition
    )_     e#     Increment and duplicate to test the condition on the copy
    mF     e#     Find prime factors with multiplicity
    _z~    e#     Duplicate and split into the primes and the multiplicities
    2f>    e#     Map the multiplicities to whether or not they're too high
    @::#   e#     Bring factors with multiplicities to top and expand to array of
           e#     maximal prime powers
    @m*::% e#     Cartesian product with the primes and map modulo, so for each
           e#     prime power p^k and prime q we have p^k % q.
    +      e#     Combine the "multiplicity too high" and the (p^k % q) values
    1&     e#     Check whether either contains a 1
  }g
}*

```

# Answer
> 5 votes
## CJam, ~~46~~ 45 bytes

```
0{{)_mf_e`_:e>3a>\{~\,:)f#}%@fff%e_1e=|}g}ri*

```

Test it here.

I'm using the condition given on the OEIS page:

> Let the prime factorization of \\$n\\$ be \\$p\_1^{e\_1}\cdots p\_r^{e\_r}\\$. Then \\$n\\$ is in this sequence if \\$e\_i \< 3\\$ for all \\$i\\$ and \\$p\_i^k \ne 1 \text{ (mod }p\_j\text)\\$ for all \\$i, j\\$ and \\$1 \le k \le e\_i\\$ --- T. D. Noe, Mar 25 2007

I'm fairly certain this can be golfed, especially the check of the last condition.

# Answer
> 3 votes
# Pyth, 37 bytes

```
e.f!&tZ|f>hT2JrPZ8}1%M*eMJs.b*LYSNJ)Q

```

Test suite

Uses the formula from OEIS, cubefree and no prime-power factors that are 1 mod a prime factor, other than 1.

# Answer
> 2 votes
# Jelly, 23 bytes

```
ÆF*/€%þÆfn1ṭÆE<3ƊȦ
1Ç#Ṫ

```

Try it online!

Takes input via STDIN

## How it works

This uses the same condition as the other answers, given on the OEIS page:

> Let the prime factorization of \\$n\\$ be \\$p\_1^{e\_1}\cdots p\_r^{e\_r}\\$. Then \\$n\\$ is in this sequence if \\$e\_i \< 3\\$ for all \\$i\\$ and \\$p\_i^k \ne 1 \text{ (mod }p\_j\text)\\$ for all \\$i, j\\$ and \\$1 \le k \le e\_i\\$

```
1Ç#Ṫ - Main link. Takes no arguments
1 #  - Read an integer n from STDIN. Count up k = 1, 2, 3, ... until n such k
       return true under:
 Ç   -   The helper link
   Ṫ - Return the last k

ÆF*/€%þÆfn1ṭÆE<3ƊȦ - Helper link. Takes an integer k on the left
ÆF                 - Yield the prime factorisation of k in [base, exponent] pairs
   /               - Reduce
    €              -   Each
  *                -     By exponentiation
       Æf          - Yield the list of primes whose product is k
     %þ            - Yield a modulo table of these two lists. This takes all pairs
                     from the two lists and reduces each by modulo, yielding a
                     table of all possible modulo pairings. k can only return true
                     iff 1 is not in this table
         n1        - Map 1 -> 0 and everything else to 1
                Ɗ  - Group the previous three links into a monad f(k):
            ÆE     -   Exponents of k's prime factorisation
              <3   -   Less then 3? (vectorises)
                     This yields a binary list of all 1s if k is true else at least 1 0
           ṭ       - Tack. Append the modulo table to the binary list. Call this T
                 Ȧ - Any and all. Does T contain all 1s when flattened and T is non-empty?

```

---
Tags: code-golf, math, sequence, abstract-algebra
---


title: Find the average of a word

text:
# Question
Title: Find the average of a word
> Inspired by this chat message

Your task will be to take a word and find the average position of its letters on the keyboard as a letter.

## Keyboard Layout

Since layouts vary from keyboard to keyboard, we will be using a standard based of of my own keyboard in this question.

The keyboard has 3 rows, the top row from left to right contains the keys

```
QWERTYUIOP

```

The second row contains the letters

```
ASDFGHJKL

```

The final row contains

```
ZXCVBNM

```

Each letter is 1 unit horizontal from its neighbor to the left. This means that `W` is 1 away from `Q` and `E` is 1 away from `W` and so on.

The keys at the beginning of each row have the positions:

```
Q : 0,0
A : 1/3,1
Z : 2/3,2

```

This means that the rows are separated one unit vertically and the bottom two rows are shifted by a third from the row above them.

---

You should take a word as input and output the letter that is closest to the average position of the letters in its word. The average of a set of vectors is

```
(average x value, average y value)

```

When two keys are equidistant from the average you may output either as the "closest" key.

This is so answers will be scored in bytes with fewer bytes being better.

## Example solution

Let's calculate the average of `APL`.

We convert each letter to a vector

```
A -> (1/3,1)
P -> (9,0)
L -> (8 1/3,1)

```

We add these up the three vectors to get `(17 2/3, 2)`. We then divide each coordinate by 3 (The number of letters in the word) to get `(5 8/9, 2/3)`.

The closest letter to `(5 8/9, 2/3)` is `J` at `(6 1/3,1)` so our result is `J`.

## Test Cases

```
APL  -> J
TEXT -> R
PPCG -> J
QQQQ -> Q
ZZZZ -> Z
PPPP -> P
MMMM -> M
QQSS -> A or W

```

# Answer
> 5 votes
# Python 3, 130 bytes

```
lambda w,d={'QAZWSXEDCRFVTGBYHNUJMIKOOLPP'[i]:i%3*1j+i/3for i in range(28)}:min(d,key=lambda c:abs(d[c]-sum(map(d.get,w))/len(w)))

```

Try it online!

`d={'QAZWSXEDCRFVTGBYHNUJMIKOOLPP'[i]:i%3*1j+i/3for i in range(28)}` constructs the mapping from letters to points (represented as complex numbers, `(x+y*1j)`).

As for the lambda body, `sum(map(d.get,w))/len(w)` computes the average position of word `w`, and putting that in `min(d,key=lambda c:abs(d[c]-…))` finds the closest letter to that position. (For complex numbers, `abs(A-B)` corresponds to the Euclidean distance between `(A.real, A.imag)` and `(B.real, B.imag)`.)

# Answer
> 3 votes
# C# (.NET Core), 250 + 13 bytes

+13 bytes for `using System;`

```
n=>{var a=new[]{"QWERTYUIOP","ASDFGHJKL","ZXCVBNM"};float x=0,y=0;int i=0,j=0,l=n.Length;foreach(char c in n){for(i=0,j=0;i<2;){if(a[i][j]==c)break;if(++j>=a[i].Length){i++;j=0;}}x+=j;y+=i;}return a[(int)Math.Round(y/3)][(int)Math.Round(x/l+y/l/3)];}

```

Try it online!

Little sidenote: This outputs `F` for `TEXT`, since that was the original desired output.
Outputting `R` instead of `F` was changed after this answer was posted.

# Answer
> 3 votes
# Jelly, 37 bytes

```
ØQi€µT÷3Ḣ+Ṁ;T
Ç€ZÆmðạ²SðÐ€ØAÇ€¤iṂ$ịØA

```

Try it online!

lol way too long

# Explanation

```
ØQi€µT÷3Ḣ+Ṁ;T            Helper Link; compute the position of a key
   €                     For each row of
ØQ                       ["QWERTYUIOP", "ASDFGHJKL", "ZXCVBNM"] (hooray for builtins)
  i                      Find the first occurrence of the argument
    µ                    Start a new monadic chain
     T                   List of indices of truthy values; singleton list with the row of the key
      ÷                  Divide the index by
       3                 3
        Ḣ                Take the first element
         +               Add it to the original list
          Ṁ              Take the maximum (the adjusted horizontal position of the key)
           ;             Append
            T            The index of the truthy value (the row)
Ç€ZÆmðạ²SðÐ€ØAÇ€¤iṂ$ịØA  Main Link
 €                       For each character in the input
Ç                        Compute its position using the helper link
  Z                      Zip (all of the horizontal positions are in the first list; all of the vertical positions are in the second list)
   Æm                    Take the arithmetic mean (of each sublist)
     ðạ²Sð               Dyadic chain to compute the distance (squared) between two coordinates
      ạ                  Take the absolute difference between each coordinate value (auto-vectorization)
       ²                 Square each value
        S                Take the sum (returns the distance squared but for comparison that's fine)
          Ð€             Take the distance between the mean position and each element in
            ØAÇ€¤        [Nilad:] the positions of each character in the uppercase alphabet
               €         For each character in
            ØA           "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
              Ç          Compute its position
                 iṂ$     Find the index of the minimum (closest)
                 i       First occurrence of             in the list of distances
                  Ṃ                          the minimum
                    ị    Index back into
                     ØA  The alphabet

```

# Answer
> 2 votes
## JavaScript (ES6), 166 bytes

```
f=
s=>[...s].map(c=>(h+=c=s.search(c),v+=c%3,l++),h=v=l=0,s='QAZWSXEDCRFVTGBYHNUJMIKKOLLP')&&[...s].map((c,i)=>(i=(i-h/l)*(i-h/l)+(i=i%3-v/l)*i*9,i)<m&&(m=i,r=c),m=9)&&r
```

```
<input oninput=o.textContent=/^[A-Z]+$/.test(this.value)?f(this.value):``><pre id=o>
```

6 bytes could be saved by switching to ES7. Previous 131-byte solution used a simplistic distance check which is no longer acceptable.

```
f=
s=>([...s].map(c=>(h+=c=s.search(c),v+=c%3,l++),h=v=l=0,s='QAZWSXEDCRFVTGBYHNUJMIKKOLLP'),v=(v/l+.5|0),h=((h/l-v)/3+.5|0),s[h*3+v])
```

```
<input oninput=o.textContent=/^[A-Z]+$/.test(this.value)?f(this.value):``><pre id=o>
```

# Answer
> 2 votes
# Java, ~~257 243 242~~ 237 bytes

```
char h(String s){int l=s.length(),i=l+28;s="QAZWSXEDCRFVTGBYHNUJMIK<OL>P"+s;float d=9,x=0,y=0,e;for(;i>28;y+=(e=s.indexOf(s.charAt(--i)))%3/l,x+=e/3/l);for(;i-->0;)if((e=(x-i/3f)*(x-i/3f)+(y-i%3)*(y-i%3))<d){d=e;l=i;}return s.charAt(l);}

```

Saved 14 bytes - the distance away from the best key will be less than 3 units

# Answer
> 1 votes
# Java (OpenJDK 8), ~~452~~ ~~431~~ ~~424~~ ~~400~~ ~~389~~ ~~324~~ ~~322~~ ~~296~~ ~~285~~ ~~281~~ ~~276~~ ~~274~~ ~~260~~ ~~258~~ 257 bytes

Something to start golfing from

```
s->{String c="QWERTYUIOPASDFGHJKL;ZXCVBNM";int i=0,r=0,l=0;double x=0,y=0,D=99,t,f=s.length();for(;i<f;x+=l%10+l/10/3d,y+=l/10)l=c.indexOf(s.charAt(i++));for(;r<27;r++)if(D>(t=Math.pow(x/f-r/10/3d-r%10,2)+Math.pow(y/f-r/10,2))){D=t;l=r;}return c.charAt(l);}

```

Try it online!

# Answer
> 1 votes
# Charcoal, 79 bytes

```
≔⪪”$±=Ｋ≕⦃Vj@η⟲.w\`o:7➙1”¶ηＦθＦ³Ｆ⌕Ａ§ηκι⊞υ⟦λκ⟧ＩＥ²∕ΣＥυ§λιＬθ§§η⁺·⁵∕ΣＥυ⊟ιＬθ⁺·⁵∕ΣＥυ⊟ιＬθ

```

Try it online!

Neil's golf using string functions.

# Charcoal, 107 bytes

```
Ｐ”$±=Ｋ≕⦃Vj@η⟲.w\`o:7➙1”≔⟦⟧α≔⟦⟧βＦχ«Ｆ³«ＪικＦθ«¿⁼λＫＫ«⊞α⎇›ⅉ⁰⁺∕¹¦³ⅈⅈ⊞βⅉ»»»»Ｊ⌊∕⁺Σα·⁵Ｌθ⌈∕⁺Σβ·⁵Ｌθ≔ＫＫχ⎚χ¶Ｉ∕ΣαＬθ¶Ｉ∕ΣβＬθ

```

Try it online!

Draws the keyboard on the canvas and finds the average that way.

# Answer
> 1 votes
# Jelly, ~~33~~ 31 bytes

```
Æịµ÷3Ċ+
ØQœiⱮÇÆmØQŒṪ¤Çạ¥ÐṂœịØQX

```

Try it online!

Uses some features that were presumably not implemented when HyperNeutrino wrote his solution, so considering this only beats it by ~~4~~ 6 bytes, I wouldn't be surprised if a modernized version of his would come out shorter--but I started writing this before I even noticed his existed.

```
Æịµ÷3Ḟ+                    Helper link (monadic):
Æị                         convert list to complex,
  µ   +                    add the complex number to
     Ċ                     the imaginary part of
   ÷3                      its quotient by 3.

ØQœiⱮÇÆmØQŒṪ¤Çạ¥ÐṂœịØQX    Main link:
ØQœiⱮ                      multidimensional indices of input in QWERTY layout,
     Ç                     apply helper link,
      Æm                   average;
        ØQŒṪ¤              for all multidimensional indices in the layout
                ÐṂ         keep those with the smallest
              ạ¥           absolute difference between the average and
             Ç             their result from the helper link;
                  œịØQ     index back into QWERTY
                      X    and choose one key at random.

```

# Answer
> 1 votes
# 05AB1E, 44 bytes

```
žVIšεεžVsδkDZkDŠ3/+à‚]ćøÅA`UòDžVsèŠè€θDX.xkè

```

Not too happy with it, but it works.. :/ Can definitely be golfed some more using a different approach.

I/O in lowercase.

Try it online or verify all test cases.

**Explanation:**

Step 1: create a list with all the coordinate-values, and convert the input in a similar matter as well:

```
žV                     # Push builtin ["qwertyuiop","asdfghjkl","zxcvbnm"]
  Iš                   # Prepend the input-string to this list
    ε                  # Map over each string:
     ε                 #  Inner map over each individual character:
      žV               #   Push ["qwertyuiop","asdfghjkl","zxcvbnm"] again
        s              #   Swap so the current character is at the top of the stack
         δk            #   Get the index of this character in each of the three strings
                       #   (or -1 if it's not found)
           D           #   Duplicate this list of indices
            Z          #   Get the largest index (without popping)
             k         #   Get the index of this largest index in the triplet
              D        #   Duplicate this index
               Š       #   Triple swap the three values on the stack (a,b,c→c,a,b)
                3/     #   Divide it by 3
                  +    #   Add it to each index in the list we duplicated
                   à   #   Pop and push the maximum again
                    ‚  #   And pair it with the duplicated & triple-swapped index
    ]                  # Close the nested maps

```

Try just this first step.

Step 2: get the average coordinate of the input:

```
ć                      # Extract head; pop and push remainder-list and first item separated
 ø                     # Zip/transpose; swapping rows/columns
  ÅA                   # Get the arithmetic mean of both inner triplets

```

Try just the first two steps.

Step 3: get the coordinate closest to this average coordinate, and convert it back to a character to output:

```
`                      # Pop and push both separated to the stack
 U                     # Pop and store the second one in variable `X`
  ò                    # Round the first value to the nearest integer
   D                   # Duplicate this integer
    žV                 # Push ["qwertyuiop","asdfghjkl","zxcvbnm"] yet again
      s                # Swap so the integer is at the top of the stack
       è               # Index it into the list of strings
        Š              # Triple-swap the values on the stack (a,b,c→c,a,b)
         è             # Index the duplicated integer into the remainder-list
          €θ           # Leave the last value of each inner pair
            D          # Duplicate the list
             X.x       # Pop the copy and leave the value closest to value `X`
                k      # Get the index of this value in the duplicated list
                 è     # And index it into the string we triple-swapped
                       # (after which this character is output implicitly as result)

```

# Answer
> 0 votes
# Mathematica, 234 bytes

```
(r=(K=Round)@Mean[If[(w=First[q=#&@@Position[(s=X/@{"QWERTYUIOP","ASDFGHJKL","ZXCVBNM"}),#]])==1,q=q-1,If[w==2,q=q+{-1,-2/3},q=q+{-1,-1/3}]]&/@(X=Characters)@#];z=If[(h=#&@@r)==0,r=r+1,If[h==1,r=r+{1,2/3},r=r+{1,1/3}]];s[[##]]&@@K@z)&

```

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


title: Minimum rectangle cover

text:
# Question
Title: Minimum rectangle cover
## Rectangle covers

Suppose you have a matrix of bits, for example the following.

```
1 1 0 0 0 1 1 0
1 1 1 1 0 1 1 1
0 1 1 1 0 1 1 1
1 1 0 1 1 1 1 0
1 1 0 1 1 1 0 1

```

We would like to find a *rectangle cover* for this matrix. It is a set of rectangular subsets of the matrix that don't contain any 0s, but together contain all the 1s. The subsets are not required to be disjoint. Here is an example of a rectangle cover for the above matrix.

```
+----+         +----+
|1  1| 0  0  0 |1  1| 0
|    |         |    |
|  +-|-----+   |    |+-+
|1 |1| 1  1| 0 |1  1||1|
+----+     |   |    || |
   |       |   |    || |
 0 |1  1  1| 0 |1  1||1|
   +-------+   |    |+-+
+----+   +-----|-+  |
|1  1| 0 |1  1 |1| 1| 0
|    |   |     +----+
|    |   |       |   +-+
|1  1| 0 |1  1  1| 0 |1|
+----+   +-------+   +-+

```

The number of rectangles in this cover is 7.

## The task

Your input is a rectangular matrix of bits, taken in any reasonable format. You can assume it contains at least one 1. Your output is the minimum number of rectangles in a rectangle cover of the matrix.

The lowest byte count wins. Standard rules apply.

## Test cases

```
[[1]] -> 1
[[1,1]] -> 1
[[1],[1]] -> 1
[[1,0,1]] -> 2
[[1,0],[0,0]] -> 1
[[1,0],[0,1]] -> 2
[[1,0],[1,1]] -> 2
[[1,1,1],[1,0,1]] -> 3
[[0,1,0],[1,1,1],[0,1,0]] -> 2
[[1,1,1],[1,0,1],[1,1,1]] -> 4
[[1,1,0],[1,1,1],[0,1,1]] -> 2
[[1,0,1,0],[1,1,1,1],[1,0,1,0]] -> 3
[[1,1,1,0],[1,0,1,0],[1,1,1,1],[0,0,1,0]] -> 4
[[1,1,1,0],[1,0,1,0],[1,1,1,1],[0,0,1,1]] -> 5
[[1,1,1,0],[1,0,1,0],[1,1,1,1],[0,1,1,1]] -> 4
[[1,1,0,0],[1,1,1,0],[0,1,1,1],[0,0,1,1]] -> 3
[[0,1,0,0],[0,1,1,1],[1,1,1,0],[0,0,1,0]] -> 4
[[0,0,1,0,0],[0,1,1,1,0],[1,1,1,1,1],[0,1,1,1,0],[0,0,1,0,0]] -> 3

```

# Answer
# Python 2, 318 315 271 bytes

Mr.Xcoder, ovs and Jonathan Frech saved a lot of bytes

```
p=range
def f(x,i=0,j=-1):z=len(x[0]);j+=1;i+=j/z;j%=z;return i<len(x)and(x[i][j]and-~min([f([[v,v[:j]+[2]*(r-j)+v[r:]][i<=y<=e]for y,v in enumerate(x)],i,j)for e in p(i,len(x))for r in p(j+1,z+1)if all(all(k[j:r])for k in x[i:e+1])]+[f(x,i,j)-1]*(x[i][j]>1))or f(x,i,j))

```

Try it online!
> 6 votes

# Answer
# Jelly,  ~~25~~  24 bytes

```
FJ‘ṁ×⁸ẆZ€Ẇ€ẎŒPFQP$$ÐṀL€Ṃ

```

**Try it online!** A typical golf-complexity solution, don't even bother with larger test cases, they will time out (the power set of all possible rectangles is inspected\*)

### How?

Forms all the possible rectangles that may be made. Takes the power-set of those rectangles and inspects them only keeping those sets which both contain no zeros and contain each of the ones at least once.

To achieve the "keeping those sets which both contain no zeros and contain each of the ones at least once" part the code first coerces the ones to a set of distinct integers greater than one, leaving the zeros as they are so that it becomes "finding the maxima of the product of the unique values".

```
FJ‘ṁ×⁸ẆZ€Ẇ€ẎŒPFQP$$ÐṀL€Ṃ - Link: list of lists of ones and zeros, M
F                        - flatten M into a single list
 J                       - range of length = [1,2,3,...,len(flattened(M))]
  ‘                      - increment       = [2,3,4,...,len(flattened(M))+1]
   ṁ                     - mould like M - reshapes it just like M again
     ⁸                   - chain's left argument, M
    ×                    - multiply (vectorises) - unique integers > 1 at M's 1s and 0s at M's 0s
      Ẇ                  - non-empty sublists - i.e. row selections
       Z€                - transpose €ach
         Ẇ€              - non-empty sublists of €ach - column selections of those
           Ẏ             - tighten - a flat list of all of the rectangles
            ŒP           - power-set - all possible selections of rectangles
                   ÐṀ    - filter keep those for which the following is maximal:
                  $      -   last two links as a monad:
              F          -     flatten
                 $       -     last two links as a monad:
               Q         -       de-duplicate
                P        -       product
                     L€  - length of €ach - # of rectangles used by each full-cover
                       Ṃ - minimum

```

---

<sub>* For an **n** by **m** matrix that's **ways(n,m) = 2^(T(n)×T(m))**, so...
**ways(3,2) = 2^((3+2+1)×(2+1)) = 2^18 = 262,144** (the TIO link)
**ways(3,3) = 2^((3+2+1)×(3+2+1)) = 2^36 = 68,719,476,736**
**ways(3,4) = 2^((3+2+1)×(4+3+2+1)) = 2^60 = 1,152,921,504,606,846,976**
**ways(5,5) = 2^225 ~= 5.4e+67** (the largest test case)
**ways(8,5) = 2^540 ~= 3.6e+162** (the example)</sub>
> 5 votes

# Answer
# JavaScript, 434 bytes

Code:

```
for(_='),d=...-1||(,Ad<=a,u[o][n]=d,    =0,(e,r,C,m))&&()=>.map((h((A,n,on<e|o<r|n>C|o>mf=u=>(q(s=(e>C[e,C]=[C,e]r>m[r,m]=[m,r]lk=1,k&=!!A)kl|=&1,=2k&lh=f=>uA,$ABf(B,$))))(($,Bae=r=C=m=,d=to-Bt=n$&n>$e   C=nn+1~ee   C=ttn-$t=oB&o>Br    m=oo+1~rr   m=tq+=sg=[],h((ca||g.push(c)gigb,j(p=1,q+=i<j&&s(b)q)';G=/[-]/.exec(_);)with(_.split(G))_=join(shift());eval(_)

```

Hexdump (because of unprintable characters):

```
66 6F 72 28 5F 3D 27 29 2C 13 13 64 3D 12 2E 2E 2E 11 2D 31 10 7C 7C 28 0F 2C 41 0F 64 3C 3D 0E 61 2C 0C 75 5B 6F 5D 5B 6E 5D 0B 3D 64 2C 09 3D 30 2C 08 28 65 2C 72 2C 43 2C 6D 07 29 29 13 06 26 26 28 05 29 3D 3E 04 2E 6D 61 70 28 28 03 68 28 28 41 2C 6E 2C 6F 04 02 02 6E 3C 65 7C 6F 3C 72 7C 6E 3E 43 7C 6F 3E 6D 0F 01 66 3D 75 3D 3E 28 71 08 28 73 3D 07 04 28 65 3E 43 05 5B 65 2C 43 5D 3D 5B 43 2C 65 5D 13 72 3E 6D 05 5B 72 2C 6D 5D 3D 5B 6D 2C 72 5D 13 6C 08 6B 3D 31 2C 01 6B 26 3D 21 21 41 29 13 6B 05 01 6C 7C 3D 0B 26 31 2C 0B 3D 32 06 6B 26 6C 13 68 3D 66 3D 3E 75 03 41 2C 24 04 41 03 0C 42 04 66 28 0C 42 2C 24 29 29 29 29 28 28 0C 24 2C 42 04 61 10 0F 65 3D 72 3D 43 3D 6D 3D 10 2C 64 3D 74 08 02 6F 2D 42 0F 74 3D 6E 0E 24 26 6E 3E 24 05 65 09 43 3D 6E 10 12 6E 2B 31 06 7E 65 0F 65 09 43 3D 74 12 74 08 02 6E 2D 24 0F 74 3D 6F 0E 42 26 6F 3E 42 05 72 09 6D 3D 6F 10 12 6F 2B 31 06 7E 72 0F 72 09 6D 3D 74 13 71 2B 3D 73 07 06 67 3D 5B 5D 2C 68 28 28 0C 11 63 04 61 10 7C 7C 67 2E 70 75 73 68 28 63 29 13 67 03 0C 69 04 67 03 62 2C 6A 04 28 70 3D 31 2C 71 2B 3D 69 3C 6A 26 26 73 28 11 0C 11 62 29 06 71 29 27 3B 47 3D 2F 5B 01 2D 13 5D 2F 2E 65 78 65 63 28 5F 29 3B 29 77 69 74 68 28 5F 2E 73 70 6C 69 74 28 47 29 29 5F 3D 6A 6F 69 6E 28 73 68 69 66 74 28 29 29 3B 65 76 61 6C 28 5F 29

```

Try it online!

It is not very golfy, but at least it works very fast. All test cases can be computed in few milliseconds.

## Ungolfed

```
f=mat=>(
  iterate=f=>mat.map((A,x)=>A.map((a,y)=>f(a,y,x))),
  fill=(x1,y1,x2,y2)=>(
    x1>x2&&([x1,x2]=[x2,x1]),
    y1>y2&&([y1,y2]=[y2,y1]),
    isFilled=0,

    canBeFilled=1,
    iterate((A,X,Y)=>X<x1|Y<y1|X>x2|Y>y2||(
      canBeFilled&=!!A
    )),

    canBeFilled&&(
      iterate((A,X,Y)=>X<x1|Y<y1|X>x2|Y>y2||(
        isFilled|=mat[Y][X]&1,
        mat[Y][X]=2
      ))
    ),

    canBeFilled&isFilled
  ),

  rectangles=0,

  iterate((a,x,y)=>a-1||(
    x1=y1=x2=y2=-1,

    start=end=0,
    iterate((A,X,Y)=>Y-y||(
      end=X,
      A||(
        start<=x&X>x&&(x1=start,x2=X-1),
        start=X+1
      )
    )),
    ~x1||(x1=start,x2=end),

    start=end=0,
    iterate((A,X,Y)=>X-x||(
      end=Y,
      A||(
        start<=y&Y>y&&(y1=start,y2=Y-1),
        start=Y+1
      )
    )),
    ~y1||(y1=start,y2=end),

    rectangles+=fill(x1,y1,x2,y2)
  )),

  ones=[],
  iterate((a,...c)=>a-1||ones.push(c)),
  ones.map((a,i)=>ones.map((b,j)=>(
    M=1,
    rectangles+=i<j&&fill(...a,...b)
  ))),

  rectangles
)

```

## Explanation

It uses similar algorithm like for solving Karnaugh maps. Firstly it tries to find at least one `1` which can be part of exactly one non-extensible rectangle. By non-extensible I mean if we extend it in any direction (up, left, right, down) it will include at least one `0` (or will go beyond the matrix bounds). When such `1` is found, find the biggest rectangle that includes it and flag all `1`s in that rectangle. Repeat until there is no more non-flagged `1`s that satisfy these conditions.

In some cases (like in the 16th test case) there are `1`s that left over after applying the first step. Then enumerate all these `1`s and apply some kind of enhanced brute-force search. This step is rarely applied, and even in these cases, we need to brute-force check only one or two combinations, so it should work very fast even for larger test cases.
> 1 votes

# Answer
# Python 3+Numpy, 253 bytes

```
from numpy import*
from itertools import*
R=range
P=product
def f(A):s=A.shape;r=random.rand(*s);return[N for N in R(1,sum(A)+1)for m in P(*[[(A*r)[a:b+1,c:d+1]for a,c,b,d in P(*[*map(R,s)]*2)]]*N)if len({e*all(b)for b in m for e in b.flat})==sum(A)][0]

```

Try it online!

This is quite slow due to generating more than the full power set of all rectangles. I also have an optimized version to test the slower test cases, which makes three optimizations:

* Uses combinations of N rectangles instead of cartesian product to avoid duplicate rectangles
* Uses `next(...)` instead of `[...][0]` to terminate as soon as a single covering is found with minimal number of rectangles
* Prunes out rectangles that are subsets of larger rectangles containing only 1s (96% reduction in rectangles for the largest test case)

## Semi-ungolfed

```
from numpy import*
from itertools import*
R=range
# P is the itertools product
P=product

def f(A):
    # take input as a numpy array A
    s = A.shape;
    # r is a weight matrix that gives a distinct value to each entry in A
    # (probability 1)
    # Longer alternative (can be inlined): r=~reshape(range(h*w),(h,w))
    r = random.rand(*s);
    return [
        # We're finding number of rectangles N
        N
        # In the range [1..sum(A)] where sum(A) is the number of 1s (upper bound for # rectangles)
        for N in R(1, sum(A)+1)
        # m is a combination of N possible rectangles
        for m in P(
            # (this is Cartesian product instead of combinations, but duplicates
            # provide no benefit)
            # P(*[...]*N) === product(..., repeat=N)
            *[
                [
                    # A*r is modified array such that each 1 is given
                    # a distinct value and all 0s remain 0

                    # all rectangles in A*r
                    (A*r)[a:b+1, c:d+1]
                    for a,c,b,d in P(*[*map(R,s)]*2)
                ]
            ]*N
        )
        # Test that each rectangle contains no 0s and the combination of rectangles covers all 1s:
        if len({e*all(b) for b in m for e in b.flat})==sum(A)
    # Get the first N with a valid covering
    # must be min N because N is generated in order
    ][0]

```
> 0 votes

---
Tags: code-golf, matrix, optimization
---


title: Euler's Geometry Puzzle

text:
# Question
Title: Euler's Geometry Puzzle
Today (or tomorrow, depending on your timezone, by the time of posting) is the birthday of the great mathematician and physicist Leonhard Euler. To celebrate his birthday, this challenge is about one of his theorems in geometry.

For a triangle, we define its incircle to be the largest circle inside the triangle and its circumcircle to be the circle that passes through all of the traingle's vertices.

Consider a triangle in a plane, we plot the center of its incircle I (sometimes called incenter) and the center of its circumcircle O (sometimes called circumcenter). Let \\$r\\$ be the radius of the incircle, \\$R\\$ be the radius of circumcircle, \\$d\\$ be the distance between I and O. Euler's theorem in geometry states that \\$d^2=R(R-2r)\\$.

# The challenge

In the spirit of this theorem, your task, is for a triangle given by the lengths of its three sides, output \\$d\\$ (the distance between incenter I and circumcenter O described above).

* Your code needs to take only the length of the three sides of triangle and output \\$d\\$. Inputs and outputs can be in any reasonable format.
* The absolute error or relative error from your output and correct answer must be no greater than \\$10^{-2}\\$.
* It's guaranteed that the three side lengths are positive integers and can form a non-degenerate triangle.
* Standard loopholes are forbidden.

Since this is a , the shortest code in bytes wins!

# Examples

In the samples, the outputs are rounded to 3 decimal places. You, however, are free to round them to more decimal places.

```
[a,b,c]       -> d
[2,3,4]       -> 1.265
[3,4,5]       -> 1.118
[3,5,7]       -> 3.055
[7,9,10]      -> 1.507
[8,8,8]       -> 0.000
[123,234,345] -> 309.109

```

List of sample inputs:

`[[2,3,4],[3,4,5],[3,5,7],[7,9,10],[8,8,8],[123,234,345]]`

# Answer
# JavaScript (ES7),  ~~80 74 66~~  65 bytes

```
(a,b,c)=>(s=a+b+c,(p=a*b*c/s)*p/4*(s/=2)/(s-a)/(s-b)/(s-c)-p)**.5

```

Try it online!

### How?

This is derived from:

* The semiperimeter \\$s\\$ of the triangle:

$$s=\frac{a+b+c}{2}$$
* The circumradius \\$R\\$ of the triangle:

$$R=\frac{abc}{4\sqrt{s(s-a)(s-b)(s-c)}}$$
* The product of the inradius \\$r\\$ and the circumradius:

$$rR=\frac{abc}{2(a+b+c)}=\frac{abc}{4s}$$
* Euler's theorem:

$$d=\sqrt{R(R-2r)}=\sqrt{R^2-2rR}=\sqrt{R^2-\frac{abc}{2s}}$$
> 13 votes

# Answer
# Python 3, 66 bytes

This formerly took advantage of the new assignment expressions ("walrus operator") introduced in Python 3.8. Thanks to commentors, I've taken that out, so it works on previous versions too!

```
lambda a,b,c:((a*b*c/(b+c-a)/(a+c-b)/(a+b-c)-1)*a*b*c/(a+b+c))**.5

```

Try it online!

It's based on the same calculations described in Arnauld's answer, but using the perimeter \\$p\\$ instead of the semiperimeter \\$s\\$: $$ \begin{aligned}\\ p&=a+b+c\\ &=2s \end{aligned}\\ \therefore d=\sqrt{R^2-\frac{abc}{p}}\\ \text{and } R^2=\frac{\left(abc\right)^2}{p(p-2a)(p-2b)(p-2c)} $$

The grand total savings of this rearrangement is... two bytes.

Factoring \\$p\\$ out and expanding the terms in the denominator means I don't have to store \\$p\\$, saving another three bytes. I also stored the product \\$abc\\$ in a variable \\$m\\$, which saved some bytes at first... but it could later be factored out, turning the brackets-and-walrus into a liability, not a savings! Here's the final formula: \begin{aligned} d&=\sqrt{\frac{\left(abc\right)^2}{p(p-2a)(p-2b)(p-2c)}-\frac{abc}{p}}\\ &=\sqrt{\left(\frac{abc}{(b+c-a)(a+c-b)(a+b-c)}-1\right)\frac{abc}{p}} \end{aligned}
> 8 votes

# Answer
# 05AB1E, ~~23~~ ~~22~~ ~~21~~ ~~20~~ ~~15~~ 14 bytes

```
PDIœÆPt/<*IO/t

```

-5 bytes porting *@Neil*'s Charcoal answer, so make sure to upvote him!!
-1 byte thanks to *@Grimmy*.

Try it online or verify all test cases.

**Explanation:**

```
P              # Take the product of the (implicit) input-list
               #  [a,b,c] → abc
 D             # Duplicate it
  Iœ           # Get all permutations of the input-triplet
               #  [a,b,c] → [[a,b,c],[a,c,b],[b,a,c],[b,c,a],[c,a,b],[c,b,a]]
    Æ          # Reduce each by subtracting:
               #  → [a-b-c,a-c-b,b-a-c,b-c-a,c-a-b,c-b-a]
     P         # Take the product of that
               #  → (a-b-c)(a-c-b)(b-a-c)(b-c-a)(c-a-b)(c-b-a)
               #   → (a-b-c)²*(b-a-c)²*(c-a-b)²
      t        # Take the square-root
               #  → sqrt((a-b-c)²*(b-a-c)²*(c-a-b)²)
       /       # Divide the initially duplicated product by it
               #  → abc/(sqrt((a-b-c)²*(b-a-c)²*(c-a-b)²))
        <      # Decrease it by 1
               #  → abc/(sqrt((a-b-c)²*(b-a-c)²*(c-a-b)²))-1
         *     # Multiply it by the initial product
               #  → abc(abc/(sqrt((a-b-c)²*(b-a-c)²*(c-a-b)²))-1)
          IO/  # Divide it by the input-sum
               #  → abc(abc/(sqrt((a-b-c)²*(b-a-c)²*(c-a-b)²))-1)/(a+b+c)
             t # And take the square-root of that
               #  → sqrt(abc(abc/(sqrt((a-b-c)²*(b-a-c)²*(c-a-b)²))-1)/(a+b+c))
               # (after which it is output implicitly as result)

```

Or as a single formula:

$$d=\sqrt{\frac{abc\left(\frac{abc}{\sqrt{(a-b-c)^2\times(b-a-c)^2\times(c-a-b)^2}}-1\right)}{a+b+c}}$$
> 4 votes

# Answer
# Charcoal, ~~31~~ 18 bytes

```
Ｉ₂∕×⊖∕ΠθΠ⁻Σθ⊗θΠθΣθ

```

Try it online! Link is to verbose version of code. Takes input as a vector of doubles and outputs a double. Explanation:

$$ \begin{align}d &=\sqrt{R(R-2r)}\\ &=\sqrt{R^2-2Rr}\\ &=\sqrt{\left(\frac{abc}{4\Delta}\right)^2-\frac{abc}{2s}}\\ &=\sqrt{\frac{(abc)^2}{16\Delta^2}-\frac{abc}{2s}}\\ &=\sqrt{\frac{(abc)^2}{2s(2s-2a)(2s-2b)(2s-2c)}-\frac{abc}{2s}}\\ &=\sqrt{\frac{abc}{2s}\left(\frac{abc}{(2s-2a)(2s-2b)(2s-2c)}-1\right)}\\ \end{align} $$

where \\$ 2s=a+b+c \\$ and \\$ \Delta=\sqrt{s(s-a)(s-b)(s-c)} \\$.

```
            ⊗θ      `[2a, 2b, 2c]`
         ⁻Σθ        Vectorised subtract from `a+b+c`
        Π           Take the product
     ∕Πθ            Divide `abc` by that
    ⊖               Decrement
   ×          Πθ    Multiply by `abc`
  ∕             Σθ  Divide by `a+b+c`
 ₂                  Take the square root
Ｉ                   Cast to string
                    Implicitly print

```
> 4 votes

# Answer
# Java 8, 67 bytes

```
(a,b,c)->Math.sqrt(a*b*c*(a*b*c/(b+c-a)/(a+c-b)/(a+b-c)-1)/(a+b+c))

```

Try it online.

Not much to say. Uses the same formula as in *@TimPederick*'s Python answer, which was based on *@Arnauld*'s JavaScript answer, but which uses a rather similar formula as *@Neil*'s Charcoal answer.

$$d=\sqrt{\frac{abc\left(abc\div(b+c-a)\div(a+c-b)\div(a+b-c)-1\right)}{a+b+c}}$$
> 3 votes

# Answer
# Io, 87 bytes

Port of Arnauld's answer.

```
method(a,b,c,((y :=b*a*c/(z :=((b+c-a)*(c+a-b)*(a+b-c)/(x :=a+b+c))**.5)/x)*(y-z))**.5)

```

Try it online!
> 1 votes

# Answer
# C (gcc), <sup>~~76~~</sup> 72 bytes

Saved 4 bytes thanks to ceilingcat!!!

```
#define f(a,b,c)sqrt(a*b*c*(a*b*c/(0.+b+c-a)/(a+c-b)/(a+b-c)-1)/(a+b+c))

```

Try it online!

Port of Kevin Cruijssen's Java answer.
> 1 votes

# Answer
# APL (Dyalog Unicode), 22 bytes

```
.5*⍨×/÷+/÷¯1+⊢×.÷+/-+⍨

```

Try it online!

Yet another port of Tim Pederick's Python answer.

$$ \begin{align} d&=\sqrt{\left(\frac{abc}{(b+c-a)(a+c-b)(a+b-c)}-1\right)\frac{abc}{a+b+c}} \\ &=\sqrt{\frac{abc}{\frac{a+b+c}{\frac{abc}{(b+c-a)(a+c-b)(a+b-c)}-1}}} \end{align} $$

Kind of ugly, but this is precisely what the code does. Requires `⎕DIV←1`, i.e. division by 0 gives 0 (otherwise `a=b=c` case will throw an error).

### How it works

```
.5*⍨×/÷+/÷¯1+⊢×.÷+/-+⍨  ⍝ Input: a 3-length vector [a b c]
                 +/-+⍨  ⍝ (a+b+c) - [2a, 2b, 2c] = [b+c-a, c+a-b, a+b-c]
             ⊢×.÷       ⍝ product([a,b,c] ÷ above)
          ¯1+           ⍝ above minus 1
    ×/÷+/÷  ⍝ product(a,b,c) ÷ (sum(a,b,c) ÷ above)
.5*⍨        ⍝ square root

```
> 1 votes

# Answer
# Forth (gforth), 90 bytes

```
: f dup 2over * * s>f fdup 3. do dup 2over - - s>f f/ rot loop 1e f- f* + + s>f f/ fsqrt ;

```

Try it online!

Port of Kevin Cruijssen's Java answer. Since the inputs are positive integers, it takes the input from the data stack and returns the result through the FP stack.

A separate FP stack makes the task a bit easier, but having to work through three alternating sums explicitly is definitely a pain.

In order to copy top three elements, I used `dup 2over` which converts `a b c` into `a b c c a b`. Thankfully I didn't need exactly "3dup" because addition `+` and multiplication `*` are commutative, and alternating sums (`c - (a - b)`) are calculated for all three rotations (`abc`, `bca`, `cab`).

```
: f ( a b c -- f:result )
  dup 2over * * s>f fdup  ( a b c ) ( f: prod prod )
  3. do dup 2over - - s>f f/ rot loop  ( a b c ) ( f: prod prod/rots )
  1e f- f* + + s>f f/ fsqrt
;

```
> 0 votes

---
Tags: code-golf, math, arithmetic, geometry
---


# Question
Title: Format the given number of bytes to a human readable format
## Challenge and origin

On Stack Overflow a popular question is: How to convert byte size into human readable format in java? The most up voted answer has a quite nice method for doing this, but this is codegolf and we can do better, can't we?

> Your challenge is to write a method or program that coverts the given number of bytes to the correct human readable format and prints the result to the standard out of your language.\*

\*See the rules for more clarification!

## Input

The input will always be a positive number of bytes with a maximum of (2^31)-1.

## Output

You may choose if you prefer the International System of Units or the binary notation as output (the SI notation probably saves you some bytes).

```
SI:      B, kB,  MB,  GB
Binary:  B, KiB, MiB, GiB

```

Note: Higher units than GB or GiB are not posible due to the restricted input range.

## Example output

International System of Units:

```
Input       Output
0           0.0     B
999         999.0   B
1000        1.0     kB
1023        1.0     kB
1024        1.0     kB
1601        1.6     kB
160581      160.6   kB
4066888     4.1     MB
634000000   634.0   MB
2147483647  2.1     GB

```

Binary:

```
Input       Output
0           0.0     B
999         999.0   B
1000        1000.0  B
1023        1023.0  B
1024        1.0     KiB
1601        1.6     KiB
160581      156.8   KiB
4066888     3.9     MiB
634000000   604.6   MiB
2147483647  2.0     GiB

```

## Rules

* Build-in functions for byte formatting are not allowed!
* The output should always be in the same notation standard, you may not mix SI or binary;
* The output should always be in the largest unit possible where the resulting number is still higher or equal to one;
* The output should always have one decimal number, but you may choose to print an integer number when the resulting output is in bytes (B);
* You may choose if you would like to add a space, tab or nothing between the number and the unit;
* Input is received via STDIN or function parameters;
* Output is printed to the console or returned as string (or similar character container);
* This is code golf, so the shortest answer wins. Have fun!

## Edit: Even more clarification

Some numbers have interesting rounding behaviors like the number 999950. Most code implementations would return 1000.0 kB instead of 1.0 MB. Why? Because 999950/1000 evaluates to 999.950 which is effectively rounded to 1000.0 when using String.format in Java (in most other languages too). Hench some extra checks are needed to handle cases like this.

For this challenge both styles, 1000.0 kB and 1.0 MB are accepted, although the last style is preferred.

**Pseudo code / java test code:**

> ```
>
> public static String bytesToSI(long bytes){
>       if (bytes < 1000){
>           return bytes + ".0 B";
>       }
>       //Without this rounding check:
>       //999950    would be 1000.0 kB instead of 1.0 MB
>       //999950000 would be 1000.0 MB instead of 1.0 GB
>       int p = (int) Math.ceil(Math.log(bytes) / Math.log(1000));
>       if(bytes/Math.pow(1000, p) < 0.99995){
>           p--;
>       }
>       //Format
>       return String.format("%.1f %sB", bytes/Math.pow(1000, p), "kMGTPE".charAt(p-1));
> }
>
> ```

# Answer
# TI-BASIC, 44

Would be the right tool for the job if TI-BASIC had halfway decent string manipulation (I had to resort to overwriting the exponent of the number, displayed in engineering notation, with the unit). As it is it rounds and outputs correctly, but it's not even close to winning entries. Maybe a different calculator language could win this one?

```
Fix 1
Eng
ClrHome
Disp Ans
Output(1,15,sub(" kMG",1+iPart(log(Ans+.5)/3),1)+"B

```

Input in the form `[number]:[program name]` on the homescreen.

Given test cases:

```
Input       Output (leading spaces intentional; screen clear before each output)
0                      0.0 B
999                  999.0 B
1000                   1.0kB
1023                   1.0kB
1024                   1.0kB
1601                   1.6kB
160581               160.6kB
4066888                4.1MB
634000000            634.0MB
2147483647             2.1GB

```
> 10 votes

# Answer
# CJam, 35 27 bytes

```
ri{_e-3_i}g;1mOo]," kMG"='B

```

Thanks Dennis for removing 8 bytes.

This doesn't print `.0` in the online interpreter. But as Dennis has pointed out, it works fine in the Java interpreter.

### Explanation

```
ri         e# Read the input as an integer.
{          e# Do:
    _e-3   e#   Make a copy and divide by 1000.
           e#   This will generate one more item in the stack for each iteration.
    _i     e#   Make a copy and truncate to integer.
}g         e# until the integer part is 0.
;          e# Discard the final value with integer part 0.
1mOo       e# Output the number before it with the correct format.
],         e# Count the number of iterations - 1.
" kMG"=    e# Select a character according to the number of iterations.
'B         e# Output B.

```
> 6 votes

# Answer
# Pyth, ~~29~~ 27 bytes

```
p@" kMG"Js.lQK^T3.RcQ^KJ1\B

```

Demonstration. Test Harness.

Explanation:

```
p@" kMG"Js.lQK^T3.RcQ^KJ1\B
                                 Implicit: Q = eval(input())
p                                print, in the order 2nd arg then 1st arg:
             K^T3                K = 10^3 = 1000
          .lQK                   log of Q base K
         s                       Floored
        J                        Store to J
 @" kMG"J                        The Jth character of ' kMG'
                     ^KJ         K^J
                   cQ            Q/K^J (Floating point division)
                 .R     1        Round to 1 decimal place.
                         \B      Print a trailing 'B'.

```
> 5 votes

# Answer
# Python 2 - 76 bytes

Uses the Internation System of Units, simply because it's easier to do in your head ;)

```
n=input();m=0;f=1e3
while n>=f:n/=f;m+=2
print"%.1f%s"%(n,'B kBMBGB'[m:m+2])

```
> 2 votes

# Answer
# CJam, 28

```
r_dA@,(3/:X3*#/1mO" kMG"X='B

```

Try it online

Note: it doesn't show ".0" with the online interpreter, but does so with the official java interpreter.

**Explanation:**

```
r_          read and duplicate
dA          convert to double and push 10
@           bring the initial string to the top
,(          get the length and decrement
3/          divide by 3 (for thousands)
:X3*        store in X and multiply by 3 again
#           raise 10 to that power
/           divide the original number by it
1mO         round to 1 decimal
" kMG"X=    convert X from 0/1/2/3 to space/k/M/G
'B          add a 'B'

```
> 2 votes

# Answer
# Haskell, 119

I sadly couln't find a shorter way in Haskell to ensure 1 decimal place in floats, but I'm posting for posterity.

```
import Text.Printf
a#n|p>=1=(a+1)#p|1<2=(a,n)where p=n/1000
m n=let(a,b)=0#n in printf"%.1f"b++["B","kB","MB","GB"]!!a

```

Usage:

```
> m 160581
"160.6kB"

```

Moderately less golfed version:

```
import Text.Printf

countThousands :: Int -> Float -> (Int, Float)
countThousands count num
 |nextNum >= 1 = countThousands (count+1) nextNum
 |otherwise    = (count,num)
 where nextNum = num/1000

printHuman :: Float -> String
printHuman n = let (a,b) = countThousands 0 n in
  (printf "%.1f" b) ++ (["B","kB","MB","GB"]!!a)

```
> 2 votes

# Answer
## Ruby, 84

```
def f(n)
n2=Math.log10(n).to_i/3
return '%.3f'% (n/1e3**n2)+['','k','M','G'][n2]
end
p f(9012345678.0)=='9.012G'

```

## Python, 94

```
import math
def f(n):
 n2=int(math.log10(n)/3)
 return '%.3f'%(n/1e3**n2)+('','k','M','G')[n2]
print(f(9012345678)=='9.012G')

```

## JavaScript, 104

```
function f(n){
let n2=Math.trunc(Math.log10(n)/3);
return (n/1e3**n2).toFixed(3)+['','k','M','G'][n2];
}
console.log(f(9012345678)=='9.012G');

```

## PHP, 105

```
<?php
function f($n){
$n2=(int)(log10($n)/3);
return sprintf('%.3f',$n/1e3**$n2).['','k','M','G'][$n2];
}
var_dump(f(9012345678)=='9.012G');

```

## Dart, 146

```
import 'dart:math';
String f(double n){
var n2=(log(n)/ln10/3).toInt();
var n3=n/pow(1e3,n2);
return n3.toStringAsFixed(3)+['','k','M','G'][n2];
}
void main(){
print(f(9012345678)=='9.012G');
}

```
> 2 votes

# Answer
# Java, 106 bytes

This one's a method that takes a number and returns a string.

```
String f(int n){int k=0;for(;n>1e3;k++)n/=1e3;return(int)(10*n)/10.0+new String[]{"","k","M","G"}[k]+"B";}

```
> 1 votes

# Answer
**POWERSHELL,190**

```
$x=Read-Host
function f($a,$b){"$x`t"+[math]::Round($x/$a,1).ToString("F1")+"`t$b"}
if(1KB-gt$x){f 1 "B"}elseif(1MB-gt$x){f 1KB KiB}
elseif(1GB-gt$x){f 1MB MiB}elseif(1TB-gt$x){f 1GB GiB}

```

usage

```
PS C:\> .\makehum.ps1
1601
1601    1.6     KiB
PS C:\> .\makehum.ps1
4066888
4066888 3.9     MiB
PS C:\> .\makehum.ps1
160581
160581  156.8   KiB
PS C:\> .\makehum.ps1
634000000
634000000       604.6   MiB
PS C:\> .\makehum.ps1
2147483647
2147483647      2.0     GiB
PS C:\>

```
> 1 votes

# Answer
# C, 77 75

```
f(float l){char*u=" kMG";while((l/=1e3)>=1)++u;printf("%.1f%cB",l*1e3,*u);}

```

This uses SI units and takes the 1000.0kB option for rounding.

Expanded code:

```
f(float l)
{
    char *u = " kMG";
    while ((l/=1000) >= 1)
        ++u;
    printf("%.1f%cB", l*1000, *u);
}

```

### Output

```
9 => 9.0 B
9999 => 10.0kB
1023 => 1.0kB
1024 => 1.0kB
999990 => 1000.0kB
1048575 => 1.0MB
1048576 => 1.0MB
2147483647 => 2.1GB

```

### Variants

To get binary units, change `1000` to `1024`, and add `i` to the format string if there's a multiplier. To avoid 4-digit rounding, compare `>=.95` instead of `>=1`. To accept larger units, extend the `u` string. Combining all these options, we get:

```
f(float l)
{
    char*u=" kMGTPEZY";
    while((l/=1024)>=.95)++u;
    printf(*u-' '?"%.1f%ciB":"%.0fB",l*1024,*u);
}

```

### Variant output

```
9 => 9B
9999 => 9.8kiB
1023 => 1.0kiB
1024 => 1.0kiB
999990 => 1.0MiB
1048575 => 1.0MiB
1048576 => 1.0MiB
2147483647 => 2.0GiB
1000000000 => 953.7MiB
1000000000000 => 931.3GiB
1000000000000000 => 909.5TiB
1000000000000000000 => 888.2PiB
1000000000000000000000 => 867.4EiB
1000000000000000000000000 => 847.0ZiB
999999999999999999999999999 => 827.2YiB
1176043059457204080886151645 => 972.8YiB

```

### Test program

Pass any number of inputs as command-line arguments:

```
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char **argv)
{
    while (*++argv) {
        printf("%s => ", *argv);
        f(strtod(*argv, 0));
        puts("");
    }
    return 0;
}

```
> 1 votes

# Answer
## Rust, 124

```
fn f(n:f64)->String{
let n2=n.log(1e3);
let n3=n/1e3f64.powi(n2 as i32);
format!("{:.3}",n3)+["","k","M","G"][n2 as usize]
}
fn main(){
println!("{}",f(9012345678e0)=="9.012G");
}

```

## Nim, 139

```
import math,strformat
proc f(n:float):string=
 let n2=int log10(n)/3
 let n3=n/pow(1e3,float n2)
 return fmt"{n3:.3f}"&["","k","M","G"][n2]
echo f(9012345678e0)=="9.012G"

```

## Go, 145

```
package m
import(."fmt"
."math")
func f(g float64)string{h:=int(Log10(g))/3
i:=g/Pow10(h*3)
return Sprintf("%.3f",i)+[]string{"","k","M","G"}[h]}

```

## D, 156

```
import std.format,std.math,std.stdio;
string f(real n){
auto n2=cast(int)log10(n)/3;
auto n3=n/pow(1e3,n2);
return format("%.3f",n3)~["","k","M","G"][n2];
}
void main(){
writeln(f(9012345678)=="9.012G");
}

```

## C#, 168

```
using System;
class P{
static string f(double n){
var n2=(int)Math.Log10(n)/3;
var n3=n/Math.Pow(1e3,n2);
return String.Format("{0:f3}",n3)+new[]{"","k","M","G"}[n2];
}
static void Main(){
Console.WriteLine(f(9012345678)=="9.012G");
}
}

```
> 1 votes

# Answer
# Python 2, 127 bytes

Using the ISU. The snippet declares a function 'C' that takes the number to be converted as argument.

```
C=lambda v:min(['%.1f %sB'%(x,u)for x,u in[(v/1000.0**i,'bkMG'[i])for i in range(4)]if x>=1]).replace('.0 b',' ')if v else'0 B'

```

Some test code:

```
    print 'Input\tOutput'
for v in [0,999,1000,1023,1023,1601,160581,4066888,634000000,2147483647]:
 print v,C(v)

```
> 0 votes

# Answer
# JavaScript (*ES6*), 71

Using SI units - A function returning the requested string.

```
f=(a,b=3)=>+(r=eval('a/1e'+b*3).toFixed(1))[0]?r+' kMG'[b]+'B':f(a,b-1)

```

This shorter one follows the rules, particularly 3 and 4

* The output should always be in the largest unit possible where the resulting number is still higher or equal to one **then 995 =\> 1.0kB**
* The output should always have one decimal number, but you may choose to print an integer number when the resulting output is in bytes (B) **I choose not, so 10 =\> 10.0 B**

Alas, this way, the results do not match the examples.

To match the examples, here is a longer one, special cased for small numbers (82 bytes)

```
f=(a,b=3)=>a<1e3?a+'B':+(r=eval('a/1e'+b--*3).toFixed(1))[0]?r+'kMG'[b]+'B':f(a,b)

```

Run the snippet to test (being EcmaScript 6, Firefox only)

```
f=(a,b=3)=>+(r=eval('a/1e'+b*3).toFixed(1))[0]?r+' kMG'[b]+'B':f(a,b-1)
```

```
Value <input id=I><button onclick="O.innerHTML+=f(+I.value)+'\n'">-></button><pre id=O></pre>
```
> 0 votes

# Answer
# Ruby, 91 bytes

```
n=gets.to_i;i=0;while n>1023;n/=1024.0;i+=1;end;puts "#{n.round 1} #{%w[B KiB MiB GiB][i]}"

```

I could probably do a bit better if I tried harder but here's what I've got so far.
> 0 votes

# Answer
# Python, 61 bytes

```
f=lambda n,i=0:"%.1f%cB"%(n," kMG"[i])*(n<1e3)or f(n/1e3,i+1)

```

Call like `f(999)`. Note that `1e3` is a float, so this works with both Python 2 and Python 3.
> 0 votes

# Answer
# PHP4.1, ~~63~~ 62 bytes

Not the best golfing, but surely is quite short.

```
<?for($S=kMG;$B>1e3;$I++)$B/=1e3;printf("%.1f{$S[$I-1]}B",$B);

```

To use it, access over POST/GET or set a value in the SESSION, on the key `B`.

Leave the key `I` unset!
> 0 votes

# Answer
# SpecBAS - 100 bytes

Using the ISU convention.

I realised that having a variable set to 1e3 (which needs a LET statement to assign it), and then using that variable in the working out, actually used more characters than just hardcoding the 1e3 where it was needed.

```
1 INPUT n: LET i=1
2 DO WHILE n>1e3: LET n=n/1e3: INC i: LOOP
3 PRINT USING$("&.*0#",n);" kMG"(i);"B"

```
> 0 votes

# Answer
# Javascript ES5, 69 bytes

This uses a different way to reach the end goal that @edc65's answer.
Actually, this is pretty close to my PHP answer.

```
for(i=+prompt(z=0);i>1e3;z++)i/=1e3;alert(i.toFixed(1)+' kMG'[z]+'B')
```

Simply run the stack snippet or paste this on your console.
> 0 votes

# Answer
# Ruby, 128 bytes

```
c=->i{p i.to_s+'B'if i<1e3;p (i/1e3).to_s+'kB'if i>=1e3&&i<1e6;p (i/1e6).to_s+'MB'if i>=1e6&&i<1e9;p (i/1e9).to_s+'GB'if i>=1e9}

```

I did it the long way, this is pretty bad.

# Output

```
c[0] # => "0B"
c[999] # => "999B"
c[1000] # => "1.0kB"
c[1023] # => "1.023kB"
c[1024] # => "1.024kB"
c[1601] # => "1.601kB"
c[160581] # => "160.581kB"
c[4066888] # => "4.066888MB"
c[634000000] # => "634.0MB"
c[2147483647] # => "2.147483647GB"

```

# Edit

Added TB for an extra 39 bytes

```
c=->i{p i.to_s+'B'if i<1e3;p (i/1e3).to_s+'kB'if i>=1e3&&i<1e6;p (i/1e6).to_s+'MB'if i>=1e6&&i<1e9;p (i/1e9).to_s+'GB'if i>=1e9&&i<1e12;p (i/1e12).to_s+'TB'if i>=1e12}

```

# Output:

```
c[1000000000000] # => "1.0TB"

```
> 0 votes

# Answer
# Sed `-r`, 218+1

I'm using SI units; I think that choosing binary units would be *a courageous policy*. ;-)

```
s/(.)((...)+)$/\1z\2/;h;s/[^z]*z?//;s/.../k/g;s/kk/M/;s/Mk/G/;x;s/(z.)[5-9].*/\1c/;s/(z.c?).*/\1/;:;s/9c/c0/;s/zc/cz/;t;s/(^|0)c/1/;s/1c/2/;s/2c/3/;s/3c/4/;s/4c/5/;s/5c/6/;s/6c/7/;s/7c/8/;s/8c/9/;G;s/\n//;s/$/B/;y/z/./

```

Reformatted:

```
#!/bin/sed -rf

# Place decimal point (use z as shorthand for \.)
s/(.)((...)+)$/\1z\2/
h

# count thousands into hold space
s/[^z]*z?//
s/.../k/g
s/kk/M/;s/Mk/G/
x

# truncate to 1 decimal place
s/(z.)[5-9].*/\1c/
s/(z.c?).*/\1/

# propagate carry
:
s/9c/c0/
s/zc/cz/
t
s/(^|0)c/1/
s/1c/2/
s/2c/3/
s/3c/4/
s/4c/5/
s/5c/6/
s/6c/7/
s/7c/8/
s/8c/9/

# Append units
G;s/\n//
s/$/B/
y/z/./

```

### Output

```
1 => 1B
9 => 9B
99 => 99B
999 => 999B
1000 => 1.0kB
9999 => 10.0kB
99949 => 99.9kB
99950 => 100.0kB
99999 => 100.0kB
999999 => 1000.0kB
9999999 => 10.0MB
9999999999 => 10.0GB
1000 => 1.0kB
10000 => 10.0kB
10005 => 10.0kB
10440 => 10.4kB
10450 => 10.5kB
10950 => 11.0kB

```

### Variations

The rules seem to imply round-to-nearest, but for human display, I believe rounding down is an acceptable alternative, and saves 123 bytes (better than 50%):

```
s/(.)((...)+)$/\1.\2/;h;s/[^\.]*\.?//;s/.../k/g;s/kk/M/;s/Mk/G/;x;s/(\..).*/\1/;G;s/\n//;s/$/B/

```

The natural extension to larger units (still rounding down, 130+1 bytes):

```
s/(.)((...)+)$/\1.\2/;h;s/[^\.]*\.?//;s/.../k/g;s/kk/M/g;s/Mk/G/;s/MM/T/g;s/TT/Y/;s/TM/E/;s/TG/Z/;x;s/(\..).*/\1/;G;s/\n//;s/$/B/

```

### Variation output:

```
1 => 1B
9 => 9B
99 => 99B
999 => 999B
1000 => 1.0kB
9999 => 9.9kB
99949 => 99.9kB
99950 => 99.9kB
99999 => 99.9kB
999999 => 999.9kB
9999999 => 9.9MB
9999999999 => 9.9GB
1000 => 1.0kB
10000 => 10.0kB
10005 => 10.0kB
10440 => 10.4kB
10450 => 10.4kB
10950 => 10.9kB
1000000000 => 1.0GB
1000000000000 => 1.0TB
1000000000000000 => 1.0MGB
1000000000000000000 => 1.0EB
1000000000000000000000 => 1.0ZB
1000000000000000000000000 => 1.0YB
999999999999999999999999999 => 999.9YB

```
> 0 votes

# Answer
# Ruby, 90 bytes

```
proc{|n|q=((1..3).find{|i|n<(1<<i*10)}||4)-1;[n*10/(1<<q*10)/10.0,%w[B kB MB GB][q]].join}

```
> 0 votes

# Answer
# brainfuck, ~~396~~ 376 bytes

```
,[<[->>+<<]>>+>,]<<[>[<<+>>-]<<<]<-------<---<--<-[>+>-->+>>>>>>+<<<<<<<<<-------]>>>>>>>+++>>++++<<<<<--[>>>+<<<++++++]+>-[-[-[-[-[-[-[-[-[-[-<->]<[>>.>.>.[<<]>.>>>-]>]<[->>.>>.>>.<<<.>>>>>.<<<.<<<<<]>]<[->>.>>.<.>>>.<.<<<<<]>]<[->>.>.>.>.[<]<]>]<[>>.>>.>>.<<<.>>>>>.[<<]>>.>>-]>]<[>>.>>.<.>>>.[<<]>>.>>-]>]<[->>.>.>.<<<<<<.>>]>]<[->>[.>>]<<[<<]]>]<[->>.>>.<<<<]>]<[->>.<<]<.

```

Try it online!
> 0 votes

---
Tags: code-golf
---