title: Tips for golfing in Ruby

text:
# Question
Title: Tips for golfing in Ruby
What general tips can you give for golfing in Ruby?

I'm looking for ideas that can be applied to code golf problems in general that are specific to Ruby. (For example, "Remove comments" would not be an answer.)

Please post one tip per answer.

# Answer
* The numbers 100 to 126 can be written as `?d` to `?~` in 1.8.
* On a similar note if you need a single-character string in 1.9 ?x is shorter than "x".
* If you need to print a string without appending a newline, `$><<"string"` is shorter than `print"string"`.
* If you need to read multiple lines of input `$<.map{|l|...}` is shorter than `while l=gets;...;end`. Also you can use `$<.read` to read it all at once.
* If you're supposed to read from a file, `$<` and `gets` will read from a file instead of stdin if the filename is in `ARGV`. So the golfiest way to reimplement `cat` would be: `$><<$<.read`.
> 59 votes

# Answer
Use the splat operator to get the tail and head of an array:

```
head, *tail = [1,2,3]
head => 1
tail => [2,3]

```

This also works the other way:

```
*head, tail = [1,2,3]
head => [1,2]
tail => 3

```

Use the `*` method with a string on an array to join elements:

```
[1,2,3]*?,
=> "1,2,3"

```
> 40 votes

# Answer
* Use `abort` to terminate the program and print a string to STDERR - shorter than `puts` followed by `exit`
* If you read a line with `gets`, you can then use `~/$/` to find its length (this doesn't count a trailing newline if it exists)
* Use `[]` to check if a string contains another: `'foo'['f'] #=> 'f'`
* Use `tr` instead of `gsub` for character-wise substitutions: `'01011'.tr('01','AB') #=> 'ABABB'`
* If you need to remove trailing newlines, use `chop` instead of `chomp`
> 32 votes

# Answer
# End your `end`.

Try to remove `end` from your code.

Don't use `def...end` to define functions. Make a lambda with the new -\> operator in Ruby 1.9. (The -\> operator is a "stabby lambda", or "dash rocket".) This saves 5 characters per function.

```
# 28 characters
def c n
/(\d)\1/=~n.to_s
end

# 23 characters, saves 5
c=->n{/(\d)\1/=~n.to_s}

```

Method calls are `c n` or `c(n)`. Lambda calls are `c[n]`. Changing each `c n` to `c[n]` costs 1 character, so if you can use `c n` more than 5 times, then keep the method.

All methods that take `do...end` blocks can take `{...}` blocks instead. This saves 3 to 5 characters. If the precedence of `{...}` is too high, then use parentheses to fix it.

```
# 48 characters
(?a..?m).zip (1..5).cycle do|a|puts a.join','end

# WRONG: passes block to cycle, not zip
(?a..?m).zip (1..5).cycle{|a|puts a.join','}

# 45 characters, saves 3
(?a..?m).zip((1..5).cycle){|a|puts a.join','}

```

Replace `if...else...end` with the ternary operator `?:`. If a branch has two or more statements, wrap them in parentheses.

```
# 67 characters
if a<b
puts'statement 1'
puts'statement 2'else
puts'statement 3'end

# 62 characters, saves 5
a<b ?(puts'statement 1'
puts'statement 2'):(puts'statement 3')

```

You probably don't have `while` or `until` loops, but if you do, then write them in modifier form.

```
(a+=1
b-=1)while a<b

```
> 25 votes

# Answer
Addition to w0lf

> When working with arrays, `.compact` can be replaced with `-[nil]` to save 2 chars.

Combined with above -\> you can make it even shorter with `-[p]` to save another 2 chars.
> 20 votes

# Answer
Use the short predefined variables wherever possible, e.g. `$*` instead of `ARGV`. There's a good list of them here, along with a lot of other useful information.
> 19 votes

# Answer
# Use operator methods instead of parentheses

Let's say you want to express `a*(b+c)`. Because of precedence, `a*b+c` won't work (obviously). Ruby's cool way of having operators as methods comes to the rescue! You can use `a.*b+c` to make the precedence of `*` lower than that of `+`.

```
a*(b+c) # too long
a*b+c   # wrong
a.*b+c  # 1 byte saved!

```

This can also work with the `!` and `~` operators (things like unary `+` or unary `-` don't work because their methods are `-@` and `+@`, saving `()` but adding `.@`)

```
(~x).to_s # too long
~x.to_s   # error
x.~.to_s  # 1 byte saved!

```
> 17 votes

# Answer
Don't use the `true` and `false` keywords.

Use:

* `!p` for `true` (thanks, histocrat!)
* `!0` for `false`. If all you need is a falsy value, then you can simply use `p` (which returns `nil`).

to save some chars.
> 16 votes

# Answer
When you are using string interpolation, (as you should pr Martin Büttner's post), you don't need the curly brackets if your object has a sigil (`$`, `@`) in front of it. Useful for magical variables like `$_`, `$&`, `$1` etc:

```
puts "this program has read #$. lines of input"

```

So also if you need to print a variable more than you use it otherwise, you may save some bytes.

```
a=42; puts "here is a: #{a}"; puts "here is a again: #{a}"
$b=43; puts "here is b: #$b"; puts "here is b again: #$b"

```
> 15 votes

# Answer
If you need to find if a particular element `e` is inside a range `r`, you can use

```
r===e

```

instead of the longer:

```
r.cover?(e) # only works if `r.exclude_end?` is false

```

or

```
r.member?(e)

```

or

```
r.include?(e)

```
> 14 votes

# Answer
# New features in Ruby 2.3 and 2.4

It's good to stay abreast of new language features that will help your golf game. There are a few great ones in the latest Rubies.

## Ruby 2.3

### The safe navigation operator: `&.`

When you call a method that might return `nil` but you want to chain additional method calls if it's not, you waste bytes handling the `nil` case:

```
arr = ["zero", "one", "two"]
x = arr[5].size
# => NoMethodError: undefined method `size' for nil:NilClass

x = arr[5].size rescue 0
# => 0

```

The "safe navigation operator" stops the chain of method calls if one returns `nil` and returns `nil` for the whole expression:

```
x = arr[5]&.size || 0
# => 0

```

### `Array#dig` & `Hash#dig`

Deep access to nested elements, with a nice short name:

```
o = { foo: [{ bar: ["baz", "qux"] }] }
o.dig(:foo, 0, :bar, 1) # => "qux"

```

Returns `nil` if it hits a dead end:

```
o.dig(:foo, 99, :bar, 1) # => nil

```

### `Enumerable#grep_v`

The inverse of `Enumerable#grep`—returns all elements that don't match the given argument (compared with `===`). Like `grep`, if a block is given its result is returned instead.

```
(1..10).grep_v 2..5 # => [1, 6, 7, 8, 9, 10]
(1..10).grep_v(2..5){|v|v*2} # => [2, 12, 14, 16, 18, 20]

```

### `Hash#to_proc`

Returns a Proc that yields the value for the given key, which can be pretty handy:

```
h = { N: 0, E: 1, S: 2, W: 3 }
%i[N N E S E S W].map(&h)
# => [0, 0, 1, 2, 1, 2, 3]

```

## Ruby 2.4

Ruby 2.4 isn't out yet, but it will be soon and has some great little features. (When it's released I'll update this post with some links to the docs.) I learned about most of these in this great blog post.

### `Enumerable#sum`

No more `arr.reduce(:+)`. You can now just do `arr.sum`. It takes an optional initial value argument, which defaults to 0 for Numeric elements (`[].sum == 0`). For other types you'll need to provide an initial value. It also accepts a block that will be applied to each element before addition:

```
[[1, 10], [2, 20], [3, 30]].sum {|a,b| a + b }
# => 66

```

### `Integer#digits`

This returns an array of a number's digits in least-to-greatest significance order:

```
123.digits # => [3, 2, 1]

```

Compared to, say, `123.to_s.chars.map(&:to_i).reverse`, this is pretty nice.

As a bonus, it takes an optional radix argument:

```
a = 0x7b.digits(16) # => [11, 7]
a.map{|d|"%x"%d} # => ["b", "7"]

```

### `Comparable#clamp`

Does what it says on the tin:

```
v = 15
v.clamp(10, 20) # => 15
v.clamp(0, 10) # => 10
v.clamp(20, 30) # => 20

```

Since it's in Comparable you can use it with any class that includes Comparable, e.g.:

```
?~.clamp(?A, ?Z) # => "Z"

```

### `String#unpack1`

A 2-byte savings over `.unpack(...)[0]`:

```
"".unpack(?U)    # => [128123]
"".unpack(?U)[0] # => 128123
"".unpack1(?U)   # => 128123

```

### Precision argument for `Numeric#ceil`, `floor`, and `truncate`

```
Math::E.ceil(1) # => 2.8
Math::E.floor(1) # => 2.7
(-Math::E).truncate(1) # => -2.7

```

### Multiple assignment in conditionals

This raises an error in earlier versions of Ruby, but is allowed in 2.4.

```
(a,b=1,2) ? "yes" : "no" # => "yes"
(a,b=nil) ? "yes" : "no" # => "no"

```
> 14 votes

# Answer
`$_` is last read line.

* `print` \- if no argument given print content of `$_`
* `~/regexp/` \- short for `$_=~/regexp/`

In Ruby 1.8, you have four methods in `Kernel` that operate on `$_`:

* `chop`
* `chomp`
* `sub`
* `gsub`

In Ruby 1.9, these four methods exist only if your script uses `-n` or `-p`.

If you want to print some variable often then use `trace_var(:var_name){|a|p a}`
> 13 votes

# Answer
Build arrays using `a=i,*a` to get them in reverse order. You don't even need to initialize `a`, and if you do it doesn't have to be an array.
> 13 votes

# Answer
Use string interpolation!

1. To replace `to_s`. If you need parentheses around whatever you want to turn into a string, `to_s` is two bytes longer than string interpolation:

```
(n+10**i).to_s
"#{n+10**i}"

```
2. To replace concatenation. If you concatenate something surrounded by two other strings, interpolation can save you one byte:

```
"foo"+c+"bar"
"foo#{c}bar"

```

Also works if the middle thing is itself concatenated, if you just move the concatenation inside the interpolation (instead of using multiple interpolations):

```
"foo"+c+d+e+"bar"
"foo#{c+d+e}bar"

```
> 13 votes

# Answer
# Avoid `length` in `if a.length<n`

`length` is 6 bytes, a bit costly in code golf. in many situations, you can instead check if the array has anything at a given point. if you grab past the last index you will get `nil`, a falsey value.

So you can Change:

`if a.length<5` to `if !a[4]` for -5 bytes

or

`if a.length>5` to `if a[5]` for -6 bytes

or

`if a.length<n` to `if !a[n-1]` for -3 bytes

or

`if a.length>n` to `if a[n]` for -6 bytes

**Note**: will only work with an array of all truthy values. having `nil` or `false` within the array may cause problems.
> 13 votes

# Answer
# New features in Ruby 2.7 (experimental)

Ruby 2.7 is in prerelease (as of 17 Jun 2019) and has some features that look great for golfing. Note that some of them might not make it into the final 2.7 release.

All changes in Ruby 2.7-preview1: https://github.com/ruby/ruby/blob/v2\_7\_0\_preview1/NEWS

### Numbered block parameters

This is my favorite. It lets you *finally* drop the `|a,b|` in a block:

**Edit:** The syntax was changed from `@1` to `_1`.

```
%w[a b c].zip(1..) { puts _1 * _2 }
# => a
#    bb
#    ccc

```

### ~~Method reference operator: `.:`~~

**Edit:** This was unfortunately removed before release.

`.:` is syntactic sugar for the `.method` method, e.g.:

```
(1..5).map(&1r.:/)
# => [(1/1), (1/2), (1/3), (1/4), (1/5)]

```

### Pattern matching

I'm not sure how much use this will see in golf, but it's a great feature for which I only have a contrived example:

```
def div(*a)
  case a
    in [0, 0] then nil
    in [x, 0] if x > 0 then Float::INFINITY
    in [x, 0] then -Float::INFINITY
    in [x, y] then x.fdiv(y)
  end
end

div(-3, 0) # => -Infinity

```

The pattern matching syntax has lots of features. For a complete list, check out this presentation: https://speakerdeck.com/k\_tsj/pattern-matching-new-feature-in-ruby-2-dot-7

This is also the feature most likely to change before 2.7 is finished; it even prints a warning when you try to use it, which you should heed:

> warning: Pattern matching is experimental, and the behavior may change in future versions of Ruby!

### Beginless Range: `..3`

Analogous to the endless Range introduced in 2.6, it may or may not have much use in golfing:

```
%w[a v o c a d o].grep(..?m)
# => ["a", "c", "a", "d"]

```

### `Enumerable#tally` to count like elements

This could be useful in golfing:

```
%w[a v o c a d o].tally
# => {"a"=>2, "v"=>1, "o"=>2, "c"=>1, "d"=>1}

```

### `Enumerable#filter_map` to `filter`+`map` in one

```
(1..20).filter_map {|i| 10 * i if i.even? }
# => [20, 40, 60, 80, 100]

```

If the block returns `nil` or `false` the element will be omitted from the result.

### `Integer#[]` takes a second argument or range:

You've long been able to get a specific bit from an integer with with subscript notation:

```
n = 77 # (binary 01001101)
n[3] # => 1

```

Now you can get the value of a range of bits by a second length argument or a range.

```
n = 0b01001101
n[2, 4] # => 3 (0011)
n[2..5] # => 3

```

Note that bits are indexed from least- to most-significant (right to left).
> 13 votes

# Answer
If you ever need to get a number from `ARGV`, `get`, or something similar to do something that many times, instead of calling `to_i` on it, you can just use `?1.upto x{do something x times}` where x is a string.

So using `?1.upto(a){}` instead of `x.to_i.times{}` will save you 2 characters.

You can also re-write things like `p 1 while 1` or `p 1 if 1` as `p 1while 1` or `p 1if 1`

That example isn't very useful, but it could be used for other things.

Also, if you need to assign the first element of an array to a variable, `a,=c` will save two characters as opposed to `a=c[0]`
> 11 votes

# Answer
Don't use #each. You can loop over all elements just fine with #map. So instead of

```
ARGV.each{|x|puts x}

```

you can do the same in less bytes.

```
ARGV.map{|x|puts x}

```

Of course, in this case `puts $*` would be even shorter.

---

There are literals for rational and complex numbers:

```
puts 3/11r == Rational(3,11)
puts 3.3r == Rational(66,20)
puts 1-1.i == Complex(1,-1)

=> true
true
true

```

---

You can use most bytes within strings. `"\x01"` (6 bytes) can be shortened to `""` (3 bytes). If you only need this one byte, this can be shortened even further to `?` (2 bytes).

By the same token, you can get newlines shorter like this:

```
(0..10).to_a.join'
'

 => "0\n1\n2\n3\n4\n5\n6\n7\n8\n9\n10"

```

You can use `?\n` and `?\t` as well, which is one byte shorter than `"\n"` and `"\t"`. For obfuscation, there also ?\s, a space.

---

Use constants instead of passing arguments around, even if you need to change them. The interpreter will give warnings to *stderr*, but who cares. If you need to define more variables related to each other, you can chain them like this:

```
A=C+B=7+C=9

=> A=17, B=16, C=9

```

This is shorter than `C=9;B=16;A=17` or `C=0;B=C+7;A=C+B`.

---

If you need an infinite loop, use `loop{...}`. Loops of unknown length may be shorter with other loops:

```
loop{break if'
'==f(gets)}

while'
'!=f(gets);end

```

---

Some more gsub/regexp tricks. Use the special `'\1'` escape characters instead of a block:

```
"golf=great short=awesome".gsub(/(\w+)=(\w+)/,'(\1~>\2)')

"golf=great short=awesome".gsub(/(\w+)=(\w+)/){"(#{$1}~>#{$2})")

```

And the special variables `$1` etc. if you need to perform operations. Keep in mind they are defined not only inside the block:

```
"A code-golf challenge." =~ /(\w+)-(\w+)/
p [$1,$2,$`,$']

=> ["code", "golf", "A ", " challenge."]

```

---

Get rid of spaces, newlines, and parentheses. You can omit quite a bit in ruby. If in doubt, always try if it works without, and keep in mind this might break some editor syntax highlighting...

```
x+=1if$*<<A==????::??==??

```
> 11 votes

# Answer
# Save some bytes when removing repeated elements of an array

```
a.uniq # before
a|[]   # after
    ^^

```

If you will be using an empty array `[]` in a variable, you can save even more bytes:

```
a.uniq;b=[] # before
a|b=[]      # after
      ^^^^^

```
> 10 votes

# Answer
Scientific notation can often be used to shave off a char or two:

```
x=1000
#versus
x=1e3

```
> 9 votes

# Answer
Kernel#p is a fun method.

Use `p var` instead of `puts var`. This works perfectly with integers and floats, but not with all types. It prints quotation marks around strings, which is probably not what you want.

Used with a single argument, `p` returns the argument after printing it.

Used with multiple arguments, `p` returns the arguments in an array.

Use `p` (with no arguments) instead of `nil`.
> 9 votes

# Answer
Yet another way to use the splat operator: if you want to assign a single array literal, a `*` on the left-hand side is shorter than brackets on the right-hand side:

```
a=[0]
*a=0

```

With multiple values you don't even need the splat operator (thanks to histocrat for correcting me on that):

```
a=[1,2]
a=1,2

```
> 9 votes

# Answer
To join an array, instead of this

```
[...].join

```

do this

```
[...]*''

```

which saves 2 bytes. To join with a separator use

```
[...]*?,

```
> 8 votes

# Answer
# Save a byte when printing a word with symbols

This is a bit situational, but every byte counts!

```
puts"thing" # before
puts:thing  # after
          ^

```
> 8 votes

# Answer
# Avoid `Array#repeated_permutation` and `Array#repeated_combination`

*Credit to @AsoneTuhid who golfed the code for repeated permutations of length \\$\ge5\\$.*

Some of Ruby's built-in methods have unfortunately long names. Never use `Array#repeated_permutation` or `Array#repeated_combination`; save bytes as follows.

### Repeated permutations

Assume `a` is an array. To get repeated permutations of length \\$L = n + 1\\$ of the elements of `a`:

```
a.product(a,a,a)  # L <= 4; number of arguments = n
a.product(*[a]*n) # L >= 5

```

Depending on context, the parentheses may not be required. Both of the above yield an array. To iterate over the permutations, simply call with a block.

### Repeated combinations

For repeated combinations of length \\$L\\$, use one of

```
a.send(a.methods[42],L)    # enumerator
[*a.send(a.methods[42],L)] # array

```

The index that yields `:repeated_combination` depends on the Ruby version and possibly the OS (`42` is correct for Ruby 2.5.5 on Linux, which is the version on TIO at the time of writing). The default indexing may also be disrupted if any libraries are loaded. The correct index in any case can always be found using `[].methods.index(:repeated_combination)`.

---

In general, calling a method by index using `Object#send` and `Object#methods`, as demonstrated above for repeated combinations, is shorter than a direct method call when the number of bytes in the method name and the index of the method in the `methods` array satisfy:

```
+-------+-------+
| **Bytes** | **Index** |
+-------+-------+
|  19+  |  0-9  |
|  20+  | 10-99 |
|  21+  | 100+  |
+-------+-------+
Subtract 1 from byte count if parentheses not needed for send.

```
> 8 votes

# Answer
Use Goruby instead of Ruby, which is something like an abbreviated version of Ruby. You can install it with rvm via

```
rvm install goruby

```

Goruby allows you to write most of your code as you would be writing Ruby, but has additional abbreviations built in. To find out the shortest available abbreviation for something, you can use the helper method `shortest_abbreviation`, for example:

```
shortest_abbreviation :puts
#=> "pts"

Array.new.shortest_abbreviation :map
#=> "m"

String.new.shortest_abbreviation :capitalize
#=> "cp"

Array.new.shortest_abbreviation :join
#=> "j"

```

Also very handy is the alias `say` for `puts` which itself can be abbreviated with `s`. So instead of

```
puts [*?a..?z].map(&:capitalize).join

```

you can now write

```
s [*?a..?z].m(&:cp).j

```

to print the alphabet in capitals (which is not avery good example). This blog post explains more stuff and some of the inner workings if you are interested in further reading.

PS: don't miss out on the `h` method ;-)
> 7 votes

# Answer
I just attempted a TDD code-golf challenge i.e. Write shortest code to make specs pass. The specs were something like

```
describe PigLatin do
  describe '.translate' do
    it 'translates "cat" to "atcay"' do
      expect(PigLatin.translate('cat')).to eq('atcay')
    end
    # And similar examples for .translate
  end
end

```

For the sake of code-golf, one need not create a module or class.

Instead of

```
module PigLatin def self.translate s;'some code'end;end

```

one can do

```
def(PigLatin=p).translate s;'some code'end

```

Saves 13 characters!
> 7 votes

# Answer
When a challenge requires that you output multiple lines, you don't have to loop through your results in order to print each line of e.g. an array. The `puts` method will flatten an array and print each element on a separate line.

```
> a = %w(testing one two three)
> puts a
testing
one
two
three

```

Combining the splat operator with `#p` you can make it even shorter:

```
p *a

```

The splat operator (technically the `*@` method, I think) also casts your non-array enumerables to arrays:

```
> p a.lazy.map{|x|x*2}
#<Enumerator::Lazy: #<Enumerator::Lazy: [1, 2, 3]>:map>

```

vs

```
> p *a.lazy.map{|x|x*2}
2
4
6

```
> 7 votes

# Answer
# Subscripting Numbers!

I just discovered this yesterday. `n[i]` returns `n`'s bit at the `i`-th position. Example:

```
irb(main):001:0> n = 0b11010010
=> 210
irb(main):002:0> n[0]
=> 0
irb(main):003:0> n[1]
=> 1
irb(main):004:0> n[2]
=> 0
irb(main):005:0> n[3]
=> 0
irb(main):006:0> n[4]
=> 1
irb(main):007:0> n[5]
=> 0

```
> 7 votes

# Answer
# On looping

### `while...end`

If you need to `break` out of the loop, `while condition;code;end` will probably be shorter than `loop{code;condition||break}`.

The `;` before `end` is not always required, eg. `while condition;p("text")end`

`until c;...;end` is equivalent to `while !c;...;end` and 1 byte shorter.

Note that in most cases `code while condition` and `code until condition` are significantly shorter as they don't require the `end` keyword and can often drop semicolons. Also, `i+=1 while true` is equivalent to `i+=1while true` and 1 byte shorter.

### `redo`

When run, the `redo` command jumps back to the beginning of the block it's in.

When using `redo` in a lambda, you will have to move any setup variables to the arguments to avoid them being reset at every iteration (see examples).

### recursion

Recursion can be shorter is some cases. For instance, if you're working on an array element by element, something like `f=->s,*t{p s;t[0]&&f[*t]}` can be shorter than the alternatives depending on the `stuff`.

Note that per the current consensus, if you're calling your function by name, you need to include the assignment (`f=`) in the byte count making all recursive lambdas 2 bytes longer by default.

### `eval`

If you need to run some code `n` times, you can use `eval"code;"*n`.

This will concatenate `code;` `n` times and run the whole thing.

Note that in most cases you need to include a `;` after your code.

## Examples

### A lambda to print all numbers from `1` to `a` inclusive:

```
->n{i=0;loop{p i+=1;i<n||break}} # 32 bytes
f=->n,i=1{i>n||p(i)&&f[n,i+1]}   # 30 bytes
->n,i=0{p(i+=1)<n&&redo}         # 24 bytes
->n{i=0;p i+=1while i<n}         # 24 bytes
->n{i=0;eval"p i+=1;"*n}         # 24 bytes
->n{n.times{|i|p i+1}}           # 22 bytes # thanks to @benj2240
->n{n.times{p _1+1}}             # 20 bytes # thanks to @AgentIvan

```

In this case, since the end-point is defined (`n`), the `n.times` loop is the shortest.

The `redo` loop works because `i+=1` modifies i and returns its new value and `p(x)` returns `x` (this is not true of `print` and `puts`).

### Given a function `g` and a number `n`, find the first number strictly larger than `n` for which `g[n]` is truthy

```
->g,n{loop{g[n+=1]&&break};n}     # 29 bytes
f=->g,n{g[n+=1]?n:f[g,n]}         # 25 bytes
->g,n{1until g[n+=1];n}           # 23 bytes
->g,n{(n+1..).find &g}            # 22 bytes
->g,n{g[n+=1]?n:redo}             # 21 bytes

```

In this case, with an unknown end-point, `redo` is the best option.

The `(n+1..Inf)` loop is equivalent to simply `loop`ing indefinitely but more verbose.

A `1` (or anything else) is required before the `until` keyword to complete the syntax, using a number allows you to drop a space.

The `eval` method is not viable in this case because there is neither a defined end-point nor an upper bound.

Update: with the new open ranges `(n+1..Inf)` can be written simply as `(n+1..)`, also `.find{|x|g[x]}` is equivalent to `.find &g` where `g` is converted to a block.

TL;DR check out `redo`, it can very often shave off a couple of bytes
> 7 votes

# Answer
Use `||` instead `or` and `&&` instead `and`.

Beside the one character from `and` you can save the spaces (and perhaps the bracket) around the operator.

```
p true and false ? 'yes' :'no'   #-> true (wrong result)
p (true and false) ? 'yes' :'no' #-> 'no'
p true&&false ? 'yes' :'no'      #-> 'no', saved 5 characters

p true or false ? 'yes' :'no'   #-> true (wrong result)
p (true or false) ? 'yes' :'no' #-> 'yes'
p true||false ? 'yes' :'no'      #-> 'yes', saved 4 characters

```

---

If you loop on an array you normally use `each`. But `map` loops also over an array and it is one character shorter.
> 6 votes

# Answer
If the first line starts with `#!` and contains `ruby`, then Ruby will take command-line switches from it.

For example, if you require two libraries, you can golf

```
require'benchmark'
require'prime'

```

into

```
#!ruby -rbenchmark -rprime

```

which saves 7 bytes.
> 6 votes

# Answer
You may be able to save 2 chars and use

```
[*(...)]

```

instead of

```
(...).to_a

```

For example, suppose we have a range that we want as an array:

```
(1..2000).to_a

```

Just do it like this:

```
[*1..2000]  #  Parentheses around the (ran..ge) is not needed!

```

And now you have your range as an array.
> 6 votes

# Answer
# Re(ab)use predefined globals

There is a whole bunch of predefined global variables that you can use instead of initialising new variables.

A very common example is that you have some golfed one-liner that loops, but you also need to keep a counter for later:

```
i=0
s.gsub!(/../){i+=1;"foo"}while s=~/.../
p i

```

So frustrating. Luckily, `$.` comes to the rescue! It is initially `0`, and is incremented each time you read a line from input. This is of course incredibly useful if you actually need to keep track of the amount of lines you have read, but otherwise you can just manually update it:

```
s.gsub!(/../){$.+=1;"foo"}while s=~/.../
p$.

```

That's 3 bytes saved.

If you for example need to append your counter to a string `s`, you may save some more bytes though string interpolation because the variable has a sigil:

```
i=0;i+=1;s+i.to_s
i=0;i+=1;s+"#{i}"
$.+=1;s+"#$."

```

Another interesting global is `$:`. It's an alias for `$LOAD_PATH` and is an array full of strings. I haven't actually used this in a golf yet, but I imagine it could come in handy if you need a cache for checking previously visited values or something, and don't care if it's completely empty. Your values are unlikely to crash with any of its initial contents anyways.
> 6 votes

# Answer
# \<\< trick

```
a.push x

```

can be shortened to:

```
a<<x

```

for -4 bytes.
> 5 votes

# Answer
To subtract one (-1), instead of doing this

```
(i - 1) * 2

```

do the following

```
~-i * 2

```

which will save you 2 bytes in cases where you otherwise have to use brackets (e.g. arithmetics).
> 5 votes

# Answer
# `Array#assoc`/`rassoc`

When you have an array of arrays and want to find the sub-array that starts with a particular value, don't use `Enumerable#find`, use `Array#assoc`:

```
a = [[0,"foo"],[0,"bar"],[1,"baz"],[0,"qux"]]
a.find{|x,|x==1} # => [1,"baz"]
a.assoc(1) # => [1,"baz"]

```

This is also a good replacement for `Enumerable#any?` in some situations.

`Array#rassoc` does the same thing, but checks the sub-arrays' last element:

```
a = [[123,"good"],[456,"good"]]
a.any?{|*,x|x=="bad"} # => false
a.rassoc("bad") # => nil

```
> 5 votes

# Answer
## Fun with arrays

There are many ways to do the same thing in ruby, and often times the default methods are inefficient - as a case study, a new arrays with set size and initialized to all `10`:

```
Array.new(20,10) # idiomatic
[10]*20

```

You may already be informed not to use this syntax, however, when you are initializing elements in an array that needs to not be shallow-cloned, for example 2D arrays:

```
[[]]*20               # beware, all 20 elements points to the one same array
Array.new(20){[]}     # idiomatic
20.times.map{[]}
([0]*20).map{[]}      # free ticket, you can move any line into `0` to save newline
([a,b,c,d]*5).map{[]} # saves a char when you move 4 1-time use expressions
(1..20).map{[]}

```

Many operations in ruby will create new objects. Sometimes this is to our advantage. For example, to create a new array with the same size as another array, we can get by without even knowing its `.size` at all:

```
[0]*a.size # looks kinda nice
a.map{0}   # -2 chars

```

(Note: the `[]*` version may be preferable in cases where you also want to reuse the value, so `[0]*b=a.size` might end up helping you cut a char elsewhere)

To shallow clone an array:

```
b=a[0..-1] # makes sense
b=a.clone
b=a*1      # this returns new_ary
b=*a       # this version for assignments - use [*a] in expressions

```
> 5 votes

# Answer
# Use `eval` instead of `reduce`

While `array.sum` is great and shorter than `array.reduce(:+)`, there are no similar methods for the other operators `*`, `-`, `/` ...

Joining arrays and `eval`ing them saves some space:

```
a = [1,2,3,4]

a.reduce(:*)   # => 24
eval(a*?*)     # => 24
          ^^   two bytes saved.

```

It also removes the need to map string input to numbers first:

```
b = "1 2 3 4".split

b.map(&:to_i).reduce(:*)
eval(b*?*)
          ^^^^^^^^^^^^^^

```
> 5 votes

# Answer
# New features in Ruby 2.5 and 2.6

Ruby keeps getting new features that look like they could be handy for golfing. Here are some that caught my eye. If there's any you think should be added feel free to edit or mention them in the comments.

(See also New features in Ruby 2.3 and 2.4.)

## Ruby 2.5

Here's an easy-to-read reference with all of the new features in Ruby 2.5: https://rubyreferences.github.io/rubychanges/2.5.html

## Regexp absence operator: `(?~foo)`

This matches any string that doesn't end with `foo`. I don't have a specific use for this one off the top of my head, but here's a good article about it.

### `Enumerable#all?`, `any?`, `none?`, and `one?` accept objects that respond to `===`

Similar to `Enumerable#grep`:

```
%w[Foo bar].one?(/[A-Z]/) # => true
%w[Foo bar].any?("bar") # => true
[1, 2, 3, 5, 7, 11].all?(0..10) # => false

```

### `Hash#slice` gets a subset of a Hash

I don't see a lot of Hashes in Ruby golf, but it might come in handy:

```
{foo: 1, bar: 2, baz: 3}.slice(:bar, :baz) # => {foo: 1, bar: 2}

```

---

## Ruby 2.6

All of the changes in Ruby 2.6: https://rubyreferences.github.io/rubychanges/2.6.html

### Endless Range: `1..`

Lots of potential uses for this.

```
%w[a b c].zip("X"..).to_a
# => [["a", "X"], ["b", "Y"], ["c", "Z"]]

[1, 2, 3, 5, 7, 11].any?(10..)
# => true

```

### `String#split` takes a block

Saves four bytes when iterating over the result of `String#split`, e.g.:

```
"foo;bar;baz".split(?;).map {|s| x << s.upcase if ... }

```

You can do this:

```
"foo;bar;baz".split(?;) {|s| x << s.upcase if ... }

```

Note that it still returns the original string, so it won't always be fewer bytes than `map`.

### Proc composition with `>>` and `<<`

Procs now have `>>` and `<<` methods that let them be combined with other procs, or any object that responds to `call`:

```
double = ->n{ n * 2 }
square = ->n{ n ** 2 }
(double >> square)[5] # => 100
(double << square)[5] # => 50

```

### `%` operator for Range

An alias for `Range#step`:

```
((1..10) % 2).to_a
# => [1, 3, 5, 7, 9]

```

### `Random.bytes`

Could be handy.

```
Random.bytes(10)
# => "'\xB2\xD7\ny"

```
> 5 votes

# Answer
# Avoid `String#sub!`

Instead of

```
a.sub!b,c

```

save a byte with

```
a[b]&&=c

```

Both return `nil` if no substitution occurs. If a substitution does occur, be aware that the return values differ: `a.sub!b,c` returns the modified string `a` whereas `a[b]&&=c` returns `c`. However, given that you're using `sub!` (as opposed to `sub`) chances are that either:

* You just need to modify `a` in place and will be discarding the return value anyway; or
* You just need the return value to be truthy.

The shorter form meets your needs in both cases.
> 5 votes

# Answer
When working with arrays, `.compact` can be replaced with `-[nil]` to save 2 chars.
> 3 votes

# Answer
When getting **input of fixed length** the optional integer parameter to `gets` may come in handy.

* Getting a substring:

`gets 10` vs `gets[0,10]` -- saves 3 bytes
* Cutting trailing newline:

`gets 10` vs `gets.chop` -- saves *3 - log<sub>10</sub>(required\_length)* bytes (= 2 in this case)
> 3 votes

# Answer
## Cloning strings

Strings are mutable in Ruby so if you have two variables holding the same string (`a=b="string"`) and you modify one (`a[0]="S"`), the other will also change (`b=="String"`)

To clone a string:

```
a="string"

b=a.clone # 9 bytes
b=a.dup # 7 bytes
b=+-a # 5 bytes
b=-a # 4 bytes (b will be frozen)

```
> 3 votes

# Answer
# Use `~//` and `!//` to match against `$_` (last line read)

These can be used with the `-n` or `-p` flags.

`~/regex/` is equivalent to `$_=~/regex/` returning the index of the first match or `nil`.

Try it online!

`!/regex/` equivalent to `$_!~/regex/` returning `true` or `false`.

Try it online!

### Note that `!//` is weird as it doesn't call the `!` method on the regex but only if you use a literal.

`!/regex/` matches the expression.

`r=/regex/;!r` calls the `!` (`not`) method and always returns `false`.

Also, `!r=/regex/` gives an `assignment in conditional` warning so there's some syntactic sugar going on.
> 3 votes

# Answer
# Filtering a specific class from an Array

Suppose, you've to choose only `Integer` from

```
a = [1, 2, "3", 4.0, [5], "6".to_sym, 7r]

```

then you can do,

```
a.keep_if{|x|x.kind_of? Integer} # 32 bytes
a.keep_if{|x|x.is_a? Integer} # 29 bytes
a.select{|x|x.is_a? Integer} # 28 bytes
a.select{|x|Integer===x} # 24 bytes
a.grep(Integer) # 15 bytes

```

Try it online!

---

You can use `Numeric` class in case you want numbers only.
> 3 votes

# Answer
* To generate symmetric output, you can use a single range like (-x..x) and then map a function on the absolute value: `(-8..8).map{|x|x.abs}`
* Use short-circuit evaluation of boolean expressions to avoid if...else: `x>1&&s+=x`
* To check if an integer array `a` contains a number `x`, you can use `a-[x]!=a`, especially useful if `x` is an expression.
* Defining a variable as an accumulator is often shorter than using map and then reduce.
* Use string interpolation with `%` for alignment: `"x%12s"%?x` is shorter than `?x+11*" "+?x` or for base conversions: `"%b"%65` vs `65.to_s(2)`
* Use complex number for trigonometric functions: `-1.arg`is PI, `1i.arg` is PI/2, `(a+b*1i).arg` is `Math.atan(b/a)` and works even when a and b are integers.
> 2 votes

# Answer
String split function uses `$;` or space by default; if input is space-seperated, you can omit the argument.

```
# Reads 3 integers from line 1 of input file
x,y,z=gets.split.map &:to_i

```

Or, you can configure the behaviour of ARGF with `$/` (if there is only one line):

```
# Reads 3 integers from input file
# Not seperated by newlines, so in case of:
# 1 2
# 3 4
# You will get: 1 2 4 ("2\n3".to_i -> 2)
$/=' '
x,y,z=$<.map &:to_i

```

Due to the predictable behaviour of `.to_i` / `.to_f`, if you only have two numbers, you can use `string.to_i`(/**.to\_f**) to get the first number and substring after the non-digit (even simpler for space) for the two values. There are tricks if you already know the constraints on the length of the numbers and especially so if the first one is length 1-2:

```
v=gets           # 1 2 / 11 22 / 11 22222222222222222222 / 123 4567890123456
v.to_i           # 1*    11*     11*                       123*
v[2,9].to_i      # 2*#$  22*#$   22222222                  3
v[2,99].to_i     # 2#$   22#$    22222222222222222222*#    3
v[2..-1].to_i    # 2#    22#     22222222222222222222*#    3
v[/\d+$/].to_i   # 2     22      22222222222222222222      4567890123456
~~v[~/ /,9].to_i   # 2$    22$     22222222                  45678901
v[~/ /,99].to_i  # 2     22      22222222                  4567890123456*
v[~/ /..-1].to_i # 2     22      22222222                  4567890123456~~
```

<sub>\*: recommend to use in cases as specific than this
#: 1st int in string length is expected to be \<=2 (-10 \< x \< 100)
$: 2nd int in string length is expected to be \<=8 (if 1st int is length 1: \<=9)
Note: `[x,99]` will take `99` characters, while `..-1` goes all the way to end of string. ~~Because `~/ /` matches the index of the space, this should be accounted for: `[~/ /,9]` will get length 8 int at most, as first char is the space~~
Note: If there are three+ numbers, please just use `split` or `map`</sub>

The above trick can be combined with `$_`:

```
p *gets.to_i..$_[2,9].to_i

```

Handy ways to repeat strings:

```
# aaaaabcbcbcbcaaaaa,aaaaa,aaaaa
$><<?a*5+'bc'*4+[?a*5]*3*?,

```

Shorthand for size of input line:

```
p (eval gets.chars*?+)/~/$/
# is equivalent to:
p (eval gets.chars*?+)/$_.size

```
> 2 votes

# Answer
# Is it an array?

Originally from histocrat.

Rather than writing

```
a.class==Array  # 14 bytes

```

you could write

```
a.is_a? Array   # 13 bytes

```

or even

```
a!=[*a]         # 7 bytes

```
> 2 votes

# Answer
To check if `a` is an `Array`, instead of doing:

```
a.kind_of?(Array)

```

you can do

```
a.to_s['[']

```

Won't work if `a` can be a string that contains `[`.
> 1 votes

# Answer
## Default function arguments

Pre-defining your variables within a function can save you from calling particular arguments if you already know what they are and are calling the function multiple times.

```
def f(a,b,c)
  return a+b+c
end
puts f(f(3,3,3),f(3,3,3),f(3,3,3))
# => 27

```

One can shorten this quite easily:

```
def f(a,b=3,c=3)
  return a+b+c
end
puts f(f(3),f(3),f(3))
# => 27

```

If you do not assign any second or third arguments, then `b=3` and `c=3` automatically. One can shorten this further:

```
def f(a,b=a,c=a)
  return a+b+c
end
puts f(f(3))
# => 27

```

Note however that you'll need to give it at least one variable, the first one, and I'm not quite sure how you can avoid assigning a value to `b` while assigning a value to `c`.

---

See here for more argument methods.
> 1 votes

# Answer
The `<=>` (spaceship) operator compares two expressions and returns -1, 0, or 1. Applies to anything that can be compared with `<`, `>`, and `==`.

Some example uses:

`x<=>0` is equivalent to the sign function.

`x.*x<=>0` is the absolute value of `x`.
> 1 votes

# Answer
Quick way to check if all items in a Ruby array are unique lists various ways to check whether everything in an array is unique. Unfortunately, none of them are methods that I can send to a receiver, I need to have my array on both sides of an operator. Lame!

Fortunately, `uniq!` returns `nil` if no changes are made, and returns the modified array if changes are made, meaning that it can be placed at the end of a pipeline to check for uniqueness;

`x.method1.method2.method3.uniq! ? "not unique" : "everything is unique!"`

Various other shouty methods have similar behaviour - returning the modified array if changes are made and `nil` if no changes are made.
> 0 votes

---
Tags: code-golf, tips, ruby
---


title: Concatenation Coincidence

text:
# Question
Title: Concatenation Coincidence
This challenge (and test cases) are inspired by the work of Project Euler users amagri, Cees.Duivenvoorde, and oozk, and Project Euler Problem 751. (And no, this isn't on OEIS). Sandbox

A non-decreasing sequence of integers \\$a\_n\\$ can be generated from any positive real value \\$\theta\\$ by the following procedure:

$$ \newcommand{\flr}\[1\]{\left\lfloor #1 \right\rfloor} \begin{align} b\_n & = \begin{cases} \theta, & n = 1 \\ \flr {b\_{n-1}} (b\_{n-1} - \flr{b\_{n-1}} + 1), & n \ge 2 \end{cases} \\ a\_n & = \flr{b\_n} \end{align} $$

Where \\$\flr x\\$ is the floor function.

For example, \\$\theta=2.956938891377988...\\$ generates the Fibonacci sequence: 2, 3, 5, 8, 13, 21, 34, 55, 89, ...

The *concatenation* of a sequence of positive integers \\$a\_n\\$ is a real value denoted \\$τ\\$ constructed by concatenating the elements of the sequence after the decimal point, starting at \\$a\_1\\$: $$\tau = a\_1.a\_2a\_3a\_4...$$

For example, the Fibonacci sequence constructed from \\$\theta=2.956938891377988...\\$ yields the concatenation \\$τ=2.3581321345589...\\$ Clearly, \\$τ ≠ \theta\\$ for this value of \\$\theta\\$.

We call a positive real number \\$\theta\\$ **coincidental** if \\$\theta = τ\\$ as generated above.

# Challenge

Given a natural number \\$k \> 0\\$ as input, you must output the number of coincidental numbers \\$\theta\\$ such that \\$k = \flr \theta\\$.

# Test Cases

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

```

# Answer
> 4 votes
# 05AB1E, 33 bytes

```
žhтã'.ì«ʒтsλ£Dï©->®*}ïć'.«šJyÅ?}g

```

Brute-force, so extremely slow. The program above validates all real values \\$\theta\\$ in the range \\$\[input,input+1)\\$ in increments of \\$10^{-100}\\$. Replacing the two `т` above with `4` and `5` respectively (to make the increments of size \\$10^{-4}\\$) at least gives outputs, although does still fail for some of the test cases unfortunately:
Try it online.

<sup>: the failing test cases when we use `4` & `5` are: \\$k=21\\$ (requires at least `9` & `6`); \\$k=29\\$ (requires at least `5` & `4`); \\$k=33\\$ (requires at least `5` & `4`); \\$k=36\\$ (requires at least `6` & `4`); \\$k=37\\$ (requires at least `5` & `4`); \\$k=39\\$ (requires at least `5` & `4`); \\$k=40\\$ (requires at least `5` & `4`); \\$k=43\\$ (requires at least `7` & `5`); \\$k=44\\$ (requires at least `5` & `4`); and \\$k=49\\$ (requires at least `5` & `4`).</sup>

**Explanation:**

```
žh                     # Push builtin 0123456789
  тã                   # Cartesian power of 100: create all possible strings of size 100
                       # using these digits
    '.ì               '# Prepend a "." in front of each
       «               # Merge each to the (implicit) input-integer
                       # (we now have a list of decimal values in the range
                       # [input,input+1) in increments of 1e-100)
        ʒ              # Filter this list of real values `θ` by:
           λ           #  Start a recursive environment,
         т  £          #  to output the first 100 values
          s            #  Where a(0)=`θ`
                       #  and where every following a(n) is calculated as follows:
                       #   (Implicitly push a(n-1))
             D         #   Duplicate this a(n-1)
              ï        #   Floor it
               ©       #   Store this floored a(n-1) in variable `®` (without popping)
                -      #   Subtract it from a(n-1)
                 >     #   Increase it by 1
                  ®*   #   Multiply it by `®`
           }ï          #  After the recursive method: floor all values in the list
             ć         #  Extract the head (the floored value we started with; a.k.a. the
                       #  input); pop and push remainder-list and first item separated to
                       #  the stack
              '.«     '#  Append a "."
                 š     #  Prepend it back to the list
                  J    #  Join this list together to a string
                   yÅ? #  Check if it starts with the current `θ` as prefix
        }g             # After the filter: pop and push the length
                       # (which is output implicitly as result)

```

---
Tags: code-golf, sequence, number-theory
---


# Question
Title: Remove duplicates from list and order it by count? (python 3)
How do I remove all duplicates from list and order it based on count?

```
s = ["foo", "this", "lem", "foo", "lem"]
s = ["foo", "ebh", "wosv", "wosv", "ebh", "4whcu"]
#should return
>>> ["foo", "lem", "this"]
>>> ["ebh", "wosv", "foo", "4whcu"]

```

**Rules:**

* Must be shorter than the below code in terms of byte size.
* Order must be based on the count of in descending order.
* If there are two strings with the same count, the first appearance comes first
* All duplicates must be removed, only one of each string should be in the final list

I currently have

```
list({}.fromkeys(sorted(s,key=lambda y:-s.count(y))))

```

I've noticed answers like `set` but that arbitrarily changes the order, which I do not want.

**Edit:** Sorry for the poor quality before. I had whipped this right before I slept and I was quite tired. This is not for StackOverflow because I'm trying to golf/shorten the size of this code as much as possible. I've tried looking for answers but I haven't been able to find anything.

# Answer
# 44 bytes

```
sorted({}.fromkeys(s),key=s.count,reverse=1)

```

Try it online!

An improvement to the below, replacing the key with a built-in rather than a `lambda`, and using `reverse` to swap the comparisons. We'd like to do `[::-1]` on the final result instead, but that doesn't do the right stable tiebreaks.

We could also use `dict(zip(s,s))` in place of `{}.fromkeys(s)` for the same length.

---

# 47 bytes

```
sorted({}.fromkeys(s),key=lambda y:-s.count(y))

```

Try it online!

A simple transposition of your code, moving your `{}.fromkeys` de-duplication trick before the sorting. Since sorting converts to a list, extracting the keys from a dictionary, this saves the `list()` call of the original.

For ease of reference, the original code is:

**53 bytes**

```
list({}.fromkeys(sorted(s,key=lambda y:-s.count(y))))

```

Try it online!
> 4 votes

# Answer
**APL, 11 chars**

`∪⌷⍨∘⊂∘⍒⊢∘≢⌸`

`⊢∘≢⌸` right arg: number of apperance of each element, in order of first appearance

left arg: unique elements, in order of first appearance\`

`⌷⍨∘⊂∘⍒`  sorts elements of the left arg based on the grade-down of the right arg\`

Try it online: https://tio.run/##SyzI0U2pTMzJT///v9jwUdsE9bT8fHUF9ZKMzGIglZOaCyQhQiA2V7ERQk1qUgaQLM8vLkNQEDGT8ozkUnUurjSg4kcdqx71bH/Uu@JRx4xHXU0gsnfSo65FIEbnokc9O7i4HvVNBSpMUyg2RDCN/v8HAA
> 0 votes

---
Tags: code-golf, array, tips, counting, python
---


title: Find the k-th order summary of a number

text:
# Question
Title: Find the k-th order summary of a number
### Background

The summary of a non-negative integer \\$n\\$ is the concatenation of all digits that appear in \\$n\\$ in increasing order, with each digit being preceded by the number of times it appears in \\$n\\$.

Some Examples:

```
n            -> summary(n)
1221         -> 2122 (2 ones, 2 twos)
1212         -> 2122 (2 ones, 2 twos)
912334       -> 1112231419 (1 one, 1 two, 2 threes, 1 four, 1 nine)
888888888888 -> 128 (12 eights)

```

The \\$k\\$-th order summary is result repeatedly applying the summary operation on a number \\$k\\$ times (i.e. \\$2\\$nd order summary of \\$n\\$ is `summary(summary(n))`, \\$3\\$rd order summary of \\$n\\$ is `summary(summary(summary(n)))`, etc.).

**Note:** The \\$0\\$th order summary of a number is itself

### Task

Write a program/function that outputs the \\$k\\$-th order summary of a non-negative integer \\$n\\$.

### Scoring

This is so shortest bytes wins

### Sample Testcases

```
n, k             -> answer
0, 1             -> 10
1, 10            -> 41122314
1221, 0          -> 1221
1221, 1          -> 2122
1212, 1          -> 2122
912334, 1        -> 1112231419
912334, 3        -> 412213141519
21322314, 1      -> 21322314
21322314, 123    -> 21322314
21322314, 2222   -> 21322314
888888888888, 1  -> 128
888888888888, 2  -> 111218
1888888888888, 1 -> 11128

```

---

*Inspired by A005151*

# Answer
# Proton, 67 bytes

```
f=(n,k)=>k?f("".join(str(n.count(x))+x for x:sorted(set(n))),k-1):n

```

Try it online!

# Python 3, 78 bytes

```
f=lambda n,k:k and f("".join(str(n.count(x))+x for x in sorted({*n})),k-1)or n

```

Try it online!

-7 bytes thanks to Mukundan314
> 5 votes

# Answer
# Jelly, 8 bytes

```
ṢŒrUFVµ¡

```

Try it online!

Credit to hyper-neutrino for the `µ` trick, and for telling me I was wrong :P

Full program. Takes `n` then `k` on the command line

## How it works

```
ṢŒrUFVµ¡ - Main link. Takes n on the left, k on the right
      µ  - Last links as a monadic chain f(n):
Ṣ        -   Sort the digits of n
 Œr      -   Run length encode
   UF    -   Reverse each and flatten
     V   -   Eval as a single number
       ¡ - Iterate f(n) k times

```
> 5 votes

# Answer
# Vyxal, 7 bytes

```
(søeRf∑

```

Try it Online!

```
(       # k times...
 s      # Sort
  øe    # Run length encode
    R   # Reverse each
     f  # Flatten
      ∑ # Sum

```
> 5 votes

# Answer
# Wolfram Language (Mathematica), 55 bytes

```
ToString@#2<>#&@@@Sort@Tally@Characters@#<>""&~Nest~##&

```

Try it online!

Input `["n", k]`.
> 5 votes

# Answer
# JavaScript (ES6), 73 bytes

Expects `(k)(n)`, where `n` is given as a string. Returns a string.

```
k=>g=n=>k--?g([...n].sort().join``.replace(/(.)\1*/g,s=>s.length+s[0])):n

```

Try it online!

### Commented

```
k =>                 // outer function taking k
g = n =>             // inner recursive function taking n as a string
  k-- ?              // decrement k; if it was not 0:
    g(               //   do a recursive call:
      [...n]         //     split n into a list of digits
      .sort()        //     sort this list in ascending order
      .join``        //     join the digits again
      .replace(      //     replace ...
        /(.)\1*/g,   //       ... runs of consecutive identical digits ...
        s =>         //       ... with:
          s.length + //         the number of occurrences
          s[0]       //         followed by the digit
      )              //     end of replace()
    )                //   end of recursive call
  :                  // else:
    n                //   we're done: return n

```
> 4 votes

# Answer
# Husk, 15 bytes

```
d!¡oṁoṁd§eL←kDd

```

Try it online!

Order is taken 1-indexed.

## Explanation

```
d!¡oṁoṁd§eL←kDd
              d digits
  ¡             apply the following repeatedly and collect results:
            kD   group digits into lists
    ṁ            map each list and join:
        §e        two element list with:
          L        length
           ←       first element
     oṁd          convert each to individual digits
 !              index into that using order
d               convert back to integer.

```
> 3 votes

# Answer
# , 94 bytes

Or **\>=4.1, 87 bytes** by replacing the word `function` with `\`.

```
function(n,k){while(k<-k-1)n=Reduce(paste0,c(rbind(r<-table(el(strsplit(n,""))),names(r))));n}

```

Try it online!

Expects `n` as a string and `k` 1-indexed. Outputs a string.

Creates `table` of digits and interleaves resulting values (counts) with their names (digits) using this trick from SO.

The rest is just string manipulation which is quite cumbersome in R.

---

Recursive approach results in the same byte-count:

### , 94 bytes

Or **\>=4.1, 87 bytes** by replacing the word `function` with `\`.

```
f=function(n,k)"if"(k,f(Reduce(paste0,c(rbind(r<-table(el(strsplit(n,""))),names(r)))),k-1),n)

```

Try it online!

Here `k` is 0-indexed.
> 2 votes

# Answer
# Retina, 25 bytes

```
1A`
"$+"{O`.
(.)\1*
$.&$1

```

Try it online! Takes input in the order `k, n`. No test suite due to the program's use of history. Explanation:

```
1A`

```

Delete `k` from the input.

```
"$+"{`

```

Retrieve `k` from the history and repeat the rest of the program `k` times.

```
O`.

```

Sort the digits in ascending order.

```
(.)\1*
$.&$1

```

Precede each distinct digit by its count.

The best I could do in # Retina 0.8.2 is 45 bytes:

```
,\d+
$*_
{O`.(?=.*_)
(\d)\1*(?=.*_)
$.&$1
_$

```

Try it online! Link includes test cases. Explanation:

```
,\d+
$*_

```

Convert `k` to unary, using `_` because they sort after digits, saving a byte.

```
{`

```

Repeat (until `k` is zero, at which point the loop converges).

```
O`.(?=.*_)

```

If `k` is not zero, sort the digits in ascending order. (If `k>1`, `k` is also sorted, but it always sorts after digits.)

```
(\d)\1*(?=.*_)
$.&$1

```

If `k` is not zero, precede each distinct digit by its count.

```
_$

```

If `k` is not zero, then decrement `k`.
> 2 votes

# Answer
# Ruby, ~~74~~ 66 bytes

```
->n,k{k.times{a=n.chars
n=(a|a).sort.map{|d|[a.count(d),d]}*''}
n}

```

Try it online!

* Thanks to @ovs for actually golfing thus saving 8 Bytes!
.uniq =\> a|a and join by \*'' instead of appending values
* takes *n* as string, *k* as int
* reconstruct *n* by appending each (count,digit) *k* times
* uses a=n.split n='' instead of a,n=n.chars,'' which is the same byte count
> 2 votes

# Answer
# Raku, 44 bytes

```
{($^a,{[R~] .comb.Bag{~9...0}:kv}...*)[$^k]}

```

Try it online!

* `($^a, { ... } ... *)[$^k]` selects the `$^k`-th element of the infinite sequence starting with `$^a`, where `$^a` and `$^k` are the first and second arguments to the function, respectively. The bracketed expression is an anonymous function that generates each summary number from the previous one, passed as `$_`.
* `.comb` splits the number `$_` into its (string) digits.
* `.Bag` assembles those digits into a Bag--a set with multiplicity.
* `{~9...0}` slices into that bag with the digits from 9 to 0. The leading `~` stringifies the `9` and gives us a sequence of strings, not numbers. (The Bag knows the difference.)
* The `:kv` adverb on the slicing subscript `{...}` does two things: it returns a flat list of key-value pairs (ie, each digit along with its multiplicity, in order from 9 to 0), and it omits elements from the slice which don't exist in the Bag.
* `[R~]` reduces that list with the operator `R~`, which is the `R`eversed string concatenation operator `~`. That gives us the required summary of the previous number in the series.
> 2 votes

# Answer
# 05AB1E, ~~9~~ ~~8~~ 7 bytes

```
F{Åγøí˜J

```

-1 byte thanks to a tip of *@ovs*

Inputs in the order \\$k,n\\$. Outputs as a digit-list (unless \\$k=0\\$, in which case it outputs \\$n\\$ as is - although we could take input \\$n\\$ as digit-list as well to be consistent).

Try it online or verify all test cases.

**Explanation:**

```
F        # Loop the first (implicit) input amount of times:
 {       #  Sort the digits of the current number
         #  (which is the second implicit input-integer in the first iteration)
  Åγ     #  Pop and run-length encode, pushing a list of digits and a list of lengths
         #  separated to the stack
    ø    #  Create pairs of these two lists
     í   #  Reverse each pair
      S  #  Convert the list of integer-pairs to a flattened list of digits
         # (after which the result is output implicitly)

```
> 2 votes

# Answer
# PowerShell Core, 73 bytes

```
param($n,$k)for(;$k--){$n=-join("$n"|% t*y|group|%{$_.Count,$_.Name})}
$n

```

Try it online!

Same byte count using `$ofs`: Try it online!

Takes two integer parameters and returns a string or an integer
> 2 votes

# Answer
# Charcoal, 18 bytes

```
ＦＮ≔⭆Φ⭆χκ№ηκ⁺№ηκκηη

```

Try it online! Link is to verbose version of code. Takes input in the order `k, n`. Explanation:

```
ＦＮ

```

Input `k` and loop that many times.

```
≔⭆Φ⭆χκ№ηκ⁺№ηκκη

```

Filter the characters `0-9` that are present in `n`, prefixing them with their count and joining the result.

```
η

```

Output the final value of `n`.
> 1 votes

# Answer
# C (gcc), <sup>~~112~~ \\$\cdots\\$ ~~123~~</sup> 125 bytes

```
f(n,k){int c[10]={!n},t=n,i=-1,l;for(;t;t/=10)++c[t%10];for(;i++<9;t=l?i+l*10+t*exp10(l=log10(l)+2):t)l=c[i];n=k?f(t,k-1):n;}

```

Try it online!

*Saved ~~a~~ 2 bytes thanks to ceilingcat!!!*
*Added 21 bytes to fix an error kindly pointed out by Arnauld.*
*Saved 8 bytes thanks to att!!!*
*Added 2 bytes to handle \\$n=0\\$.*
> 1 votes

# Answer
# C (gcc), ~~121 125 117~~ 116 bytes

```
E=10,r,c,t,i;g(n,k){for(;k--;n=n?r:E)for(r=i=0;i<E;r=c?r*E*E+c*E+i:r,i++)for(c=0,t=n;t;t/=E)r*=t%E-i||++c%E?:E;r=n;}

```

Try it online!

* Saved 1 thanks to @ceilingcat
* Fixed: now works with n=0 , k\>0 as required.

Try it uint64\_t
> 1 votes

# Answer
# Excel (Insider Beta), 108 bytes

```
=LAMBDA(q,k,IF(k,LET(a,f(q,k-1),x,SEQUENCE(10)-1,y,LEN(a)-LEN(SUBSTITUTE(a,x,"")),CONCAT(FILTER(y&x,y))),q))

```

Link to Spreadsheet

Set name f equal to the above formula. Spreadsheet requires Insider Beta version of Excel to work currently because of LAMBDA.

### Explanation

```
=LAMBDA(q,k,
IF(k,                                      # if k <> 0 then
     LET(a,f(q,k-1),                       #   a = f(q,k-1)
         x,SEQUENCE(10)-1,                 #   x = [0..9]
         y,LEN(a)-LEN(SUBSTITUTE(a,x,"")), #   y = count of each x in a
         CONCAT(FILTER(y&x,y)))            #   concatenate y&x if y > 0
     ,q))                                  # else q

```
> 1 votes

# Answer
# Core Maude, 354 bytes

```
mod R is pr LIST{Nat}+ CONVERSION . ops k s : Nat Nat ~> Nat . op f : Nat
~> String . var N K : Nat . var X Y :[Nat]. eq k(N,0)= N . eq k(N,s K)=
k(rat(f(s(N,0 0 0 0 0 0 0 0 0 0)),10),K). eq s(0,X)= X . ceq s(N,X K Y)=
s(N quo 10,X(s K)Y)if size(X)= N rem 10[owise]. eq f(nil)= "" . eq f(X 0)=
f(X). eq f(X s N)= f(X)+ string(10 * s N + size(X),10). endm

```

The result is obtained by reducing the `k` function with \\$n\\$ and \\$k\\$.

### Example Session

```
Maude> red k(1, 10) .  --- Expected: 41122314
result NzNat: 41122314
Maude> red k(1221, 0) .  --- Expected: 1221
result NzNat: 1221
Maude> red k(1221, 1) .  --- Expected: 2122
result NzNat: 2122
Maude> red k(1212, 1) .  --- Expected: 2122
result NzNat: 2122
Maude> red k(912334, 1) .  --- Expected: 1112231419
result NzNat: 1112231419
Maude> red k(912334, 3) .  --- Expected: 412213141519
result NzNat: 412213141519
Maude> red k(21322314, 1) .  --- Expected: 21322314
result NzNat: 21322314
Maude> red k(21322314, 123) .  --- Expected: 21322314
result NzNat: 21322314
Maude> red k(21322314, 2222) .  --- Expected: 21322314
result NzNat: 21322314
Maude> red k(888888888888, 1) .  --- Expected: 128
result NzNat: 128
Maude> red k(888888888888, 2) .  --- Expected: 111218
result NzNat: 111218
Maude> red k(1888888888888, 1) .  --- Expected: 11128
result NzNat: 11128

```

### Ungolfed

```
mod R is
    pr LIST{Nat} + CONVERSION .

    ops k s : Nat Nat ~> Nat .
    op f : Nat ~> String .

    var N K : Nat .
    var X Y : [Nat] .

    eq k(N, 0) = N .
    eq k(N, s K) = k(rat(f(s(N, 0 0 0 0 0 0 0 0 0 0)), 10), K) .

    eq s(0, X) = X .
    ceq s(N, X K Y) = s(N quo 10, X (s K) Y) if size(X) = N rem 10 [owise] .

    eq f(nil) = "" .
    eq f(X 0) = f(X) .
    eq f(X s N) = f(X) + string(10 * s N + size(X), 10) .
endm

```

Maude doesn't have logarithms for integers, only for floating-point numbers, so the only good way I could find to "concatenate" integers is to convert them to strings, concatenate, and convert back.

# Core Maude + Cheating, 331 bytes

```
mod R is pr CONVERSION . ops k s : Nat Nat -> Nat . op f : Nat Nat -> String
. var N K S : Nat . eq k(N,0)= N . eq k(N,s K)= k(rat(f(0,s(N,0)),10),K). eq
s(0,S)= S . eq s(N,S)= s(N quo 10,S + 512 ^(N rem 10))[owise]. eq f(10,S)=
"" . eq f(N,S)= if(S & 511)> 0 then string(10 *(S & 511)+ N,10)else "" fi +
f(s N,S >> 9)[owise]. endm

```

### Ungolfed

```
mod R is
    pr CONVERSION .

    ops k s : Nat Nat -> Nat .
    op f : Nat Nat -> String .

    var N K S : Nat .

    eq k(N, 0) = N .
    eq k(N, s K) = k(rat(f(0, s(N, 0)), 10), K) .

    eq s(0, S) = S .
    eq s(N, S) = s(N quo 10, S + 512 ^ (N rem 10)) [owise] .

    eq f(10, S) = "" .
    eq f(N, S) = if (S & 511) > 0 then string(10 * (S & 511) + N, 10) else "" fi + f(s N, S >> 9) [owise] .
endm

```

If we make the small assumption that no digit occurs more than 511 times, we can avoid having to import `LIST` and keep the intermediate summary packed in an integer with 9 bits per digit tracked. The bit size is sort of arbitrary since Maude has unbounded integers, so I picked 9 bits to avoid paying 4 extra bytes for `10` and `1024`.
> 1 votes

# Answer
# Perl 5, 72 bytes

```
sub g{($c,$d)=@_;$c=join"",map{(@e=$c=~/$_/g)?@e.$_:""}0..9for 1..$d;$c}

```

Try it online!

Ungolfed:

```
sub g{
    ($c, $d) = @_;
    for (1 .. $d) {
        $c = join('', map {(@e = $c =~ /$_/g) ? @e . $_ : ""} 0 .. 9);
    }
    $c;
}

```
> 1 votes

# Answer
# Lua, 112 bytes

Chunk function (can be executed using `loadstring(code)("42",0)`). Expects `n` as a string and `k` as either number or string. Doesn't play well with TIO; replace the `return n` with `print(n)` to test.

```
n,k=...for _=1,k do m=""for j=1,9 do c=""..#n:gsub("[^"..j.."]","")m=m..(c>"0"and c..j or"")end n=m end return n

```

Try it online!
> 0 votes

---
Tags: code-golf, math, number
---


title: A rolling drop gathers all pearls?

text:
# Question
Title: A rolling drop gathers all pearls?
Quell is a single-player grid-based puzzle game. Pearls are scattered across a 2D map and the aim is to collect them all by rolling a drop of water over them. For this challenge we will only consider basic maps containing the drop, pearls, walls, and empty spaces. (The full game includes a variety of additional objects/interactions such as spikes, movable blocks, and teleport rings.) We will also assume that the map is bounded and connected, that is, it is surrounded by walls and a continuous path exists between any two squares.

The drop, initially stationary, may be rolled up, down, left, or right. A distinctive feature of Quell is that once you start the drop rolling, it rolls as far as possible in that direction, stopping *only* when it hits a wall. Any pearls along the path are collected automatically. Your inability to stop the drop or change its direction until it hits a wall has two consequences:

* There may be empty spaces on the map that the drop can never pass through or pearls that can never be collected (the latter never happens in the real game).
* The order in which pearls are collected matters on some maps because certain moves cut the drop off from areas that were previously accessible.

For example, consider the following map, where `O` = drop, `@` = pearl, `#` = wall, `.` = empty space:

```
#######
#@.#.@#
#..#..#
#O....#
#..####
#@.#
####

```

We see that the move sequence `RULDLUD` (among others) collects all three pearls:

```
#######      #######      #######      #######      #######      #######      #######      #######
#@.#.@#      #@.#.@#      #@.#.O#      #@.#O.#      #@.#..#      #@.#..#      #O.#..#      #..#..#
#..#..#  R   #..#..#  U   #..#..#  L   #..#..#  D   #..#..#  L   #..#..#  U   #..#..#  D   #..#..#
#O....#  =>  #....O#  =>  #.....#  =>  #.....#  =>  #...O.#  =>  #O....#  =>  #.....#  =>  #.....#
#..####      #..####      #..####      #..####      #..####      #..####      #..####      #..####
#@.#         #@.#         #@.#         #@.#         #@.#         #@.#         #@.#         #O.#
####         ####         ####         ####         ####         ####         ####         ####

```

However, if the first move is `U` or `D` the drop will become trapped in the 'alley' on the left side and then unable to collect the pearl in the top-right corner.

### Task

Your goal in this challenge is to decide whether all pearls in a given map can be collected. Your program/function may take the map in any sensible format (e.g. multiline string, list of lines, matrix), which extends to replacing `O@#.` with distinct characters/digits of your choice. To indicate whether the map is solvable or not, output/return either

* any truthy/falsy value (swapping allowed) according to your language's convention, or
* one of two distinct, fixed values of your choice.

For reference, a polynomial-time algorithm for solving this problem is presented here. You are not required to implement this algorithm (though of course you may).

### Test cases

#### Solvable

```
 #########
##....@..#
#.@.O...@#
##....@#.#
 #########
(possible solution: RULDR)

 ######
##@...##
#@.....#
##.....#
 ###...#
   #@O.#
   #####
(possible solution: LULDRUL)

#######
#@.#.@#
#..#..#
#O....#
#..####
#@.#
####
(possible solution: RULDLUD)

###############
#..#..........#
#....@.O.@....#
#......@......#
#.@#########@.#
#...@.@.@.@...#
#..........#..#
###############
(possible solution: RLURDRULRDLULDR)

#############
#O........#@#
#.#.........#
#.@....@#...#
#...#@......#
#...@#......#
#........#..#
#..#........#
#..........##
##@........@#
#############
(possible solution: DRULDRULRUDLUDRLUR)

```

#### Unsolvable

```
######
#O...##
#.....#
#..@..#
#@...@#
#######

   #####
   #.@.#
####...####
#@...O...@#
####...####
   #.@.#
   #####

#######
#@.#.@#
#..#..#
#O....#
#..#..#
#@.#.@#
#######

###############
#..#..........#
#....@.O.@....#
#....#.@......#
#.@#########@.#
#...@.@.@.@...#
#..........#..#
###############

#############
#O........#@#
#.#.........#
#.@.#..@#...#
#...#@......#
#...@#......#
#........#..#
#..#........#
#..........##
##@........@#
#############

```

# Answer
> 3 votes
# Python 2, ~~247~~ ~~237~~ ~~229~~ 217 bytes

Thanks to Dingus for removing 12 bytes of code residue.

A simple breadth first search, definitely not in polynomial time.

```
q=[`input()`]
s={0}
r=1
for b in q:
 r&='4'in b;s|={b}
 for v,w in(0,1),(0,-1),(1,0),(-1,0):
	n=eval(b);f=b.find;y,x=divmod(f('3')-1,f(']')+2);x/=3
	while~-n[y][x]:n[y][x]=2;x+=v;y+=w
	n[y-w][x-v]=3;q+={`n`}-s
print r

```

Try it online! or Try an ungolfed version

Prints `0` if the map is solvable and `1` otherwise. Takes input as a list of list of integer with the following mapping:

```
OUTSIDE = 0
WALL = 1
INSIDE = 2
DROPLET = 3
PEARL = 4

```

# Answer
> 3 votes
# Charcoal, 76 bytes

```
⊞υυＷＳ⊞υ⁺⊟υ⪪ι¹ＦυＦ⟦Ｌθ¹±¹±Ｌθ⟧«≔Ｅιλη≔⌕ηOζＷ‹#§η⁺ζκ«§≔ηζ.≧⁺κζ§≔ηζO»¿¬№υη⊞υη»⊙υ¬№ι@

```

Try it online! Link is to verbose version of code. Takes input as a rectangular newline-terminated list of strings and outputs a Charcoal boolean, i.e. `-` if all the pearls can be collected, nothing if not. Explanation:

```
⊞υυＷＳ⊞υ⁺⊟υ⪪ι¹

```

Read in the list and convert it into a character array for convenience. Start a breadth first search from the initial position.

```
ＦυＦ⟦Ｌθ¹±¹±Ｌθ⟧«

```

Loop over all positions and directions.

```
≔Ｅιλη

```

Clone the current position.

```
≔⌕ηOζ

```

Get the index of the drop.

```
Ｗ‹#§η⁺ζκ«

```

While it's not hitting a wall...

```
§≔ηζ.≧⁺κζ§≔ηζO»

```

... move the drop one square in the current direction.

```
¿¬№υη⊞υη

```

If this results in a new position then save it to the search list.

```
»⊙υ¬№ι@

```

Output whether any positions have no pearls left.

---
Tags: code-golf, decision-problem, grid, game
---


title: Almost Illegal Strings, Mark II (Cops)

text:
# Question
Title: Almost Illegal Strings, Mark II (Cops)
> Edit 2020-11-06: This challenge has been edited with new provisions to encourage participation. The edits have been **bolded** for emphasis.

Welcome to a cops and robbers version of Find an Illegal String.

An *illegal string* is "a string of characters that cannot appear in any legal program in your programming language of choice" (from the linked post).

For this challenge, we will define an *almost illegal string*, which is a string of characters that is very hard, but not impossible, to include in a valid program.

## The Cops' Challenge

* Choose a programming language, and choose an 'almost illegal string' - this is a sequence of characters that is very hard to include in a valid program without causing it to error.
* Write a program that contains the 'almost illegal string' as a contiguous substring that does not error.
* **Optionally, you may also specify a set of banned characters. These are characters that do not appear in your program, except in the 'almost illegal string'. (Therefore: banned characters can still appear inside the almost illegal string)**

That's it! You will reveal the programming language, the almost illegal string, **and the set of banned characters**, and challenge robbers to write a program that contains the illegal string but does not error.

For the purposes of this challenge, we define 'does not error' as:

* Your program exits with exit code 0.
* Your program does not print any output to standard error.
* Your program may print anything to standard output, if you wish, but it does not have to.
* If (and only if) your language *always* prints output to standard error regardless of the program, such as debugging or timing information, you may instead design a program that *only* outputs this to standard error. If you are making use of this clause, mention it in your cop post.

## The Robbers' Challenge

Find an uncracked answer. Write a program in the language specified that contains as a contiguous substring the almost illegal string specified and does not error. **Your program may not use any character in the set of banned characters, unless it is part of the almost illegal string.** Your program does not need to be exactly what the cop had in mind. Post an answer to the robber's thread and leave a comment on the cops' answer to crack it.

## Clarifications

* If your cop answer requires a specific operating environment or version, you must specify this in your answer.
* The cop's almost illegal string that they reveal is to be interpreted with respect to the standard encoding for the language's interpreter. For most programs, this will be UTF8.
* Solutions should not take any input (via standard input, argv, or any other source) and may assume no such input is given.
* Solutions must terminate in a finite amount of time. This means entering an infinite loop and getting killed by TIO's 60 second timeout is not a valid solution.
* Cops should make sure if their almost illegal string contains leading or trailing newlines that it is very clear it does so. Robbers should carefully note any leading or trailing newlines in a cop's post.

## Formatting hint

The clearest way to include leading or trailing newlines is to use the backtick syntax for your post:

```

foo

```

Renders as:

```

foo

```

To remove any ambiguity, *explicitly mention* the leading/trailing newlines in your post.

## Scoring

After 10 days without a crack, a cop can mark their answer as *safe* and reveal their solution. Once the cop has revealed their solution, it is no longer able to be cracked.

Cops are scored based on the length (in bytes) of their almost illegal string in their safe answer(s), with lower being better.

Robbers are scored by the number of answers they crack, with higher being better.

---

## Example

### Python 3, 5 bytes

Illegal string:

```
"'1/0

```

Banned characters:

```
#'

```

### Python 3, cracks example's answer

Program:

```
""" "'1/0 """

```

The idea is that we can just comment out the string, since `"` is not banned.

# Answer
> 9 votes
# Python 2, 5 bytes (cracked by tsh)

```
bin()

```

Try it online!

Banned: all characters *except* alphanumeric characters

```
abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789

```

So, you're allowed the above characters and nothing else (in addition to `bin()` itself).

(This idea isn't mine, I remember it from an earlier challenge, but I don't remember who deserves credit for it.)

# Answer
> 6 votes
# Haskell, 3 bytes

```

#"

```

(begins with a newline)

Disallowed charachters: `-`

# Answer
> 5 votes
# Jelly, 4 bytes, cracked by HyperNeutrino

```

«{

```

Try it online!

You may not use newlines. Any other character/byte is fair game

---

My intended solution was any of the banned characters here aside from . Each of these characters cause the parsing of the link to break, meaning everything before them gets ignored:

Try it online!

# Answer
> 5 votes
# Python 3, 7 bytes, cracked by @EasyasPi

Still not the intended answer, so I'm just revealing it. Scroll to the bottom to see it.

```

raise

```

### Banned characters

```
`TAB` "'(),.=[\]_{|}
```

Non-ASCII characters are all banned as well. Try it online or validate it online!

## Some cracks that work without the banned chars

```
'''
raise'''

```

```
"""
raise"""

```

```

raise SystemExit

```

```

raise`TAB`SystemExit # originally posted by EasyasPi here, he found yet another loophole
```

```

raise\
SystemExit

```

```

raiser=3 # originally posted by EasyasPi on v1 of this challenge

```

# Intended Answer

> ```
> #coding:U7
> quit+ACgAKQ-
> raise
>
>
> ```

This works because

> the magic comment at the top sets the file encoding to UTF-7

and

> in UTF-7, characters can be encoded by first converting them to their UTF-16 binary representations, and concatenating them if there are multiple characters to be encoded. Here, we want to call `quit`, so we need to convert `()`. This becomes `0000 0000 0010 1000 0000 0000 0010 1001`. Next, we regroup them into groups of 6, to get `000000 000010 100000 000000 001010 01`, and pad the last group with trailing zeros (if necessary). In this case, we get `000000 000010 100000 000000 001010 010000`. Finally, we convert these to the corresponding Base64 characters (table here), getting `ACgAKQ`, prepend a `+`, and append a `-`.

So,

> `()` in UTF-7 is `+ACgAKQ-`. We use this fact to bypass the banned `()` and call `quit` anyways, by replacing `()` with `+ACgAKQ-`. This exits the program before it can throw any errors.

# Answer
> 3 votes
# Jelly, 4 bytes, cracked by Unrelated String

```

«{

```

Try it online!

I'm giving Jelly another go, but with slightly more restrictions. You may not use `quƁƘȤ(ƈɦƙɱɲƥʠʂȥ` (the unimplemented commands in Jelly),  or newlines, as these make it *far* too trivial to crack (thanks to HyperNeutrino for showing that)

---

Neither HyperNeutrino's crack in the comments, nor Unrelated String's crack was my intended solution. Putting a `Œ` (or any of `ÐÆØœæ`) with nothing after it at the end causes the same behaviour as any of `quƁƘȤ(ƈɦƙɱɲƥʠʂȥ`, as they always expect to have a character after them. Without any character, they cause a break in the program chain, meaning that everything before them is ignored:

Try it online!

# Answer
> 3 votes
# , 2 bytes, cracked by Dominic van Essen

```
'"

```

Try it online!

Banned characters (newlines are banned):

```
'"`#\qel

```

This bans the obvious cracks I can think of, but I wouldn't be surprised if you come up with a crack very different to what I intend.

Dominic van Essen cracked a first version of this challenge, and then a second; then Giuseppe cracked a third version. I have added `qel` and newlines to the list of banned character to sidestep their cracks.

---

The solution I had in mind was

```
assign(intToUtf8(c(37,39,34,37)), c); 1 %'"% 2

```

Try it online!

The assign call creates a new binary operator, `%'"%`; it is equivalent to `"%'"%" <- c`. In R, you can create new operators of the form `%x%` where `x` is *any* string: `%}%`, `%$@%` and `%µ£$%` are all valid operator names. Here, the new operator is equal to the concatenation function `c` and so the output is the vector `1 2`.

Dominic's crack doesn't define the operator; he simply buried it in a `try` call, which is also valid R code.

The trick used here means that any future attempt at an almost illegal string will probably have to ban the `%` character.

# Answer
> 3 votes
# Desmos, 9 bytes,

```
sort(3,2

```

Banned characters: New Lines

```

```

I'm hoping that most people are not familiar with Desmos here, so people wouldn't know what to try.

Note:

An expression in Desmos would be considered an error if it shows a "danger sign" next to the expression, like this:

# Answer
> 3 votes
# Rust, 5 Bytes (Safe)

```
:! =1

```

Banned Characters:

```
|!/"'

```

A nightly compiler is used, you may pass any flags to rustc if you like.

---

A crack by @EasyasPi does work (and is brilliant), but I think because the question says "you must write a program that contains ...", if your code is not designed to run, it isn't a program :)

## The intended solution

The idea is to create a local variable that has the never type, call some functions on the integer 1 such that it becomes the never type.

However, with `!` as a banned character, we can't simply put the `#![feature(never_type)]` attribute on the top of the program. We must use an unstable rustc flag that allows us to inject crate-level attributes. The command to compile would be:

```
cargo rustc -- -Z crate-attr='feature(never_type, core_panic)'

```

Because closures (`|| something`) and the use of the `!` type outside are restricted, we must operate on the integer literal with provided functions. This is where the `core_panic` feature comes in and gives us a nice way to transform a `&str` into `!`. We know the start and the end, we can just put them together:

```
use std::io::stdout;
use core::panicking::panic_str;
use std::borrow::Borrow;

fn main() {
    let a:! =1i8.checked_neg().as_ref().map(ToString::to_string).as_ref().map(Borrow::borrow).map(panic_str).unwrap();
}

```

# Answer
> 3 votes
# Python 3, 10 bytes, cracked by The Fifth Marshal

```

?"""?'''?

```

## Banned characters

Alphanumeric, whitespace, and non-ASCII.

---

> The intended solution makes use of an interesting quirk in the Python parser.

Here's a hint if you want one:

> The hint is that there is no hint. (This isn't a joke. This is actually the hint.)

---

# Intended Answer

> Hexdump:
>
> ```
> 00000000: 2300 0a3f 2222 223f 2727 273f  #..?"""?'''?
> ```

For some reason,

> the Python parser seems to ignore characters following null characters.

So,

> it ignores the newline after the `#␀`, therefore treating the `?"""?'''?` as part of the comment.

Fun fact: This was actually posted on the original Find an Illegal String challenge, but when I found a way to get around it, I decided to post it here.

# Answer
> 3 votes
# Vim, 4 bytes, cracked by tail spark rabbit ear

```
<Esc><Esc>ZQ

```

This one is a bit more difficult than my other Vim one.

### Intended Solution:

> `i<C-o>:<C-r><Esc><Esc>ZQ`

# Answer
> 2 votes
# Julia, 5 bytes, Cracked by Dingus

```
?""":

```

Disallowed charachters: `#`

# Answer
> 2 votes
# Ruby, 17 bytes, cracked by Dingus

```
=end
#{"""'}
=end

```

(no newline at start)

Disallowed charachters: `N`

# Answer
> 2 votes
# Julia, 6 bytes

```
?""":

```

There is a zero width space before the `:`

Disallowed characters: `#`

# Answer
> 2 votes
# Python 3, 13 bytes, Cracked by EasyasPi

```
int(А,В,С)

```

Banned Characters: All ascii characters except `2()~+` and newlines. `'"#=` are banned.

```
 !"#$%&'*,-./013456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}

```

The solution makes use of an odd python 3 feature.

Try it online!

# Answer
> 2 votes
# nasm, 4 bytes, safe

```
[al]

```

Banned characters:

```
;"`'%#

```

## Solution:

> `section` is, as far as I know, the only thing in NASM which accepts an arbitrary string without quotes.
>
> ```
>         section [al]
>         section .text
>         global _start
> _start:
>         mov     eax, 60
>         syscall
> ```
> Try it online!

Stop giving me these assembly ones for free.

# Answer
> 2 votes
# Python 3, 3 bytes, Cracked by user

I can't believe I missed that obvious loophole! I am adding a slightly revised version of my code that should avoid this.

## New Answer, 4 bytes, Cracked by Unrelated String

```
 1=2

```

Note: There is a `space` at the beginning of the code.

Banned characters: All non-ascii characters, quotes, and #.

```
"'#

```

Try it online!

## Old Answer, 3 bytes, Cracked by user:

```
1=2

```

Banned characters: All non-ascii characters, quotes, and #.

```
"'#

```

Try it online!

### My intended solution for both posts:

```
foo : 1=2

```

# Answer
> 2 votes
# Javascript, 7 bytes, cracked by Makonede

```
...void

```

# Javascript, 8 bytes, cracked by Makonede

Note one trailing space

```
...void

```

Banned characters:

* all comments: `//`, `/**/`
* all strings: `""`, ````, `''`
* curlies: `{}`
* brackets: `[]`
* asterisk: `*`
* the letter `w`

Clarifications: My cop answer works in a browser environment, but there are probably solutions in Node too.

# Answer
> 1 votes
# Ruby, 17 bytes

```
=end
#{"""'}
=end

```

Disallowed characters: `N`,`%`

This time I made it a bit harder.

# Answer
> 1 votes
# Ruby, 18 bytes

```
=end
#{/"""'}
=end

```

Disallowed characters: `N`,`%`,`/`

my final variation, hopefully the next solution is the intended one.

# Answer
> 1 votes
# Zsh

```

#include <cstdlib>
#include <iostream>

int main() {
    srand(time(NULL));
    hello();
    return rand() % 2;
}

/*
  main
  a=0
  \
  print "$((1/$a))"
*/

void hello() std::cout << "Hello, World!" << std::endl;

```
* Allowed characters: all printable ASCII *except* `blxy<'`$` (lowercase B, L, X, and Y, single-quote, grave, dollar sign)
* Please note all the leading and trailing whitespace.

Probably not too hard but you may learn a lot about the many - shall we say "quirks" - of zsh.

# Answer
> 1 votes
# Desmos, 2 bytes, cracked by PkmnQ

Substring:

```

\

```

(Note the newline in the beginning)

Banned characters: All alphanumeric characters

```
abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789

```

I'm hoping that most people are not familiar with Desmos here, so people wouldn't know what to try.

Note:

An expression in Desmos would be considered an error if it shows a "danger sign" next to the expression, like this:

# Answer
> 1 votes
# Python 3, 6 bytes, cracked by EasyasPi

@EasyasPi's crack does work (and I'm dumb for letting it work), but I'm not revealing the original solution yet; I've posted a v2 hopefully preventing any loopholes.

```

raise

```

### Banned characters

```
 "'(),.:[\]_{|}

```

Non-ASCII characters are all banned as well. Try it online or validate it online!

## Some cracks that work without the banned chars

```
'''
raise'''

```

```
"""
raise"""

```

```

raise SystemExit

```

```

raise\
SystemExit

```

# Answer
> 1 votes
# Vim, 3 bytes, cracked by tail spark rabbit ear

```
<Esc>ZQ

```

A Vim program doesn't really "error out" per se, but `ZQ` will exit the current file without saving, so it can't be executed in a valid program, thereby making it "illegal".

This is a bit of an easier one, if you know Vim.

### Intended Solution:

> `i<C-v><Esc>ZQ`

# Answer
> 1 votes
# Vyxal, 15 bytes, Cracked by lyxal

```

«Wi«»Wi»`Wi`Wi

```

Try it Online!

No bans, do what you want. Note that silently erroring at compile-time (Nothing appears in the 'output' box) counts as an error - even the empty program outputs 0...

My intended solution was prepending a `[` to just make sure the code isn't run.

# Answer
> 0 votes
# JavaScript (THREE.js 105) (Must include canvas element) ~48 bytes

```

const scene = new THREE.Scene();
scene.add(cube);

```

*Note empty lines* Try it!

Banned Characters: All quote characters

`/`

# Answer
> 0 votes
# Pyth, 32 bytes

```
X$globals()$"imp_print"$mod$

""

```

Banned characters are:

```
$\LMN."

```

Try it online!

# Answer
> 0 votes
# Python 3, 7 bytes

```
"""'''$

```

(Note no starting or trailing newline.)

Disallowed characters:

```
#

```

---
Tags: code-challenge, restricted-source, cops-and-robbers
---